class CollectFruit: def __init__(self): self.game = Game() self.tm = TiledMap(self.game) self.player = Sprite(self.game, 'b.pac_right', (4, 1), speed=4) self.tm.set_map(FRUITMAP) self.draw() self.events = None self.score = 0 def draw(self): self.player.move() self.tm.draw() self.player.draw() self.check_player_square() def move(self, direction): if self.player.finished: nearpos = self.player.pos + direction near = self.tm.at(nearpos) if near == WALL_TILE: return self.player.add_move(direction) def check_player_square(self): field = self.tm.at(self.player.pos) if field == EXIT_TILE: self.game.exit() elif field in FRUIT: self.score += 100 self.tm.set_tile(self.player.pos, '.') def run(self): self.game.event_loop(figure_moves=self.move, draw_func=self.draw)
class Boxes: def __init__(self): self.screen = Screen(Vector(600, 400), 'data/background.png') self.frame = Frame(self.screen, Rect(64, 64, 320, 320)) tile_factory = TileFactory('data/tiles.conf') self.tm = TiledMap(self.frame, tile_factory) self.player = Sprite(self.frame, tile_factory.get('b.tail'), Vector(4, 1), speed=2) self.tm.set_map(BOXMAP) self.draw() self.events = None def draw(self): self.tm.draw() self.player.draw() pygame.display.update() def move(self, direction): nearpos = self.player.pos + direction farpos = nearpos + direction near = self.tm.at(nearpos) far = self.tm.at(farpos) if near == '#': return if near in 'xX' and far in '#xX': return else: # move possible moves = MoveGroup() self.player.add_move(direction) moves.add(self.player) if near in 'xX': # crate moved floor = near=='x' and '.' or '*' insert = far=='*' and 'X' or 'x' moves.add(MapMove(self.tm, nearpos, direction, 1, floor_tile=floor, insert_tile=insert)) wait_for_move(moves, self.screen, self.draw, 0.01) self.tm.cache_map() self.draw() self.check_complete() def check_complete(self): s = self.tm.get_map() if s.count('X') == 4: print("\nCongratulations!\n") time.sleep(2) self.events.exit_signalled() def run(self): self.events = EventGenerator() self.events.add_listener(FigureMoveListener(self.move)) self.events.add_listener(ExitListener(self.events.exit_signalled)) with draw_timer(self, self.events): self.events.event_loop()
class Pac: def __init__(self, frame, tile_factory, pos, level): self.level = level self.tile_factory = tile_factory tile = tile_factory.get('b.pac_right') self.sprite = Sprite(frame, tile, pos, speed=4) self.eaten = None self.score = 0 self.buffered_move = None def set_direction(self, direction): self.sprite.tile = self.tile_factory.get(PAC_TILES[direction]) def move(self, direction): if not self.sprite.finished: self.buffered_move = direction return newpos = self.sprite.pos + direction self.set_direction(direction) tile = self.level.at(newpos) if tile != '#': self.sprite.add_move(direction, when_finished=self.try_eating) def try_eating(self): tile = self.level.at(self.sprite.pos) if tile != '.': self.level.remove_dot(self.sprite.pos) if tile == '*': self.score += 100 else: self.score += 1000 self.eaten = tile def update(self): """Try eating dots and fruit""" if self.sprite.finished and self.buffered_move: self.move(self.buffered_move) self.buffered_move = None if not self.sprite.finished: self.sprite.move() def draw(self): self.sprite.draw() def collision(self, sprites): for sprite in sprites: if self.sprite.pos == sprite.sprite.pos: return True def die(self): self.buffered_move = None self.sprite.path = []
class Boxes: def __init__(self): self.game = Game() self.tm = TiledMap(self.game) self.player = Sprite(self.game, 'b.tail', (4, 1), speed=4) self.tm.set_map(BOXMAP) def draw(self): self.tm.draw() self.player.draw() def move(self, direction): nearpos = self.player.pos + direction farpos = nearpos + direction near = self.tm.at(nearpos) far = self.tm.at(farpos) if near == '#': return if near in 'xX' and far in '#xX': return else: # move possible self.player.add_move(direction) moves = [self.player] if near in 'xX': # crate moved floor = '.' if near == 'x' else '*' insert = 'X' if far == '*' else 'x' moves.append(MapMove(self.tm, nearpos, direction, 4, floor_tile=floor, insert_tile=insert)) self.game.wait_for_move(moves, self.draw, 0.02) self.draw() self.check_complete() def check_complete(self): s = self.tm.get_map() if s.count('X') == 4: print("\nCongratulations!\n") time.sleep(2) self.game.exit() def run(self): self.game.event_loop(figure_moves=self.move, draw_func=self.draw)
class SpaceMine: def __init__(self, frame, tile_factory, pos): tile = tile_factory.get('+') self.sprite = Sprite(frame, tile, pos) [self.sprite.add_move(LEFT) for x in range(10)] def draw(self): self.sprite.draw()
class CollectFruit: def __init__(self, screen): self.screen = screen self.frame = Frame(self.screen, Rect(64, 64, 320, 320)) tile_factory = TileFactory('data/tiles.conf') self.tm = TiledMap(self.frame, tile_factory) self.player = Sprite(self.frame, tile_factory.get('b.pac_right'), Vector(4, 1), speed=2) self.tm.set_map(FRUITMAP) self.draw() self.events = None self.score = 0 def draw(self): self.tm.draw() self.player.draw() pygame.display.update() def move(self, direction): nearpos = self.player.pos + direction near = self.tm.at(nearpos) if near == '#': return self.player.add_move(direction) wait_for_move(self.player, self.screen, self.draw, 0.01) self.check_player_square() def check_player_square(self): field = self.tm.at(self.player.pos) if field == '*': time.sleep(1) self.events.exit_signalled() elif field in 'abcdefgh': self.score += 100 self.tm.set_tile(self.player.pos, '.') self.tm.cache_map() self.draw() def run(self): self.events = EventGenerator() self.events.add_listener(FigureMoveListener(self.move)) self.events.add_listener(ExitListener(self.events.exit_signalled)) with draw_timer(self, self.events): self.events.event_loop()
class Ghost: def __init__(self, game, pos, level): self.sprite = Sprite(game, GHOST_TILES[0], pos, speed=2) self.sprite.tile = AnimatedTile(GHOST_TILES, game.tile_factory, game.frame, pos, loop=True) self.level = level self.direction = RIGHT self.set_random_direction() def get_possible_moves(self): result = [] directions = [LEFT, RIGHT, UP, DOWN] for vector in directions: if not vector * -1 == self.direction: newpos = self.sprite.pos + vector tile = self.level.at(newpos) if tile != '#': result.append(vector) if not result: result = [self.direction * (-1)] return result def set_random_direction(self): moves = self.get_possible_moves() self.direction = random.choice(moves) def move(self): if self.sprite.finished: self.set_random_direction() self.sprite.add_move(self.direction) else: self.sprite.tile.move() self.sprite.move() def update(self): self.move() def draw(self): self.sprite.draw()
class Ghost: def __init__(self, frame, tile_factory, pos, level): tile = tile_factory.get(GHOST_TILE) self.level = level self.sprite = Sprite(frame, tile, pos, self.level.get_speed()) self.direction = None self.set_random_direction() self.stuck = True def get_possible_moves(self): result = [] directions = [LEFT, RIGHT, UP, DOWN] for vector in directions: if vector * -1 != self.direction: newpos = self.sprite.pos + vector tile = self.level.at(newpos) if tile != '#': result.append(vector) if not result: result = [self.direction * (-1)] return result def set_random_direction(self): moves = self.get_possible_moves() i = random.randint(0, len(moves) - 1) self.direction = moves[i] def move(self): if self.sprite.finished: self.set_random_direction() self.sprite.add_move(self.direction) elif not self.stuck: self.sprite.move() def update(self): self.move() def draw(self): self.sprite.draw() def unstuck(self): self.stuck = False
class MiniGame: def __init__(self): self.game = Game() self.map = TiledMap(self.game) self.map.fill_map('#', (10, 10)) self.map.set_map(MAZE) self.map.set_tile((4,4), 'a') self.game.frame.print_text("Hello World", (32, 330)) self.sprite = Sprite(self.game, 'b.pac_right', (1, 1), speed=4) self.game.event_loop(figure_moves=self.move, draw_func=self.draw) def draw(self): self.sprite.move() self.map.draw() self.sprite.draw() def move(self, direction): self.sprite.add_move(direction)
class SpaceshipSprite: def __init__(self, frame, tile_factory, pos, level): self.frame = frame self.tile_factory = tile_factory self.level = level self.sprite = None self.create_sprite(pos) self.direction = DOWN self.crashed = False self.finished = False def is_moving(self): if not self.sprite.finished: return True def create_sprite(self, pos): tile = self.tile_factory.get('rot.rechts') self.sprite = Sprite(self.frame, tile, pos, SHIP_SPEED) def set_direction(self, direction): if direction in (UP, DOWN): self.direction = direction self.sprite.add_move(self.direction) newpos = self.sprite.pos + self.direction #tile = self.level.at(newpos) #if tile in ('#', '+'): # self.crashed = True def draw(self): if self.is_moving(): self.sprite.move() self.sprite.draw() @property def position(self): return self.sprite.pos def move_forward(self): pass
class Ghost: def __init__(self, frame, tile_factory, pos, level): tile = tile_factory.get(GHOST_TILE) self.sprite = Sprite(frame, tile, pos, speed=2) self.level = level self.direction = None self.set_random_direction() def get_possible_moves(self): result = [] directions = [LEFT, RIGHT, UP, DOWN] for vector in directions: if vector * -1 != self.direction: newpos = self.sprite.pos + vector tile = self.level.at(newpos) if tile != '#': result.append(vector) if not result: result = [self.direction * (-1)] return result def set_random_direction(self): moves = self.get_possible_moves() i = random.randint(0, len(moves) - 1) self.direction = moves[i] def move(self): if self.sprite.finished: self.set_random_direction() self.sprite.add_move(self.direction) else: self.sprite.move() def update(self): self.move() def draw(self): self.sprite.draw()
class SpriteTests(TestCase): def setUp(self): self.factory = TEST_GAME_CONTEXT.tile_factory self.tile = self.factory.get('g') self.frame = Frame(TEST_GAME_CONTEXT.screen, Rect(40, 50, 160, 160)) self.sprite = Sprite(self.frame, self.tile, Vector(1, 1), speed=2) def test_sprite_pos(self): """Sprite has a position.""" sprite = Sprite(self.frame, self.factory.get('g'), pos=Vector(4, 3)) self.assertEqual(sprite.pos.x, 4) self.assertEqual(sprite.pos.y, 3) def move(self): """Moves sprite until movement terminates.""" while self.sprite.is_moving(): self.sprite.move() self.frame.clear() self.sprite.draw() pygame.display.update() time.sleep(SHORT_DELAY) @showdoc def test_move_sprite(self): """Sprite moves east, then southeast.""" self.sprite.add_move(RIGHT) self.sprite.add_move(DOWNRIGHT) self.move() self.assertEqual(self.sprite.pos.x, 3) self.assertEqual(self.sprite.pos.y, 2) @showdoc def test_priority_move_sprite(self): """Sprite moves southeast, then east.""" self.sprite.add_move(RIGHT) self.sprite.add_move(DOWNRIGHT, True) self.move()
def test_sprite_list(self, game): """Two sprites are moving.""" sprites = SpriteList() s1 = Sprite(game, 'g', pos=(1, 0), speed=2) s2 = Sprite(game, 'b', pos=(1, 1), speed=4) sprites.append(s1) sprites.append(s2) s1.add_move(RIGHT) s1.add_move(DOWN) s2.add_move(DOWN) while sprites.is_moving(): sprites.update() self.frame.clear() sprites.draw() pygame.display.update() time.sleep(config.SHORT_DELAY)
def test_sprite_list(self): """Two sprites are moving.""" sprites = SpriteList() s1 = Sprite(self.frame, self.factory.get('g'), pos=Vector(1,0), speed=2) s2 = Sprite(self.frame, self.factory.get('b'), pos=Vector(1,1), speed=4) sprites.append(s1) sprites.append(s2) s1.add_move(RIGHT) s1.add_move(DOWN) s2.add_move(DOWN) while sprites.is_moving(): sprites.update() self.frame.clear() sprites.draw() pygame.display.update() time.sleep(SHORT_DELAY)
class MazeGame: def __init__(self): self.game = Game() self.map = TiledMap(self.game) self.map.set_map(MAZE) self.fruechte = self.fruechte_zaehlen(MAZE) self.sprite = Sprite(self.game, 'b.pac_right', (1, 1), speed=4) self.geist = Sprite(self.game, 'b.ghost_center', (8, 8), speed=4) self.game.event_loop(figure_moves=self.move, draw_func=self.draw) def fruechte_zaehlen(self, level): """Zählt die einzusammelnden Obststücke""" return len([c for c in level if c in "abcdefgh"]) def draw(self): """ Alles bewegen und zeichnen. Wird von event_loop() regelmäßig aufgerufen """ self.map.draw() self.sprite.move() self.sprite.draw() self.geist_bewegen() self.geist.draw() self.frucht_fressen() self.kollision() def geist_bewegen(self): """Bewegt den Geist, aber nicht durch Wände""" if self.geist.finished: richtung = random.choice([UP, DOWN, LEFT, RIGHT]) neues_feld = self.geist.pos + richtung if self.map.at(neues_feld) != '#': self.geist.add_move(richtung) self.geist.move() def kollision(self): """Prüft, ob Geist und Spieler auf dem gleichen Feld sind.""" if self.sprite.pos == self.geist.pos: self.game.frame.print_text('VERLOREN!!!', (50, 400)) pygame.display.update() time.sleep(5) self.game.exit() def frucht_fressen(self): """Mampft ein Obststück weg""" if self.map.at(self.sprite.pos) in 'abcdefgh': self.map.set_tile(self.sprite.pos, '.') self.fruechte -= 1 if self.fruechte == 0: self.game.frame.print_text('GEWONNEN!!!', (50, 400)) pygame.display.update() time.sleep(5) self.game.exit() def move(self, direction): """Bewegt die Spielfigur. Wird von event_loop() aufgerufen, wenn Pfeiltaste gedrückt""" neues_feld = self.sprite.pos + direction if self.sprite.finished and \ not self.map.at(neues_feld) == '#': self.sprite.add_move(direction)
class SnakeSprite: def __init__(self, frame, tile_factory, pos, level): self.frame = frame self.tile_factory = tile_factory self.level = level self.head = None self.tail = [] self.tail_waiting = [] self.create_head(pos) self.direction = RIGHT self.past_directions = [] self.crashed = False self.eaten = '' @property def length(self): return 1+ len(self.tail) + len(self.tail_waiting) @property def sprites(self): return [self.head] + self.tail def is_moving(self): if not self.head.finished: return True def create_head(self, pos): tile = self.tile_factory.get('b.pac_right') self.head = Sprite(self.frame, tile, pos, HEAD_SPEED) def set_direction(self, direction): # prevent reverse move if self.tail and direction == self.past_directions[0] * -1: return self.direction = direction headtile = HEAD_TILES[direction] self.head.tile = self.tile_factory.get(headtile) def draw(self): for s in self.sprites: s.draw() def move(self): if self.is_moving(): for s in self.sprites: s.move() @property def positions(self): return [self.head.pos] + [seg.pos for seg in self.tail] def grow(self): tile = self.tile_factory.get('b.tail') self.tail_waiting.append(Sprite(self.frame, tile, self.positions[-1], HEAD_SPEED)) if not self.past_directions: self.past_directions.append(self.direction) else: self.past_directions.append(self.past_directions[-1]) def move_forward(self): newpos = self.head.pos + self.direction tile = self.level.at(newpos) if newpos in self.positions or tile == '#': self.crashed = True else: self.head.add_move(self.direction) if self.tail_waiting: self.tail.append(self.tail_waiting.pop()) for sprite, direction in zip(self.tail, self.past_directions): sprite.add_move(direction) if tile != '.': self.grow() self.eaten = tile if len(self.tail) > 0: self.past_directions = [self.direction] + self.past_directions[:-1]
class Pac: def __init__(self, game, pos, level): self.game = game self.level = level self.sprite = Sprite(game, 'b.pac_right', pos, speed=4) self.set_direction(RIGHT) self.eaten = None self.score = 0 self.buffered_move = None def set_direction(self, direction): tiles = PAC_TILES[direction] tile = AnimatedTile(tiles, self.game.tile_factory, self.game.frame, self.sprite.pos, loop=True) self.sprite.tile = tile self.direction = direction self.move() def move(self, direction=None): if direction is None: direction = self.direction if not self.sprite.finished: self.buffered_move = direction return newpos = self.sprite.pos + direction tile = self.level.at(newpos) if tile != '#': self.sprite.add_move(direction, when_finished=self.try_eating) def try_eating(self): tile = self.level.at(self.sprite.pos) if tile != '.': self.level.remove_dot(self.sprite.pos) if tile == '*': self.score += 100 else: self.score += 1000 self.eaten = tile def update(self): """Try eating dots and fruit""" self.sprite.tile.move() if self.sprite.finished and not self.buffered_move is None: self.move(self.buffered_move) self.buffered_move = None if not self.sprite.finished: self.sprite.move() else: self.move() def draw(self): self.sprite.draw() def collision(self, ghosts): for g in ghosts: if self.sprite.pos == g.sprite.pos: return True def die(self): self.buffered_move = None self.sprite.path = []
class Player: def __init__(self, frame, tile_factory, pos, level): self.level = level self.tile_factory = tile_factory tile = tile_factory.get('p_red_d') self.sprite = Sprite(frame, tile, pos, speed=4) self.eaten = None self.buffered_move = None self.color = RED self.direction = DOWN self.lives = 3 def get_sprite_from_table(self, color, direction): row = 0 col = 0 if color == RED: row = 0 elif color == BLUE: row = 1 elif color == YELLOW: row = 2 elif color == PURPLE: row = 3 elif color == GREEN: row = 4 elif color == ORANGE: row = 5 if direction == UP: col = 0 if direction == DOWN: col = 1 if direction == LEFT: col = 2 if direction == RIGHT: col = 3 return self.tile_factory.get(FIGURE_SPRITES[row][col]) def set_direction(self, direction): self.direction = direction self.sprite.tile = self.get_sprite_from_table(self.color, self.direction) def set_color(self, color): self.color = color self.sprite.tile = self.get_sprite_from_table(self.color, self.direction) def move(self, direction): if not self.sprite.finished: self.buffered_move = direction return nearpos = self.sprite.pos + direction self.set_direction(direction) near = self.level.at(nearpos) allowedToMove = near == self.color and near != '#' or near == 'w' or near == 'i' or near == 's' # Allows movement to portal tiles if player color matches if near == '1' and BLUE == self.color: allowedToMove = True elif near == '2' and RED == self.color: allowedToMove = True elif near == '3' and YELLOW == self.color: allowedToMove = True elif near == '4' and GREEN == self.color: allowedToMove = True elif near == '5' and ORANGE == self.color: allowedToMove = True elif near == '6' and PURPLE == self.color: allowedToMove = True if allowedToMove: self.sprite.add_move(direction) movesound.play() else: blocksound.play() def update(self): if self.sprite.finished and self.buffered_move: self.move(self.buffered_move) self.buffered_move = None if not self.sprite.finished: self.sprite.move() def draw(self): self.sprite.draw() def collision(self, sprites): for sprite in sprites: if self.sprite.pos == sprite.sprite.pos: return True def die(self): self.buffered_move = None self.sprite.path = [] damsound.play()
class SnakeSprite: def __init__(self, game, pos, level): self.game = game self.level = level self.head = None self.tail = [] self.tail_waiting = [] self.head = Sprite(self.game, 'b.pac_right', pos, HEAD_SPEED) self.direction = RIGHT self.past_directions = [] self.crashed = False self.eaten = '' @property def length(self): return 1 + len(self.tail) + len(self.tail_waiting) @property def sprites(self): return [self.head] + self.tail def is_moving(self): if not self.head.finished: return True def set_direction(self, direction): # prevent reverse move if len(self.tail) > 0 and direction == self.past_directions[0] * -1: return self.direction = direction headtile = HEAD_TILES[str(direction)] self.head.tile = self.game.get_tile(headtile) if EASY: self.move_forward() def draw(self): for s in self.sprites: s.draw() def move(self): if self.is_moving(): for s in self.sprites: s.move() @property def positions(self): return [self.head.pos] + [seg.pos for seg in self.tail] def grow(self): self.tail_waiting.append( Sprite(self.game, 'b.tail', self.positions[-1], HEAD_SPEED)) if not self.past_directions: self.past_directions.append(self.direction) else: self.past_directions.append(self.past_directions[-1]) def move_forward(self): newpos = self.head.pos + self.direction tile = self.level.tmap.at(newpos) if newpos in self.positions or tile == '#': self.crashed = True else: self.head.add_move(self.direction) if self.tail_waiting: self.tail.append(self.tail_waiting.pop()) for sprite, direction in zip(self.tail, self.past_directions): sprite.add_move(direction) if tile != '.': self.grow() self.eaten = tile if len(self.tail) > 0: self.past_directions = [self.direction ] + self.past_directions[:-1]