9 敌机制作
敌机制作与子弹制作原理类似,也是每隔一定的时间让敌机出场
制作步骤如下:
- 创建敌机文件和类
- 添加敌机类中的成员函数和成员属性
- 实现成员函数
- 敌机出场
- 测试敌机
9.1 创建敌机文件和类
创建EnemyPlane类以及生成对应的文件
创建好后生成enemyPlane.h 和 enemyPlane.cpp两个文件
9.2 敌机成员函数和成员属性
在enemyPlane.h中添加如下代码:
#ifndef ENEMYPLANE_H
#define ENEMYPLANE_H
#include <QPixmap>
class EnemyPlane
{
public:
EnemyPlane();
//更新坐标
void updatePosition();
public:
//敌机资源对象
QPixmap m_enemy;
//位置
int m_X;
int m_Y;
//敌机的矩形边框(碰撞检测)
QRect m_Rect;
//状态
bool m_Free;
//速度
int m_Speed;
};
#endif // ENEMYPLANE_H
9.3 敌机成员函数实现
在config.h中追加敌机配置信息
/********** 敌机配置数据 **********/
#define ENEMY_PATH ":/res/img-plane_5.png" //敌机资源图片
#define ENEMY_SPEED 5 //敌机移动速度
#define ENEMY_NUM 20 //敌机总数量
#define ENEMY_INTERVAL 30 //敌机出场时间间隔
在enemyPlane.cpp中实现成员函数,代码如下:
EnemyPlane::EnemyPlane()
{
//敌机资源加载
m_enemy.load(ENEMY_PATH);
//敌机位置
m_X = 0;
m_Y = 0;
//敌机状态
m_Free = true;
//敌机速度
m_Speed = ENEMY_SPEED;
//敌机矩形
m_Rect.setWidth(m_enemy.width());
m_Rect.setHeight(m_enemy.height());
m_Rect.moveTo(m_X,m_Y);
}
void EnemyPlane::updatePosition()
{
//空闲状态,不计算坐标
if(m_Free)
{
return;
}
m_Y += m_Speed;
m_Rect.moveTo(m_X,m_Y);
if(m_Y >= GAME_HEIGHT)
{
m_Free = true;
}
}
9.4 敌机出场
在MainScene.h中追加敌机出场的成员函数
在MainScene.h中追加敌机数组 和 敌机出场间隔记录 的成员属性
//敌机出场
void enemyToScene();
//敌机数组
EnemyPlane m_enemys[ENEMY_NUM];
//敌机出场间隔记录
int m_recorder;
初始化间隔记录属性,在MainScene.cpp的 initScene 成员函数中追加
m_recorder = 0;
实现成员函数 enemyToScene
void MainScene::enemyToScene()
{
m_recorder++;
if(m_recorder < ENEMY_INTERVAL)
{
return;
}
m_recorder = 0;
for(int i = 0 ; i< ENEMY_NUM;i++)
{
if(m_enemys[i].m_Free)
{
//敌机空闲状态改为false
m_enemys[i].m_Free = false;
//设置坐标
m_enemys[i].m_X = rand() % (GAME_WIDTH - m_enemys[i].m_Rect.width());
m_enemys[i].m_Y = -m_enemys[i].m_Rect.height();
break;
}
}
}
在PlayGame成员函数的timeout信号发送时候,槽函数中首先追加 enemyToScene
//敌机出场
enemyToScene();
更新敌机坐标,在updatePosition成员函数中追加代码
//敌机坐标计算
for(int i = 0 ; i< ENEMY_NUM;i++)
{
//非空闲敌机 更新坐标
if(m_enemys[i].m_Free == false)
{
m_enemys[i].updatePosition();
}
}
绘制敌机,在paintEvent成员函数中追加绘制敌机代码
//绘制敌机
for(int i = 0 ; i< ENEMY_NUM;i++)
{
if(m_enemys[i].m_Free == false)
{
painter.drawPixmap(m_enemys[i].m_X,m_enemys[i].m_Y,m_enemys[i].m_enemy);
}
}
添加随机数种子
在MainScene.cpp中 initScene 成员函数里添加随机数种子
//随机数种子
srand((unsigned int)time(NULL)); //头文件 #include <ctime>
运行测试敌机出场效果
10 碰撞检测
实现碰撞检测步骤如下:
- 添加并实现碰撞检测成员函数
- 调用并测试函数
10.1 添加并实现碰撞检测函数
在MainScene.h中添加新的成员函数
void collisionDetection();
在MainScene.cpp中实现该成员函数
void MainScene::collisionDetection()
{
//遍历所有非空闲的敌机
for(int i = 0 ;i < ENEMY_NUM;i++)
{
if(m_enemys[i].m_Free)
{
//空闲飞机 跳转下一次循环
continue;
}
//遍历所有 非空闲的子弹
for(int j = 0 ; j < BULLET_NUM;j++)
{
if(m_hero.m_bullets[j].m_Free)
{
//空闲子弹 跳转下一次循环
continue;
}
//如果子弹矩形框和敌机矩形框相交,发生碰撞,同时变为空闲状态即可
if(m_enemys[i].m_Rect.intersects(m_hero.m_bullets[j].m_Rect))
{
m_enemys[i].m_Free = true;
m_hero.m_bullets[j].m_Free = true;
}
}
}
}
10.2 调用并测试函数
在MainScene.cpp中 playGame成员函数里,追加碰撞检测代码
运行查看效果,子弹和敌机碰撞后会同时消失