Example #1
0
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()
Example #2
0
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()