changeset 6:96fffc932ba7

Add sprites and animations
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sun, 17 Jun 2012 22:37:30 +0200
parents 03fe34478f69
children 2a0f43c87b80
files 002/004.py 002/005.py 002/006.py 002/007.py 002/level.tmx
diffstat 5 files changed, 484 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/002/004.py	Sun Jun 17 22:37:30 2012 +0200
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import pygame
+import pygame.locals as pg
+from pytmx import tmxloader
+
+
+def load_sheet(filename, width=32, height=None):
+    if height is None:
+        height = width
+    image = pygame.image.load(filename)
+    image = image.convert()
+    image.set_colorkey((0xff, 0, 0xff))
+    w, h = image.get_size()
+    images = []
+    for x in xrange(w // width):
+        for y in xrange(h // height):
+            rect = pygame.rect.Rect(x * width, y * height, width, height)
+            images.append(image.subsurface(rect))
+    return images
+
+
+class Level(object):
+    def __init__(self, filename):
+        self.tiled_map = tmxloader.load_pygame(filename)
+        self.hero_position = 1, 1
+        self.spritesheet = load_sheet('spritesheet.png', 64)
+
+    def render(self, screen):
+        w = self.tiled_map.tilewidth
+        h = self.tiled_map.tileheight
+        get_image = self.tiled_map.getTileImage
+        for l, layer in enumerate(self.tiled_map.tilelayers):
+            for y in xrange(self.tiled_map.height):
+                for x in xrange(self.tiled_map.width):
+                    image = get_image(x, y, l)
+                    if image:
+                        screen.blit(image, (x * w, y * h))
+        x, y = self.hero_position
+        screen.blit(self.spritesheet[2], (x * 32 - 16, y * 32 - 32))
+
+    def move_hero(self, (dx, dy)):
+        x, y = self.hero_position
+        self.hero_position = x + dx, y + dy
+
+
+class Game(object):
+    def __init__(self):
+        pygame.display.init()
+        pygame.font.init()
+        self.screen = pygame.display.set_mode((800, 600))
+        self.screen.fill((0x66, 0x66, 0x66))
+        self.keys = {
+            pg.K_UP: (self.move_hero, (0, -1)),
+            pg.K_DOWN: (self.move_hero, (0, 1)),
+            pg.K_LEFT: (self.move_hero, (-1, 0)),
+            pg.K_RIGHT: (self.move_hero, (1, 0)),
+            pg.K_ESCAPE: (self.quit,),
+        }
+
+    def load_level(self, filename):
+        self.level = Level(filename)
+
+    def quit(self):
+        self.game_over = True
+
+    def move_hero(self, direction):
+        self.level.move_hero(direction)
+
+    def control(self):
+        event = pygame.event.wait()
+        if event.type == pg.QUIT:
+            self.quit()
+        elif event.type == pg.KEYDOWN:
+            try:
+                action = self.keys[event.key]
+            except KeyError:
+                pass
+            else:
+                action[0](*action[1:])
+
+    def display(self):
+        self.level.render(self.screen)
+        pygame.display.update()
+
+    def run(self):
+        self.game_over = False
+        while not self.game_over:
+            self.display()
+            self.control()
+
+
+if __name__ == '__main__':
+    game = Game()
+    game.load_level('level.tmx')
+    game.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/002/005.py	Sun Jun 17 22:37:30 2012 +0200
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import pygame
+import pygame.locals as pg
+from pytmx import tmxloader
+
+
+def load_sheet(filename, width=32, height=None):
+    if height is None:
+        height = width
+    image = pygame.image.load(filename)
+    image = image.convert()
+    image.set_colorkey((0xff, 0, 0xff))
+    w, h = image.get_size()
+    images = []
+    for x in xrange(w // width):
+        for y in xrange(h // height):
+            rect = pygame.rect.Rect(x * width, y * height, width, height)
+            images.append(image.subsurface(rect))
+    return images
+
+
+class Level(object):
+    def __init__(self, filename):
+        self.tiled_map = tmxloader.load_pygame(filename)
+        self.hero_position = 1, 1
+        self.spritesheet = load_sheet('spritesheet.png', 64)
+
+    def render(self, screen):
+        w = self.tiled_map.tilewidth
+        h = self.tiled_map.tileheight
+        get_image = self.tiled_map.getTileImage
+        for l, layer in enumerate(self.tiled_map.tilelayers):
+            for y in xrange(self.tiled_map.height):
+                for x in xrange(self.tiled_map.width):
+                    image = get_image(x, y, l)
+                    if image:
+                        screen.blit(image, (x * w, y * h))
+        x, y = self.hero_position
+        screen.blit(self.spritesheet[2], (x * 32 - 16, y * 32 - 32))
+
+    def get_properties(self, (x, y)):
+        properties = {}
+        for l, layer in enumerate(self.tiled_map.tilelayers):
+            properties.update(self.tiled_map.getTileProperties((x, y, l)) or {})
+        return properties
+
+    def is_blocked(self, (x, y)):
+        return self.get_properties((x, y)).get('block')
+
+    def move_hero(self, (dx, dy)):
+        x, y = self.hero_position
+        if not self.is_blocked((x + dx, y + dy)):
+            self.hero_position = x + dx, y + dy
+
+
+class Game(object):
+    def __init__(self):
+        pygame.display.init()
+        pygame.font.init()
+        self.screen = pygame.display.set_mode((800, 600))
+        self.screen.fill((0x66, 0x66, 0x66))
+        self.keys = {
+            pg.K_UP: (self.move_hero, (0, -1)),
+            pg.K_DOWN: (self.move_hero, (0, 1)),
+            pg.K_LEFT: (self.move_hero, (-1, 0)),
+            pg.K_RIGHT: (self.move_hero, (1, 0)),
+            pg.K_ESCAPE: (self.quit,),
+        }
+
+    def load_level(self, filename):
+        self.level = Level(filename)
+
+    def quit(self):
+        self.game_over = True
+
+    def move_hero(self, direction):
+        self.level.move_hero(direction)
+
+    def control(self):
+        event = pygame.event.wait()
+        if event.type == pg.QUIT:
+            self.quit()
+        elif event.type == pg.KEYDOWN:
+            try:
+                action = self.keys[event.key]
+            except KeyError:
+                pass
+            else:
+                action[0](*action[1:])
+
+    def display(self):
+        self.level.render(self.screen)
+        pygame.display.update()
+
+    def run(self):
+        self.game_over = False
+        while not self.game_over:
+            self.display()
+            self.control()
+
+
+if __name__ == '__main__':
+    game = Game()
+    game.load_level('level.tmx')
+    game.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/002/006.py	Sun Jun 17 22:37:30 2012 +0200
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import pygame
+import pygame.locals as pg
+from pytmx import tmxloader
+
+
+def load_sheet(filename, width=32, height=None):
+    if height is None:
+        height = width
+    image = pygame.image.load(filename)
+    image = image.convert()
+    image.set_colorkey((0xff, 0, 0xff))
+    w, h = image.get_size()
+    images = []
+    for x in xrange(w // width):
+        for y in xrange(h // height):
+            rect = pygame.rect.Rect(x * width, y * height, width, height)
+            images.append(image.subsurface(rect))
+    return images
+
+
+class HeroSprite(pygame.sprite.Sprite):
+    def __init__(self, (x, y)):
+        super(HeroSprite, self).__init__()
+        self.spritesheet = load_sheet('spritesheet.png', 64)
+        self.image = self.spritesheet[2]
+        self.rect = self.image.get_rect()
+        self.rect.midbottom = (x * 32 + 16, y * 32 + 32)
+
+    def move(self, (dx, dy)):
+        self.rect.move_ip(dx * 32, dy * 32)
+
+
+class Level(object):
+    def __init__(self, filename):
+        self.tiled_map = tmxloader.load_pygame(filename)
+        self.hero_position = 1, 1
+
+    def render(self, screen):
+        w = self.tiled_map.tilewidth
+        h = self.tiled_map.tileheight
+        get_image = self.tiled_map.getTileImage
+        for l, layer in enumerate(self.tiled_map.tilelayers):
+            for y in xrange(self.tiled_map.height):
+                for x in xrange(self.tiled_map.width):
+                    image = get_image(x, y, l)
+                    if image:
+                        screen.blit(image, (x * w, y * h))
+        x, y = self.hero_position
+
+    def get_properties(self, (x, y)):
+        properties = {}
+        for l, layer in enumerate(self.tiled_map.tilelayers):
+            properties.update(self.tiled_map.getTileProperties((x, y, l)) or {})
+        return properties
+
+    def is_blocked(self, (x, y)):
+        return self.get_properties((x, y)).get('block')
+
+    def move_hero(self, (dx, dy)):
+        x, y = self.hero_position
+        if not self.is_blocked((x + dx, y + dy)):
+            self.hero_position = x + dx, y + dy
+            return True
+        return False
+
+
+class Game(object):
+    def __init__(self):
+        pygame.display.init()
+        pygame.font.init()
+        self.screen = pygame.display.set_mode((800, 600))
+        self.screen.fill((0x66, 0x66, 0x66))
+        self.keys = {
+            pg.K_UP: (self.move_hero, (0, -1)),
+            pg.K_DOWN: (self.move_hero, (0, 1)),
+            pg.K_LEFT: (self.move_hero, (-1, 0)),
+            pg.K_RIGHT: (self.move_hero, (1, 0)),
+            pg.K_ESCAPE: (self.quit,),
+        }
+        self.sprites = pygame.sprite.RenderUpdates()
+
+    def load_level(self, filename):
+        self.level = Level(filename)
+        self.hero_sprite = HeroSprite(self.level.hero_position)
+        self.sprites.add(self.hero_sprite)
+        self.background = self.screen.copy()
+        self.level.render(self.background)
+        self.screen.blit(self.background, (0, 0))
+        self.sprites.draw(self.screen)
+        pygame.display.update()
+
+    def quit(self):
+        self.game_over = True
+
+    def move_hero(self, direction):
+        if self.level.move_hero(direction):
+            self.hero_sprite.move(direction)
+
+    def control(self):
+        event = pygame.event.wait()
+        if event.type == pg.QUIT:
+            self.quit()
+        elif event.type == pg.KEYDOWN:
+            try:
+                action = self.keys[event.key]
+            except KeyError:
+                pass
+            else:
+                action[0](*action[1:])
+
+    def display(self):
+        self.sprites.clear(self.screen, self.background)
+        self.sprites.update()
+        dirty = self.sprites.draw(self.screen)
+        pygame.display.update(dirty)
+
+    def run(self):
+        self.game_over = False
+        while not self.game_over:
+            self.display()
+            self.control()
+
+
+if __name__ == '__main__':
+    game = Game()
+    game.load_level('level.tmx')
+    game.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/002/007.py	Sun Jun 17 22:37:30 2012 +0200
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import pygame
+import pygame.locals as pg
+from pytmx import tmxloader
+
+
+def load_sheet(filename, width=32, height=None):
+    if height is None:
+        height = width
+    image = pygame.image.load(filename)
+    image = image.convert()
+    image.set_colorkey((0xff, 0, 0xff))
+    w, h = image.get_size()
+    images = []
+    for x in xrange(w // width):
+        for y in xrange(h // height):
+            rect = pygame.rect.Rect(x * width, y * height, width, height)
+            images.append(image.subsurface(rect))
+    return images
+
+
+class HeroSprite(pygame.sprite.Sprite):
+    def __init__(self, (x, y)):
+        super(HeroSprite, self).__init__()
+        self.spritesheet = load_sheet('spritesheet.png', 64)
+        self.image = self.spritesheet[2]
+        self.rect = self.image.get_rect()
+        self.rect.midbottom = (x * 32 + 16, y * 32 + 32)
+        self.animations = []
+
+    def move(self, (dx, dy)):
+        self.animations.append(self.animation_slide((dx, dy)))
+
+    def animation_slide(self, (dx, dy)):
+        for step in xrange(8):
+            self.rect.move_ip(dx * 4, dy * 4)
+            yield
+
+    def update(self):
+        if self.animations:
+            try:
+                self.animations[0].next()
+            except StopIteration:
+                self.animations.pop(0)
+
+class Level(object):
+    def __init__(self, filename):
+        self.tiled_map = tmxloader.load_pygame(filename)
+        self.hero_position = 1, 1
+
+    def render(self, screen):
+        w = self.tiled_map.tilewidth
+        h = self.tiled_map.tileheight
+        get_image = self.tiled_map.getTileImage
+        for l, layer in enumerate(self.tiled_map.tilelayers):
+            for y in xrange(self.tiled_map.height):
+                for x in xrange(self.tiled_map.width):
+                    image = get_image(x, y, l)
+                    if image:
+                        screen.blit(image, (x * w, y * h))
+        x, y = self.hero_position
+
+    def get_properties(self, (x, y)):
+        properties = {}
+        for l, layer in enumerate(self.tiled_map.tilelayers):
+            properties.update(self.tiled_map.getTileProperties((x, y, l)) or {})
+        return properties
+
+    def is_blocked(self, (x, y)):
+        return self.get_properties((x, y)).get('block')
+
+    def move_hero(self, (dx, dy)):
+        x, y = self.hero_position
+        if not self.is_blocked((x + dx, y + dy)):
+            self.hero_position = x + dx, y + dy
+            return True
+        return False
+
+
+class Game(object):
+    def __init__(self):
+        pygame.display.init()
+        pygame.font.init()
+        self.screen = pygame.display.set_mode((800, 600))
+        self.screen.fill((0x66, 0x66, 0x66))
+        self.keys = {
+            pg.K_UP: (self.move_hero, (0, -1)),
+            pg.K_DOWN: (self.move_hero, (0, 1)),
+            pg.K_LEFT: (self.move_hero, (-1, 0)),
+            pg.K_RIGHT: (self.move_hero, (1, 0)),
+            pg.K_ESCAPE: (self.quit,),
+        }
+        self.sprites = pygame.sprite.RenderUpdates()
+
+    def load_level(self, filename):
+        self.level = Level(filename)
+        self.hero_sprite = HeroSprite(self.level.hero_position)
+        self.sprites.add(self.hero_sprite)
+        self.background = self.screen.copy()
+        self.level.render(self.background)
+        self.screen.blit(self.background, (0, 0))
+        self.sprites.draw(self.screen)
+        pygame.display.update()
+
+    def quit(self):
+        self.game_over = True
+
+    def move_hero(self, direction):
+        if self.level.move_hero(direction):
+            self.hero_sprite.move(direction)
+
+    def control(self):
+        for event in pygame.event.get():
+            if event.type == pg.QUIT:
+                self.quit()
+            elif event.type == pg.KEYDOWN:
+                try:
+                    action = self.keys[event.key]
+                except KeyError:
+                    pass
+                else:
+                    action[0](*action[1:])
+
+    def display(self):
+        self.sprites.clear(self.screen, self.background)
+        self.sprites.update()
+        dirty = self.sprites.draw(self.screen)
+        pygame.display.update(dirty)
+
+    def run(self):
+        self.clock = pygame.time.Clock()
+        self.game_over = False
+        while not self.game_over:
+            self.display()
+            self.control()
+            self.clock.tick(30)
+
+
+if __name__ == '__main__':
+    game = Game()
+    game.load_level('level.tmx')
+    game.run()
--- a/002/level.tmx	Sun Jun 17 16:34:43 2012 +0200
+++ b/002/level.tmx	Sun Jun 17 22:37:30 2012 +0200
@@ -2,7 +2,7 @@
 <map version="1.0" orientation="orthogonal" width="25" height="18" tilewidth="32" tileheight="32">
  <tileset firstgid="1" name="control" tilewidth="32" tileheight="32">
   <properties>
-   <property name="block" value="1"/>
+   <property name="control" value="1"/>
   </properties>
   <image source="control.png" trans="ff00ff" width="64" height="32"/>
   <tile id="0">
@@ -10,6 +10,11 @@
     <property name="block" value="1"/>
    </properties>
   </tile>
+  <tile id="1">
+   <properties>
+    <property name="block" value="1"/>
+   </properties>
+  </tile>
  </tileset>
  <tileset firstgid="3" name="tilesheet" tilewidth="32" tileheight="32">
   <image source="tilesheet.png" trans="ff00ff" width="288" height="192"/>