Pygame飞机大战一个简单的双人模式测试

在之前完成了飞机大战整个项目以后就想提升一下,所以萌生出了做双人模式的想法。

那么在单人模式的基础上重写一个HeroB,我们将一号玩家称为HeroA

class HeroB(Plane):
    """英雄飞机类"""

    def __init__(self, *groups):
        """构造方法
        :param groups: 要添加的精灵组
        """
        super().__init__(1000, 5, 0, "me_down.wav", ["me%d.png" % i for i in range(1, 3)], "me1.png",
                         ["me_destroy_%d.png" % i for i in range(1, 5)], *groups)
        self.is_power = False                       # 无敌判断标记
        self.bomb_count = HERO_BOMB_COUNT           # 炸弹数量
        self.bullets_kind = 0                       # 子弹类型
        self.bullets_group = pygame.sprite.Group()  # 子弹精灵组
        # 初始位置
        self.rect.midbottom = HERO_DEFAULT_MID_BOTTOM
        # 设置发射子弹定时器事件
        pygame.time.set_timer(HERO_FIRE_EVENT, 40)

    def update(self, *args):
        """更新英雄飞机的图像及矩形区域
        :param args: 0 更新图像标记, 1 水平移动基数, 2 垂直移动基数
        """
        # 调用父类方法更新飞机图像 - 注意 args需要解包
        super().update(*args)

        # 限定在游戏窗口内部移动
        self.rect.x = 0 if self.rect.x < 0 else self.rect.x
        if self.rect.right > SCREEN_RECT.right:
            self.rect.right = SCREEN_RECT.right
        self.rect.y = 0 if self.rect.y < 0 else self.rect.y
        if self.rect.bottom > SCREEN_RECT.bottom:
            self.rect.bottom = SCREEN_RECT.bottom

    def blowup(self, enemies_group):
        """引爆炸弹
        :param enemies_group: 敌机精灵组
        :return: 累计得分
        """
        # 如果没有足够数量的炸弹或者英雄飞机被摧毁,直接返回
        if self.bomb_count <= 0 or self.hp <= 0:
            return 0
        self.bomb_count -= 1            # 炸弹数量-1
        score = 0                       # 本次得分
        count = 0                       # 炸毁数量
        # 遍历敌机精灵组,将游戏窗口内的敌机引爆
        for enemy in enemies_group.sprites():
            # 判断敌机是否进入游戏窗口
            if enemy.rect.bottom > 0:
                score += enemy.value    # 计算得分
                count += 1              # 累计数量
                enemy.hp = 0            # 摧毁敌机
        print("炸毁了 %d 架敌机,得分 %d" % (count, score))
        return score

    def reset_plane(self):
        """重置英雄飞机"""
        # 调用父类方法重置图像相关属性
        super().reset_plane()
        self.is_power = True               # 无敌判断标记
        # self.bomb_count = HERO_BOMB_COUNT       # 炸弹数量
        self.bullets_kind = 0                    # 子弹类型
        # 发布英雄牺牲事件
        pygame.event.post(pygame.event.Event(HERO_DEAD_EVENT))
        # 设置3s之后取消无敌定时器事件
        pygame.time.set_timer(HERO_POWER_OFF_EVENT, 3000)

    def fire(self, display_group):
        """发射子弹
        :param display_group: 要添加的显示精灵组
        """
        # 需要将子弹精灵添加到2个精灵组
        groups = (self.bullets_group, display_group)
        # 测试子弹增强效果
        # self.bullets_kind = 1
        for i in range(3):
            # 创建子弹精灵
            bullet1 = Bullet(self.bullets_kind, *groups)
            # 计算子弹的垂直位置
            y = self.rect.y - i * 15
            # 判断子弹类型
            if self.bullets_kind == 0:
                bullet1.rect.midbottom = (self.rect.centerx, y)
            else:
                bullet1.rect.midbottom = (self.rect.centerx - 20, y)
                # 再创建一颗子弹
                bullet2 = Bullet(self.bullets_kind, *groups)
                bullet2.rect.midbottom = (self.rect.centerx + 20, y)

HeroB与HeroA为一致的代码

之后再在game里在所有调用HeroA的位置调用HeroB

# 英雄精灵
self.hero = HeroA(self.all_group)
self.herob = HeroB(self.all_group)

重新赋予玩家操作按键

# 获得当前时刻的按键元组
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
    self.herob.rect.x += 6
elif keys[pygame.K_a]:
    self.herob.rect.x -= 6
elif keys[pygame.K_w]:
    self.herob.rect.y -= 6
elif keys[pygame.K_s]:
    self.herob.rect.y += 6

if keys[pygame.K_RIGHT]:
    self.hero.rect.x += 6
elif keys[pygame.K_LEFT]:
    self.hero.rect.x -= 6
elif keys[pygame.K_UP]:
    self.hero.rect.y -= 6
elif keys[pygame.K_DOWN]:
    self.hero.rect.y += 6

修改碰撞体积方法

def check_collide(self):
    """碰撞检测"""
    global enemies
    # 检测英雄飞机和敌机的碰撞,若英雄飞机处于无敌状态彼此不会碰撞
    if not self.hero.is_power:
        enemies = pygame.sprite.spritecollide(self.hero, self.enemies_group, False, pygame.sprite.collide_mask)
    # 过滤掉已经被摧毁的敌机
        enemies = list(filter(lambda x: x.hp > 0, enemies))
    # 检测英雄飞机和敌机的碰撞,若英雄飞机处于无敌状态彼此不会碰撞
    if not self.herob.is_power:
        enemiesb = pygame.sprite.spritecollide(self.herob, self.enemies_group, False, pygame.sprite.collide_mask)
        # 过滤掉已经被摧毁的敌机
        enemies = list(filter(lambda x: x.hp > 0, enemiesb))
    # 是否撞到敌机
    if enemies:
        # 播放英雄飞机被撞毁音效
        self.player.play_sound(self.hero.wav_name)
        self.hero.hp = 0        # 英雄被摧毁
        self.herob.hp = 0
    for enemy in enemies:
        enemy.hp = 0            # 摧毁敌机
    # 检测敌机是否被子弹击中
    hit_enemies = pygame.sprite.groupcollide(self.enemies_group, self.hero.bullets_group, False, False,
                                             pygame.sprite.collide_mask)
    hit_enemiesb = pygame.sprite.groupcollide(self.enemies_group, self.herob.bullets_group, False, False,
                                             pygame.sprite.collide_mask)
    # 遍历字典
    for enemy in hit_enemies:
        # 已经被摧毁的敌机不再浪费子弹
        if enemy.hp <= 0:
            continue
        # 遍历击中敌机的子弹列表
        for bullet in hit_enemies[enemy]:
            # 将子弹从所有精灵组中删除
            bullet.kill()
            # 修改敌机的生命值
            enemy.hp -= bullet.damage
            # 如果没有敌机被摧毁,继续判定下一颗子弹
            if enemy.hp > 0:
                continue
            # 修改游戏得分并判断是否升级
            if self.hud_panel.increase_score(enemy.value):
                # 播放升级音效
                self.player.play_sound("upgrade.wav")
                self.create_enemies()
            # 播放敌机爆炸音效
            self.player.play_sound(enemy.wav_name)
            # 退出遍历子弹列表循环
            break
    # 遍历字典
    for enemy in hit_enemiesb:
        # 已经被摧毁的敌机不再浪费子弹
        if enemy.hp <= 0:
            continue
        # 遍历击中敌机的子弹列表
        for bullet in hit_enemiesb[enemy]:
            # 将子弹从所有精灵组中删除
            bullet.kill()
            # 修改敌机的生命值
            enemy.hp -= bullet.damage
            # 如果没有敌机被摧毁,继续判定下一颗子弹
            if enemy.hp > 0:
                continue
            # 修改游戏得分并判断是否升级
            if self.hud_panel.increase_score(enemy.value):
                # 播放升级音效
                self.player.play_sound("upgrade.wav")
                self.create_enemies()
            # 播放敌机爆炸音效
            self.player.play_sound(enemy.wav_name)
            # 退出遍历子弹列表循环
            break
    # 英雄拾取道具
    supplies = pygame.sprite.spritecollide(self.hero, self.supplies_group, False, pygame.sprite.collide_mask)
    suppliesb = pygame.sprite.spritecollide(self.herob, self.supplies_group, False, pygame.sprite.collide_mask)
    if supplies:
        supply = supplies[0]
        # 播放拾取道具音效
        self.player.play_sound(supply.wav_name)
        # 蒋道具设置到游戏窗口下方
        supply.rect.y = SCREEN_RECT.h
        # 判断道具类型
        if supply.kind == 0:                                        # 设置炸弹补给
            self.hero.bomb_count += 1
            self.hud_panel.show_bomb(self.hero.bomb_count)
        else:                                                       # 设置子弹增强
            self.hero.bullets_kind += 1
            # 设置子弹增强效果的定时器事件
            pygame.time.set_timer(BULLET_ENHANCED_OFF_EVENT, 8000)

    if suppliesb:
        supply = suppliesb[0]
        # 播放拾取道具音效
        self.player.play_sound(supply.wav_name)
        # 蒋道具设置到游戏窗口下方
        supply.rect.y = SCREEN_RECT.h
        # 判断道具类型
        if supply.kind == 0:  # 设置炸弹补给
            self.hero.bomb_count += 1
            self.hud_panel.show_bomb(self.hero.bomb_count)
        else:  # 设置子弹增强
            self.herob.bullets_kind += 1
            # 设置子弹增强效果的定时器事件
            pygame.time.set_timer(BULLET_ENHANCED_OFF_EVENT, 8000)

运行游戏便可看到可以双人模式进行游戏了

 第一次写文章有问题还希望大家多多指出

谢谢大家伙的观看

 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
嗨!欢迎来到 C知道!Pygame一个非常流行的用于制作游戏的 Python 库,而飞机大战一个经典的游戏主题。如果你想制作一个 Pygame 飞机大战游戏,我可以为你提供一些简单的指导。 首先,你需要安装 Pygame 库。你可以使用以下命令在 Python 中安装它: ```python pip install pygame ``` 接下来,你可以创建一个新的 Python 文件,并导入 Pygame: ```python import pygame ``` 然后,你可以初始化 Pygame 并创建一个游戏窗口: ```python pygame.init() screen = pygame.display.set_mode((800, 600)) pygame.display.set_caption("飞机大战") ``` 接下来,你可以创建一个飞机精灵,并加载飞机的图像: ```python player_image = pygame.image.load("player.png") player_rect = player_image.get_rect() ``` 然后,你可以在游戏循环中处理玩家输入,并更新飞机的位置: ```python running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_rect.x -= 5 if keys[pygame.K_RIGHT]: player_rect.x += 5 if keys[pygame.K_UP]: player_rect.y -= 5 if keys[pygame.K_DOWN]: player_rect.y += 5 screen.fill((0, 0, 0)) screen.blit(player_image, player_rect) pygame.display.flip() pygame.quit() ``` 上述代码中,我们使用键盘的方向键来控制飞机的移动。游戏窗口被清空,并在每个游戏循环中绘制飞机图像。 当然,这只是一个简单的示例。你可以进一步添加敌机、子弹、碰撞检测等功能,以使游戏更加完整。希望这些信息对你有所帮助!如果你对制作飞机大战游戏还有其他问题,欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花涧曲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值