-
Notifications
You must be signed in to change notification settings - Fork 0
/
tower.cpp
121 lines (107 loc) · 2.89 KB
/
tower.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "tower.h"
#include "enemy.h"
#include "bullet.h"
#include "mainwindow.h"
#include "utility.h"
#include <QPainter>
#include <QColor>
#include <QTimer>
#include <QVector2D>
#include <QtMath>
const QSize Tower::ms_fixedSize(42, 42);
Tower::Tower(QPoint pos, MainWindow *game, const QPixmap &sprite/* = QPixmap(":/image/tower.png"*/) //炮塔图片【可改】
: m_attacking(false)
, m_attackRange(70)
, m_damage(10)
, m_fireRate(1000)
, m_rotationSprite(0.0)
, m_chooseEnemy(nullptr)
, m_game(game)
, m_pos(pos)
, m_sprite(sprite)
{
m_fireRateTimer = new QTimer(this);
connect(m_fireRateTimer, SIGNAL(timeout()), this, SLOT(shootWeapon()));
}
Tower::~Tower()
{
delete m_fireRateTimer;
m_fireRateTimer = nullptr;
}
void Tower::checkEnemyInRange()
{
if (m_chooseEnemy)
{
// 这种情况下,需要旋转炮台对准敌人
// 向量标准化
QVector2D normalized(m_chooseEnemy->pos() - m_pos);
normalized.normalize();
m_rotationSprite = qRadiansToDegrees(qAtan2(normalized.y(), normalized.x())) - 90;
// 如果敌人脱离攻击范围
if (!collisionWithCircle(m_pos, m_attackRange, m_chooseEnemy->pos(), 1))
lostSightOfEnemy();
}
else
{
// 遍历敌人,看是否有敌人在攻击范围内
QList<Enemy *> enemyList = m_game->enemyList();
foreach (Enemy *enemy, enemyList)
{
if (collisionWithCircle(m_pos, m_attackRange, enemy->pos(), 1))
{
chooseEnemyForAttack(enemy);
break;
}
}
}
}
void Tower::draw(QPainter *painter) const
{
painter->save(); //保存当前画笔状态
painter->setPen(Qt::white); //颜色【可改】
// 绘制攻击范围
painter->drawEllipse(m_pos, m_attackRange, m_attackRange);
// 绘制偏转坐标,由中心+偏移=左上
static const QPoint offsetPoint(-ms_fixedSize.width() / 2, -ms_fixedSize.height() / 2);
// 绘制炮塔并选择炮塔
painter->translate(m_pos); //这里将坐标原点移到m_pos
painter->rotate(m_rotationSprite);
painter->drawPixmap(offsetPoint, m_sprite);
painter->restore(); //恢复画笔状态
}
void Tower::attackEnemy()
{
//启动打炮模式
m_fireRateTimer->start(m_fireRate);
}
void Tower::chooseEnemyForAttack(Enemy *enemy)
{
//选择敌人,同时设置对敌人开火
m_chooseEnemy = enemy;
//启动timer,开始打炮
attackEnemy();
//敌人自己要关联一个攻击者,这个用QList管理攻击者,因为可能有多个
m_chooseEnemy->getAttacked(this);
}
void Tower::shootWeapon()
{
Bullet *bullet = new Bullet(m_pos, m_chooseEnemy->pos(), m_damage, m_chooseEnemy, m_game);
bullet->move();
m_game->addBullet(bullet);
}
void Tower::targetKilled()
{
if (m_chooseEnemy)
m_chooseEnemy = nullptr;
//停止计时器
m_fireRateTimer->stop();
m_rotationSprite = 0.0;
}
void Tower::lostSightOfEnemy()
{
m_chooseEnemy->gotLostSight(this);
if (m_chooseEnemy)
m_chooseEnemy = nullptr;
m_fireRateTimer->stop();
m_rotationSprite = 0.0;
}