class HitTheTarget: """Overall class to manage assets and behavior.""" def __init__(self): """Initialize the game and create game resources.""" pygame.init() self.settings = Settings() self.screen = pygame.display.set_mode( (self.settings.screen_width, self.settings.screen_height)) pygame.display.set_caption("Hit the Target") # self.screen_rect = self.screen.get_rect() # Create an instance to store game statistics. self.stats = GameStats(self) self.target = Target(self) self.gun = Gun(self) self.bullets = pygame.sprite.Group() # Make the Play button. self.play_button = Button(self, "Play") def run_game(self): """Start the main loop for the game.""" while True: self._check_events() if self.stats.game_active: self._target_direction() self.gun.update() self.target.update() self._update_bullets() self._screen_update() def _check_events(self): """Check for key presses and mouse events.""" for event in pygame.event.get(): if event.type == pygame.QUIT: exit() elif event.type == pygame.KEYDOWN: self._check_keydown_events(event) elif event.type == pygame.KEYUP: self._check_keyup_events(event) elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() self._check_play_button(mouse_pos) def _check_play_button(self, mouse_pos): """Start a new game when the player clicks Play.""" button_clicked = self.play_button.rect.collidepoint(mouse_pos) if button_clicked and not self.stats.game_active: self._start_game() def _check_keydown_events(self, event): """Respond for keypresses.""" if event.key == pygame.K_q: exit() elif event.key == pygame.K_UP: self.gun.moving_up = True elif event.key == pygame.K_DOWN: self.gun.moving_down = True elif event.key == pygame.K_SPACE: self._fire_bullet() elif event.key == pygame.K_p: self._start_game() def _check_keyup_events(self, event): """Respond for key releases.""" if event.key == pygame.K_UP: self.gun.moving_up = False elif event.key == pygame.K_DOWN: self.gun.moving_down = False def _start_game(self): """Start a new game.""" # Reset the game statistics. self.stats.reset_stats() self.stats.game_active = True # Get rid of any remaining aliens and bullets. self.target.start_position() self.bullets.empty() self.gun.start_position() # Hide the mouse cursor. pygame.mouse.set_visible(False) def _target_direction(self): """Change target direction if hit the edges.""" if self.target.rect.bottom >= self.settings.screen_height \ or self.target.rect.top <= 0: self.settings.target_direction *= -1 def _fire_bullet(self): """Create a new bullet and add it to the bullet group.""" if self.stats.bullets_left > 0: new_bullet = Bullet(self) self.bullets.add(new_bullet) self.stats.bullets_left -= 1 def _screen_update(self): self.screen.fill(self.settings.bg_color) self.target.blitme() self.gun.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() # Make the play button if the game is inactive. if not self.stats.game_active: self.play_button.draw_button() pygame.display.flip() def _update_bullets(self): """Update position of bullets and get rid of old bullets.""" # Update bullets position self.bullets.update() # Get rid of bullets that have disappeared. for bullet in self.bullets.copy(): if bullet.rect.left > self.settings.screen_width: self.bullets.remove(bullet) self._check_bullet_target_collisions() def _check_bullet_target_collisions(self): """Respond to bullet-target collisions.""" # Remove any bullets and aliens that have collided. if pygame.sprite.spritecollideany(self.target, self.bullets): self.bullets.empty() self.stats.bullets_left = 3 self.target.start_position() self.settings.increase_target_speed() if not self.bullets and self.stats.bullets_left == 0: self.stats.game_active = False pygame.mouse.set_visible(True) self.settings.initialize_dynamic_settings()
class Game(arcade.Window): def __init__(self): super().__init__(title="Game", width=15 * 64, height=9 * 64, fullscreen=False) # Load background image self.background_sprite = arcade.Sprite("assets/background.png", center_x=self.width / 2, center_y=self.height / 2) self.static_sprites = arcade.SpriteList(is_static=True) self.static_sprites.append(self.background_sprite) # Create game objects self.test_gun = Gun(300, 200) self.bullets = [] self.player = Player(50, 50) def on_key_press(self, symbol, modifiers): if symbol == arcade.key.ESCAPE: arcade.close_window() if symbol == arcade.key.SPACE: self.bullets.append(self.test_gun.fire()) # Start moving the player in the direction indicated if symbol == arcade.key.W: self.player.move_up(4) if symbol == arcade.key.A: self.player.move_left(4) if symbol == arcade.key.S: self.player.move_down(4) if symbol == arcade.key.D: self.player.move_right(4) def on_key_release(self, symbol, modifiers): # Stop moving the player if the correct key is released if symbol == arcade.key.W and self.player.direction == "up": self.player.stop() if symbol == arcade.key.A and self.player.direction == "left": self.player.stop() if symbol == arcade.key.S and self.player.direction == "down": self.player.stop() if symbol == arcade.key.D and self.player.direction == "right": self.player.stop() def on_draw(self): arcade.start_render() # Draw backgroud and all non-moving sprites self.static_sprites.draw() # Draw game objects self.player.draw() self.test_gun.draw() for bullet in self.bullets: bullet.draw() def on_update(self, deltatime): # Update game objects for bullet in self.bullets: bullet.update() self.test_gun.update(deltatime) self.player.update() self.player.update_animation(deltatime)
class Tower: def __init__(self, i, x, y, s, t=0): self.identity = i self.x = x self.y = y self.size = s self.t_num = t self.box = pygame.Rect((self.x, self.y), (self.size, self.size)) self.level = 1 self.__c_mod = 1.0 # gets smaller self.coolness = 0 # 0 means ready to shoot self.__r_mod = 1.0 # gets bigger self.__p_mod = 1.0 # gets bigger self.__s_mod = 1.0 # gets bigger self.gun = Gun((self.x, self.y), s, t, tower_colors[self.t_num], self.level) self.upgrade_cost = 10 self.follow_mouse = False self.show_r = False self.font = pygame.font.SysFont('Century Gothic', 12) def color(self): return tower_colors[self.t_num] def cooldown(self): return enums.tower_cooldown[self.t_num] * self.__c_mod def range(self): return (enums.tower_range[self.t_num] * self.__r_mod * self.size) + self.size / 2 def power(self): return enums.tower_power[self.t_num] * self.__p_mod def speed(self): return enums.tower_speed[self.t_num] * self.__s_mod def t_type(self): return enums.TowerType(self.t_num) def pos(self): return self.x, self.y def render(self, surf): if self.t_num == 0 or self.t_num == 7: # PATH = 7, ZEROTOWER = 0 pass else: pygame.draw.circle(surf, self.color(), self.box.center, self.size // 2, 4) self.gun.render(surf) text = self.font.render(str(self.level), False, self.color()) surf.blit(text, (self.pos()[0] + 15, self.pos()[1] + 10)) if self.show_r: pygame.draw.circle(surf, red, self.box.center, int(self.range()), 1) def update(self, enemies, on_screen_shots, register): if self.t_num != 0 and self.t_num != 7: aim_spot = (0, 0) for e in enemies: if is_in_circle(e.center(), self.box.center, self.range()): aim_spot = e.pos() if self.coolness <= 0: on_screen_shots.append( Shot(self.box.center, e.id, self.color(), self.speed(), self.power())) register(on_screen_shots[ len(on_screen_shots) - 1]) # register this bullet to be drawn if self.t_num == 1: on_screen_shots[len(on_screen_shots) - 1].poison = True if self.t_num == 2: on_screen_shots[len(on_screen_shots) - 1].ice = True self.coolness = self.cooldown() break if self.coolness > 0: self.coolness -= 1 # point at the first enemy in range self.gun.update(aim_spot) def move(self, pos): self.x = pos[0] self.y = pos[1] self.gun.x = pos[0] self.gun.y = pos[1] self.box = pygame.Rect((self.x, self.y), (self.size, self.size)) def is_in(self, pos): if self.x < pos[0] < self.x + self.size: if self.y < pos[1] < self.y + self.size: return True return False def upgrade(self): self.__c_mod -= 0.05 # gets smaller self.__r_mod += 0.07 # gets bigger self.__p_mod += 1.0 # gets bigger # self.__s_mod += 0.5 # gets bigger self.upgrade_cost += (self.upgrade_cost / 2) self.upgrade_cost = int(self.upgrade_cost * 1.5) self.level += 1 def show_range(self, mouse): if self.is_in(mouse): self.show_r = True else: self.show_r = False
def run_game(): pygame.init() # 设置窗口 os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (128, 60) settings = Settings() screen = pygame.display.set_mode( (settings.screen_width, settings.screen_height)) pygame.display.set_caption("Shooting Practice") # 背景图 dir_path = os.path.dirname(os.path.abspath(__file__)) background = pygame.image.load(dir_path + r'\images\background.jpg').convert() # 创建枪支、子弹编组 gun = Gun(settings, screen) bullets = Group() # 创建全局计时器 overall_timer = MyTimer() # 创建靶机编组、提示条编组 target_sample = TargetSample() targets = Group() notice_bars = Group() # 创建用于存储游戏统计信息的实例 stats = GameStats(settings, overall_timer) # 文件读写 io_helper = IOHelper(stats) # 创建信息显示板 running_info = RunningInfo(settings, screen, stats) win_info = WinInfo(settings, screen, stats, io_helper) failed_info = FailedInfo(screen, stats) # 创建输入框 pregame_info = PregameInfo(settings, screen, stats) # 开始游戏主循环 while True: # 检查事件 func.check_events(settings, screen, stats, running_info, win_info, failed_info, gun, targets, bullets, pregame_info, notice_bars) # 更新屏幕 func.common_update_screen(background, settings, screen, stats, running_info, gun, target_sample, targets, bullets, notice_bars) # 游戏进行中,更新枪支、子弹、靶机提示条、靶机位置 if stats.game_state == GameState.RUNNING: gun.update() func.update_bullets(settings, screen, stats, targets, bullets, notice_bars, win_info, io_helper) func.update_notice(notice_bars) func.update_targets(targets) elif stats.game_state == GameState.PREGAME: pregame_info.draw_pregame_info() elif stats.game_state == GameState.GAME_OVER: failed_info.show_info() elif stats.game_state == GameState.GAME_FINISH: win_info.show_info() # 让最近绘制的屏幕可见 pygame.display.flip()