class Game: SPLASH = 0 START = 1 PLAYING = 2 PAUSED = 3 LEVEL_COMPLETED = 4 GAME_OVER = 5 VICTORY = 6 def __init__(self): self.window = pygame.display.set_mode( [constants.WIDTH, constants.HEIGHT]) pygame.display.set_caption(constants.TITLE) self.clock = pygame.time.Clock() self.done = False self.reset() def start(self): self.level = Level(constants.LEVELS[self.current_level]) self.level.reset() self.hero.respawn(self.level) def advance(self): self.current_level += 1 self.start() self.stage = Game.START def reset(self): self.hero = Character(hero_images) self.current_level = 0 self.start() self.stage = Game.SPLASH def display_splash(self, surface): line1 = FONT_LG.render(constants.TITLE, True, DARK_BLUE) line2 = FONT_SM.render("Press any key to start.", True, WHITE) x1 = constants.WIDTH / 2 - line1.get_width() / 2 y1 = constants.HEIGHT / 3 - line1.get_height() / 2 x2 = constants.WIDTH / 2 - line2.get_width() / 2 y2 = y1 + line1.get_height() + 16 surface.blit(line1, (x1, y1)) surface.blit(line2, (x2, y2)) def display_message(self, surface, primary_text, secondary_text): line1 = FONT_MD.render(primary_text, 1, WHITE) line2 = FONT_SM.render(secondary_text, 1, WHITE) x1 = constants.WIDTH / 2 - line1.get_width() / 2 y1 = constants.HEIGHT / 3 - line1.get_height() / 2 x2 = constants.WIDTH / 2 - line2.get_width() / 2 y2 = y1 + line1.get_height() + 16 surface.blit(line1, (x1, y1)) surface.blit(line2, (x2, y2)) def display_stats(self, surface): hearts_text = FONT_SM.render("Hearts: " + str(self.hero.hearts), True, WHITE) lives_text = FONT_SM.render("Lives: " + str(self.hero.lives), True, WHITE) score_text = FONT_SM.render("Score: " + str(self.hero.score), True, WHITE) surface.blit(score_text, (constants.WIDTH - score_text.get_width() - 32, 32)) surface.blit(hearts_text, (32, 32)) surface.blit(lives_text, (32, 64)) def process_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.done = True elif event.type == pygame.KEYDOWN: if self.stage == Game.SPLASH or self.stage == Game.START: self.stage = Game.PLAYING play_music() elif self.stage == Game.PLAYING: if event.key == JUMP: self.hero.jump(self.level.blocks) elif self.stage == Game.PAUSED: pass elif self.stage == Game.LEVEL_COMPLETED: self.advance() elif self.stage == Game.VICTORY or self.stage == Game.GAME_OVER: if event.key == pygame.K_r: self.reset() pressed = pygame.key.get_pressed() if self.stage == Game.PLAYING: if pressed[LEFT]: self.hero.move_left() elif pressed[RIGHT]: self.hero.move_right() else: self.hero.stop() def update(self): if self.stage == Game.PLAYING: self.hero.update(self.level) self.level.enemies.update(self.level, self.hero) if self.level.completed: if self.current_level < len(constants.LEVELS) - 1: self.stage = Game.LEVEL_COMPLETED else: self.stage = Game.VICTORY pygame.mixer.music.stop() elif self.hero.lives == 0: self.stage = Game.GAME_OVER pygame.mixer.music.stop() elif self.hero.hearts == 0: self.level.reset() self.hero.respawn(self.level) def calculate_offset(self): x = -1 * self.hero.rect.centerx + constants.WIDTH / 2 if self.hero.rect.centerx < constants.WIDTH / 2: x = 0 elif self.hero.rect.centerx > self.level.width - constants.WIDTH / 2: x = -1 * self.level.width + constants.WIDTH return x, 0 def draw(self): offset_x, offset_y = self.calculate_offset() self.level.active_layer.fill(TRANSPARENT) self.level.active_sprites.draw(self.level.active_layer) if self.hero.invincibility % 3 < 2: self.level.active_layer.blit(self.hero.image, [self.hero.rect.x, self.hero.rect.y]) self.window.blit(self.level.background_layer, [offset_x / 3, offset_y]) self.window.blit(self.level.scenery_layer, [offset_x / 2, offset_y]) self.window.blit(self.level.inactive_layer, [offset_x, offset_y]) self.window.blit(self.level.active_layer, [offset_x, offset_y]) self.display_stats(self.window) if self.stage == Game.SPLASH: self.display_splash(self.window) elif self.stage == Game.START: self.display_message(self.window, "Ready?!!!", "Press any key to start.") elif self.stage == Game.PAUSED: pass elif self.stage == Game.LEVEL_COMPLETED: self.display_message(self.window, "Level Complete", "Press any key to continue.") elif self.stage == Game.VICTORY: self.display_message(self.window, "You Win!", "Press 'R' to restart.") elif self.stage == Game.GAME_OVER: self.display_message(self.window, "Game Over", "Press 'R' to restart.") pygame.display.flip() def loop(self): while not self.done: self.process_events() self.update() self.draw() self.clock.tick(constants.FPS)
# mainloop running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False elif event.key == pygame.K_x: char.attack() elif event.key == pygame.K_z: char.jump() pressed = pygame.key.get_pressed() if pressed[pygame.K_LEFT]: char.move(left=True) elif pressed[pygame.K_RIGHT]: char.move() else: char.stop() screen.fill((0, 0, 0)) char.update(screen) pygame.display.flip() clock.tick(15) pygame.quit()