Mercurial > qq-pygrafix
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()
