zoukankan      html  css  js  c++  java
  • 27飞机大战_发射子弹

    1.  设计 英雄 和 子弹 类


    英雄需求

    1. 游戏启动后,  英雄 出现在屏幕的 水平中间 位置,  距离 屏幕底部 120 像素
    2. 英雄 每隔 0.5 秒发射一次子弹,  每次 连发三枚子弹
    3. 英雄 默认不会移动, 需要通过 左/右 方向键, 控制 英雄 在水平方向移动

    子弹需求

    1. 子弹 从 英雄 的正上方 沿直线 向 上方 飞行
    2. 飞出屏幕后,  需要从 从精灵组 中删除

    Hero ---- 英雄

    • 初始化方法

      指定 英雄图片

      初始速度 = 0 ---- 英雄默认静止不定

      定义 bullets 子弹精灵组 保存子弹精灵
    • 重写 update() 方法

      英雄需要 水平移动

      并且需要保证不能 移除屏幕
    • 增加 bullets 属性, 记录所有 子弹精灵
    • 增加 fire 方法,  用于发射子弹

    Bullet -- 子弹

    • 初始化方法

      指定 子弹图片

      初始速度 = -2 ---- 子弹需要向上飞行
    • 重写 update() 方法

      判断 是否飞出屏幕, 如果是, 从 精灵组 删除

    2.  创建英雄


    2.1  准备英雄类

    • 在 plane_sprites 新建 Hero 类
    • 重写 初始化方法,  直接指定 图片名称, 并且将初始化速度设置为 0 
    • 设置 英雄的初始位置
    class Hero(GameSprite):
        """英雄精灵"""
     
        def __init__(self):
            # 1. 调用父类方法, 设置image&speed
            super().__init__("./images/me1.png", 0)
            # 2. 设置英雄的初始位置
            self.rect.centerx = SCREEN_RECT.centerx
            self.rect.bottom = SCREEN_RECT.bottom - 120

    2.2  绘制英雄

      1. 在 __create_sprites,  添加 英雄精灵 和 英雄精灵组

        后续要针对 英雄 做 碰撞检测 以及 发射子弹

        所以 英雄 需要 单独定义成属性
      2. 在 __upadte_sprites,  让 英雄精灵组 调用 update 和 draw 方法

    代码实现

    • 修改 __create_sprites 方法如下 :
    # 创建英雄的精灵和精灵组
            self.hero = Hero()
            self.hero_group = pygame.sprite.Group(self.hero)
    • 修改 __update_sprites 方法如下 :
    self.hero_group.update()
    self.hero_group.draw(self.screen)

    3.  移动英雄位置


    在 pygame 中针对 键盘按键的捕获, 有 两种 方式

    • 第一种方式 判断 event.type == pygame.KEYDOWN
    • 第二种方式

    1.  首先使用 pygame.key.get_pressed() 返回 所有按键元组

    2.  通过 键盘常量,  判断元组中 某一个键是否被按下 ---- 如果被按下,  对应数值为 1

    这两种方式之间有什么区别呢?

    • 第一种方式
    elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
        print("向右移动...")
    • 第二种方式
    # 使用键盘提供的方法获取键盘按键
    keys_pressed = pygame.key.get_pressed()
    # 判断元组中对应的按键索引值 1
    if keys_pressed[pygame.K_RIGHT]:
        print("向右移动...")

    结论

    • 第一种方式 event.type 用户 必须要抬起按键 才算一次 按键事件, 操作灵活性会大打折扣
    • 第二种方式 用户可以按住方向键不放, 就能够实现持续向某一个方向移动了,  操作灵活性更好

    3.1  移动英雄位置

    演练步骤

    1.在 Hero 类中重写 update 方法

    用 速度 speed 和 英雄 rect.x 进行叠加

    不需要调用父类方法 ---- 父类方法只是实现了单纯的垂直活动

    2.在 __event_hander 增加判断条件

    # 使用键盘提供的方法获取键盘按键
            keys_pressed = pygame.key.get_pressed()
            # 判断元组中对应的按键索引值 1
            if keys_pressed[pygame.K_RIGHT]:
                self.hero.speed = 3
            elif keys_pressed[pygame.K_LEFT]:
                self.hero.speed = -3
            else:
                self.hero.speed = 0

    3.2  控制英雄运动边界

    • 在 Hero 类的 update() 方法判断 英雄 是否超出 屏幕边界
    • right = x + width 利用 right 属性可以非常容易的针对右侧设置精灵位置
            # 控制英雄的位置
            if self.rect.x < 0:
                self.rect.x = 0
            elif self.rect.right > SCREEN_RECT.right:
                self.rect.right = SCREEN_RECT.right

    4.  发射子弹


    4.1  添加发射子弹事件

    pagame 的 定时器:

    1. 定义 定时器常量 ---- eventid
    2. 在 初始化方法 中,  调用 set_timer 方法 设置定时器事件
    3. 在 游戏循环 中, 监听定时器事件

    代码实现

    • 在 Hero 中定义 fire 方法
        def fire(self):
            print("发射子弹...")
    • 定义定时器常量
    # 英雄发射子弹事件定时器常量
    HERO_FIRE_EVENT = pygame.USEREVENT + 1
    • 在 __event_handler 方法中让英雄发射子弹
    elif event.type == HERO_FIRE_EVENT:
        self.hero.fire()

    4.2  定义子弹类

    Bullet ---- 子弹

    • 初始化方法

      指定 子弹图片

      初始速度 = -2 ---- 子弹需要向上方飞行
    • 重写 update()方法

      判断 是否飞出屏幕,  如果是, 从 精灵组 删除

    定义子弹类

    • 在 plane_sprites 新建 Bullet 继承自 GameSprites
    • 重写 初始化方法,  直接指定 图片名称, 并且设置 初始速度
    • 重写 update() 方法, 判断子弹 飞出屏幕从精灵组删除 
    class Bullet(GameSprite):
        """子弹精灵"""
     
        def __init__(self):
     
            # 调用父类方法, 设置子弹图片, 设置初始速度
            super().__init__("./images/bullet1.png", -2)
     
        def update(self):
     
            # 调用父类方法, 让子弹沿垂直方向飞行
            super().update()
     
            # 判断子弹是否飞出屏幕
            if self.rect.bottom < 0:
                self.kill()
     
        def __del__(self):
            print("子弹被销毁了...")

    4.3  发射子弹

    演练步骤

    1. 在 Hero 的 初始化方法 中创建 子弹精灵组 属性
    2. 调用 update 和 draw 方法
    3. 实现 fire() 方法
    1. 创建子弹精灵

      设置初始位置 ---- 在 英雄的正上方

      将 子弹 添加到精灵组

    代码实现

    • 初始化方法 
    # 3. 创建子弹的精灵组
    self.bullets = pygame.sprite.Group()
    •  修改 fire() 方法
        def fire(self):
            print("发射子弹...")
     
            # 1. 创建子弹精灵
            bullet = Bullet()
     
            # 2. 设置精灵的位置
            bullet.rect.bottom = self.rect.y - 20
            bullet.rect.centerx = self.rect.centerx
     
            # 3. 将精灵添加到精灵组
            self.bullets.add(bullet)

    一次发射三枚子弹

    • 修改 file() 方法
        def fire(self):
            print("发射子弹...")
     
            for i in (0, 1, 2):
                # 1. 创建子弹精灵
                bullet = Bullet()
     
                # 2. 设置精灵的位置
                bullet.rect.bottom = self.rect.y - i*20
                bullet.rect.centerx = self.rect.centerx
     
                # 3. 将精灵添加到精灵组
                self.bullets.add(bullet)
  • 相关阅读:
    bzoj 1176 cdq分治套树状数组
    Codeforces 669E cdq分治
    Codeforces 1101D 点分治
    Codeforces 1100E 拓扑排序
    Codeforces 1188D Make Equal DP
    Codeforces 1188A 构造
    Codeforces 1188B 式子转化
    Codeforces 1188C DP 鸽巢原理
    Codeforces 1179D 树形DP 斜率优化
    git commit -m "XX"报错 pre -commit hook failed (add --no-verify to bypass)问题
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/10354629.html
Copyright © 2011-2022 走看看