Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python2.6
- ##################################################################
- # A prototype impelementation of a spritesheet management tool #
- ##################################################################
- # Author: Karol Kozub #
- # Description: #
- # This is a very simple prototype. It allows the user to pack or #
- # unpack a single predefined spritesheet. The configuration file #
- # is read from disk and parsed and appropriate images are #
- # displayed. Clicking the UI triggers packing or unpacking of #
- # sprites. #
- # The code was written for fast results and most of it is dirty. #
- # None of this code is expected to be used in the actual tool. #
- ##################################################################
- import sys, pygame, re, os
- from pygame.locals import *
- #
- # The Images class - manipulates the images
- #
- class Images:
- def __init__(self, config):
- self.spr_conf = config.root["spritesheets"][0]
- self.unpacked_images = {}
- if self.are_packed():
- self.packed_image = pygame.image.load(self.spr_conf["name"])
- else:
- for img_conf in self.spr_conf["images"]:
- name = img_conf["name"]
- self.unpacked_images[name] = pygame.image.load(name)
- def toggle_pack(self):
- if self.are_packed():
- self.unpack()
- else:
- self.pack()
- def are_packed(self):
- return self.spr_conf["is_packed"] == "true";
- def unpack(self):
- for img_conf in self.spr_conf["images"]:
- self.unpack_image(img_conf)
- os.remove(self.spr_conf["name"])
- def pack(self):
- w, h = self.calculate_packed_size()
- self.packed_image = pygame.Surface((w, h), SRCALPHA, 32)
- self.packed_image = self.packed_image.convert_alpha()
- for img_conf in self.spr_conf["images"]:
- self.blit_image(self.packed_image, img_conf)
- pygame.image.save(self.packed_image, self.spr_conf["name"])
- for img_conf in self.spr_conf["images"]:
- os.remove(img_conf["name"])
- def calculate_packed_size(self):
- w, h = 0, 0
- for img_conf in self.spr_conf["images"]:
- w = max(w, int(img_conf["x"]) + int(img_conf["width"]))
- h = max(h, int(img_conf["y"]) + int(img_conf["height"]))
- return w, h
- def unpack_image(self, img_conf):
- x, y = int(img_conf["x"]), int(img_conf["y"])
- w, h = int(img_conf["width"]), int(img_conf["height"])
- name = img_conf["name"]
- rect = pygame.Rect(x, y, w, h)
- surf = self.packed_image.subsurface(rect).copy()
- self.unpacked_images[name] = surf
- pygame.image.save(surf, name)
- def blit_image(self, dest, img_conf):
- src = self.unpacked_images[img_conf["name"]]
- xy = (int(img_conf["x"]), int(img_conf["y"]))
- dest.blit(src, xy)
- #
- # The UI class - shows the UI and responds to events
- #
- class UI:
- def __init__(self, config, images):
- self.config = config
- self.images = images
- self.resolution = 390, 240
- def run(self):
- self.screen = pygame.display.set_mode(self.resolution)
- pygame.display.set_caption("Spritesheet management tool prototype")
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- sys.exit()
- if event.type == pygame.MOUSEBUTTONUP:
- self.images.toggle_pack()
- self.config.toggle_pack()
- self.display_images()
- def display_images(self):
- self.screen.fill((128, 128, 128))
- if(self.images.are_packed()):
- self.screen.blit(self.images.packed_image, (1, 1))
- w, h = self.images.packed_image.get_size()
- pygame.draw.rect(self.screen, (255,255,255), (0,0,w+2,h+2), 1)
- else:
- x, y = 1, 1
- for name in self.images.unpacked_images:
- img = self.images.unpacked_images[name]
- w, h = img.get_size()
- self.screen.blit(img, (x, y))
- pygame.draw.rect(self.screen, (255,255,255), (x-1,y-1,w+2,h+2), 1)
- x += 40
- y += 40
- pygame.display.flip()
- #
- # The Config class - reads and modifies the config file
- #
- class Config:
- def __init__(self, filename):
- self.root = {}
- self.filename = filename
- self.parse_file(filename)
- def parse_file(self, filename):
- f = open(filename, 'r')
- while True:
- stype, section = self.read_next_section(f);
- if section == None:
- break
- self.append_section(self.root, stype, section)
- f.close()
- def read_next_section(self, f):
- while True:
- line = f.readline()
- if(line == ""):
- return None, None
- if(self.is_section_start(line)):
- stype = self.read_section_start_type(line)
- return stype, self.read_section(stype, f)
- def read_section(self, stype, f):
- section = {}
- while True:
- line = f.readline()
- if(line == "" or self.is_section_end(line)):
- return section
- elif(self.is_section_start(line)):
- stype = self.read_section_start_type(line)
- subsection = self.read_section(stype, f)
- self.append_section(section, stype, subsection)
- elif(self.is_param_def(line)):
- name, value = self.read_param_def(line)
- section[name] = value
- def is_section_start(self, line):
- return re.match("^[\t ]*\[[^\]]+\]$", line) != None
- def read_section_start_type(self, line):
- match = re.match("^[\t ]*\[([^\]]+)\]$", line)
- return match.group(1)
- def is_section_end(self, line):
- return re.match("^[\t ]*\[/[^\]]+\]$", line) != None
- def is_param_def(self, line):
- return re.match("^[\t ]*[^\t =]+=[a-z0-9/.-]+$", line) != None
- def read_param_def(self, line):
- match = re.match("^[\t ]*([^\t =]+)=([a-z0-9/.-]+)$", line)
- return match.group(1), match.group(2)
- self.append_section(self.root, stype, section)
- def append_section(self, parent, stype, section):
- stypes = stype + "s"
- if(stypes not in parent):
- parent[stypes] = []
- parent[stypes].append(section)
- # Packing and unpacking uses a simple substitution (dirty)
- # Assumption: only one spritesheet
- def toggle_pack(self):
- if(self.root["spritesheets"][0]["is_packed"] == "true"):
- self.unpack()
- else:
- self.pack()
- def pack(self):
- self.replace_in_file("is_packed=false", "is_packed=true")
- self.root["spritesheets"][0]["is_packed"] = "true"
- def unpack(self):
- self.replace_in_file("is_packed=true", "is_packed=false")
- self.root["spritesheets"][0]["is_packed"] = "false"
- def replace_in_file(self, pattern, repl):
- replacement = []
- f = open(self.filename, 'r')
- for line in f.readlines():
- replacement.append(line.replace(pattern, repl))
- f.close
- f = open(self.filename, 'w')
- for line in replacement:
- f.write(line)
- f.close
- #
- # The SpritesheetManager class - provides an interface to the joined functionality of all of the classes above
- #
- class SpritesheetManager:
- def __init__(self, config_filename):
- self.config = Config(config_filename)
- self.images = Images(self.config)
- self.ui = UI(self.config, self.images)
- def run(self):
- self.ui.run()
- pygame.init()
- manager = SpritesheetManager("config/spritesheets.cfg")
- manager.run()
Advertisement
Add Comment
Please, Sign In to add comment