Radomir Dopieralski
europython@sheep.art.pl
http://lpc.opengameart.org
import pygame
import pygame.locals as pg
def initialize_screen():
screen = None
return screen
def load_and_display_image(screen):
def wait_for_quit():
if __name__ == '__main__':
screen = initialize_screen()
load_and_display_image(screen)
wait_for_quit()
def initialize_screen():
pygame.display.init()
screen = pygame.display.set_mode((800, 600))
screen.fill((0x66, 0x66, 0x66))
return screen
pygame.Surface((width, height), flags=0, depth=0, masks=None): return Surface
pygame.Surface((width, height), flags=0, Surface): return Surface
Surface.fill(color, rect=None, special_flags=0): return Rect
Surface.blit(source, dest, area=None, special_flags = 0): return Rect
Surface.get_rect(**kwargs): return Rect
def wait_for_quit():
while True:
event = pygame.event.wait()
if event.type == pg.QUIT:
return
pygame.event.wait(): return Event
pygame.event.get(): return Eventlist
def wait_for_quit():
pygame.display.update()
while True:
event = pygame.event.wait()
if event.type == pg.QUIT:
return
def load_and_display_image(screen):
image = pygame.image.load('cup.png')
screen.blit(image, (0, 0))
def load_and_display_image(screen):
image = pygame.image.load('cup.png')
image = image.convert()
image.set_colorkey((0xff, 0x00, 0xff))
screen_rect = screen.get_rect()
image_rect = image.get_rect()
screen.blit(image, (
(screen_rect.width - image_rect.width) // 2,
(screen_rect.height - image_rect.height) // 2,
)
)
pygame.Rect(left, top, width, height): return Rect
pygame.Rect((left, top), (width, height)): return Rect
pygame.Rect(object): return Rect
def load_and_display_image(screen):
image = pygame.image.load('cup.png')
image = image.convert()
image.set_colorkey((0xff, 0x00, 0xff))
screen_rect = screen.get_rect()
image_rect = image.get_rect()
image_rect.center = screen_rect.center
screen.blit(image, image_rect)
def load_images():
images = {
'X': pygame.image.load('wall.png').convert(),
'.': pygame.image.load('dirt.png').convert(),
'@': pygame.image.load('hero.png').convert(),
}
return images
def draw_map(screen, images):
screen_rect = screen.get_rect()
for y in xrange(screen_rect.h // 32):
for x in xrange(screen_rect.w // 32):
screen.blit(images['.'], (x * 32, y * 32))
def draw_map(screen, images, level_map):
for y, row in enumerate(level_map):
for x, square in enumerate(row):
screen.blit(images[square], (x * 32, y * 32))
>>> for i, c in enumerate('abc'):
... print i, c
...
0 a
1 b
2 c
def wait_for_quit(screen, images, level_map):
hero_x, hero_y = 1, 1
level_map = [list(row) for row in level_map]
level_map[hero_y][hero_x] = '@'
while True:
draw_map(screen, images, level_map)
pygame.display.update()
event = pygame.event.wait()
if event.type == pg.QUIT:
return
>>> level_map = ['abc', 'def', 'ghi']
>>> [list(row) for row in level_map]
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
def walk_around(screen, images, level_map):
hero_x, hero_y = 1, 1
level_map = [list(row) for row in level_map]
while True:
level_map[hero_y][hero_x] = '@'
draw_map(screen, images, level_map)
pygame.display.update()
event = pygame.event.wait()
level_map[hero_y][hero_x] = '.'
if event.type == pg.QUIT:
return
elif event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
return
elif event.key == pg.K_DOWN:
hero_y += 1
elif event.key == pg.K_UP:
hero_y -= 1
elif event.key == pg.K_LEFT:
hero_x -= 1
elif event.key == pg.K_RIGHT:
hero_x += 1
def move_hero(level_map, x, y, dx, dy):
if level_map[y + dy][x + dx] == '.':
level_map[y][x] = '.'
x += dx
y += dy
level_map[y][x] = '@'
return x, y
class Level(object):
def __init__(self, level_map):
self.level_map = [list(row) for row in level_map]
self.hero_position = 1, 1
self[self.hero_position] = '@'
def __setitem__(self, (x, y), square):
self.level_map[y][x] = square
def __getitem__(self, (x, y)):
return self.level_map[y][x]
def render(self, screen, images):
for y, row in enumerate(self.level_map):
for x, square in enumerate(row):
screen.blit(images[square], (x * 32, y * 32))
def move_hero(self, (dx, dy)):
x, y = self.hero_position
if self[x + dx, y + dy] == '.':
self[self.hero_position] = '.'
self.hero_position = x + dx, y + dy
self[self.hero_position] = '@'
class Game(object):
def __init__(self):
pygame.display.init()
self.screen = pygame.display.set_mode((800, 600))
self.screen.fill((0x66, 0x66, 0x66))
self.images = {
'X': pygame.image.load('wall.png').convert(),
'.': pygame.image.load('dirt.png').convert(),
'@': pygame.image.load('hero.png').convert(),
}
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, level_map):
self.level = Level(level_map)
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, self.images)
pygame.display.update()
def run(self):
self.game_over = False
while not self.game_over:
self.display()
self.control()
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, layers, tiles):
self.layers = []
for layer in layers:
self.layers.append([[tiles[c] for c in row] for row in layer])
def render(self, screen, tilesheet):
for layer in self.layers:
for y, row in enumerate(layer):
for x, tile in enumerate(row):
screen.blit(tilesheet[tile], (x * 32, y * 32))
LAYERS = [
[
'XxXxXXxxXxXxXxx',
'x.............X',
'x.............x',
'x...XxXxXxX...x',
'X...XxxXXxX...X',
'X...XxXXxXx...x',
'x.............X',
'x.............X',
'XXxxxXXxXxXXxXx',
],
[
' ',
' FMMMMMMMMMMMT ',
' E dWWWWWWWb K ',
' E K E K ',
' E K E K ',
' E K E K ',
' E YMMMMMMMP K ',
' LWWWWWWWWWWWJ ',
' ',
],
]
TILES = {
' ': -1, '.': 27, 'X': 11, 'd': 2, 'K': 3, 'Y': 4, 'b': 14, 'E': 15,
'P': 16, 'M': 10, 'W': 8, 'L': 7, 'F': 6, 'J': 13, 'T': 12, 'x': 9,
}
class Level(object):
def __init__(self, filename):
self.tiled_map = tmxloader.load_pygame(filename)
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))
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
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
pygame.sprite.Sprite(*groups): return Sprite
.image
.rect
.update(*args)
pygame.sprite.RenderUpdates(*sprites): return RenderUpdates
.draw(screen)
.clear(screen, background)
.update(*args)
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 Game(object):
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 move_hero(self, direction):
if self.level.move_hero(direction):
self.hero_sprite.move(direction)
def display(self):
self.sprites.clear(self.screen, self.background)
self.sprites.update()
dirty = self.sprites.draw(self.screen)
pygame.display.update(dirty)
class Game(object):
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 run(self):
self.clock = pygame.time.Clock()
self.game_over = False
while not self.game_over:
self.display()
self.control()
self.clock.tick(30)
pygame.time.Clock(): return Clock
Clock.tick(framerate=0): return milliseconds
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)
>>> def itergen():
... yield 1
... yield 2
... yield 3
...
>>> ig = itergen()
>>> ig.next()
1
>>> ig.next()
2
>>> ig.next()
3
>>> ig.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
class HeroSprite(pygame.sprite.Sprite):
def animation_slide(self, (dx, dy)):
facing = FACING[dx, dy]
self.image = self.spritesheet[facing]
for step in xrange(8):
self.rect.move_ip(dx * 4, dy * 4)
yield
class HeroSprite(pygame.sprite.Sprite):
def move(self, (dx, dy)):
self.animations.append(self.animation_walk((dx, dy)))
def animation_walk(self, (dx, dy)):
facing = FACING[dx, dy]
for step in xrange(8):
self.image = self.spritesheet[facing + step * 4 + 4]
self.rect.move_ip(dx * 4, dy * 4)
yield
self.image = self.spritesheet[facing]
class Game(object):
def control(self):
for event in pygame.event.get():
if event.type == pg.QUIT:
self.quit()
elif event.type == pg.KEYDOWN:
self.key = event.key
if not self.hero_sprite.animations:
keys = pygame.key.get_pressed()
for key, action in self.keys.iteritems():
if keys[key] or self.key == key:
action[0](*action[1:])
break
self.key = None
class HeroSprite(pygame.sprite.Sprite):
def __init__(self, (x, y)):
super(HeroSprite, self).__init__()
self.spritesheet = load_sheet('spritesheet.png', 64)
self.facing = 2
self.image = self.spritesheet[self.facing]
self.rect = self.image.get_rect()
self.rect.midbottom = (x * 32 + 16, y * 32 + 32)
self.animations = []
def move(self, (dx, dy)):
self.facing = FACING[dx, dy]
self.animations.append(self.animation_walk((dx, dy)))
def animation_walk(self, (dx, dy)):
for step in xrange(8):
self.image = self.spritesheet[self.facing + step * 4 + 4]
self.rect.move_ip(dx * 4, dy * 4)
yield
def animation_stand(self):
self.image = self.spritesheet[self.facing]
return
yield
def update(self):
if not self.animations:
self.animations.append(self.animation_stand())
while self.animations:
try:
self.animations[0].next()
return
except StopIteration:
self.animations.pop(0)
class ShadowSprite(pygame.sprite.Sprite):
def __init__(self, sprite):
super(ShadowSprite, self).__init__()
self.spritesheet = load_sheet('effects.png', 32)
self.image = self.spritesheet[0]
self.rect = self.image.get_rect()
self.image.set_alpha(0.6 * 255)
self.sprite = sprite
self.rect.midbottom = self.sprite.rect.midbottom
def update(self):
self.rect.midbottom = self.sprite.rect.midbottom
__init__.py
__main__.py
game.py
level.py
sprites.py
import os
def file_path(filename):
return os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'resources',
filename
)
class DecorationSprite(pygame.sprite.Sprite):
def __init__(self, (x, y)):
super(DecorationSprite, self).__init__()
self.spritesheet = resources.load_sheet('objects.png', 64)
self.image = self.spritesheet[0]
self.rect = self.image.get_rect()
self.rect.midbottom = (x * 32 + 16, y * 32 + 32)
class Level(object):
def objects(self):
w = self.tiled_map.tilewidth
h = self.tiled_map.tileheight
for og in self.tiled_map.objectgroups:
for o in og:
yield o.name, (o.x // w, o.y // h)
class Game(object):
def load_level(self, filename):
self.level = level.Level(filename)
for name, pos in self.level.objects():
sprite = sprites.DecorationSprite(pos)
self.sprites.add(sprites.DecorationSprite(pos))
self.hero_sprite = sprites.HeroSprite(self.level.hero_position)
self.sprites.add(self.hero_sprite)
self.shadow_sprites.add(sprites.ShadowSprite(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()
class SortedUpdates(pygame.sprite.RenderUpdates):
def sprites(self):
return sorted(self.spritedict.keys(),
key=lambda sprite: getattr(sprite, "depth", 0))
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygame
from intro import Intro
pygame.display.init()
pygame.font.init()
pygame.display.set_mode((800, 600))
scenes = [Intro()]
while scenes:
scene = scenes.pop()
scene.run(scenes)
# -*- coding: utf-8 -*-
import pygame
import pygame.locals as pg
import resources
import game
class Intro(object):
def __init__(self):
self.screen = pygame.display.get_surface()
self.screen.fill((0x66, 0x66, 0x66))
self.background = pygame.image.load(
resources.file_path('intro.png')).convert()
def run(self, scenes):
self.screen.blit(self.background, (0, 0))
pygame.display.update()
while True:
event = pygame.event.wait()
if event.type == pg.QUIT:
return
elif event.type == pg.KEYDOWN:
scene = game.Game()
scene.load_level('level.tmx')
scenes.append(self)
scenes.append(scene)
return
class Game(object):
def refresh(self):
self.level.render(self.background)
self.screen.blit(self.background, (0, 0))
self.sprites.draw(self.screen)
pygame.display.update()
def run(self, scenes):
self.refresh()
self.clock = pygame.time.Clock()
self.game_over = False
while not self.game_over:
self.display()
self.control()
self.clock.tick(30)
class Pause(object):
def __init__(self):
self.screen = pygame.display.get_surface()
self.background = pygame.surface.Surface(self.screen.get_size(),
pg.SRCALPHA)
self.background.fill((0x00, 0x00, 0x00, 0x66))
font = pygame.font.Font(None, 24)
text = font.render('Paused.', True, (0xff, 0xff, 0xff))
rect = text.get_rect()
rect.center = self.background.get_rect().center
self.background.blit(text, rect)
def run(self, scenes):
self.screen.blit(self.background, (0, 0))
pygame.display.update()
while True:
event = pygame.event.wait()
if event.type == pg.QUIT or event.type == pg.KEYDOWN:
return
class Game(object):
def control(self, scenes):
for event in pygame.event.get():
if event.type == pg.QUIT:
sys.exit()
elif event.type == pg.KEYDOWN:
self.key = event.key
if self.key == pg.K_p:
scenes.append(self)
scenes.append(pause.Pause())
self.game_over = True
if not self.hero_sprite.animations:
keys = pygame.key.get_pressed()
for key, action in self.keys.iteritems():
if keys[key] or self.key == key:
action[0](*action[1:])
break
self.key = None
Questions?
pygame@sheep.art.pl