QT案例:飞机大战(五)

7 子弹制作

制作步骤如下:

  • 创建子弹文件和类
  • 添加子弹类中的成员函数和成员属性
  • 实现成员函数
  • 测试子弹

7.1 创建子弹文件和类

创建Bullet类以及生成对应的文件

创建好后生成bullet.h 和 bullet.cpp两个文件
QT案例:飞机大战(五)_第1张图片

7.2 子弹的成员函数和成员属性

在Bullet.h中添加代码

#ifndef BULLET_H
#define BULLET_H
#include "config.h"
#include 

class Bullet
{
public:
    Bullet();

    //更新子弹坐标
    void updatePosition();

public:
    //子弹资源对象
    QPixmap m_Bullet;
    //子弹坐标
    int m_X;
    int m_Y;
    //子弹移动速度
    int m_Speed;
    //子弹是否闲置
    bool m_Free;
    //子弹的矩形边框(用于碰撞检测)
    QRect m_Rect;
};

#endif // BULLET_H

7.3 子弹类成员函数实现

在config.h中追加子弹配置信息

/**********  子弹配置数据 **********/
#define BULLET_PATH ":/res/bullet_11.png"   //子弹图片路径
#define BULLET_SPEED 5  //子弹移动速度

在bullet.cpp中实现成员函数,代码如下:

#include "bullet.h"

Bullet::Bullet()
{
    //加载子弹资源
    m_Bullet.load(BULLET_PATH);

    //子弹坐标 初始坐标可随意设置,后期会重置
    m_X = GAME_WIDTH*0.5 - m_Bullet.width()*0.5;
    m_Y = GAME_HEIGHT;

    //子弹状态
    m_Free = true;

    //子弹速度
    m_Speed = BULLET_SPEED;

    //子弹矩形框
    m_Rect.setWidth(m_Bullet.width());
    m_Rect.setHeight(m_Bullet.height());
    m_Rect.moveTo(m_X,m_Y);
}
void Bullet::updatePosition()
{
    //如果子弹是空闲状态,不需要坐标计算
    //玩家飞机可以控制子弹的空闲状态为false
    if(m_Free)
    {
        return;
    }

    //子弹向上移动
    m_Y  -= m_Speed;
    m_Rect.moveTo(m_X,m_Y);

    if(m_Y <= -m_Rect.height())
    {
        m_Free = true;
    }
}

7.4 测试子弹

子弹本身应该由飞机发射,测试阶段我们写一段辅助代码,看看效果即可

测试过后,这些代码可以删除掉

在MainScene.h中添加测试代码

//测试子弹代码
    Bullet temp_bullet;

在MainScene.cpp中的updatePosition里添加测试代码

 //测试子弹代码
    temp_bullet.m_Free = false;
    temp_bullet.updatePosition();

在MainScene.cpp中的paintEvent里添加测试代码

 //测试子弹代码
    painter.drawPixmap(temp_bullet.m_X,temp_bullet.m_Y,temp_bullet.m_Bullet);

运行程序,此时会有一发子弹从屏幕中射出
QT案例:飞机大战(五)_第2张图片
测试完毕后,测试代码删除或注释即可

8 玩家发射子弹

玩家发射子弹制作步骤如下:

  • 英雄飞机添加新的成员属性
  • 实现发射成员函数
  • 主场景控制子弹发射

8.1 飞机添加新成员属性

在config.h中添加新的配置数据

#define BULLET_NUM 30   //弹匣中子弹总数
#define BULLET_INTERVAL 20 //发射子弹时间间隔

在HeroPlane.h中新增成员属性如下:

 //弹匣
    Bullet m_bullets[BULLET_NUM];

    //发射间隔记录
    int m_recorder;

8.2 成员函数补充

在构造函数 HeroPlane 中初始化发生间隔记录

 //初始化发射间隔记录
    m_recorder = 0;

之前在英雄飞机类中预留的一个shoot函数我们进行实现,代码如下:

void HeroPlane::shoot()
{
    //累加时间间隔记录变量
    m_recorder++;
    //判断如果记录数字 未达到发射间隔,直接return
    if(m_recorder < BULLET_INTERVAL)
    {
        return;
    }
    //到达发射时间处理
    //重置发射时间间隔记录
    m_recorder = 0;

    //发射子弹
    for(int i = 0 ; i < BULLET_NUM;i++)
    {
        //如果是空闲的子弹进行发射
        if(m_bullets[i].m_Free)
        {
            //将改子弹空闲状态改为假
            m_bullets[i].m_Free = false;
            //设置发射的子弹坐标
            m_bullets[i].m_X = m_X + m_Rect.width()*0.5 - 10;
            m_bullets[i].m_Y = m_Y - 25 ;
            break;
        }
    }
}

8.3 主场景中实现发射子弹

在MainScene.cpp的updatePosition成员函数中追加如下代码

  //发射子弹
    m_hero.shoot();
    //计算子弹坐标
    for(int i = 0 ;i < BULLET_NUM;i++)
    {
        //如果子弹状态为非空闲,计算发射位置
        if(!m_hero.m_bullets[i].m_Free)
        {
            m_hero.m_bullets[i].updatePosition();
        }
    }

在MainScene.cpp的paintEvent成员函数中追加如下代码:

    //绘制子弹
    for(int i = 0 ;i < BULLET_NUM;i++)
    {
        //如果子弹状态为非空闲,计算发射位置
        if(!m_hero.m_bullets[i].m_Free)
        {
            painter.drawPixmap(m_hero.m_bullets[i].m_X,m_hero.m_bullets[i].m_Y,m_hero.m_bullets[i].m_Bullet);
        }
    }

测试运行,玩家可以发射子弹
QT案例:飞机大战(五)_第3张图片

你可能感兴趣的:(MFC与QT)