Guest User

tool-prototype.py

a guest
Apr 9th, 2011
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.19 KB | None | 0 0
  1. #!/usr/bin/env python2.6
  2.  
  3. ##################################################################
  4. # A prototype impelementation of a spritesheet management tool   #
  5. ##################################################################
  6. #   Author: Karol Kozub                                          #
  7. #   Description:                                                 #
  8. # This is a very simple prototype. It allows the user to pack or #
  9. # unpack a single predefined spritesheet. The configuration file #
  10. # is read from disk and parsed and appropriate images are        #
  11. # displayed. Clicking the UI triggers packing or unpacking of    #
  12. # sprites.                                                       #
  13. # The code was written for fast results and most of it is dirty. #
  14. # None of this code is expected to be used in the actual tool.   #
  15. ##################################################################
  16.  
  17. import sys, pygame, re, os
  18. from pygame.locals import *
  19.  
  20. #
  21. # The Images class - manipulates the images
  22. #
  23. class Images:
  24.     def __init__(self, config):
  25.         self.spr_conf = config.root["spritesheets"][0]
  26.  
  27.         self.unpacked_images = {}
  28.  
  29.         if self.are_packed():
  30.             self.packed_image = pygame.image.load(self.spr_conf["name"])
  31.         else:
  32.             for img_conf in self.spr_conf["images"]:
  33.                 name = img_conf["name"]
  34.                 self.unpacked_images[name] = pygame.image.load(name)
  35.        
  36.     def toggle_pack(self):
  37.         if self.are_packed():
  38.             self.unpack()
  39.         else:
  40.             self.pack()
  41.    
  42.     def are_packed(self):
  43.         return self.spr_conf["is_packed"] == "true";
  44.    
  45.     def unpack(self):
  46.         for img_conf in self.spr_conf["images"]:
  47.             self.unpack_image(img_conf)
  48.        
  49.         os.remove(self.spr_conf["name"])
  50.    
  51.     def pack(self):
  52.         w, h = self.calculate_packed_size()
  53.        
  54.         self.packed_image = pygame.Surface((w, h), SRCALPHA, 32)
  55.         self.packed_image = self.packed_image.convert_alpha()
  56.  
  57.         for img_conf in self.spr_conf["images"]:
  58.             self.blit_image(self.packed_image, img_conf)
  59.  
  60.         pygame.image.save(self.packed_image, self.spr_conf["name"])
  61.  
  62.         for img_conf in self.spr_conf["images"]:
  63.             os.remove(img_conf["name"])
  64.    
  65.     def calculate_packed_size(self):
  66.         w, h = 0, 0
  67.        
  68.         for img_conf in self.spr_conf["images"]:
  69.             w = max(w, int(img_conf["x"]) + int(img_conf["width"]))
  70.             h = max(h, int(img_conf["y"]) + int(img_conf["height"]))
  71.        
  72.         return w, h
  73.    
  74.     def unpack_image(self, img_conf):
  75.         x, y = int(img_conf["x"]), int(img_conf["y"])
  76.         w, h = int(img_conf["width"]), int(img_conf["height"])
  77.         name = img_conf["name"]
  78.  
  79.         rect = pygame.Rect(x, y, w, h)
  80.         surf = self.packed_image.subsurface(rect).copy()
  81.  
  82.         self.unpacked_images[name] = surf
  83.         pygame.image.save(surf, name)
  84.    
  85.     def blit_image(self, dest, img_conf):
  86.         src = self.unpacked_images[img_conf["name"]]
  87.         xy = (int(img_conf["x"]), int(img_conf["y"]))
  88.         dest.blit(src, xy)
  89.  
  90. #
  91. # The UI class - shows the UI and responds to events
  92. #
  93. class UI:
  94.     def __init__(self, config, images):
  95.         self.config = config
  96.         self.images = images
  97.         self.resolution = 390, 240
  98.        
  99.  
  100.     def run(self):
  101.         self.screen = pygame.display.set_mode(self.resolution)
  102.         pygame.display.set_caption("Spritesheet management tool prototype")
  103.  
  104.         while True:
  105.             for event in pygame.event.get():
  106.                 if event.type == pygame.QUIT:
  107.                     sys.exit()
  108.                
  109.                 if event.type == pygame.MOUSEBUTTONUP:
  110.                     self.images.toggle_pack()
  111.                     self.config.toggle_pack()
  112.  
  113.                 self.display_images()
  114.  
  115.     def display_images(self):
  116.         self.screen.fill((128, 128, 128))
  117.  
  118.         if(self.images.are_packed()):
  119.             self.screen.blit(self.images.packed_image, (1, 1))
  120.  
  121.             w, h = self.images.packed_image.get_size()
  122.            
  123.             pygame.draw.rect(self.screen, (255,255,255), (0,0,w+2,h+2), 1)
  124.         else:
  125.             x, y = 1, 1
  126.             for name in self.images.unpacked_images:
  127.                 img = self.images.unpacked_images[name]
  128.                 w, h = img.get_size()
  129.  
  130.                 self.screen.blit(img, (x, y))
  131.  
  132.                 pygame.draw.rect(self.screen, (255,255,255), (x-1,y-1,w+2,h+2), 1)
  133.  
  134.                 x += 40
  135.                 y += 40
  136.  
  137.         pygame.display.flip()
  138.  
  139. #
  140. # The Config class - reads and modifies the config file
  141. #
  142. class Config:
  143.     def __init__(self, filename):
  144.         self.root = {}
  145.         self.filename = filename
  146.         self.parse_file(filename)
  147.  
  148.     def parse_file(self, filename):
  149.         f = open(filename, 'r')
  150.         while True:
  151.             stype, section = self.read_next_section(f);
  152.  
  153.             if section == None:
  154.                 break
  155.            
  156.             self.append_section(self.root, stype, section)
  157.        
  158.         f.close()
  159.  
  160.     def read_next_section(self, f):
  161.         while True:
  162.             line = f.readline()
  163.  
  164.             if(line == ""):
  165.                 return None, None
  166.  
  167.             if(self.is_section_start(line)):
  168.                 stype = self.read_section_start_type(line)
  169.                 return stype, self.read_section(stype, f)
  170.  
  171.     def read_section(self, stype, f):
  172.         section = {}
  173.  
  174.         while True:
  175.             line = f.readline()
  176.  
  177.             if(line == "" or self.is_section_end(line)):
  178.                 return section
  179.  
  180.             elif(self.is_section_start(line)):
  181.                 stype = self.read_section_start_type(line)
  182.                 subsection = self.read_section(stype, f)
  183.                 self.append_section(section, stype, subsection)
  184.                
  185.             elif(self.is_param_def(line)):
  186.                 name, value = self.read_param_def(line)
  187.                 section[name] = value
  188.  
  189.  
  190.     def is_section_start(self, line):
  191.         return re.match("^[\t ]*\[[^\]]+\]$", line) != None
  192.  
  193.     def read_section_start_type(self, line):
  194.         match = re.match("^[\t ]*\[([^\]]+)\]$", line)
  195.         return match.group(1)
  196.  
  197.     def is_section_end(self, line):
  198.         return re.match("^[\t ]*\[/[^\]]+\]$", line) != None
  199.  
  200.     def is_param_def(self, line):
  201.         return re.match("^[\t ]*[^\t =]+=[a-z0-9/.-]+$", line) != None
  202.  
  203.     def read_param_def(self, line):
  204.         match = re.match("^[\t ]*([^\t =]+)=([a-z0-9/.-]+)$", line)
  205.         return match.group(1), match.group(2)
  206.         self.append_section(self.root, stype, section)
  207.        
  208.     def append_section(self, parent, stype, section):
  209.         stypes = stype + "s"
  210.  
  211.         if(stypes not in parent):
  212.             parent[stypes] = []
  213.        
  214.         parent[stypes].append(section)
  215.  
  216.     # Packing and unpacking uses a simple substitution (dirty)
  217.     # Assumption: only one spritesheet
  218.     def toggle_pack(self):
  219.         if(self.root["spritesheets"][0]["is_packed"] == "true"):
  220.             self.unpack()
  221.         else:
  222.             self.pack()
  223.  
  224.     def pack(self):
  225.         self.replace_in_file("is_packed=false", "is_packed=true")
  226.         self.root["spritesheets"][0]["is_packed"] = "true"
  227.    
  228.     def unpack(self):
  229.         self.replace_in_file("is_packed=true", "is_packed=false")
  230.         self.root["spritesheets"][0]["is_packed"] = "false"
  231.    
  232.     def replace_in_file(self, pattern, repl):
  233.         replacement = []
  234.  
  235.         f = open(self.filename, 'r')
  236.         for line in f.readlines():
  237.             replacement.append(line.replace(pattern, repl))
  238.  
  239.         f.close
  240.  
  241.         f = open(self.filename, 'w')
  242.  
  243.         for line in replacement:
  244.             f.write(line)
  245.  
  246.         f.close
  247.  
  248. #
  249. # The SpritesheetManager class - provides an interface to the joined functionality of all of the classes above
  250. #
  251. class SpritesheetManager:
  252.     def __init__(self, config_filename):
  253.         self.config = Config(config_filename)
  254.         self.images = Images(self.config)
  255.         self.ui = UI(self.config, self.images)
  256.  
  257.     def run(self):
  258.         self.ui.run()
  259.  
  260.  
  261. pygame.init()
  262.  
  263. manager = SpritesheetManager("config/spritesheets.cfg")
  264. manager.run()
Advertisement
Add Comment
Please, Sign In to add comment