示例#1
0
    def update(self, d_time, players: pygame.sprite.Group, missile_wrapper: MissileWrapper):
        for e in self.sprites():
            if e.life > 0:
                missile_wrapper.enemy_hit(e)
        for e in self.sprites():
            if e.life > 0:
                missile_wrapper.enemy_aoe_hit(e)
                missile_wrapper.add_from_enemy(e.shoot())
            if e.state is Enemy.State.DEAD:
                self.remove(e)

        if len(players.sprites()) > 1:
            for e in self.sprites():
                dps = [Vector(p.rect.center[0] - e.rect.center[0], p.rect.center[1] - e.rect.center[1]).magnitude()
                       for p in players.sprites()]
                min_dp = min(dps)
                for i in range(len(dps)):
                    if min_dp == dps[i]:
                        e.update(d_time, players.sprites()[i].rect.center)
        elif len(players.sprites()) == 1:
            super().update(d_time, players.sprites()[0].rect.center)

        if len(self.sprites()) < self.max_enemies:
            self.timer += d_time
            if self.timer > self.new_enemy_spawn_interval:
                self.add([self.enemy_prefab((random.randrange(0, self.screen.get_width(), 1), -30))
                          for i in range(self.new_enemies_number)])
                self.timer = 0
示例#2
0
    def render(self, sprites: pygame.sprite.Group):

        self.display.fill((0, 0, 0))
        for star in self.stars:
            pygame.draw.rect(self.display, (200, 200, 200), star)
        sprites.draw(self.display)
        pygame.display.update()
示例#3
0
    def update(self, frametime: int, food_group: pygame.sprite.Group):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN and event.key in self.shortcuts.keys(
            ):
                event: pygame.event.Event
                # Prevents movement to the opposite direction(snake would collide with itself)
                opposites = {
                    Direction.N: Direction.S,
                    Direction.S: Direction.N,
                    Direction.W: Direction.E,
                    Direction.E: Direction.W,
                }
                direction = self.shortcuts.get(event.key)
                if opposites.get(self.direction) != direction:
                    self.new_direction = direction

        # Using frametime keeps the movement relatively stable despite the FPS the game is running at
        if self.frametime_counter >= self.frametime_for_step:
            self.direction = self.new_direction

            if self.new_head is None:
                self.step()
            else:
                head: SnakeUnit = self.sprites().pop()
                x_mov = self.direction.value[0]
                y_mov = self.direction.value[1]
                self.new_head.rect = head.rect.move(x_mov, y_mov)
                self.add(self.new_head)
                self.new_head = None

            self.frametime_counter = 0
            head: SnakeUnit = self.sprites().pop()
            collided_foods = pygame.sprite.spritecollide(head,
                                                         food_group,
                                                         dokill=True)
            if collided_foods:
                self.new_head = SnakeUnit()
                food_group.add(Food(self))

            # Kill snake if it is out of screen
            head: SnakeUnit = self.sprites().pop()
            if (head.rect.x < 0 or head.rect.x > Screen.WIDTH - head.rect.w
                    or head.rect.y < 0
                    or head.rect.y > Screen.HEIGHT - head.rect.h):
                self.dead = True

            # Kill snake if it collides with itself
            if not self.dead:
                sprites: List[SnakeUnit] = self.sprites()
                head: SnakeUnit = sprites.pop()
                for sprite in sprites:
                    if pygame.sprite.collide_rect(sprite, head):
                        self.dead = True
                        break

        else:
            self.frametime_counter += frametime
def check_play_button(ai_settings: Settings, stats: GameStats,
                      screen: pygame.Surface, play_button: Button,
                      sb: ScoreBoard, ship: Ship, aliens: pygame.sprite.Group,
                      bullets: pygame.sprite.Group, mouse_x: int,
                      mouse_y: int) -> NoReturn:
    """在晚间单机play按钮时开始新游戏"""
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
        # 重置游戏设置
        ai_settings.initialize_dynamic_settings()
        # 隐藏光标
        pygame.mouse.set_visible(False)
        # 重置游戏统计信息
        stats.reset_stats()
        stats.game_active = True

        # 重置记分牌图像
        sb.prep_score()
        sb.prep_high_score()
        sb.prep_level()
        sb.prep_ships()

        # 清空外星人列表和子弹列表
        aliens.empty()
        bullets.empty()

        # 创建一群新的外星人,并让飞船居中
        create_fleet(ai_settings, screen, ship, aliens)
        ship.center_ship()
示例#5
0
 def update_fire(self, projectile_group: pygame.sprite.Group):
     if self.fire_timer > self.fire_delay:
         projectile_group.add(
             MultiProjectile(self.p_speed, self.rect.x + self.rect.w / 2, self.rect.bottom, [self.p_im], 0,
                             self.p_count, self.p_fire_angle, self.p_spread).projectiles_group)
         self.fire_timer = 0
     self.dirty = 1
示例#6
0
def partie_perdue(hauteur_lave: int, générateur,
                  liste_de_sprites: pygame.sprite.Group) -> None:
    """Vérifie si le joueur touche la lave, si oui, afficher qu'il a perdu puis le faire retourner au menu

    :param hauteur_lave: (int) la hauteur de la lave depuis le haut de la fenêtre de jeu
    :param générateur: le générateur de niveaux, l'accès est donné pour pouvoir afficher les platformes
    :param liste_de_sprites: une liste qui contient le joueur, permet d'afficher le joueur
    """
    global niveau
    # Si le joueur touche la lave
    # Remet le niveau actif à 0
    niveau = 0
    # Dessiner tout le niveau et afficher qu'il a perdu
    générateur.draw()
    player.handle_keys()
    liste_de_sprites.update()
    liste_de_sprites.draw(screen)
    étiquette('Vous avez perdu!', 720, 400, 60)
    org_screen.blit(screen, (0, 0))
    pygame.display.flip()
    sleep(1)
    # Faire attendre le joueur 3 secondes avant que le jeu ne le ramène au menu
    for i in range(3):
        screen.fill((0, 0, 0))
        étiquette('Vous avez perdu!'.format(3 - i), 720, 400, 60)
        étiquette('Retour au menu dans {} secondes'.format(3 - i), 600, 500,
                  60)
        org_screen.blit(screen, (0, 0))
        pygame.display.flip()
        sleep(1)
    # Retoune le joueur au menu principal
    menu_général()
示例#7
0
 def fire(self, projectiles_group: pygame.sprite.Group):
     # swap get_height and get_width because of rotation
     projectile = MultiProjectile(self.projectile_speed,
                                  self.x + self.rect.w / 2, self.y,
                                  self.attack_imgs, self.anim_delay,
                                  self.projectile_count, 90,
                                  self.projectile_spread)
     projectiles_group.add(projectile.projectiles_group)
def create_alien(ai_settings: Settings, screen: pygame.Surface,
                 aliens: pygame.sprite.Group, alien_number: int,
                 row_number: int) -> NoReturn:
    """创建一个外星人并将其放在当前行"""
    alien = Alien(ai_settings, screen)
    alien_width = alien.rect.width
    alien.x = alien_width + 2 * alien_width * alien_number
    alien.rect.x = int(alien.x)
    alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
    aliens.add(alien)
示例#9
0
def collision_pairs(grpSprites1: pygame.sprite.Group,
                    grpSprites2: pygame.sprite.Group,
                    fncCollided=pygame.sprite.collide_rect) -> List[Tuple[Sprite, Sprite]]:
    lstPairs = []
    lstSpr1 = grpSprites1.sprites()
    lstSpr2 = grpSprites2.sprites()
    for i in range(len(lstSpr1)):
        for j in range(len(lstSpr2)):
            if fncCollided(lstSpr1[i], lstSpr2[j]):
                lstPairs.append((lstSpr1[i], lstSpr2[j]))
    return lstPairs
示例#10
0
def draw(screen: pygame.Surface, background: pygame.Surface,
         framerate: int, all_sprites: pygame.sprite.Group,
         clock: pygame.time.Clock, grid: Grid, current_time: int,
         grid_visible: bool) -> None:
    screen.blit(background, [0, 0])
    all_sprites.update()
    if grid_visible:
        grid.draw_grid(screen, current_time)
    all_sprites.draw(screen)
    pygame.display.flip()
    clock.tick(framerate)
示例#11
0
def render_pipes(image_list: list, group: pygame.sprite.Group) -> Enemy:
    """Renders pipe images onto the screen. Pipe objects are created after a set
	number of milliseconds. The newly formed pipe is then added to the pipes
	group"""
    milliseconds = pygame.time.get_ticks()
    if milliseconds % 1500 < 15:
        characteristics = spawn_pipe(image_list)
        if characteristics is not None:
            pipe = Enemy(characteristics[0], characteristics[1],
                         characteristics[2])
            group.add(pipe)
            return pipe
示例#12
0
def move_with_gravity(asteroids: pygame.sprite.Group):
    """
    Function takes tuple of planets(asteroids) calculate their gravitational
    interaction.
    """
    asteroids = tuple(asteroids)
    for asteroid in asteroids:
        asteroid.reset_forses()
    for asteroid_i in asteroids:
        for asteroid_j in asteroids:
            # In order for not to do the same action twice
            if asteroids.index(asteroid_i) < asteroids.index(asteroid_j):
                asteroid_i.gravitational_force(asteroid_j)
示例#13
0
 def _add_extra_numbers(self, pos_x: int, score: str, nums_images: Dict,
                        nums_coords: List, nums_position: Tuple,
                        score_sprites: pygame.sprite.Group) -> None:
     if len(score) > 1:
         for i in range(1, len(score)):
             if score[i] == score[0] or score[i] == score[i - 1]:
                 extra_number = Image(self.nums_assets, nums_coords[i],
                                      nums_position)
             else:
                 extra_number = nums_images[score[i]]
             pos_x += extra_number.rect.width + 2
             extra_number.rect = (pos_x, nums_position[1])
             score_sprites.add(extra_number)
示例#14
0
def display_game(sprites: pygame.sprite.Group, live_blocks: Shape,
                 solid_blocks: list):
    sprites.empty()
    for i in live_blocks:
        sprites.add(i)
    for i in solid_blocks:
        sprites.add(i)
    sprites.update()

    screen.blit(background, (0, 0))
    sprites.draw(screen)

    pygame.display.flip()
示例#15
0
def render_pipes(speed: int, timer: float, scaling: float, image_list: list,
                 group: pygame.sprite.Group) -> Enemy:
    """Renders pipe images onto the screen. Pipe objects are created after a set
    number of milliseconds. The newly formed pipe is then added to the pipes
    group"""

    if timer > scaling * (1 / speed) * 1000:
        characteristics = spawn_pipe(image_list)

        if characteristics is not None:
            pipe = Enemy(characteristics[0], characteristics[1],
                         characteristics[2])
            group.add(pipe)
            return pipe
示例#16
0
def spawn_car(config: Config, rolling_counter: int, all_sprites: pygame.sprite.Group, supervisor: Supervisor, current_time: int) -> int:
    rolling_counter += 1
    if rolling_counter + 1 >= (framerate / config["spawn_cooldown"]):
        car = Car(config["car"], dir=-90, supervisor=supervisor)
        if pygame.sprite.spritecollideany(car, all_sprites):
            car.kill()
            return 0
        all_sprites.add(car)
        id, res = supervisor.reserve_road(car, current_time)
        logging.debug(f"Spawned car: {car} with reservation {id}:{res}")
        if res is False:
            car.kill()
        return 0
    return rolling_counter + 1
示例#17
0
def update_aliens(ai_settings: Settings, stats: GameStats,
                  screen: pygame.Surface, aliens: pygame.sprite.Group,
                  ship: Ship, bullets: pygame.sprite.Group,
                  sb: ScoreBoard) -> NoReturn:
    """更新外星人群中所有外星人的位置"""
    check_fleet_edges(ai_settings, aliens)
    aliens.update()

    # 检测外星人和飞船之间的碰撞
    if pygame.sprite.spritecollide(ship, aliens, False):
        ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets)

    # 检查是否有外星人到达了屏幕底端
    check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets, sb)
示例#18
0
def update_bullets(ai_settings: Settings, stats: GameStats,
                   screen: pygame.Surface, sb: ScoreBoard, ship: Ship,
                   aliens: pygame.sprite.Group,
                   bullets: pygame.sprite.Group) -> NoReturn:
    """更新子弹的位置,并删除已消失的子弹"""
    # 更新子弹的位置
    bullets.update()

    # 删除已消失的子弹
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)

    check_bullet_alien_collisions(ai_settings, stats, sb, aliens, bullets,
                                  screen, ship)
 def update(self, gold: pygame.sprite.Group) -> None:
     """Update the spinning animation and possibly jump."""
     # Update the disappear timer and remove from group if time.
     self._disappear_timer += 1
     if self._disappear_timer % self._disappear_time == 0:
         gold.remove(self)
     else:
         # Update the spinning animation.
         self._rotation_timer += 1
         if self._rotation_timer % 3 == 0:
             self._current_image += 1
             self.image = self._images[self._current_image % len(self._images)]
             loc: tuple = self.rect.topleft
             self.rect = self.image.get_rect()
             self.rect.topleft = loc
示例#20
0
def check_fleet_edges(ai_settings: Settings,
                      aliens: pygame.sprite.Group) -> NoReturn:
    """有外星人到达边缘是采取相应的措施"""
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(ai_settings, aliens)
            break
示例#21
0
def draw(sprites: pygame.sprite.Group, gas_bar: Bar, temp_bar: Bar,
         score: int):
    """
    :param sprites: Group of stripes
    :param gas_bar: The gas bar that will be drawn
    :param temp_bar: The temp_bar that will be drawn
    :param score: The current score
    This function renders all sprites, bars and borders.
    """
    WINDOW.fill(BACKGROUND_COLOR)
    sprites.draw(WINDOW)

    score_text = FONT.render(str(round(score)), True, WHITE_COLOR)
    WINDOW.blit(score_text, (SCREEN_SIZE[0] - score_text.get_width() - 20, 20))

    gas_bar.draw(WINDOW)
    temp_bar.draw(WINDOW)
示例#22
0
    def update(self, frametime: int, food_group: pygame.sprite.Group):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN and event.key in self.shortcuts.keys():
                event: pygame.event.Event
                # Prevents movement to the opposite direction(snake would collide with itself)
                opposites = {
                    Direction.N: Direction.S,
                    Direction.S: Direction.N,
                    Direction.W: Direction.E,
                    Direction.E: Direction.W,
                }
                direction = self.shortcuts.get(event.key)
                if opposites.get(self.direction) != direction:
                    self.new_direction = direction

        # Using frametime keeps the movement relatively stable despite the FPS the game is running at
        if self.frametime_counter >= self.frametime_for_step:
            self.step()
            self.frametime_counter = 0
            head: SnakeUnit = self.sprites().pop()
            collided_foods = pygame.sprite.spritecollide(head, food_group, dokill=True)
            if len(collided_foods) > 0:
                food_group.add(Food(self))
                new_head = SnakeUnit()
                x_mov = self.direction.value[0]
                y_mov = self.direction.value[1]
                new_head.rect = head.rect.move(x_mov, y_mov)
                self.add(new_head)

            # Correct snake position if it is out of screen
            head: SnakeUnit = self.sprites().pop()
            if head.rect.x < 0:
                head.rect.x = Screen.WIDTH - head.rect.w
            elif head.rect.x > Screen.WIDTH - head.rect.w:
                head.rect.x = 0
            elif head.rect.y < 0:
                head.rect.y = Screen.HEIGHT - head.rect.h
            elif head.rect.y > Screen.HEIGHT - head.rect.h:
                head.rect.y = 0

        else:
            self.frametime_counter += frametime
示例#23
0
def collision_pairs_self(grpSprites: pygame.sprite.Group,
                         fncCollided=pygame.sprite.collide_rect) -> List[Tuple[Sprite, Sprite]]:
    lstPairs = []
    lstSpr = grpSprites.sprites()
    for i in range(len(lstSpr)):
        for j in range(i + 1, len(lstSpr)):
            if fncCollided(lstSpr[i], lstSpr[j]):
                lstPairs.append((lstSpr[i], lstSpr[j]))
    return lstPairs
示例#24
0
def SpriteGroupRect(sg: pygame.sprite.Group):
    if sg.__len__() > 0:
        minLeft = min((o.rect.left for o in sg))
        minTop = min((o.rect.top for o in sg))
        maxRight = max((o.rect.right for o in sg))
        maxBottom = max((o.rect.bottom for o in sg))
        return pygame.rect.Rect(minLeft, minTop, maxRight - minLeft,
                                maxBottom - minTop)
    else:
        return pygame.rect.Rect(0, 0, 0, 0)
示例#25
0
    def update_keys(self, projectiles_group: pygame.sprite.Group,
                    enemy_projectiles_group: pygame.sprite.Group):
        keys = pygame.key.get_pressed()
        # math.ceil to avoid integer truncation
        if keys[settings.keys["UP"]]:
            #print(self.rect.y)
            self.y -= (self.speed * settings.DELTA_T)
            #print(self.rect.y)
            self.dirty = 1

        if keys[settings.keys["DOWN"]]:
            self.y += (self.speed * settings.DELTA_T)
            self.dirty = 1

        if keys[settings.keys["LEFT"]]:
            self.x -= (self.speed * settings.DELTA_T)
            self.dirty = 1

        if keys[settings.keys["RIGHT"]]:
            self.x += (self.speed * settings.DELTA_T)
            self.dirty = 1

        if keys[settings.keys["BOMB"]]:
            if self.bomb_timer <= 0:
                enemy_projectiles_group.empty()
                self.bomb_timer = 10000

        self.x = max(self.x, settings.LEFT_BOUND)
        self.x = min(self.x + self.rect.w, settings.RIGHT_BOUND) - self.rect.w
        self.y = max(self.y, settings.LOWER_BOUND)
        self.y = min(self.y + self.rect.h, settings.UPPER_BOUND) - self.rect.h

        self.rect.topleft = round(self.x), round(self.y)
        self.hitbox.topleft = utils.x_offset(self.rect,
                                             self.hitbox.w), utils.y_offset(
                                                 self.rect, self.hitbox.h)

        if keys[settings.keys["SHOOT"]]:
            if self.timer > self.fire_delay:
                settings.sounds["effects"]["shoot"].play()
                self.fire(projectiles_group)
                self.timer = 0
            self.dirty = 1
示例#26
0
def check_aliens_bottom(ai_settings: Settings, stats: GameStats,
                        screen: pygame.Surface, ship: Ship,
                        aliens: pygame.sprite.Group,
                        bullets: pygame.sprite.Group,
                        sb: ScoreBoard) -> NoReturn:
    """检查是否有外星人到达了屏幕底端"""
    screen_rect = screen.get_rect()
    for alien in aliens.sprites():
        if alien.rect.bottom >= screen_rect.bottom:
            # 像飞船被撞到一样进行处理
            ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets)
示例#27
0
def find_angle(missiles: pygame.sprite.Group, player):
    missiles.update()
    for missile in missiles:
        lista = []
        for num in range(2):
            vec = player.rect.center[num] - missile.rect.center[num]
            lista.append(vec)
        vector = pygame.math.Vector2(lista[0], lista[1])
        clockwise = pygame.math.Vector2.angle_to(missile.direction, vector)
        if clockwise < 0:
            clockwise = 360 + clockwise
        anticlockwise = abs(360 - clockwise)
        if clockwise < anticlockwise:
            if clockwise > 10 or clockwise < -10:
                missile.angle_speed = 5
            else:
                missile.angle_speed = 0
        else:
            if anticlockwise > 10 or anticlockwise < -10:
                missile.angle_speed = -5
            else:
                missile.angle_speed = 0
示例#28
0
def check_bullet_alien_collisions(ai_settings: Settings, stats: GameStats,
                                  sb: ScoreBoard, aliens: pygame.sprite.Group,
                                  bullets: pygame.sprite.Group,
                                  screen: pygame.Surface,
                                  ship: Ship) -> NoReturn:
    """响应子弹和外星人的碰撞"""
    # 删除相应的子弹和外星人
    collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
    if collisions:
        for alien in collisions.values():
            stats.score += ai_settings.alien_points * len(alien)
            sb.prep_score()
        check_high_scord(stats, sb)
    if len(aliens) == 0:
        # 删除现有的子弹并创建一群外星人
        bullets.empty()
        ai_settings.increase_speed()

        # 提高等级
        stats.level += 1
        sb.prep_level()
        create_fleet(ai_settings, screen, ship, aliens)
示例#29
0
 def spawn(self, all_sprites, mobs: pg.sprite.Group) -> int:
     """
     Spawns enemies pseudo-randomly in an 8x8 tile area
     centered on the Spawner.
     Returns count of enemies spawned.
     """
     max_count = randint(
         self.settings["gen"]["spawn_min"],
         self.settings["gen"]["spawn_max"],
     )
     count = 0
     for row in range(self.rows - 4, self.rows + 4):
         for col in range(self.cols - 4, self.cols + 4):
             if col <= self.settings["lvl"]["tiles_wide"]:
                 if count >= max_count:
                     break
                 elif self.level_data[row][col] == "." and random() < 0.25:
                     if random() < 0.5:
                         mob = Mob(
                             self.settings,
                             self.img,
                             "sleeper",
                             col,
                             row,
                         )
                     else:
                         mob = Mob(
                             self.settings,
                             self.img,
                             "thrall",
                             col,
                             row,
                         )
                     all_sprites.add(mob)
                     mobs.add(mob)
                     count += 1
     self.kill()
     return count
示例#30
0
    def update(self, player_projectile_group: pygame.sprite.Group,
               enemy_projectile_group: pygame.sprite.Group,
               player_group: pygame.sprite.Group,
               powerup_group: pygame.sprite.Group):
        self.fire_timer += settings.DELTA_T * 1000
        self.hit_timer += settings.DELTA_T * 1000
        self.update_movement()
        self.update_fire(enemy_projectile_group)

        hit_count = len(pygame.sprite.spritecollide(self, player_projectile_group, False))
        if self.hit_timer > self.invuln_delay and pygame.sprite.spritecollide(self, player_projectile_group, True):
            self.health -= hit_count
            self.hit_timer = 0
            if self.health <= 0:
                self.kill()
                settings.sounds["effects"]["explode"].play()
                for p in player_group:
                    p.score += self.score
                    powerups = ["heart", "speed", "firerate", "count", "spread", "invuln"]
                    powerup = random.choices(powerups, weights=[settings.LIVES - p.health, 5 - p.p_speed_count,
                                                                5 - p.p_firerate_count, 5 - p.p_count_count,
                                                                5 - p.p_spread_count, 5 - p.invuln_count])
                    if random.randint(0,0) % 3 == 0:
                        powerup_group.add(Powerup(100, self.rect.x, self.rect.y, pygame.transform.rotate(powerup_ims[powerup[0]], 90), powerup[0]))

        if self.is_hit():
            self.image = self.image.copy()
            self.image.set_alpha(127)
        else:
            self.image = self.image.copy()
            self.image.set_alpha(255)

        if pygame.sprite.spritecollide(self, player_group, False):
            self.dirty = 1

        if self.rect.right <= settings.LEFT_BOUND or self.rect.x >= settings.RIGHT_BOUND or \
                self.rect.bottom <= settings.LOWER_BOUND or self.rect.y >= settings.UPPER_BOUND:
            self.dirty = 0