Commits

Szymon Wróblewski committed bd25010

Added MaskedSprite class, updated images (better quality will be tomorrow)

Comments (0)

Files changed (10)

alchemymadness/blocks.py

 from itertools import izip, chain
 
 import pygame
-from pygame.sprite import DirtySprite
 
 import resources
 import layout
+from sprite import MaskedSprite
 
-class Block(DirtySprite):
+class Block(MaskedSprite):
     """ A single block.
     """
     rect = layout.Main.block_rect
-    changed = False # True if sprite image need to be regenerated
 
     def __init__(self, color, *groups):
-        """
-            color - (r,g,b) tuple
-        """
-        super(Block, self).__init__(*groups)
-        self._image = pygame.Surface(self.rect.size) # Sprite image
+        super(Block, self).__init__(color, *groups)
         self.t_image = resources.block
-        self._color = color  # Block color
-        self.changed = True
-        self.dirty = 1
-
-    @property
-    def image(self):
-        if self.changed:
-            self._image = self.t_image.copy()
-            self._image.fill(self._color, special_flags=pygame.locals.BLEND_RGBA_MULT)
-        return self._image
-
-    @property
-    def color(self):
-        return self._color
-
-    @color.setter
-    def color(self, value):
-        self._color = value
-        self.changed = True
-
 
     def grid_pos(self, pos, grid_rect):
         """ set the rect for the given (x,y) grid pos

alchemymadness/data/bg.png

Old
Old image
New
New image

alchemymadness/data/bg_mask.png

Added
New image

alchemymadness/data/block.png

Old
Old image
New
New image

alchemymadness/data/future_bg.png

Removed
Old image

alchemymadness/layout.py

 screen_size = (800, 600)
 
 class Main(object):
-    block_rect = Rect(0, 0, 30, 30)
-    small_block_rect = Rect(0, 0, 15, 15)
-    grid_size = Rect(0, 0, 9, 16) # size in blocks
+    block_rect = Rect(0, 0, 25, 25)
+    small_block_rect = Rect(0, 0, 12, 12)
+    grid_size = Rect(0, 0, 10, 15) # size in blocks
     grid_rects = (
-        Rect(30, 20, block_rect.w * grid_size[0], block_rect.h * grid_size[1]),
-        Rect(300, 20, small_block_rect.w * grid_size[0], small_block_rect.h * grid_size[1]),
-        Rect(470, 20, small_block_rect.w * grid_size[0], small_block_rect.h * grid_size[1]),
-        Rect(630, 20, small_block_rect.w * grid_size[0], small_block_rect.h * grid_size[1]),
+        Rect(50, 50, block_rect.w * grid_size[0], block_rect.h * grid_size[1]),
+        Rect(330, 58, small_block_rect.w * grid_size[0], small_block_rect.h * grid_size[1]),
+        Rect(478, 58, small_block_rect.w * grid_size[0], small_block_rect.h * grid_size[1]),
+        Rect(626, 58, small_block_rect.w * grid_size[0], small_block_rect.h * grid_size[1]),
     )
-    potion_rect = Rect(450, 470, 170, 113)
+    potion_rect = Rect(372, 360, 130, 194)
+    small_potion_rect = Rect(553, 454, 68, 100)
+    spiral_rect = Rect(718, 255, 82, 280)
+    tube_rects = tuple(Rect(63 + i * 25, 447, 24, 76) for i in range(9))
+    input_rects = (
+        Rect(300, 277, 56, 71),
+        Rect(400, 236, 50, 40),
+        Rect(513, 236, 50, 40),
+        Rect(625, 236, 50, 40),
+    )

alchemymadness/main.py

         # Draw sprites
         rects = sprites.draw(screen)
         # TODO: Move text code somewhere else
-        screen.blit(resources.font[40].render('Alchemy Madness', True, (255,255,255)), (10,550))
+        screen.blit(resources.font[40].render('Alchemy Madness', True, (255,255,255)), (10,555))
         pygame.display.update(rects)
 
 

alchemymadness/potion.py

 
 import pygame
 from pygame.locals import Rect
-from pygame.sprite import DirtySprite
 
 import resources
 import layout
+from sprite import MaskedSprite
 
-class Potion(DirtySprite):
+class Potion(MaskedSprite):
     chems = 0  # Chem count
     formula = (0,0,0)  # Target formula
-    col = (0,0,0)  # Current formula
     target_col = None
     max_chems = 0  # Target number of chems
     rect = layout.Main.potion_rect
-    image_rect = Rect((0, rect.y), rect.size)
     target_y = None
     changed = False
 
           groups to add sprite to
 
         """
-        super(Potion, self).__init__(*groups)
-        # Image with transparency
-        self.t_image = resources.background.subsurface(self.rect)
-        # Sprite image
-        self._image = pygame.Surface(self.rect.size)
-        self.changed = True
-
-    @property
-    def image(self):
-        if self.changed:
-            self._image.fill((0,0,0))
-            self._image.fill(self.col, self.image_rect)
-            self._image.blit(self.t_image, (0,0))
-        return self._image
-
+        super(Potion, self).__init__((0,0,0), *groups)
+        self.t_image = resources.background_mask.subsurface(self.rect)
+        self.mask_rect = Rect((0, self.rect.h), self.rect.size)
 
     def set_formula(self, r=0, g=0, b=0):
         """Set the target formula for the level."""
         self.formula = (r, g, b)
         self.max_chems = sum(self.formula)
         # Offset the rect to be at bottom of potion
-        self.image_rect.y = self.image_rect.h
+        self.mask_rect.y = self.mask_rect.h
 
     def add_color(self, col):
         """
         """
         self.chems += 1
         n = ((self.chems-1) / float(self.chems))
-        self.target_col = (self.col[0] * n, self.col[1] * n, self.col[2] * n)
+        self.target_col = (self.color[0] * n, self.color[1] * n, self.color[2] * n)
         self.target_col = (self.target_col[0] + col[0]/float(self.chems),
                            self.target_col[1] + col[1]/float(self.chems),
                            self.target_col[2] + col[2]/float(self.chems))
-        self.diff_col = ((self.target_col[0] - self.col[0]),
-                         (self.target_col[1] - self.col[1]),
-                         (self.target_col[2] - self.col[2]))
+        self.diff_col = ((self.target_col[0] - self.color[0]),
+                         (self.target_col[1] - self.color[1]),
+                         (self.target_col[2] - self.color[2]))
 
         # Update position
         n = self.chems / float(self.max_chems)
-        self.target_y = self.image_rect.h*(1-n)
+        self.target_y = self.mask_rect.h*(1-n)
 
     def get_score(self):
         """Returns a score based on accuracy of the formula."""
         # Move rect smoothly
         if self.target_y is not None:
             self.dirty = 1
-            self.image_rect.y -= 5*(time/1000.)
-            if self.image_rect.y < self.target_y:
-                self.image_rect.y = self.target_y
+            self.mask_rect.y -= 5*(time/1000.)
+            if self.mask_rect.y < self.target_y:
+                self.mask_rect.y = self.target_y
                 self.target_y = None
         # Lerp colours
         if self.target_col is not None:
             diff = (self.diff_col[0] * (time/500.),
                     self.diff_col[1] * (time/500.),
                     self.diff_col[2] * (time/500.))
-            col = [self.col[0] + diff[0], self.col[1] + diff[1],
-                   self.col[2] + diff[2]]
+            col = [self.color[0] + diff[0], self.color[1] + diff[1],
+                   self.color[2] + diff[2]]
             for i in range(3):
                 if diff[i] > 0:
                     col[i] = min(col[i], self.target_col[i])
                 else:
                     col[i] = max(col[i], self.target_col[i])
 
-            self.col = tuple(col)
-            if self.col == self.target_col:
+            self.color = tuple(col)
+            if self.color == self.target_col:
                 self.target_col = None

alchemymadness/resources.py

 import pygame
 import skelutil
 
-background = None
-block = None
-sblock = None
+background = background_mask = None
+block = sblock = None
 font = None
 
 def init():
-    global background, block, sblock, font
+    global background, background_mask, block, sblock, font
     background = pygame.image.load(skelutil.data_dir("bg.png")).convert_alpha()
+    background_mask = pygame.image.load(skelutil.data_dir("bg_mask.png")).convert_alpha()
     block = pygame.image.load(skelutil.data_dir("block.png")).convert_alpha()
     sblock = pygame.transform.scale(block, (int(block.get_rect().w/2), int(block.get_rect().h/2)))
     font = Font(skelutil.data_dir("The Alchemist.ttf"))
 
 class Font(object):
-    """multiresolution font"""
+    """multi sized font"""
     def __init__(self, path):
         self.path = path
         self.fonts = {}
 
     def __getitem__(self, size):
-        """get font size"""
+        """get font of specified size"""
         try:
             return self.fonts[size]
         except KeyError:

alchemymadness/sprite.py

+"""Sprites module"""
+
+import pygame
+from pygame.locals import Rect
+from pygame.sprite import DirtySprite
+
+class MaskedSprite(DirtySprite):
+    """ Sprite with color
+
+    rect, mask_rect, t_image should be overriden
+    changed should be set to True whenever mask_rect is modified
+    """
+    rect = Rect(0,0,10,10)
+    changed = False # True if sprite image need to be colored
+    fill_flags = pygame.locals.BLEND_RGBA_MULT
+
+    def __init__(self, color, *groups):
+        """
+            color - color of sprite - (r,g,b) tuple
+        """
+        super(MaskedSprite, self).__init__(*groups)
+        self._image = pygame.Surface(self.rect.size) # Sprite colored image
+        self.t_image = pygame.Surface(self.rect.size) # Sprite image
+        self._color = color  # Block color
+        self.mask_rect = Rect((0,0), self.rect.size)
+        self.changed = True
+        self.dirty = 1
+
+    @property
+    def image(self):
+        if self.changed:
+            self._image = self.t_image.copy()
+            self._image.fill(self._color, self.mask_rect.clip(self._image.get_rect()), self.fill_flags)
+        return self._image
+
+    @property
+    def color(self):
+        return self._color
+
+    @color.setter
+    def color(self, value):
+        self._color = value
+        self.changed = True