changeset 30:8b1c56119566

Ported to pygrafix
author sheep
date Wed, 01 Feb 2012 20:34:33 +0100
parents 1090d7e5537f
children 10c457e588c3
files qq.py
diffstat 1 files changed, 86 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/qq.py	Sat Aug 20 11:27:49 2011 +0200
+++ b/qq.py	Wed Feb 01 20:34:33 2012 +0100
@@ -19,9 +19,10 @@
 """
 
 import ConfigParser
+import time
 
-import pygame
-import pygame.locals as pg
+import pygrafix
+pg = pygrafix.window.key
 
 # Motion offsets for particular directions
 #     N  E  S   W
@@ -54,75 +55,99 @@
     def _load_tile_table(self, filename, width, height):
         """Load an image and split it into tiles."""
 
-        image = pygame.image.load(filename).convert()
-        image_width, image_height = image.get_size()
+        image = pygrafix.image.load(filename)
+        image_width, image_height = image.width, image.height
         tile_table = []
         for tile_x in range(0, image_width/width):
             line = []
             tile_table.append(line)
             for tile_y in range(0, image_height/height):
-                rect = (tile_x*width, tile_y*height, width, height)
-                line.append(image.subsurface(rect))
+                line.append(image.get_texture_region(
+                    tile_x*width, tile_y*height, width, height))
         return tile_table
 
 
-class SortedUpdates(pygame.sprite.RenderUpdates):
+class SortedUpdates(object):
     """A sprite group that sorts them by depth."""
 
-    def sprites(self):
-        """The list of sprites in the group, sorted by depth."""
+
+    def __init__(self, *sprites):
+        self.sprite_list = list(sprites)
+
+    def add(self, sprite):
+        self.sprite_list.append(sprite)
 
-        return sorted(self.spritedict.keys(), key=lambda sprite: sprite.depth)
+    def update(self):
+        for sprite in self.sprite_list:
+            sprite.update()
+
+    def draw(self):
+        self.sprite_list.sort(key=lambda sprite: sprite.depth)
+        for sprite in self.sprite_list:
+            sprite.sprite.draw()
 
 
-class Shadow(pygame.sprite.Sprite):
+class Shadow(object):
     """Sprite for shadows."""
 
     def __init__(self, owner):
-        pygame.sprite.Sprite.__init__(self)
         self.image = SPRITE_CACHE["shadow.png"][0][0]
-        self.image.set_alpha(64)
-        self.rect = self.image.get_rect()
+        self.sprite = pygrafix.sprite.Sprite(self.image)
+        self.sprite.alpha = 0.25
+        self.size = self.image.width, self.image.height
         self.owner = owner
 
     def update(self, *args):
         """Make the shadow follow its owner."""
 
-        self.rect.midbottom = self.owner.rect.midbottom
+        self.sprite.x, self.sprite.y = (
+            self.owner.sprite.x + self.owner.size[0]/2 - self.size[0]/2,
+            self.owner.sprite.y + self.owner.size[1] - self.size[1]
+        )
 
-
-class Sprite(pygame.sprite.Sprite):
+class Sprite(object):
     """Sprite for animated items and base class for Player."""
 
     is_player = False
 
     def __init__(self, pos=(0, 0), frames=None):
-        super(Sprite, self).__init__()
         if frames:
             self.frames = frames
-        self.image = self.frames[0][0]
-        self.rect = self.image.get_rect()
+        self.sprite = pygrafix.sprite.Sprite(self.frames[0][0])
+        self.size = self.image.width, self.image.height
         self.animation = self.stand_animation()
         self.pos = pos
 
+    def _set_image(self, image):
+        self.sprite.texture = image
+
+    def _get_image(self):
+        return self.sprite.texture
+
+    image = property(_get_image, _set_image)
+
     def _get_pos(self):
         """Check the current position of the sprite on the map."""
 
-        return (self.rect.midbottom[0]-12)/24, (self.rect.midbottom[1]-16)/16
+        return (
+            int((self.sprite.x + 4) / 24),
+            int((self.sprite.y + 16) / 16)
+        )
 
     def _set_pos(self, pos):
         """Set the position and depth of the sprite on the map."""
 
-        self.rect.midbottom = pos[0]*24+12, pos[1]*16+16
-        self.depth = self.rect.midbottom[1]
+        self.sprite.x, self.sprite.y = pos[0]*24 - 4, pos[1]*16 - 16
+        self.depth = self.sprite.y
 
     pos = property(_get_pos, _set_pos)
 
     def move(self, dx, dy):
         """Change the position of the sprite on screen."""
 
-        self.rect.move_ip(dx, dy)
-        self.depth = self.rect.midbottom[1]
+        self.sprite.x += dx
+        self.sprite.y += dy
+        self.depth = self.sprite.y
 
     def stand_animation(self):
         """The default animation."""
@@ -209,8 +234,8 @@
 
         wall = self.is_wall
         tiles = MAP_CACHE[self.tileset]
-        image = pygame.Surface((self.width*MAP_TILE_WIDTH, self.height*MAP_TILE_HEIGHT))
-        overlays = {}
+        image = pygrafix.sprite.SpriteGroup()
+        overlays = pygrafix.sprite.SpriteGroup()
         for map_y, line in enumerate(self.map):
             for map_x, c in enumerate(line):
                 if wall(map_x, map_y):
@@ -243,7 +268,11 @@
                             over = 2, 0
                         else:
                             over = 3, 0
-                        overlays[(map_x, map_y)] = tiles[over[0]][over[1]]
+                        sprite = pygrafix.sprite.Sprite(tiles[over[0]][over[1]])
+                        sprite.x = map_x * MAP_TILE_WIDTH
+                        sprite.y = map_y * MAP_TILE_HEIGHT - 16
+
+                        overlays.add_sprite(sprite)
                 else:
                     try:
                         tile = self.key[c]['tile'].split(',')
@@ -252,8 +281,10 @@
                         # Default to ground tile
                         tile = 0, 3
                 tile_image = tiles[tile[0]][tile[1]]
-                image.blit(tile_image,
-                           (map_x*MAP_TILE_WIDTH, map_y*MAP_TILE_HEIGHT))
+                sprite = pygrafix.sprite.Sprite(tile_image)
+                sprite.x = map_x * MAP_TILE_WIDTH
+                sprite.y = map_y * MAP_TILE_HEIGHT
+                image.add_sprite(sprite)
         return image, overlays
 
     def get_tile(self, x, y):
@@ -291,20 +322,18 @@
     """The main game object."""
 
     def __init__(self):
-        self.screen = pygame.display.get_surface()
+        self.screen = pygrafix.window.Window(424, 320)
         self.pressed_key = None
         self.game_over = False
-        self.shadows = pygame.sprite.RenderUpdates()
+        self.shadows = []
         self.sprites = SortedUpdates()
-        self.overlays = pygame.sprite.RenderUpdates()
         self.use_level(Level())
 
     def use_level(self, level):
         """Set the level as the current one."""
 
-        self.shadows = pygame.sprite.RenderUpdates()
+        self.shadows = []
         self.sprites = SortedUpdates()
-        self.overlays = pygame.sprite.RenderUpdates()
         self.level = level
         # Populate the game with the level's objects
         for pos, tile in level.items.iteritems():
@@ -314,24 +343,18 @@
             else:
                 sprite = Sprite(pos, SPRITE_CACHE[tile["sprite"]])
             self.sprites.add(sprite)
-            self.shadows.add(Shadow(sprite))
+            self.shadows.append(Shadow(sprite))
         # Render the level map
-        self.background, overlays = self.level.render()
-        # Add the overlays for the level map
-        for (x, y), image in overlays.iteritems():
-            overlay = pygame.sprite.Sprite(self.overlays)
-            overlay.image = image
-            overlay.rect = image.get_rect().move(x*24, y*16-16)
+        self.background, self.overlays = self.level.render()
 
     def control(self):
         """Handle the controls of the game."""
 
-        keys = pygame.key.get_pressed()
 
         def pressed(key):
             """Check if the specified key is pressed."""
 
-            return self.pressed_key == key or keys[key]
+            return self.screen.is_key_pressed(key)
 
         def walk(d):
             """Start walking in specified direction."""
@@ -341,57 +364,47 @@
             if not self.level.is_blocking(x+DX[d], y+DY[d]):
                 self.player.animation = self.player.walk_animation()
 
-        if pressed(pg.K_UP):
+        if pressed(pg.UP):
             walk(0)
-        elif pressed(pg.K_DOWN):
+        elif pressed(pg.DOWN):
             walk(2)
-        elif pressed(pg.K_LEFT):
+        elif pressed(pg.LEFT):
             walk(3)
-        elif pressed(pg.K_RIGHT):
+        elif pressed(pg.RIGHT):
             walk(1)
         self.pressed_key = None
 
     def main(self):
         """Run the main loop."""
 
-        clock = pygame.time.Clock()
         # Draw the whole screen initially
-        self.screen.blit(self.background, (0, 0))
-        self.overlays.draw(self.screen)
-        pygame.display.flip()
+        self.screen.clear()
+        self.background.draw()
+        self.overlays.draw()
+        self.screen.flip()
         # The main game loop
         while not self.game_over:
-            # Don't clear shadows and overlays, only sprites.
-            self.sprites.clear(self.screen, self.background)
+            self.screen.clear()
             self.sprites.update()
             # If the player's animation is finished, check for keypresses
             if self.player.animation is None:
                 self.control()
                 self.player.update()
-            self.shadows.update()
-            # Don't add shadows to dirty rectangles, as they already fit inside
-            # sprite rectangles.
-            self.shadows.draw(self.screen)
-            dirty = self.sprites.draw(self.screen)
-            # Don't add ovelays to dirty rectangles, only the places where
-            # sprites are need to be updated, and those are already dirty.
-            self.overlays.draw(self.screen)
-            # Update the dirty areas of the screen
-            pygame.display.update(dirty)
-            # Wait for one tick of the game clock
-            clock.tick(15)
-            # Process pygame events
-            for event in pygame.event.get():
-                if event.type == pg.QUIT:
+            self.background.draw()
+            for shadow in self.shadows:
+                shadow.update()
+                shadow.sprite.draw()
+            self.sprites.draw()
+            self.overlays.draw()
+            self.screen.flip()
+            time.sleep(0.05)
+            self.screen.poll_events()
+            if not self.screen.is_open() or self.screen.is_key_pressed(pg.ESCAPE):
                     self.game_over = True
-                elif event.type == pg.KEYDOWN:
-                    self.pressed_key = event.key
 
 
 if __name__ == "__main__":
     SPRITE_CACHE = TileCache()
     MAP_CACHE = TileCache(MAP_TILE_WIDTH, MAP_TILE_HEIGHT)
     TILE_CACHE = TileCache(32, 32)
-    pygame.init()
-    pygame.display.set_mode((424, 320))
     Game().main()