QT飞机大战四(敌机出场类)_#include

如图所示,一架架敌机出场

联想子弹类,可以发现他们的结构是别无二致的,所以就比较简单了。

需要有自己的坐标,资源图片

需要有一个飞行速度,来控制它的 y y y坐标一次加多少

需要有一个矩形框用于爆炸检测

同样敌机是不断出场的,所以在主场景中我们有一个敌机数组,需要重复利用

所以有一个布尔变量闲置状态,为 t r u e true true表示在飞行,否则可以拿来用

需要提供一个更新坐标的函数,同时更新闲置状态

敌机类 E n e m y P l a n e EnemyPlane EnemyPlane

​enemyPlane.h​

#ifndef ENEMYPLANE_H
#define ENEMYPLANE_H
#include <QPixmap>
#include <config.h>
#include <QRect>

class EnemyPlane
{
public:
EnemyPlane();
//更新坐标函数
void updatePosition();
public:
//图片资源
QPixmap img_enemy;
//位置
int m_x,m_y;
//边框
QRect m_Rect;
//是否闲置
bool m_Free;
//飞行速度
int m_Speed;
};

#endif // ENEMYPLANE_H

​enemyPlane.cpp​

#include "enemyplane.h"

EnemyPlane::EnemyPlane()
{
//敌机资源加载
img_enemy.load(ENEMY_PATH);
//敌机位置
m_x = 0, m_y = 0;
//敌机状态
m_Free = true;
//敌机速度
m_Speed = ENEMY_SPEED;
//敌机矩形框
m_Rect.setWidth(img_enemy.width());
m_Rect.setHeight(img_enemy.height());
m_Rect.moveTo(m_x,m_y);
}

void EnemyPlane::updatePosition()
{
if( m_Free==true ) return;//空闲的,不需要移动
m_y += m_Speed;//往前飞
m_Rect.moveTo(m_x,m_y);
if( m_y>=GAME_HEIGHT )
m_y = 0, m_Free = true;
}

然后在主场景中,需要在定时器中不断产生敌机

但是不能产生的太快了,所以设置一个变量​​int enemy_record;​​来控制

主场景中,开个敌机数组​​EnemyPlane enemys[ENEMY_NUM];​

敌机产生的逻辑主要如下

写一个​​enemyToScene()​​函数让定时器每次去调用

这是个产生敌机的函数,调用函数会累加​​enemy_record​

一旦​​enemy_record​​到了一定量,就会去发射一个敌机

也就是从​​EnemyPlane enemys[ENEMY_NUM];​​数组去找一个闲置的飞机设置为非闲置

然后定时器再去更新所有非闲置敌机的位置

然后 p a i n t e r E v e n t painterEvent painterEvent再去绘制非闲置敌机

但是这样没有实现碰撞功能

其实也简单,我们写一个​​collisionDetection()​​函数判断所有敌机和子弹的矩形框是否相交

发现相交,就把两者的闲置状态设置为 t r u e true true,相当于删掉了这两个元素

当然,这个函数也是每次在定时器里调用

​MainScene.cpp​

#include "mainscene.h"
#include "ui_mainscene.h"
#include <config.h>
#include <QDebug>
#include <QTimer>
#include <QPainter>
#include <bullet.h>
#include <QSound>
MainScene::MainScene(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainScene)
{
ui->setupUi(this);
initScene();
}

MainScene::~MainScene()
{
delete ui;
}

void MainScene::initScene()
{
//播放背景音乐
QSound::play(SOUND_BACKGROUND);
//设置随机数种子
srand( (unsigned int)time(NULL) );
//设置窗口的固定尺寸,设置标题
setFixedSize(GAME_WIDTH,GAME_HEIGHT);
setWindowTitle(GAME_TITLE);
setWindowIcon(QIcon(":/res/app.ico") );
m_map = new map(":/res/img_bg_level_1.jpg");
//场景定时器设置
timer.setInterval(10);
//敌机出场间隔
enemy_record = 0;
playGame();
}

void MainScene::playGame()
{

//监听定时器发送的信号
connect(&timer,&QTimer::timeout,[=](){
//敌机出场
enemyToScene();
//更新所有元素的坐标
updatePosition();
//碰撞检测
collisionDetection();
//绘制所有元素
update();
});
//启动定时器
timer.start();
}

void MainScene::paintEvent(QPaintEvent *)
{
QPainter painter(this);
//绘制地图
painter.drawPixmap(0,m_map->map1_posY,m_map->map1);
painter.drawPixmap(0,m_map->map2_posY,m_map->map2);
//绘制英雄飞机
painter.drawPixmap(m_hero.m_x,m_hero.m_y,m_hero.m_Plane);
//绘制子弹
for(int i=0;i<BULLET_NUM;i++)
{
if( m_hero.bullets[i].m_Free==false )
painter.drawPixmap(m_hero.bullets[i].m_x,m_hero.bullets[i].m_y,m_hero.bullets[i].m_Bullet);
}
//绘制敌机
for(int i=0;i<ENEMY_NUM;i++)
{
if( enemys[i].m_Free==false )
painter.drawPixmap(enemys[i].m_x,enemys[i].m_y,enemys[i].img_enemy);
}
}

void MainScene::updatePosition()
{
//更新地图坐标
m_map->mapPosition();
//发射子弹
m_hero.shoot();
for(int i=0;i<BULLET_NUM;i++)
{
if( m_hero.bullets[i].m_Free==false )
m_hero.bullets[i].updatePosition();
}
//敌机出场
for(int i=0;i<ENEMY_NUM;i++)
{
if( enemys[i].m_Free==false )
enemys[i].updatePosition();
}
}

void MainScene::mouseMoveEvent(QMouseEvent *event)
{
int x = event->x()-m_hero.m_Rect.width()/2;
int y = event->y()-m_hero.m_Rect.height()/2;
if( x<0 ) x = 0;
if( y<0 ) y = 0;
if( x>this->width()-m_hero.m_Rect.width() ) x = this->width()-m_hero.m_Rect.width();
if( y>this->height()-m_hero.m_Rect.height() ) y = this->height()-m_hero.m_Rect.height();
m_hero.setPosition(x,y);
}

void MainScene::enemyToScene()
{
if( ++enemy_record<ENEMY_INTERVAL ) return;
enemy_record = 0;
for(int i=0;i<ENEMY_NUM;i++)
{
if( enemys[i].m_Free==false ) continue;//非空闲,不能使用
enemys[i].m_Free = false;
enemys[i].m_x = rand()%(GAME_WIDTH-enemys[i].m_Rect.width());
enemys[i].m_y = -enemys[i].m_Rect.height();
break;
}
}
//碰撞检测
void MainScene::collisionDetection()
{
//遍历所有非空闲敌机
for(int i=0;i<ENEMY_NUM;i++)
{
if( enemys[i].m_Free ) continue;
for(int j=0;j<BULLET_NUM;j++)
{
if( m_hero.bullets[j].m_Free ) continue;
QRect res = m_hero.bullets[j].m_Rect;
if( res.intersects(enemys[i].m_Rect) )
{
enemys[i].m_Free = true;
m_hero.bullets[j].m_Free = true;
break;
}
}
}
}