在上一篇文章中,我们实现了地图,航点,防御塔坑的绘制,并实现了鼠标点击出现防御塔,现在敌人可以登场了!
在这一阶段,我们要完成如下功能:
1:敌人的出现和移动。
2:子弹类的构造,为防御塔的攻击做准备。
3:防御塔类的完善,能够对敌人进行攻击。
敌人的出现和移动
我们先添加一个头文件utility,来判断两个点是否相撞
utility.h中的实现:
#ifndef UTILITY_H
#define UTILITY_H
#endif // UTILITY_H
#include <QPoint>
#include <cmath>
inline bool collisionWithCircle(QPoint p1,int r1,QPoint p2,int r2)
{
//我们只创建了h文件,没有创建cpp文件,所以要定义内联函数,直接在h文件内部实现函数
int xx=p1.x()-p2.x();
int yy=p1.y()-p2.y();
int dis=sqrt(xx*xx+yy*yy);
if(dis<r1+r2)
{
return true;
}
return false;
}
添加Enemy类。
enemy.h中的实现:
#ifndef ENEMY_H
#define ENEMY_H
#include <QObject>
#include <QPoint>
#include <QString>
#include <QPainter>
#include <QSize>
#include "waypoint.h"
#include "mainwindow.h"
#include "tower.h"
class MainWindow;
class Tower;
class QPainter;
class wayPoint;
class Enemy:public QObject
{
Q_OBJECT
public:
Enemy(wayPoint * startPoint, MainWindow * game,QString path=":/images/monster1.png");
~Enemy();
void draw(QPainter * painter)const;
void move();//敌人的移动
QPoint getPos();//得到敌人的当前位置
void getAttacked(Tower * tower);//被tower攻击
void getDamaged(int damage);//敌人被攻击受到伤害
void getRemoved();//当血量非正时,敌人死亡,需要移除
void getLostSight(Tower * tower);//敌人脱离tower的攻击范围
private slots:
void doActive();//私有信号槽,敌人是否可以移动
private:
int m_maxHp;//最大血量
int m_currentHp;//当前血量
int m_walkingSpeed;//移动速度
bool m_active;//是否可以移动
wayPoint * m_destinationWayPoint;//目标航点的指针
MainWindow * m_game;//mainwindow的指针
QPoint m_pos;//当前位置
QString m_path;//图片路径
QList<Tower *> m_attackerTowerList;//正在攻击该敌人的防御塔list
static const QSize m_fixedSize;
};
#endif // ENEMY_H
在mainwindow.h中做如下添加:
//类外
#include "enemy.h"
class Enemy;
//类内
public:
void getHpDamaged();//敌人进入基地内部,基地要扣血
void awardGlod();//敌人死亡,奖励金钱
void removeEnemy(Enemy * enemy);//敌人死亡,在mainwindow中要移除
QList<Enemy *> getEnemyList();//得到Enemy*的list
private:
QList<Enemy *> m_enemyList;//用来储存敌人的list
int m_playerHp;//基地的血量
int m_playerGlod;//初始金钱
在mainwindow.cpp中添加:
构造函数完善:
, m_playerHp(5)
,m_playerGlod(1000)
其他函数的实现:
void MainWindow::getHpDamaged()
{
m_playerHp-=1;//敌人进入基地,扣一滴血
}
void MainWindow::awardGlod()
{
m_playerGlod+=200;//杀死一个敌人,奖励200,制作者可以自由更改数值
}
void MainWindow::removeEnemy(Enemy *enemy)
{
Q_ASSERT(enemy);
m_enemyList.removeOne(enemy);//死亡的敌人从enemylist中移除
delete enemy;
}
QList<Enemy *> MainWindow::getEnemyList()
{
return m_enemyList;
}
下面在enemy.cpp中进行Enemy类的实现:
#include "enemy.h"
#include "mainwindow.h"
#include "tower.h"
#include "utility.h"
#include "waypoint.h"
#include <QPainter>
#include <QPoint>
#include <QSize>
#include <QString>
#include <QVector2D>
const QSize Enemy::m_fixedSize(22,23);//
Enemy::Enemy(wayPoint * startWayPoint,MainWindow *game,QString path):
QObject(0),
m_game(game),
m_pos(startWayPoint->getPos()),
m_path(path)
{
m_maxHp=40;
m_currentHp=m_maxHp;
m_walkingSpeed=1;
m_active=false;
m_destinationWayPoint=startWayPoint->getNextWayPoint();//这里就充分利用了航点的好处,我们可以直接从当前航点得到下一个航点
}
Enemy::~Enemy()
{
m_attackerTowerList.clear();//清楚在攻击该敌人的防御塔
m_destinationWayPoint=NULL;//全部设为空指针
m_game=NULL