class ScoreTest(unittest.TestCase): def setUp(self): self.score = Score(0) def testAddingWorks(self): self.score.add_from([5, 5, 4]) self.assertEqual(self.score.total, 29) self.score.add(3) self.assertEqual(self.score.total, 87) def testKeepsTrackOfScoreString(self): self.score.add_from([1, 2, 3, 4, 5]) self.assertEqual(self.score.string, [0, 1, 2, 3, 4, 5])
def main(): parser = argparse.ArgumentParser(description='assign rides to cars') parser.add_argument('file_in', type=str, nargs='+', help='<file basename>.in file input') parser.add_argument('--solver', type=str, default='ride', choices=('ride', 'flow', 'car'), help='solver') parser.add_argument('--debug', action='store_true', help='for debug purpose') parser.add_argument('--wait', action='store_true', help='display wait time') parser.add_argument('--rides', action='store_true', help='display rides taken and left') parser.add_argument('--score', action='store_true', help='display raw score and bonus score') parser.add_argument('--progress', action='store_true', help='display progress bar') args = parser.parse_args() set_log_level(args) solver = get_solver(args.solver) score_total = Score() batch = len(args.file_in) > 1 # several input files for file_in in args.file_in: (rides_list, rows, columns, vehicles, rides, bonus, steps) = parse_input(file_in) solution, score = solver.get_solution(rides_list, rows, columns, vehicles, rides, bonus, steps, args) print_score(score, args) score_total.add(score) file_out = get_file_out_name(file_in) dump_rides(solution, file_out) if batch: print_score(score_total, args)
from score import Score score = Score() print(score) score.add(5) print(score) score.decrease(10) print(score)
class Game: sky = None def __init__(self, screen, endless = False): self.screen = screen self.sharks = [] self.shark_sprites = pygame.sprite.Group() self.player = Steamboat() self.player_sprite = pygame.sprite.Group() self.player_sprite.add(self.player) self.health = Health() self.health_sprite = pygame.sprite.Group() self.health_sprite.add(self.health) self.damage_count = 0 self.t = 0 self.water = Water.global_water #Water.global_water = self.water self.water_sprite = pygame.sprite.Group() self.water_sprite.add(self.water) if not Game.sky: Game.sky = util.load_image("taivas") Game.sky = pygame.transform.scale(self.sky, (SCREEN_WIDTH, SCREEN_HEIGHT)) self.cannonballs = [] self.cannonball_sprites = pygame.sprite.Group() self.pirates = [] self.pirate_sprites = pygame.sprite.Group() self.titanic = None self.titanic_sprite = pygame.sprite.Group() self.seagulls = [] self.seagull_sprites = pygame.sprite.Group() self.particles = Particles() self.particle_sprite = pygame.sprite.Group() self.particle_sprite.add(self.particles) self.mines = [] self.mine_sprites = pygame.sprite.Group() self.score = Score() self.score_sprite = pygame.sprite.Group() self.score_sprite.add(self.score) self.powerups = [] self.powerup_sprites = pygame.sprite.Group() self.level = Level(endless) self.lastshot = MIN_FIRE_DELAY + 1 self.gameover = False self.gameover_image = None self.gameover_rect = None self.done = False self.pause = False self.pause_image = util.bigfont.render("Pause", Variables.alpha, (0,0,0)) self.pause_rect = self.pause_image.get_rect() self.pause_rect.center = self.screen.get_rect().center self.spacepressed = None def run(self): while not self.done: if not self.pause: if not self.gameover: self.spawn_enemies() self.update_enemies() self.player.update() self.health.update() cloud.update() for cb in self.cannonballs: if not cb.underwater: #~ particle_point=cb.rect.left, cb.rect.top particle_point = cb.tail_point() self.particles.add_trace_particle(particle_point) particle_point = [particle_point[i] + cb.vect[i]/2 for i in (0,1)] self.particles.add_trace_particle(particle_point) if cb.special and (not cb.underwater or rr()>0.6) : particle_point = cb.tail_point() self.particles.add_explosion_particle(particle_point) und_old=cb.underwater cb.update() if cb.underwater and not und_old: for i in range(5): particle_point=cb.rect.right-4.0+rr()*8.0, cb.rect.top+rr()*2.0 self.particles.add_water_particle(particle_point) if (cb.rect.right < 0 and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH and cb.vect[0] > 0) or (cb.rect.top > SCREEN_HEIGHT): self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) self.score.update() # Add steam particles if Variables.particles: particle_point = self.player.get_point((5.0 + rr() * 9.0, 0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery if self.spacepressed and self.t > self.spacepressed + FPS * 3: pass #~ self.particles.add_fire_steam_particle(particle_point) else: self.particles.add_steam_particle(particle_point) particle_point = self.player.get_point((19.0 + rr() * 7.0, 5.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery if self.spacepressed and self.t > self.spacepressed + FPS * 3: pass #~ self.particles.add_fire_steam_particle(particle_point) else: self.particles.add_steam_particle(particle_point) if self.titanic: for j in range(4): particle_point = self.titanic.get_point((49 + rr() * 9.0 + 28 * j, 25)) particle_point[0] += self.titanic.rect.centerx particle_point[1] += self.titanic.rect.centery self.particles.add_steam_particle(particle_point) self.particles.update() self.water.update() if self.player.splash: if Variables.particles: for i in range(10): r = rr() x = int(r * self.player.rect.left + (1.0-r) * self.player.rect.right) point = (x, self.water.get_water_level(x)) self.particles.add_water_particle(point) for powerup in self.powerups: powerup.update() if powerup.picked: self.powerups.remove(powerup) self.powerup_sprites.remove(powerup) if not self.gameover: self.check_collisions() if self.health.hearts_left == 0 and not self.player.dying: self.player.die() if self.player.dying and not self.player.dead: if Variables.particles: self.particles.add_explosion_particle((self.player.rect.centerx, self.player.rect.centery)) self.particles.add_debris_particle((self.player.rect.centerx, self.player.rect.centery)) if self.player.dead: #self.done = True self.set_gameover() if self.damage_count > 0: self.damage_count -= 1 self.lastshot += 1 self.t += 1 self.draw() self.handle_events() return self.score.get_score() def damage_player(self): self.health.damage() for i in range(10): particle_point = self.player.get_point((rr() * 26.0, rr() * 10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery self.particles.add_debris_particle(particle_point) self.player.blinks+=12 def set_gameover(self, message = "Game Over"): self.gameover = True images = [] height = 0 width = 0 for text in message.split("\n"): images.append(util.bigfont.render(text, Variables.alpha, (0,0,0))) height += images[-1].get_height() if images[-1].get_width() > width: width = images[-1].get_width() self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32) self.gameover_image.fill((0,0,0,0)) for i in range(len(images)): rect = images[i].get_rect() rect.top = i * images[i].get_height() rect.centerx = width / 2 self.gameover_image.blit(images[i], rect) self.gameover_rect = self.gameover_image.get_rect() self.gameover_rect.center = self.screen.get_rect().center def take_screenshot(self): i = 1 filename = "sshot.tga" while os.path.exists(filename): i += 1 filename = "sshot" + str(i) + ".tga" pygame.image.save(self.screen, filename) print("Screenshot saved as " + filename) def handle_events(self): nextframe = False framecount = 0 while not nextframe: # wait until there's at least one event in the queue #nextframe = True pygame.event.post(pygame.event.wait()) for event in pygame.event.get(): #event = pygame.event.wait() if event.type == QUIT or \ event.type == KEYDOWN and event.key == K_ESCAPE: self.done = True nextframe = True elif event.type == NEXTFRAME: framecount += 1 nextframe = True elif self.gameover: if event.type == JOYBUTTONDOWN: self.done = True nextframe = True elif event.type == KEYDOWN: self.done = True nextframe = True continue elif event.type == JOYAXISMOTION: if event.axis == 0: if event.value < -0.5: self.player.move_left(True) elif event.value > 0.5: self.player.move_right(True) else: self.player.move_left(False) self.player.move_right(False) elif event.type == JOYBUTTONDOWN: if event.button == 0: if not self.pause: self.player.jump() elif event.button == 1: if not self.pause: if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in range(4): self.particles.add_fire_steam_particle(particle_point) self.lastshot = 0 self.spacepressed = self.t elif event.button == 5: self.take_screenshot() elif event.button == 8: self.set_pause() elif event.type == KEYDOWN: if event.key == K_LEFT: self.player.move_left(True) elif event.key == K_RIGHT: self.player.move_right(True) elif event.key == K_SPACE: if not self.pause: # Only 3 cannonballs at once # Maximum firing rate set at the top if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in range(4): self.particles.add_fire_steam_particle(particle_point) self.lastshot = 0 self.spacepressed = self.t elif event.key == K_UP: if not self.pause: self.player.jump() elif event.key == K_s: self.take_screenshot() elif event.key == K_p: self.set_pause() elif event.type == KEYUP: if event.key == K_LEFT: self.player.move_left(False) elif event.key == K_RIGHT: self.player.move_right(False) elif event.key == K_SPACE: if not self.pause: if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle, special=True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in range(30): self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3))) self.lastshot = 0 self.spacepressed = None elif event.type == JOYBUTTONUP: if event.button == 1: if not self.pause: if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle, special=True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in range(30): self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3))) self.lastshot = 0 self.spacepressed = None #if framecount > 1: # print str(self.t) + ": missed " + str(framecount - 1) + " frames!" def set_pause(self): self.pause = not self.pause #if framecount > 1: # print str(self.t) + ": missed " + str(framecount - 1) + " frames!" def set_pause(self): self.pause = not self.pause def draw(self): self.screen.blit(Game.sky, self.screen.get_rect()) self.health_sprite.draw(self.screen) self.score_sprite.draw(self.screen) self.player_sprite.draw(self.screen) self.powerup_sprites.draw(self.screen) self.pirate_sprites.draw(self.screen) if self.titanic: self.titanic_sprite.draw(self.screen) self.seagull_sprites.draw(self.screen) cloud.draw(self.screen) self.shark_sprites.draw(self.screen) self.mine_sprites.draw(self.screen) self.cannonball_sprites.draw(self.screen) self.water_sprite.draw(self.screen) if Variables.particles: self.particle_sprite.draw(self.screen) if self.pause: self.screen.blit(self.pause_image, self.pause_rect) if self.gameover: self.screen.blit(self.gameover_image, self.gameover_rect) if self.level.t < 120: image = None i = 0 if self.level.phase < len(self.level.phase_messages): for text in self.level.phase_messages[self.level.phase].split("\n"): image = util.smallfont.render(text, Variables.alpha, (0,0,0)) rect = image.get_rect() rect.centerx = self.screen.get_rect().centerx rect.top = 100 + rect.height * i blit_image = pygame.Surface((image.get_width(), image.get_height())) blit_image.fill((166,183,250)) blit_image.set_colorkey((166,183,250)) blit_image.blit(image, image.get_rect()) if self.level.t > 60: blit_image.set_alpha(255 - (self.level.t - 60) * 255 / 60) self.screen.blit(blit_image, rect) i += 1 pygame.display.flip() def check_collisions(self): collisions = PixelPerfect.spritecollide_pp(self.player, self.powerup_sprites, 0) for powerup in collisions: if not powerup.fading: if not self.player.dying: self.health.add() powerup.pickup() collisions = PixelPerfect.spritecollide_pp(self.player, self.mine_sprites, 0) for mine in collisions: if not mine.exploding: if not self.player.dying: self.damage_player() mine.explode() collisions = PixelPerfect.spritecollide_pp(self.player, self.shark_sprites, 0) for shark in collisions: if not shark.dying: if not self.player.dying: self.damage_player() shark.die() collisions = PixelPerfect.spritecollide_pp(self.player, self.cannonball_sprites, 0) for cb in collisions: if not self.player.dying: self.damage_player() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) if (Variables.sound): Mine.sound.play() # Umm... the mine has a nice explosion sound. collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.shark_sprites, 0, 0) for cb in dict.keys(collisions): for shark in collisions[cb]: # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks. if not shark.dying and cb.vect[0] > 0: self.score.add(15) shark.die() # give her a part of ball's momentum: shark.dx+=cb.vect[0]*0.6 shark.dy+=cb.vect[1]*0.4 if not cb.special: self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.seagull_sprites, 0, 0) for cb in dict.keys(collisions): for seagull in collisions[cb]: # cb.vect test is a rude hack preventing pirates from killing seagulls if not seagull.dying and cb.vect[0] > 0: self.score.add(75) seagull.die() # give her a part of ball's momentum: seagull.vect[0]+=cb.vect[0]*0.4 seagull.vect[1]+=cb.vect[1]*0.4 if not cb.special: self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.pirate_sprites, 0, 0) for cb in dict.keys(collisions): for pirate in collisions[cb]: # cb.vect hack for preventing pirates from killing each other if not pirate.dying and cb.vect[0] > 0: if (Variables.sound): Mine.sound.play() # Umm... the mine has a nice sound. self.score.add(25) pirate.damage() for i in range(6): self.particles.add_wood_particle((pirate.rect.centerx+rrr(-0,15), pirate.rect.centery+rrr(-10,20))) if not cb.special: self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break if self.titanic: collisions = PixelPerfect.spritecollide_pp(self.titanic, self.cannonball_sprites, 0) for cb in collisions: if not self.titanic.dying and cb.vect[0] > 0: if (Variables.sound): Mine.sound.play() if cb.special: #special round is hard to fire, so lets reward our crafty player self.titanic.damage(12) self.score.add(100) else: self.score.add(7) self.titanic.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break def update_enemies(self): self.mine_sprites.update() for mine in self.mines: if mine.exploding: if mine.explode_frames == 0: self.mines.remove(mine) self.mine_sprites.remove(mine) # this should really be done in the Mine class, but oh well, here's some explosion effects: if Variables.particles: self.particles.add_explosion_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) self.particles.add_debris_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) if mine.rect.right < self.screen.get_rect().left: self.mines.remove(mine) self.mine_sprites.remove(mine) self.shark_sprites.update() for shark in self.sharks: if shark.dying: if Variables.particles: self.particles.add_blood_particle(shark.rect.center) if shark.rect.right < self.screen.get_rect().left or shark.dead: self.sharks.remove(shark) self.shark_sprites.remove(shark) self.pirate_sprites.update() for pirate in self.pirates: if pirate.t % 50 == 0 and not pirate.dying: # Pirate shoots, this should probably be handled by the Pirateboat class cb = Cannonball(pirate.rect, pirate.angle, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = pirate.get_point((0.0,10.0)) particle_point[0] += pirate.rect.centerx particle_point[1] += pirate.rect.centery for i in range(4): self.particles.add_fire_steam_particle(particle_point) if pirate.rect.right < self.screen.get_rect().left or pirate.dead: self.pirates.remove(pirate) self.pirate_sprites.remove(pirate) elif pirate.dying: if Variables.particles: self.particles.add_explosion_particle((pirate.rect.centerx, pirate.rect.centery)) self.particles.add_wood_particle((pirate.rect.centerx, pirate.rect.centery)) if self.titanic: self.titanic.update() if self.titanic.t % 100 == 0 and not self.titanic.dying: for i in range(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 50, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) elif self.titanic.t % 100 == 50 and not self.titanic.dying: for i in range(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 52.5, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) if self.titanic.dead: self.set_gameover("Congratulations!\nYou sunk Titanic!") self.titanic = None self.seagull_sprites.update() for seagull in self.seagulls: if seagull.rect.right < 0 or seagull.dead: self.seagulls.remove(seagull) self.seagull_sprites.remove(seagull) def spawn_enemies(self): spawns = self.level.get_spawns() if spawns[Level.SHARKS]: # Make a new shark self.sharks.append(Shark()) self.shark_sprites.add(self.sharks[-1]) if spawns[Level.PIRATES]: # Make a new pirate ship self.pirates.append(Pirateboat()) self.pirate_sprites.add(self.pirates[-1]) if spawns[Level.MINES]: self.mines.append(Mine()) self.mine_sprites.add(self.mines[-1]) if spawns[Level.SEAGULLS]: self.seagulls.append(Seagull()) self.seagull_sprites.add(self.seagulls[-1]) if spawns[Level.TITANIC]: self.titanic = Titanic() self.titanic_sprite.add(self.titanic) if spawns[Level.POWERUPS]: self.powerups.append(Powerup()) self.powerup_sprites.add(self.powerups[-1])
class Game(object): def __init__(self, screen_height, screen_width): pygame.init() self.screen_height = screen_height self.screen_width = screen_width self.level_maps = ("./data/level1.map", "./data/level2.map", "./data/level3.map") self.current_level_map_index = 0 self.pause = False self.won_grow_rate = 10 height_width = (self.screen_height, self.screen_width) self.screen = pygame.display.set_mode(height_width) pygame.display.set_caption("PySnake") self.score = Score((0, 500)) self.reload_game = False self.speed = 5 def init_resources(self): self.level = Level(self.level_maps[self.current_level_map_index]) self.snake = Snake((64, 64)) self.move_direction = Direction.RIGHT self.food = None def start(self): clock = pygame.time.Clock() game_over = False won = True first_load = True while not game_over: clock.tick(self.speed) for event in pygame.event.get(): self.event_handler(event) if self.reload_game: break if not self.pause: background = self.level.render() self.snake.render(background) if self.food == None: position = self.generate_free_position() self.food = Food(position, 1) background.blit(self.food.image, self.food.rect) self.screen.fill((0, 0, 0)) self.screen.blit(background, (0, 0)) self.screen.blit(self.score.image, self.score.rect) pygame.display.flip() if first_load: first_load = False self.pause = True continue not_collide = self.snake.update(self.move_direction) if not not_collide or self.level.collide(self.snake.position): game_over = True won = False if self.food.rect.colliderect(self.snake.head.rect): self.snake.grow(self.food.grow_rate) self.score.add(100) self.food = None if self.snake.length() == self.won_grow_rate: game_over = True if self.reload_game: self.load_game() elif won and game_over: self.load_next_level() elif game_over: print("Game over") def event_handler(self, event): if event.type == QUIT: sys.exit(0) elif event.type == KEYDOWN: key = pygame.key.get_pressed() new_direction = self.move_direction if key[pygame.K_LEFT]: new_direction = Direction.LEFT elif key[pygame.K_RIGHT]: new_direction = Direction.RIGHT elif key[pygame.K_UP]: new_direction = Direction.UP elif key[pygame.K_DOWN]: new_direction = Direction.DOWN elif key[pygame.K_p]: self.pause = not self.pause elif key[pygame.K_s]: self.pause = True level = self.current_level_map_index snake = self.snake.get_snake_coords() food = self.food.get_food_position() direction = self.move_direction SaveGame.save(level, snake, food, direction) elif key[pygame.K_l]: self.reload_game = True oposide_direction = self.opposite_direction(self.move_direction) if not oposide_direction == new_direction: self.move_direction = new_direction def opposite_direction(self, direction): if direction == Direction.UP: return Direction.DOWN elif direction == Direction.DOWN: return Direction.UP elif direction == Direction.LEFT: return Direction.RIGHT elif direction == Direction.RIGHT: return Direction.LEFT def generate_free_position(self): x, y = None, None while x is None or self.level.collide((x, y)) or self.snake.collide((x, y)): x = random.randrange(0, self.level.width - 32, 2) y = random.randrange(0, self.level.height - 32, 2) return (x, y) def load_next_level(self): if len(self.level_maps) - 1 == self.current_level_map_index: print("Game over, you win") return self.current_level_map_index += 1 self.init_resources() self.start() def get_current_level_map(self): return self.level_maps[self.current_level_map_index] def load_game(self): loaded_dict = LoadGame.load() self.current_level_map_index = loaded_dict["level"] self.init_resources() self.snake.load_snake_from_coord(loaded_dict["snake"]) self.food = Food(loaded_dict["food"], 1) self.move_direction = loaded_dict["direction"] self.reload_game = False self.start()
class Game: sky = None def __init__(self, screen, endless = False): self.screen = screen self.sharks = [] self.shark_sprites = pygame.sprite.Group() self.player = Steamboat() self.player_sprite = pygame.sprite.Group() self.player_sprite.add(self.player) self.health = Health() self.health_sprite = pygame.sprite.Group() self.health_sprite.add(self.health) self.damage_count = 0 self.t = 0 self.water = Water.global_water #Water.global_water = self.water self.water_sprite = pygame.sprite.Group() self.water_sprite.add(self.water) if not Game.sky: Game.sky = util.load_image("taivas") Game.sky = pygame.transform.scale(self.sky, (SCREEN_WIDTH, SCREEN_HEIGHT)) self.cannonballs = [] self.cannonball_sprites = pygame.sprite.Group() self.pirates = [] self.pirate_sprites = pygame.sprite.Group() self.titanic = None self.titanic_sprite = pygame.sprite.Group() self.seagulls = [] self.seagull_sprites = pygame.sprite.Group() self.particles = Particles() self.particle_sprite = pygame.sprite.Group() self.particle_sprite.add(self.particles) self.mines = [] self.mine_sprites = pygame.sprite.Group() self.score = Score() self.score_sprite = pygame.sprite.Group() self.score_sprite.add(self.score) self.powerups = [] self.powerup_sprites = pygame.sprite.Group() self.level = Level(endless) self.lastshot = MIN_FIRE_DELAY + 1 self.gameover = False self.gameover_image = None self.gameover_rect = None self.done = False self.pause = False self.pause_image = util.bigfont.render("Pause", Variables.alpha, (0,0,0)) self.pause_rect = self.pause_image.get_rect() self.pause_rect.center = self.screen.get_rect().center self.spacepressed = None def run(self): while not self.done: if not self.pause: if not self.gameover: self.spawn_enemies() self.update_enemies() self.player.update() self.health.update() cloud.update() for cb in self.cannonballs: if not cb.underwater: #~ particle_point=cb.rect.left, cb.rect.top particle_point = cb.tail_point() self.particles.add_trace_particle(particle_point) particle_point = [particle_point[i] + cb.vect[i]/2 for i in (0,1)] self.particles.add_trace_particle(particle_point) if cb.special and (not cb.underwater or rr()>0.6) : particle_point = cb.tail_point() self.particles.add_explosion_particle(particle_point) und_old=cb.underwater cb.update() if cb.underwater and not und_old: for i in xrange(5): particle_point=cb.rect.right-4.0+rr()*8.0, cb.rect.top+rr()*2.0 self.particles.add_water_particle(particle_point) if (cb.rect.right < 0 and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH and cb.vect[0] > 0) or (cb.rect.top > SCREEN_HEIGHT): self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) self.score.update() # Add steam particles if Variables.particles: particle_point = self.player.get_point((5.0 + rr() * 9.0, 0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery if self.spacepressed and self.t > self.spacepressed + FPS * 3: pass #~ self.particles.add_fire_steam_particle(particle_point) else: self.particles.add_steam_particle(particle_point) particle_point = self.player.get_point((19.0 + rr() * 7.0, 5.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery if self.spacepressed and self.t > self.spacepressed + FPS * 3: pass #~ self.particles.add_fire_steam_particle(particle_point) else: self.particles.add_steam_particle(particle_point) if self.titanic: for j in xrange(4): particle_point = self.titanic.get_point((49 + rr() * 9.0 + 28 * j, 25)) particle_point[0] += self.titanic.rect.centerx particle_point[1] += self.titanic.rect.centery self.particles.add_steam_particle(particle_point) self.particles.update() self.water.update() if self.player.splash: if Variables.particles: for i in xrange(10): r = rr() x = int(r * self.player.rect.left + (1.0-r) * self.player.rect.right) point = (x, self.water.get_water_level(x)) self.particles.add_water_particle(point) for powerup in self.powerups: powerup.update() if powerup.picked: self.powerups.remove(powerup) self.powerup_sprites.remove(powerup) if not self.gameover: self.check_collisions() if self.health.hearts_left == 0 and not self.player.dying: self.player.die() if self.player.dying and not self.player.dead: if Variables.particles: self.particles.add_explosion_particle((self.player.rect.centerx, self.player.rect.centery)) self.particles.add_debris_particle((self.player.rect.centerx, self.player.rect.centery)) if self.player.dead: #self.done = True self.set_gameover() if self.damage_count > 0: self.damage_count -= 1 self.lastshot += 1 self.t += 1 self.draw() self.handle_events() return self.score.get_score() def damage_player(self): self.health.damage() for i in xrange(10): particle_point = self.player.get_point((rr() * 26.0, rr() * 10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery self.particles.add_debris_particle(particle_point) self.player.blinks+=12 def set_gameover(self, message = "Game Over"): self.gameover = True images = [] height = 0 width = 0 for text in message.split("\n"): images.append(util.bigfont.render(text, Variables.alpha, (0,0,0))) height += images[-1].get_height() if images[-1].get_width() > width: width = images[-1].get_width() self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32) self.gameover_image.fill((0,0,0,0)) for i in xrange(len(images)): rect = images[i].get_rect() rect.top = i * images[i].get_height() rect.centerx = width / 2 self.gameover_image.blit(images[i], rect) self.gameover_rect = self.gameover_image.get_rect() self.gameover_rect.center = self.screen.get_rect().center def take_screenshot(self): i = 1 filename = "sshot.tga" while os.path.exists(filename): i += 1 filename = "sshot" + str(i) + ".tga" pygame.image.save(self.screen, filename) print "Screenshot saved as " + filename def handle_events(self): nextframe = False framecount = 0 while not nextframe: # wait until there's at least one event in the queue #nextframe = True pygame.event.post(pygame.event.wait()) for event in pygame.event.get(): #event = pygame.event.wait() if event.type == QUIT or \ event.type == KEYDOWN and event.key == K_ESCAPE: self.done = True nextframe = True elif event.type == NEXTFRAME: framecount += 1 nextframe = True elif self.gameover: if event.type == JOYBUTTONDOWN: self.done = True nextframe = True elif event.type == KEYDOWN: self.done = True nextframe = True continue elif event.type == JOYAXISMOTION: if event.axis == 0: if event.value < -0.5: self.player.move_left(True) elif event.value > 0.5: self.player.move_right(True) else: self.player.move_left(False) self.player.move_right(False) elif event.type == JOYBUTTONDOWN: if event.button == 0: if not self.pause: self.player.jump() elif event.button == 1: if not self.pause: if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in xrange(4): self.particles.add_fire_steam_particle(particle_point) self.lastshot = 0 self.spacepressed = self.t elif event.button == 5: self.take_screenshot() elif event.button == 8: self.set_pause() elif event.type == KEYDOWN: if event.key == K_LEFT: self.player.move_left(True) elif event.key == K_RIGHT: self.player.move_right(True) elif event.key == K_SPACE: if not self.pause: # Only 3 cannonballs at once # Maximum firing rate set at the top if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in xrange(4): self.particles.add_fire_steam_particle(particle_point) self.lastshot = 0 self.spacepressed = self.t elif event.key == K_UP: if not self.pause: self.player.jump() elif event.key == K_s: self.take_screenshot() elif event.key == K_p: self.set_pause() elif event.type == KEYUP: if event.key == K_LEFT: self.player.move_left(False) elif event.key == K_RIGHT: self.player.move_right(False) elif event.key == K_SPACE: if not self.pause: if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle, special=True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in xrange(30): self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3))) self.lastshot = 0 self.spacepressed = None elif event.type == JOYBUTTONUP: if event.button == 1: if not self.pause: if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle, special=True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = self.player.get_point((42.0,10.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery for i in xrange(30): self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3))) self.lastshot = 0 self.spacepressed = None #if framecount > 1: # print str(self.t) + ": missed " + str(framecount - 1) + " frames!" def set_pause(self): self.pause = not self.pause #if framecount > 1: # print str(self.t) + ": missed " + str(framecount - 1) + " frames!" def set_pause(self): self.pause = not self.pause def draw(self): self.screen.blit(Game.sky, self.screen.get_rect()) self.health_sprite.draw(self.screen) self.score_sprite.draw(self.screen) self.player_sprite.draw(self.screen) self.powerup_sprites.draw(self.screen) self.pirate_sprites.draw(self.screen) if self.titanic: self.titanic_sprite.draw(self.screen) self.seagull_sprites.draw(self.screen) cloud.draw(self.screen) self.shark_sprites.draw(self.screen) self.mine_sprites.draw(self.screen) self.cannonball_sprites.draw(self.screen) self.water_sprite.draw(self.screen) if Variables.particles: self.particle_sprite.draw(self.screen) if self.pause: self.screen.blit(self.pause_image, self.pause_rect) if self.gameover: self.screen.blit(self.gameover_image, self.gameover_rect) if self.level.t < 120: image = None i = 0 if self.level.phase < len(self.level.phase_messages): for text in self.level.phase_messages[self.level.phase].split("\n"): image = util.smallfont.render(text, Variables.alpha, (0,0,0)) rect = image.get_rect() rect.centerx = self.screen.get_rect().centerx rect.top = 100 + rect.height * i blit_image = pygame.Surface((image.get_width(), image.get_height())) blit_image.fill((166,183,250)) blit_image.set_colorkey((166,183,250)) blit_image.blit(image, image.get_rect()) if self.level.t > 60: blit_image.set_alpha(255 - (self.level.t - 60) * 255 / 60) self.screen.blit(blit_image, rect) i += 1 pygame.display.flip() def check_collisions(self): collisions = PixelPerfect.spritecollide_pp(self.player, self.powerup_sprites, 0) for powerup in collisions: if not powerup.fading: if not self.player.dying: self.health.add() powerup.pickup() collisions = PixelPerfect.spritecollide_pp(self.player, self.mine_sprites, 0) for mine in collisions: if not mine.exploding: if not self.player.dying: self.damage_player() mine.explode() collisions = PixelPerfect.spritecollide_pp(self.player, self.shark_sprites, 0) for shark in collisions: if not shark.dying: if not self.player.dying: self.damage_player() shark.die() collisions = PixelPerfect.spritecollide_pp(self.player, self.cannonball_sprites, 0) for cb in collisions: if not self.player.dying: self.damage_player() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) if (Variables.sound): Mine.sound.play() # Umm... the mine has a nice explosion sound. collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.shark_sprites, 0, 0) for cb in dict.keys(collisions): for shark in collisions[cb]: # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks. if not shark.dying and cb.vect[0] > 0: self.score.add(15) shark.die() # give her a part of ball's momentum: shark.dx+=cb.vect[0]*0.6 shark.dy+=cb.vect[1]*0.4 if not cb.special: self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.seagull_sprites, 0, 0) for cb in dict.keys(collisions): for seagull in collisions[cb]: # cb.vect test is a rude hack preventing pirates from killing seagulls if not seagull.dying and cb.vect[0] > 0: self.score.add(75) seagull.die() # give her a part of ball's momentum: seagull.vect[0]+=cb.vect[0]*0.4 seagull.vect[1]+=cb.vect[1]*0.4 if not cb.special: self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.pirate_sprites, 0, 0) for cb in dict.keys(collisions): for pirate in collisions[cb]: # cb.vect hack for preventing pirates from killing each other if not pirate.dying and cb.vect[0] > 0: if (Variables.sound): Mine.sound.play() # Umm... the mine has a nice sound. self.score.add(25) pirate.damage() for i in range(6): self.particles.add_wood_particle((pirate.rect.centerx+rrr(-0,15), pirate.rect.centery+rrr(-10,20))) if not cb.special: self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break if self.titanic: collisions = PixelPerfect.spritecollide_pp(self.titanic, self.cannonball_sprites, 0) for cb in collisions: if not self.titanic.dying and cb.vect[0] > 0: if (Variables.sound): Mine.sound.play() if cb.special: #special round is hard to fire, so lets reward our crafty player self.titanic.damage(12) self.score.add(100) else: self.score.add(7) self.titanic.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break def update_enemies(self): self.mine_sprites.update() for mine in self.mines: if mine.exploding: if mine.explode_frames == 0: self.mines.remove(mine) self.mine_sprites.remove(mine) # this should really be done in the Mine class, but oh well, here's some explosion effects: if Variables.particles: self.particles.add_explosion_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) self.particles.add_debris_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) if mine.rect.right < self.screen.get_rect().left: self.mines.remove(mine) self.mine_sprites.remove(mine) self.shark_sprites.update() for shark in self.sharks: if shark.dying: if Variables.particles: self.particles.add_blood_particle(shark.rect.center) if shark.rect.right < self.screen.get_rect().left or shark.dead: self.sharks.remove(shark) self.shark_sprites.remove(shark) self.pirate_sprites.update() for pirate in self.pirates: if pirate.t % 50 == 0 and not pirate.dying: # Pirate shoots, this should probably be handled by the Pirateboat class cb = Cannonball(pirate.rect, pirate.angle, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) particle_point = pirate.get_point((0.0,10.0)) particle_point[0] += pirate.rect.centerx particle_point[1] += pirate.rect.centery for i in xrange(4): self.particles.add_fire_steam_particle(particle_point) if pirate.rect.right < self.screen.get_rect().left or pirate.dead: self.pirates.remove(pirate) self.pirate_sprites.remove(pirate) elif pirate.dying: if Variables.particles: self.particles.add_explosion_particle((pirate.rect.centerx, pirate.rect.centery)) self.particles.add_wood_particle((pirate.rect.centerx, pirate.rect.centery)) if self.titanic: self.titanic.update() if self.titanic.t % 100 == 0 and not self.titanic.dying: for i in xrange(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 50, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) elif self.titanic.t % 100 == 50 and not self.titanic.dying: for i in xrange(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 52.5, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) if self.titanic.dead: self.set_gameover("Congratulations!\nYou sunk Titanic!") self.titanic = None self.seagull_sprites.update() for seagull in self.seagulls: if seagull.rect.right < 0 or seagull.dead: self.seagulls.remove(seagull) self.seagull_sprites.remove(seagull) def spawn_enemies(self): spawns = self.level.get_spawns() if spawns[Level.SHARKS]: # Make a new shark self.sharks.append(Shark()) self.shark_sprites.add(self.sharks[-1]) if spawns[Level.PIRATES]: # Make a new pirate ship self.pirates.append(Pirateboat()) self.pirate_sprites.add(self.pirates[-1]) if spawns[Level.MINES]: self.mines.append(Mine()) self.mine_sprites.add(self.mines[-1]) if spawns[Level.SEAGULLS]: self.seagulls.append(Seagull()) self.seagull_sprites.add(self.seagulls[-1]) if spawns[Level.TITANIC]: self.titanic = Titanic() self.titanic_sprite.add(self.titanic) if spawns[Level.POWERUPS]: self.powerups.append(Powerup()) self.powerup_sprites.add(self.powerups[-1])
class Game: def __init__(self, screen, usealpha = True, noparticles = False, endless = False): self.screen = screen self.usealpha = usealpha self.noparticles = noparticles self.sharks = [] self.shark_sprites = pygame.sprite.Group() self.player = Steamboat() self.player_sprite = pygame.sprite.Group() self.player_sprite.add(self.player) self.health = Health() self.health_sprite = pygame.sprite.Group() self.health_sprite.add(self.health) self.damage_count = 0 self.t = 0 self.water = Water.global_water #Water(self.usealpha) #Water.global_water = self.water self.water_sprite = pygame.sprite.Group() self.water_sprite.add(self.water) self.sky = util.load_image("taivas") self.sky = pygame.transform.scale(self.sky, (SCREEN_WIDTH, SCREEN_HEIGHT)) self.pause_icon = util.load_image("pause") self.cannonballs = [] self.cannonball_sprites = pygame.sprite.Group() self.pirates = [] self.pirate_sprites = pygame.sprite.Group() self.titanic = None self.titanic_sprite = pygame.sprite.Group() self.seagulls = [] self.seagull_sprites = pygame.sprite.Group() self.particles = Particles(self.usealpha) self.particle_sprite = pygame.sprite.Group() self.particle_sprite.add(self.particles) self.mines = [] self.mine_sprites = pygame.sprite.Group() self.score = Score() self.score_sprite = pygame.sprite.Group() self.score_sprite.add(self.score) self.powerups = [] self.powerup_sprites = pygame.sprite.Group() self.level = Level(endless) self.cheat_current = 0 self.lastshot = MIN_FIRE_DELAY + 1 self.gameover = False self.gameover_image = None self.gameover_rect = None self.done = False self.pause = False font = util.load_font("Cosmetica", 40) #pygame.font.Font(pygame.font.get_default_font(), 36) self.pause_image = font.render("Pause", True, (0,0,0)) self.pause_rect = self.pause_image.get_rect() self.pause_rect.center = self.screen.get_rect().center def run(self): while not self.done: util.android_check_pause() if not self.pause: if not self.gameover: self.spawn_enemies() self.update_enemies() self.player.update() self.health.update() cloud.update() for cb in self.cannonballs: cb.update() if (cb.rect.right < 0 and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH and cb.vect[0] > 0): self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) self.score.update() # Add steam particles if not self.noparticles: for i in range(STEAM_3): particle_point = self.player.get_point((5.0 + random.random() * 9.0, 0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery self.particles.add_steam_particle(particle_point) for i in range(STEAM_3): particle_point = self.player.get_point((19.0 + random.random() * 7.0, 5.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery self.particles.add_steam_particle(particle_point) if self.titanic: for j in range(4): for i in range(STEAM_3): particle_point = self.titanic.get_point((49 + random.random() * 9.0 + 28 * j, 25)) particle_point[0] += self.titanic.rect.centerx particle_point[1] += self.titanic.rect.centery self.particles.add_steam_particle(particle_point) self.particles.update() self.water.update() if self.player.splash: if not self.noparticles: for i in range(SPLASH_30): r = random.random() x = int(r * self.player.rect.left + (1.0-r) * self.player.rect.right) point = (x, self.water.get_water_level(x)) self.particles.add_water_particle(point) for powerup in self.powerups: powerup.update() if powerup.picked: self.powerups.remove(powerup) self.powerup_sprites.remove(powerup) if not self.gameover: self.check_collisions() if self.health.hearts_left == 0 and not self.player.dying: self.player.die() if self.player.dying and not self.player.dead: if not self.noparticles: for i in range(BLOOD_3): self.particles.add_explosion_particle((self.player.rect.centerx, self.player.rect.centery)) self.particles.add_debris_particle((self.player.rect.centerx, self.player.rect.centery)) if self.player.dead: #self.done = True self.set_gameover() if self.damage_count > 0: self.damage_count -= 1 self.lastshot += 1 self.t += 1 self.draw() self.handle_events() return self.score.get_score() def set_gameover(self, message = "Game Over"): self.gameover = True images = [] font = util.load_font("Cosmetica", 40) #pygame.font.Font(pygame.font.get_default_font(), 36) height = 0 width = 0 for text in message.split("\n"): images.append(font.render(text, True, (0,0,0))) height += images[-1].get_height() if images[-1].get_width() > width: width = images[-1].get_width() self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32) self.gameover_image.fill((0,0,0,0)) for i in range(len(images)): rect = images[i].get_rect() rect.top = i * images[i].get_height() rect.centerx = width / 2 self.gameover_image.blit(images[i], rect) self.gameover_rect = self.gameover_image.get_rect() self.gameover_rect.center = self.screen.get_rect().center def translate_mouse_event(self, event): if event.type in (MOUSEBUTTONDOWN, ): if event.pos[0] > SCREEN_WIDTH - 32 and event.pos[1] < 32: key = K_p else: rx = event.pos[0] / float(SCREEN_WIDTH) ry = event.pos[1] / float(SCREEN_HEIGHT) if rx < 0.0: key = K_LEFT elif rx > 1.0: key = K_RIGHT elif ry > 0.5: key = K_SPACE else: key = K_UP event = pygame.event.Event(KEYUP if event.type == MOUSEBUTTONUP else KEYDOWN, key=key) if util.android: self.player.move_left(False) self.player.move_right(False) return event def handle_events(self): nextframe = False framecount = 0 while not nextframe: # wait until there's at least one event in the queue pygame.event.post(pygame.event.wait()) for event in pygame.event.get(): #event = pygame.event.wait() event = self.translate_mouse_event(event) if event.type == QUIT or \ event.type == KEYDOWN and event.key == K_ESCAPE: self.done = True nextframe = True elif event.type == NEXTFRAME: nextframe = True framecount += 1 elif self.gameover: if event.type == JOYBUTTONDOWN: self.done = True nextframe = True elif event.type == KEYDOWN: self.done = True nextframe = True elif event.type == MOUSEBUTTONDOWN: self.done = True nextframe = True continue elif event.type == JOYAXISMOTION: if event.axis == 0: if event.value < -0.5: self.player.move_left(True) elif event.value > 0.5: self.player.move_right(True) else: self.player.move_left(False) self.player.move_right(False) elif event.type == JOYBUTTONDOWN: if event.button == 0: if not self.pause: self.player.jump() elif event.button == 1: if not self.pause: if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) self.lastshot = 0 elif event.button == 5: pygame.image.save(self.screen, "sshot.tga") print "Screenshot saved as sshot.tga" elif event.button == 8: self.set_pause() elif event.type == KEYDOWN: if event.key == K_LEFT: self.player.move_left(True) elif event.key == K_RIGHT: self.player.move_right(True) elif event.key == K_SPACE: if not self.pause: # Only 3 cannonballs at once # Maximum firing rate set at the top if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) self.lastshot = 0 elif event.key == K_UP: if not self.pause: self.player.jump() elif event.key == K_s: pygame.image.save(self.screen, "sshot.tga") print "Screenshot saved as sshot.tga" elif event.key == K_p: self.set_pause() elif event.key == cheat_seq[self.cheat_current]: self.cheat_current += 1 print self.cheat_current if len(cheat_seq) == self.cheat_current: print 'Cheater!' self.cheat_current = 0 self.level.phase = 5 self.level.t = 0 self.spawn_enemies() elif event.type == KEYUP: if event.key == K_LEFT: self.player.move_left(False) elif event.key == K_RIGHT: self.player.move_right(False) tiling = util.get_tiling() if tiling == -1: self.player.move_left(True) elif tiling == 1: self.player.move_right(True) #if framecount > 1: # print "Missed " + str(framecount - 1) + " frames!" def set_pause(self): self.pause = not self.pause def draw(self): self.screen.blit(self.sky, self.screen.get_rect()) self.screen.blit(self.pause_icon, (SCREEN_WIDTH - 32, 0)) self.health_sprite.draw(self.screen) self.score_sprite.draw(self.screen) self.player_sprite.draw(self.screen) self.powerup_sprites.draw(self.screen) self.pirate_sprites.draw(self.screen) if self.titanic: self.titanic_sprite.draw(self.screen) self.seagull_sprites.draw(self.screen) cloud.draw(self.screen) self.shark_sprites.draw(self.screen) self.mine_sprites.draw(self.screen) self.cannonball_sprites.draw(self.screen) self.water_sprite.draw(self.screen) if not self.noparticles: self.particle_sprite.draw(self.screen) if self.pause: self.screen.blit(self.pause_image, self.pause_rect) if self.gameover: self.screen.blit(self.gameover_image, self.gameover_rect) if self.level.t < 120: font = util.load_font("Cosmetica", 16) image = None i = 0 if self.level.phase < len(self.level.phase_messages): for text in self.level.phase_messages[self.level.phase].split("\n"): image = font.render(text, True, (0,0,0)) rect = image.get_rect() rect.centerx = self.screen.get_rect().centerx rect.top = 100 + rect.height * i blit_image = pygame.Surface((image.get_width(), image.get_height())) blit_image.fill((166,183,250)) blit_image.set_colorkey((166,183,250)) blit_image.blit(image, image.get_rect()) if self.level.t > 60: blit_image.set_alpha(255 - (self.level.t - 60) * 255 / 60) self.screen.blit(blit_image, rect) i += 1 pygame.display.flip() def check_collisions(self): collisions = PixelPerfect.spritecollide_pp(self.player, self.powerup_sprites, 0) for powerup in collisions: if not powerup.fading: if not self.player.dying: self.health.add() powerup.pickup() collisions = PixelPerfect.spritecollide_pp(self.player, self.mine_sprites, 0) for mine in collisions: if not mine.exploding: if not self.player.dying: self.health.damage() mine.explode() collisions = PixelPerfect.spritecollide_pp(self.player, self.shark_sprites, 0) for shark in collisions: if not shark.dying: if not self.player.dying: self.health.damage() shark.die() collisions = PixelPerfect.spritecollide_pp(self.player, self.cannonball_sprites, 0) for cb in collisions: if not self.player.dying: self.health.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) Mine.sound.play() # Umm... the mine has a nice explosion sound. collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.shark_sprites, 0, 0) for cb in dict.keys(collisions): for shark in collisions[cb]: # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks. if not shark.dying and cb.vect[0] > 0: self.score.add(15) shark.die() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.seagull_sprites, 0, 0) for cb in dict.keys(collisions): for seagull in collisions[cb]: # cb.vect test is a rude hack preventing pirates from killing seagulls if not seagull.dying and cb.vect[0] > 0: self.score.add(75) seagull.die() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.pirate_sprites, 0, 0) for cb in dict.keys(collisions): for pirate in collisions[cb]: # cb.vect hack for preventing pirates from killing each other if not pirate.dying and cb.vect[0] > 0: Mine.sound.play() # Umm... the mine has a nice sound. self.score.add(25) pirate.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break if self.titanic: collisions = PixelPerfect.spritecollide_pp(self.titanic, self.cannonball_sprites, 0) for cb in collisions: if not self.titanic.dying and cb.vect[0] > 0: Mine.sound.play() self.score.add(7) self.titanic.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break def update_enemies(self): for mine in self.mines: mine.update() if mine.exploding: if mine.explode_frames == 0: self.mines.remove(mine) self.mine_sprites.remove(mine) # this should really be done in the Mine class, but oh well, here's some explosion effects: if not self.noparticles: for i in range(3): self.particles.add_explosion_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) self.particles.add_debris_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) if mine.rect.right < self.screen.get_rect().left: self.mines.remove(mine) self.mine_sprites.remove(mine) for shark in self.sharks: shark.update() if shark.dying: if not self.noparticles: self.particles.add_blood_particle(shark.rect.center) if shark.rect.right < self.screen.get_rect().left or shark.dead: self.sharks.remove(shark) self.shark_sprites.remove(shark) for pirate in self.pirates: pirate.update() if pirate.t % 50 == 0 and not pirate.dying: # Pirate shoots, this should probably be handled by the Pirateboat class cb = Cannonball(pirate.rect, pirate.angle, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) if pirate.rect.right < self.screen.get_rect().left or pirate.dead: self.pirates.remove(pirate) self.pirate_sprites.remove(pirate) elif pirate.dying: if not self.noparticles: for i in range(3): self.particles.add_explosion_particle((pirate.rect.centerx, pirate.rect.centery)) self.particles.add_wood_particle((pirate.rect.centerx, pirate.rect.centery)) if self.titanic: self.titanic.update() if self.titanic.t % 100 == 0 and not self.titanic.dying: for i in range(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 50, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) elif self.titanic.t % 100 == 50 and not self.titanic.dying: for i in range(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 60, left = True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) if self.titanic.dead: self.set_gameover("Congratulations!\nYou sunk Titanic!") self.titanic = None for seagull in self.seagulls: seagull.update() if seagull.rect.right < 0 or seagull.dead: self.seagulls.remove(seagull) self.seagull_sprites.remove(seagull) def spawn_enemies(self): spawns = self.level.get_spawns() if spawns[Level.SHARKS]: # Make a new shark self.sharks.append(Shark()) self.shark_sprites.add(self.sharks[-1]) if spawns[Level.PIRATES]: # Make a new pirate ship self.pirates.append(Pirateboat()) self.pirate_sprites.add(self.pirates[-1]) if spawns[Level.MINES]: self.mines.append(Mine()) self.mine_sprites.add(self.mines[-1]) if spawns[Level.SEAGULLS]: self.seagulls.append(Seagull()) self.seagull_sprites.add(self.seagulls[-1]) if spawns[Level.TITANIC]: self.titanic = Titanic() self.titanic_sprite.add(self.titanic) if spawns[Level.POWERUPS]: self.powerups.append(Powerup()) self.powerup_sprites.add(self.powerups[-1])
class Game(object): bgColor = [208, 229, 246] textColor = (236, 247, 255) def __init__(self, screen, timer, custom=False): self.screen = screen self.timer = timer '''Game Mode''' if custom != False: # 0, if no platforms are drawn self.custom = True if isinstance(custom, list): self.customPlatTypes = custom self.customNumPlatforms = None else: self.customNumPlatforms = custom self.customPlatTypes = None else: self.custom = False '''Game Mechanics''' self.totalGameTime = 1000 self.gameover = False self.gameover_image = None self.gameover_rect = None self.pause = False self.done = False font = load.load_font("OpenSans-Semibold", 40) self.pause_image = font.render("Paused", True, (236, 247, 255)) self.pause_rect = self.pause_image.get_rect() self.pause_rect.center = self.screen.get_rect().center self.exit = True self.showFPS = False self.noCrashes = False '''Background''' self.bg = Surface((32, 32)) self.bgTime = 0 self.bgColor = Game.bgColor self.sundownTime = 0 self.rainStart = random.randint(0, self.totalGameTime) self.rainEnd = self.rainStart + random.randint(150, 500) self.rainEndColor = None self.darkenTime = (self.rainEnd - self.rainStart) / 3 self.lightenTime = 2 * (self.rainEnd - self.rainStart) / 3 self.raining = self.darkening = self.lightening = False self.snowing = False self.snow = Snow() '''Game entities''' self.entities = pygame.sprite.Group() self.rocks = pygame.sprite.Group() self.trees = pygame.sprite.Group() self.birds = pygame.sprite.Group() self.coins = pygame.sprite.Group() self.ice = pygame.sprite.Group() self.player = Player() self.entities.add(self.player) self.coinCount = 0 self.flyingBirds = [] self.collectedCoins = [] self.clouds = None '''Score''' self.score = Score() self.scoreSprite = pygame.sprite.Group() self.scoreSprite.add(self.score) '''Platforms''' self.platforms = [] self.numPlatforms = 30 self.generatePlatforms() self.createPlatforms() '''Camera''' self.totalWidth = 1024 * len(self.platformTypes) self.totalHeight = 800 self.camera = Camera(complex_camera, self.totalWidth, self.totalHeight) '''Generating obstacles''' self.iceCoords = makeIce(self.platforms) rockInfo = makeRock(self.platforms) self.treeDict = makeTrees(self.platforms) self.birdDict = generateBirds(self.platforms) self.coinDict = makeCoins(self.platforms) (self.rockRects, self.rockCoords, self.rockAngles) = \ (rockInfo[0], rockInfo[1], rockInfo[2]) # ROCKS offset = 1024 for item in range(1, len(self.rockRects)): currentPlatform = self.platforms[item] x = self.rockRects[currentPlatform][0] + offset y = self.rockRects[currentPlatform][1] angle = self.rockAngles[currentPlatform] obstacle = random.choice("001") rock = Rock(x, y, angle) if obstacle == "0" else Penguin( x, y, angle) self.rocks.add(rock) offset += 1024 # ICE iceOffset = 0 for item in range(self.numPlatforms): currentPlatform = self.platforms[item] x = iceOffset ice = Ice(x, 299, currentPlatform, self.iceCoords) self.ice.add(ice) iceOffset += 1024 # TREES offset = 0 for item in range(len(self.treeDict)): currentPlatform = self.platforms[item] treeCoords = self.treeDict[currentPlatform] for tree in treeCoords: x = offset + tree[0] yOffset = random.randint(5, 20) y = tree[1] + 300 + yOffset tree = Tree(x, y) self.trees.add(tree) offset += 1024 # BIRBS & COINS offset = 0 for item in range(self.numPlatforms): currentPlatform = self.platforms[item] coords = self.birdDict[currentPlatform] coinCoords = self.coinDict[currentPlatform] if coords != None: for point in coords: x = offset + point[0] y = point[1] bird = Bird(x, y, 0) self.birds.add(bird) if coinCoords != None: for coin in coinCoords: x = offset + coin[0] y = coin[1] coin = Coin(x, y) self.coins.add(coin) offset += 1024 def run(self): while not self.done: if not self.pause: # update all game entities self.camera.update(self.player) self.groundSpeed = \ self.player.update( self.platforms, self.iceCoords, self.rocks) clouds.update(self.bgTime, self.totalGameTime, self.raining) for bird in self.birds: if pixelPerfectCollision(self.player, bird) != None: birds.update(bird) self.flyingBirds.append(bird) if self.flyingBirds != []: # bird animation for bird in self.flyingBirds: if bird.rect.top >= 0: birds.update(bird) else: self.flyingBirds.remove(bird) self.birds.remove(bird) for c in self.coins: if pixelPerfectCollision(self.player, c) != None: self.bgTime -= 1 coin.update(c) self.collectedCoins.append([c, 0]) if self.collectedCoins != []: # coin animation existCoins = False for i in range(len(self.collectedCoins)): c, num = self.collectedCoins[i] if c != None and num != None: existCoins = True if num <= 20: coin.update(c) num += 1 self.collectedCoins[i] = [c, num] else: self.collectedCoins[i] = [None, None] self.coins.remove(c) if not existCoins: self.collectedCoins = [] # no coins to update if self.raining: self.rain.update() if self.snowing: self.snow.update() particles.update(self.player.rect.centerx, self.player.rect.centery, self.player.angle, self.groundSpeed) if self.player.crashed and not self.noCrashes: self.exit = False self.setGameOver("You crashed! Press ENTER to exit.") elif self.player.crashed and self.noCrashes: self.player.crashed = False elif self.player.tooSteep and self.custom: self.exit = False self.setGameOver( "The slopes are too steep! Press ENTER to exit.") self.score.add(self.player.getScore()) self.draw() self.handleEvents() return self.score.getScore() def draw(self): self.bg.convert() if not self.pause: self.bgTime += 1 if self.bgTime + 1 == self.totalGameTime: print(self.player.rect.right // 1024) self.exit = False self.bgTime += 1 # avoid an endless loop self.setGameOver("Time's Up! Press ENTER to exit.") if self.bgTime % 5 == 0: if self.darkening or self.lightening or self.raining: self.bgColor = self.rainSky() else: self.bgColor = self.getTimeColor() color = (self.bgColor[0], self.bgColor[1], self.bgColor[2]) try: self.bg.fill(color) except: self.bg.fill((59, 82, 119)) # blit the background for y in range(32): for x in range(32): self.screen.blit(self.bg, (x * 32, y * 32)) # draw the sun based on "time of day" sun = pygame.transform.scale(load.load_image("sun"), (150, 150)) if 50 + (SCREEN_HEIGHT) * (self.bgTime / self.totalGameTime) <= 400: self.screen.blit(sun, (SCREEN_WIDTH - 150 - 50 * (self.bgTime / self.totalGameTime), 50 + (SCREEN_HEIGHT) * (self.bgTime / self.totalGameTime))) if abs((50 + (SCREEN_HEIGHT) * (self.bgTime / self.totalGameTime)) - 250) <= 2: self.sundownTime = self.bgTime # draw game entities for tree in self.trees: self.screen.blit(tree.image, self.camera.apply(tree)) for e in self.entities: self.screen.blit(e.image, self.camera.apply(e)) for ice in self.ice: self.screen.blit(ice.image, self.camera.apply(ice)) for rock in self.rocks: self.screen.blit(rock.image, self.camera.apply(rock)) for bird in self.birds: self.screen.blit(bird.image, self.camera.apply(bird)) for coin in self.coins: self.screen.blit(coin.image, self.camera.apply(coin)) self.scoreSprite.draw(self.screen) clouds.draw(self.screen) player.drawMessage(self.screen) if self.snowing: self.snow.draw(self.screen) self.checkForRain() particles.draw(self.screen, self.camera) # Draw game info font = load.load_font("Nexa Light", 30) fps = font.render("FPS: " + str(int(self.timer.get_fps())), True, Game.textColor) speed = font.render("Speed: " + str(int(self.groundSpeed)), True, Game.textColor) if self.showFPS: self.screen.blit(fps, (50, 60)) self.screen.blit(speed, (SCREEN_WIDTH - 200, 30)) timeLeft = "Time Left: " timer = font.render(timeLeft, True, Game.textColor) rect = timer.get_rect() rect.right = int(self.screen.get_rect().centerx) rect.top = 30 self.screen.blit(timer, rect) time = font.render(str(self.totalGameTime - self.bgTime), True, Game.textColor) rect = time.get_rect() rect.left = int(self.screen.get_rect().centerx) rect.top = 30 self.screen.blit(time, rect) if self.gameover: if self.exit == False: # when time runs out self.pause = True self.screen.blit(self.gameover_image, self.gameover_rect) else: self.done = True pygame.display.update() def handleEvents(self): self.timer.tick(60) for e in pygame.event.get(): if e.type == QUIT or (e.type == KEYDOWN and e.key == K_ESCAPE): self.done = True pygame.quit() sys.exit() elif e.type == KEYDOWN: if not self.pause: if e.key == K_UP: self.player.moveUp(True) if e.key == K_SPACE: self.player.rotate(True) # cheat: make it rain if e.key == K_r: self.bgTime = self.rainStart # cheat: make it snow if e.key == K_s: self.snowing = not self.snowing # cheat: show FPS if e.key == K_f: self.showFPS = not self.showFPS # cheat: approach end of game if e.key == K_e: self.bgTime = self.totalGameTime - 50 self.rainStartColor = 0 if self.sundownTime == 0: self.sundownTime = 1 # cheat: alter player speeds if e.key == K_z: self.player.groundSpeed += 1 elif e.key == K_x: self.player.groundSpeed -= 1 # cheat: no crashing! if e.key == K_c: self.noCrashes = not self.noCrashes if e.key == K_p: self.pause = not self.pause if self.gameover and e.key == K_RETURN: self.exit = True elif e.type == KEYUP: if e.key == K_UP: self.player.moveUp(False) if e.key == K_SPACE: self.player.rotate(False) def createPlatforms(self, start=0): x = start y = 300 for c in self.platformTypes: platformTypes = str(c) p = Platform(x, y, platformTypes) self.platforms.append(p) self.entities.add(p) x += p.width def generatePlatforms(self): self.platformTypes = ["start"] for i in range(self.numPlatforms): if self.custom: if self.customPlatTypes != None: selections = "".join(self.customPlatTypes) r = random.choice(selections) platform = str(int(r) * 100) self.platformTypes.append(platform) else: self.platformTypes.append(str(random.randint(1, self.customNumPlatforms) * 100)) else: # randomly chooses platforms; weighted probability self.platformTypes.append(random.choice("911223344556")) return self.platformTypes def checkForRain(self): if abs(self.rainStart - self.bgTime) <= 1: # it started raining self.rain = Rain() self.rainStartColor = self.getTimeColor() self.darkening = True if self.rainStart < self.bgTime < self.rainEnd: # it is raining self.raining = True self.rain.draw(self.screen) else: # it's not raining self.raining = False if abs(self.bgTime - (self.rainStart + self.darkenTime)) <= 1: # sky is done darkening self.darkening = False if abs(self.bgTime - (self.rainStart + self.lightenTime)) <= 1: # 2/3 of rain is done, start lightening sky self.rainEndColor = self.getTimeColor( self.rainEnd + 40) # anticipated color self.lightening = True if abs(self.bgTime - self.rainEnd - 40) <= 1: self.lightening = False def getTimeColor(self, time=None): # throwback to rgb color blender if time != None: bgTime = time else: bgTime = self.bgTime if self.sundownTime != 0: # fraction of time elapsed r = 208 - ((208 - 59) * ((bgTime - self.sundownTime) / self.totalGameTime)) g = 229 - ((229 - 82) * ((bgTime - self.sundownTime) / self.totalGameTime)) b = 246 - ((246 - 119) * ((bgTime - self.sundownTime) / self.totalGameTime)) if r < 59: r = 59 if g < 82: g = 82 if b < 119: b = 119 return [int(r), int(g), int(b)] else: return Game.bgColor def rainSky(self): if self.darkening: if self.bgTime <= self.rainStart + self.darkenTime: timeElapsed = (self.bgTime - self.rainStart) r = (self.rainStartColor[0] - ((self.rainStartColor[0] - 135) * timeElapsed / self.darkenTime)) g = (self.rainStartColor[1] - ((self.rainStartColor[1] - 156) * timeElapsed / self.darkenTime)) b = (self.rainStartColor[2] - ((self.rainStartColor[2] - 183) * timeElapsed / self.darkenTime)) return [int(r), int(g), int(b)] else: return [135, 156, 183] elif self.lightening: secondsElapsed = self.bgTime - (self.rainEnd - self.darkenTime) if abs(secondsElapsed - (self.rainEnd - self.darkenTime + 40)) <= 5: self.raining = self.lightening = self.darkening = False # rain effects are over return self.rainEndColor else: a = self.rainEnd - self.darkenTime + 40 color = self.rainEndColor r, g, b = color[0], color[1], color[2] newR = int(135 - (135 - r) * (secondsElapsed / a)) newG = int(156 - (156 - g) * (secondsElapsed / a)) newB = int(183 - (183 - g) * (secondsElapsed / a)) return [int(newR), int(newG), int(newB)] else: # just raining return [135, 156, 183] def setGameOver(self, message="Game Over"): # sets game over, shows a message depending on cause of death self.gameover = True images = [] font = load.load_font("Nexa Light", 30) height = 0 width = 0 for text in message.split("\n"): images.append(font.render(text, True, (25, 51, 71))) height += images[-1].get_height() width = images[-1].get_width() self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32) self.gameover_image.fill((0, 0, 0, 0)) for i in range(len(images)): rect = images[i].get_rect() rect.top = i * images[i].get_height() rect.centerx = width / 2 self.gameover_image.blit(images[i], rect) self.gameover_rect = self.gameover_image.get_rect() self.gameover_rect.center = self.screen.get_rect().center
class Game: def __init__(self, screen, usealpha=True, noparticles=False, endless=False): self.screen = screen self.usealpha = usealpha self.noparticles = noparticles self.sharks = [] self.shark_sprites = pygame.sprite.Group() self.player = Steamboat() self.player_sprite = pygame.sprite.Group() self.player_sprite.add(self.player) self.health = Health() self.health_sprite = pygame.sprite.Group() self.health_sprite.add(self.health) self.damage_count = 0 self.t = 0 self.water = Water.global_water #Water(self.usealpha) #Water.global_water = self.water self.water_sprite = pygame.sprite.Group() self.water_sprite.add(self.water) self.sky = util.load_image("taivas") self.sky = pygame.transform.scale(self.sky, (SCREEN_WIDTH, SCREEN_HEIGHT)) self.cannonballs = [] self.cannonball_sprites = pygame.sprite.Group() self.pirates = [] self.pirate_sprites = pygame.sprite.Group() self.titanic = None self.titanic_sprite = pygame.sprite.Group() self.seagulls = [] self.seagull_sprites = pygame.sprite.Group() self.particles = Particles(self.usealpha) self.particle_sprite = pygame.sprite.Group() self.particle_sprite.add(self.particles) self.mines = [] self.mine_sprites = pygame.sprite.Group() self.score = Score() self.score_sprite = pygame.sprite.Group() self.score_sprite.add(self.score) self.powerups = [] self.powerup_sprites = pygame.sprite.Group() self.level = Level(endless) self.lastshot = MIN_FIRE_DELAY + 1 self.gameover = False self.gameover_image = None self.gameover_rect = None self.done = False self.pause = False font = util.load_font( "Cosmetica", 40) #pygame.font.Font(pygame.font.get_default_font(), 36) self.pause_image = font.render("Pause", True, (0, 0, 0)) self.pause_rect = self.pause_image.get_rect() self.pause_rect.center = self.screen.get_rect().center def run(self): while not self.done: if not self.pause: if not self.gameover: self.spawn_enemies() self.update_enemies() self.player.update() self.health.update() cloud.update() for cb in self.cannonballs: cb.update() if (cb.rect.right < 0 and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH and cb.vect[0] > 0): self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) self.score.update() # Add steam particles if not self.noparticles: for i in range(3): particle_point = self.player.get_point( (5.0 + random.random() * 9.0, 0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery self.particles.add_steam_particle(particle_point) for i in range(3): particle_point = self.player.get_point( (19.0 + random.random() * 7.0, 5.0)) particle_point[0] += self.player.rect.centerx particle_point[1] += self.player.rect.centery self.particles.add_steam_particle(particle_point) if self.titanic: for j in range(4): for i in range(3): particle_point = self.titanic.get_point( (49 + random.random() * 9.0 + 28 * j, 25)) particle_point[0] += self.titanic.rect.centerx particle_point[1] += self.titanic.rect.centery self.particles.add_steam_particle( particle_point) self.particles.update() self.water.update() if self.player.splash: if not self.noparticles: for i in range(30): r = random.random() x = int(r * self.player.rect.left + (1.0 - r) * self.player.rect.right) point = (x, self.water.get_water_level(x)) self.particles.add_water_particle(point) for powerup in self.powerups: powerup.update() if powerup.picked: self.powerups.remove(powerup) self.powerup_sprites.remove(powerup) if not self.gameover: self.check_collisions() if self.health.hearts_left == 0 and not self.player.dying: self.player.die() if self.player.dying and not self.player.dead: if not self.noparticles: for i in range(3): self.particles.add_explosion_particle( (self.player.rect.centerx, self.player.rect.centery)) self.particles.add_debris_particle( (self.player.rect.centerx, self.player.rect.centery)) if self.player.dead: #self.done = True self.set_gameover() if self.damage_count > 0: self.damage_count -= 1 self.lastshot += 1 self.t += 1 self.draw() self.handle_events() return self.score.get_score() def set_gameover(self, message="Game Over"): self.gameover = True images = [] font = util.load_font( "Cosmetica", 40) #pygame.font.Font(pygame.font.get_default_font(), 36) height = 0 width = 0 for text in message.split("\n"): images.append(font.render(text, True, (0, 0, 0))) height += images[-1].get_height() if images[-1].get_width() > width: width = images[-1].get_width() self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32) self.gameover_image.fill((0, 0, 0, 0)) for i in range(len(images)): rect = images[i].get_rect() rect.top = i * images[i].get_height() rect.centerx = width / 2 self.gameover_image.blit(images[i], rect) self.gameover_rect = self.gameover_image.get_rect() self.gameover_rect.center = self.screen.get_rect().center def handle_events(self): nextframe = False framecount = 0 while not nextframe: # wait until there's at least one event in the queue pygame.event.post(pygame.event.wait()) for event in pygame.event.get(): #event = pygame.event.wait() if event.type == QUIT or \ event.type == KEYDOWN and event.key == K_ESCAPE: self.done = True nextframe = True elif event.type == NEXTFRAME: nextframe = True framecount += 1 elif self.gameover: if event.type == JOYBUTTONDOWN: self.done = True nextframe = True elif event.type == KEYDOWN: self.done = True nextframe = True continue elif event.type == JOYAXISMOTION: if event.axis == 0: if event.value < -0.5: self.player.move_left(True) elif event.value > 0.5: self.player.move_right(True) else: self.player.move_left(False) self.player.move_right(False) elif event.type == JOYBUTTONDOWN: if event.button == 0: if not self.pause: self.player.jump() elif event.button == 1: if not self.pause: if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) self.lastshot = 0 elif event.button == 5: pygame.image.save(self.screen, "sshot.tga") print "Screenshot saved as sshot.tga" elif event.button == 8: self.set_pause() elif event.type == KEYDOWN: if event.key == K_LEFT: self.player.move_left(True) elif event.key == K_RIGHT: self.player.move_right(True) elif event.key == K_SPACE: if not self.pause: # Only 3 cannonballs at once # Maximum firing rate set at the top if self.lastshot > MIN_FIRE_DELAY and not self.player.dying: cb = Cannonball(self.player.rect, self.player.angle) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) self.lastshot = 0 elif event.key == K_UP: if not self.pause: self.player.jump() elif event.key == K_s: pygame.image.save(self.screen, "sshot.tga") print "Screenshot saved as sshot.tga" elif event.key == K_p: self.set_pause() elif event.type == KEYUP: if event.key == K_LEFT: self.player.move_left(False) elif event.key == K_RIGHT: self.player.move_right(False) #if framecount > 1: # print "Missed " + str(framecount - 1) + " frames!" def set_pause(self): self.pause = not self.pause def draw(self): self.screen.blit(self.sky, self.screen.get_rect()) self.health_sprite.draw(self.screen) self.score_sprite.draw(self.screen) self.player_sprite.draw(self.screen) self.powerup_sprites.draw(self.screen) self.pirate_sprites.draw(self.screen) if self.titanic: self.titanic_sprite.draw(self.screen) self.seagull_sprites.draw(self.screen) cloud.draw(self.screen) self.shark_sprites.draw(self.screen) self.mine_sprites.draw(self.screen) self.cannonball_sprites.draw(self.screen) self.water_sprite.draw(self.screen) if not self.noparticles: self.particle_sprite.draw(self.screen) if self.pause: self.screen.blit(self.pause_image, self.pause_rect) if self.gameover: self.screen.blit(self.gameover_image, self.gameover_rect) if self.level.t < 120: font = util.load_font("Cosmetica", 16) image = None i = 0 if self.level.phase < len(self.level.phase_messages): for text in self.level.phase_messages[self.level.phase].split( "\n"): image = font.render(text, True, (0, 0, 0)) rect = image.get_rect() rect.centerx = self.screen.get_rect().centerx rect.top = 100 + rect.height * i blit_image = pygame.Surface( (image.get_width(), image.get_height())) blit_image.fill((166, 183, 250)) blit_image.set_colorkey((166, 183, 250)) blit_image.blit(image, image.get_rect()) if self.level.t > 60: blit_image.set_alpha(255 - (self.level.t - 60) * 255 / 60) self.screen.blit(blit_image, rect) i += 1 pygame.display.flip() def check_collisions(self): collisions = PixelPerfect.spritecollide_pp(self.player, self.powerup_sprites, 0) for powerup in collisions: if not powerup.fading: if not self.player.dying: self.health.add() powerup.pickup() collisions = PixelPerfect.spritecollide_pp(self.player, self.mine_sprites, 0) for mine in collisions: if not mine.exploding: if not self.player.dying: self.health.damage() mine.explode() collisions = PixelPerfect.spritecollide_pp(self.player, self.shark_sprites, 0) for shark in collisions: if not shark.dying: if not self.player.dying: self.health.damage() shark.die() collisions = PixelPerfect.spritecollide_pp(self.player, self.cannonball_sprites, 0) for cb in collisions: if not self.player.dying: self.health.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) Mine.sound.play( ) # Umm... the mine has a nice explosion sound. collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.shark_sprites, 0, 0) for cb in dict.keys(collisions): for shark in collisions[cb]: # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks. if not shark.dying and cb.vect[0] > 0: self.score.add(15) shark.die() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.seagull_sprites, 0, 0) for cb in dict.keys(collisions): for seagull in collisions[cb]: # cb.vect test is a rude hack preventing pirates from killing seagulls if not seagull.dying and cb.vect[0] > 0: self.score.add(75) seagull.die() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.pirate_sprites, 0, 0) for cb in dict.keys(collisions): for pirate in collisions[cb]: # cb.vect hack for preventing pirates from killing each other if not pirate.dying and cb.vect[0] > 0: Mine.sound.play() # Umm... the mine has a nice sound. self.score.add(25) pirate.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break if self.titanic: collisions = PixelPerfect.spritecollide_pp(self.titanic, self.cannonball_sprites, 0) for cb in collisions: if not self.titanic.dying and cb.vect[0] > 0: Mine.sound.play() self.score.add(7) self.titanic.damage() self.cannonballs.remove(cb) self.cannonball_sprites.remove(cb) break def update_enemies(self): for mine in self.mines: mine.update() if mine.exploding: if mine.explode_frames == 0: self.mines.remove(mine) self.mine_sprites.remove(mine) # this should really be done in the Mine class, but oh well, here's some explosion effects: if not self.noparticles: for i in range(3): self.particles.add_explosion_particle( (mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) self.particles.add_debris_particle( (mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx)) if mine.rect.right < self.screen.get_rect().left: self.mines.remove(mine) self.mine_sprites.remove(mine) for shark in self.sharks: shark.update() if shark.dying: if not self.noparticles: self.particles.add_blood_particle(shark.rect.center) if shark.rect.right < self.screen.get_rect().left or shark.dead: self.sharks.remove(shark) self.shark_sprites.remove(shark) for pirate in self.pirates: pirate.update() if pirate.t % 50 == 0 and not pirate.dying: # Pirate shoots, this should probably be handled by the Pirateboat class cb = Cannonball(pirate.rect, pirate.angle, left=True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) if pirate.rect.right < self.screen.get_rect().left or pirate.dead: self.pirates.remove(pirate) self.pirate_sprites.remove(pirate) elif pirate.dying: if not self.noparticles: for i in range(3): self.particles.add_explosion_particle( (pirate.rect.centerx, pirate.rect.centery)) self.particles.add_wood_particle( (pirate.rect.centerx, pirate.rect.centery)) if self.titanic: self.titanic.update() if self.titanic.t % 100 == 0 and not self.titanic.dying: for i in range(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i - 1) * 10 - 50, left=True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) elif self.titanic.t % 100 == 50 and not self.titanic.dying: for i in range(3): cb = Cannonball(self.titanic.rect, self.titanic.angle + (i - 1) * 10 - 60, left=True) self.cannonballs.append(cb) self.cannonball_sprites.add(cb) if self.titanic.dead: self.set_gameover("Congratulations!\nYou sunk Titanic!") self.titanic = None for seagull in self.seagulls: seagull.update() if seagull.rect.right < 0 or seagull.dead: self.seagulls.remove(seagull) self.seagull_sprites.remove(seagull) def spawn_enemies(self): spawns = self.level.get_spawns() if spawns[Level.SHARKS]: # Make a new shark self.sharks.append(Shark()) self.shark_sprites.add(self.sharks[-1]) if spawns[Level.PIRATES]: # Make a new pirate ship self.pirates.append(Pirateboat()) self.pirate_sprites.add(self.pirates[-1]) if spawns[Level.MINES]: self.mines.append(Mine()) self.mine_sprites.add(self.mines[-1]) if spawns[Level.SEAGULLS]: self.seagulls.append(Seagull()) self.seagull_sprites.add(self.seagulls[-1]) if spawns[Level.TITANIC]: self.titanic = Titanic() self.titanic_sprite.add(self.titanic) if spawns[Level.POWERUPS]: self.powerups.append(Powerup()) self.powerup_sprites.add(self.powerups[-1])