Mercurial > pavulon
changeset 16:4223254474e1
Add some docstrings.
| author | sheep@ghostwheel |
|---|---|
| date | Sun, 05 Jul 2009 23:19:43 +0200 |
| parents | d8731b40e57e |
| children | 31c17b907fad |
| files | level.map qq.py |
| diffstat | 2 files changed, 101 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/level.map Thu Aug 28 14:07:12 2008 +0200 +++ b/level.map Sun Jul 05 23:19:43 2009 +0200 @@ -18,41 +18,37 @@ [#] name = wall -tile = 0, 0 -pass = false wall = true +block = true [.] name = floor -pass = true tile = 0, 3 [@] name = player -pass = true tile = 0, 3 player = true sprite = player.png [s] name = skeleton -pass = false tile = 0, 3 sprite = skeleton.png +block = true [>] name = stairs -pass = true tile = 3, 3 [b] name = crate -pass = false tile = 0, 3 sprite = crate.png +block = true [h] name = house tile = 0, 3 -pass = false sprite = house.png +block = true
--- a/qq.py Thu Aug 28 14:07:12 2008 +0200 +++ b/qq.py Sun Jul 05 23:19:43 2009 +0200 @@ -14,6 +14,8 @@ class TileCache: + """Load the tilesets lazily.""" + def __init__(self): self.cache = {} @@ -38,13 +40,19 @@ return tiles class SortedUpdates(pygame.sprite.RenderUpdates): + """A sprite group that sorts them by depth.""" + def sprites(self): + """The list of sprites in the group.""" + sprites = self.spritedict.keys() sprites.sort(lambda a, b: a.depth - b.depth) return sprites class Shadow(pygame.sprite.Sprite): + """Sprite for shadows.""" + def __init__(self, sprite): self.image = tiles("shadow.png", 24, 24)[0][0] self.image.set_alpha(64) @@ -53,10 +61,14 @@ self.sprite = sprite def update(self): + """Move the shadow to the right place.""" + self.rect.midbottom = self.sprite.rect.midbottom class Sprite(pygame.sprite.Sprite): + """Sprite for animated items and base class for Player.""" + is_player = False def __init__(self, pos=(0, 0), frames=None): @@ -69,17 +81,27 @@ self.pos = pos 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 + def _set_pos(self, pos): + """Set the position of the sprite on the map.""" + self.rect.midbottom = pos[0]*24+12, pos[1]*16+16 self.depth = self.rect.midbottom[1] + 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] def stand_animation(self): + """The default animation.""" + while True: for frame in self.frames[0]: self.image = frame @@ -87,11 +109,14 @@ yield None def update(self): + """Run the current animation.""" + self.animation.next() class Player(Sprite): """ Display and animate the player character.""" + is_player = True def __init__(self, pos=(1, 1)): @@ -104,6 +129,8 @@ self.rect.move_ip((0, 1)) def walk_animation(self): + """Animation for the player walking.""" + for frame in range(4): self.image = self.frames[self.direction][frame] yield None @@ -112,6 +139,8 @@ self.move(3*DX[self.direction], 2*DY[self.direction]) def update(self): + """Run the current animation or just stand there if no animation set.""" + if self.animation is None: self.image = self.frames[self.direction][0] else: @@ -123,8 +152,13 @@ class Level: """ Load and store the map of the level, together with all the items.""" + def __init__(self, filename="level.map"): + self.load_file(filename) + + def load_file(self, filename="level.map"): """ Load the level from specified file.""" + parser = ConfigParser.ConfigParser() parser.read(filename) self.items = {} @@ -136,16 +170,17 @@ self.key[section] = dict(parser.items(section)) tile_width, tile_height = 24, 16 self.tiles = tiles(parser.get("level", "tileset"), - tile_width, tile_height) - width = len(self.map[0]) - height = len(self.map) - self.image = pygame.Surface((width*tile_width, height*tile_height)) + tile_width, tile_height) + self.width = len(self.map[0]) + self.height = len(self.map) + self.image = pygame.Surface((self.width*tile_width, + self.height*tile_height)) self.overlays = {} y = 0 for line in self.map: x = 0 for c in line: - if not self.key[c].get('wall', None): + if not self.is_wall(x, y): # floor if 'sprite' in self.key[c]: self.items[(x, y)] = self.key[c] @@ -159,47 +194,71 @@ (x*tile_width, y*tile_height)) else: # wall - if self(x, y+1): - if self(x+1, y) and self(x-1, y): - tile_image = self.tiles[3][2] - elif self(x+1, y): - tile_image = self.tiles[2][2] - elif self(x-1, y): + if not self.is_wall(x, y+1): + if self.is_wall(x+1, y) and self.is_wall(x-1, y): + tile_image = self.tiles[1][2] + elif self.is_wall(x+1, y): tile_image = self.tiles[0][2] + elif self.is_wall(x-1, y): + tile_image = self.tiles[2][2] else: - tile_image = self.tiles[1][2] + tile_image = self.tiles[3][2] else: - if self(x+1, y+1) and self(x-1, y+1): - tile_image = self.tiles[3][1] - elif self(x+1, y+1): + if self.is_wall(x+1, y+1) and self.is_wall(x-1, y+1): + tile_image = self.tiles[1][1] + elif self.is_wall(x+1, y+1): + tile_image = self.tiles[0][1] + elif self.is_wall(x-1, y+1): tile_image = self.tiles[2][1] - elif self(x-1, y+1): - tile_image = self.tiles[0][1] else: - tile_image = self.tiles[1][1] + tile_image = self.tiles[3][1] self.image.blit(tile_image, (x*tile_width, y*tile_height)) - if self(x, y-1): - if self(x+1, y) and self(x-1, y): - overlay_image = self.tiles[3][0] - elif self(x+1, y): + if not self.is_wall(x, y-1): + if self.is_wall(x+1, y) and self.is_wall(x-1, y): + overlay_image = self.tiles[1][0] + elif self.is_wall(x+1, y): + overlay_image = self.tiles[0][0] + elif self.is_wall(x-1, y): overlay_image = self.tiles[2][0] - elif self(x-1, y): - overlay_image = self.tiles[0][0] else: - overlay_image = self.tiles[1][0] + overlay_image = self.tiles[3][0] self.overlays[(x, y)] = overlay_image x += 1 y += 1 - def __call__(self, x, y): - """ Tell what is at this position on the map.""" + def get_tile(self, x, y): + """Tell what's at the specified position of the map.""" + + try: + char = self.map[y][x] + except IndexError: + return {} try: - return self.key[self.map[y][x]]['pass'] in ('true', 'yes', 'True', 'Yes', '1', 'on', 'On') - except (IndexError, AttributeError): - return None + return self.key[char] + except KeyError: + return {} + + def get_bool(self, x, y, name): + """Tell if the specified flag is set for position on the map.""" + + value = self.get_tile(x, y).get(name) + return value in ('true', 'yes', 'True', 'Yes', '1', 'on', 'On') + + def is_wall(self, x, y): + """Is there a wall?""" + + return self.get_bool(x, y, 'wall') + + def is_blocking(self, x, y): + """Is this place blocking movement?""" + + if not 0 <= x < self.width or not 0 <= y < self.height: + return True + return self.get_bool(x, y, 'block') def draw(self, surface): """ Draw the map on the provided surface.""" + surface.blit(self.image, (0, 0)) @@ -211,6 +270,8 @@ self.use_level(Level()) def use_level(self, level): + """Set the level as the current one.""" + self.shadows = pygame.sprite.RenderUpdates() self.sprites = SortedUpdates() self.overlays = pygame.sprite.RenderUpdates() @@ -231,13 +292,15 @@ self.background = self.level.image.copy() def control(self): + """Handle the controls of the game.""" + keys = pygame.key.get_pressed() def pressed(key): return self.pressed_key == key or keys[key] def walk(d): x, y = self.player.pos self.player.direction = d - if self.level(x+DX[d], y+DY[d]): + if not self.level.is_blocking(x+DX[d], y+DY[d]): self.player.animation = self.player.walk_animation() if pressed(K_UP): walk(0) @@ -250,6 +313,8 @@ self.pressed_key = None def main(self): + """Run the main loop.""" + clock = pygame.time.Clock() self.screen.blit(self.background, (0, 0)) self.overlays.draw(self.screen) @@ -280,7 +345,7 @@ if __name__ == "__main__": pygame.init() - pygame.display.set_mode((424, 400)) + pygame.display.set_mode((424, 320)) font = pygame.font.Font("MgOpenModataBold.ttf", 11) tiles = TileCache() Game().main()
