2
* Copyright 2007-2008 Thomas Gallinari <tg8187@yahoo.fr>
3
* Copyright 2007-2008 Pierre-Benoît Besse <besse.pb@gmail.com>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 2 of
8
* the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#include "character.h"
21
#include <KgDifficulty>
23
const qreal Character::LOW_SPEED = 3.75;
24
const qreal Character::MEDIUM_SPEED = 4.5;
25
const qreal Character::HIGH_SPEED = 5.25;
26
const qreal Character::LOW_SPEED_INC = 0.005;
27
const qreal Character::MEDIUM_SPEED_INC = 0.01;
28
const qreal Character::HIGH_SPEED_INC = 0.02;
30
Character::Character(qreal p_x, qreal p_y, Maze* p_maze) : Element(p_x, p_y, p_maze), m_xSpeed(0), m_ySpeed(0) {
32
m_maxSpeed = m_normalSpeed; // To avoid bugs, but will be overridden in the Ghost and Kapman constructors
35
Character::~Character() {
38
void Character::move() {
39
// Take care of the Maze borders
40
if (m_maze->getColFromX(m_x + m_xSpeed) == 0) { // First column
41
m_x = (m_maze->getNbColumns() - 1.5) * Cell::SIZE;
42
} else if (m_maze->getColFromX(m_x + m_xSpeed) == m_maze->getNbColumns() - 1) { // Last column
43
m_x = 1.5 * Cell::SIZE;
44
} else if (m_maze->getRowFromY(m_y + m_ySpeed) == 0) { // First row
45
m_y = (m_maze->getNbRows() - 1.5) * Cell::SIZE;
46
} else if (m_maze->getRowFromY(m_y + m_ySpeed) == m_maze->getNbRows() - 1) { // Last row
47
m_y = 1.5 * Cell::SIZE;
52
emit(moved(m_x, m_y));
55
void Character::die() {
59
qreal Character::getXSpeed() const {
63
qreal Character::getYSpeed() const {
67
qreal Character::getSpeed() const {
71
qreal Character::getNormalSpeed() const {
75
void Character::setXSpeed(qreal p_xSpeed) {
79
void Character::setYSpeed(qreal p_ySpeed) {
83
void Character::initSpeed() {
84
// Kapman speed increase when level up
85
switch ((int) Kg::difficultyLevel())
87
case KgDifficultyLevel::Easy:
88
m_normalSpeed = Character::LOW_SPEED;
90
case KgDifficultyLevel::Medium:
91
m_normalSpeed = Character::MEDIUM_SPEED;
93
case KgDifficultyLevel::Hard:
94
m_normalSpeed = Character::HIGH_SPEED;
97
m_speed = m_normalSpeed;
100
void Character::increaseCharactersSpeed() {
101
m_normalSpeed += m_normalSpeed * m_speedIncrease;
102
// Do not have a speed over the max allowed speed
103
if (m_normalSpeed > m_maxSpeed) {
104
m_normalSpeed = m_maxSpeed;
106
m_speed = m_normalSpeed;
109
bool Character::isInLineSight(Character* p_character) {
110
int curCallerRow; // The current row of the Character
111
int curCallerCol; // The current column of the Character
112
int curCharacterRow; // The current row of the other Character
113
int curCharacterCol; // The current column of the other Character
115
curCallerRow = m_maze->getRowFromY(m_y);
116
curCallerCol = m_maze->getColFromX(m_x);
117
curCharacterRow = m_maze->getRowFromY(p_character->getY());
118
curCharacterCol = m_maze->getColFromX(p_character->getX());
120
// If the two Characters are on the same row
121
if (curCallerRow == curCharacterRow ) {
122
// If The Character is on the right of the other one and goes to the left
123
if (curCallerCol > curCharacterCol && m_xSpeed < 0) {
124
// Check there is a wall between them
125
for (int i = curCharacterCol; i < curCallerCol; ++i) {
126
if (m_maze->getCell(curCallerRow, i).getType() != Cell::CORRIDOR) {
130
// If not, the other Character is in the line sight
132
// If the Character is on the left of the other one and goes to the right
133
} else if (curCallerCol < curCharacterCol && m_xSpeed > 0) {
134
// Check there is a wall between them
135
for (int i = curCallerCol; i < curCharacterCol; ++i) {
136
if (m_maze->getCell(curCallerRow, i).getType() != Cell::CORRIDOR) {
140
// If not, the other Character is in the line sight
143
// If the two Characters are on the same column
144
} else if (curCallerCol == curCharacterCol) {
145
// If The Character is on the bottom of the other one and goes up
146
if (curCallerRow > curCharacterRow && m_ySpeed < 0) {
147
// Check there is a wall between them
148
for (int i = curCharacterRow; i < curCallerRow; ++i) {
149
if (m_maze->getCell(i, curCallerCol).getType() != Cell::CORRIDOR) {
153
// If not, the other Character is in the line sight
155
// If the Character is on the top of the other one and goes down
156
} else if (curCallerRow < curCharacterRow && m_ySpeed > 0) {
157
// Check there is a wall between them
158
for (int i = curCallerRow; i < curCharacterRow; ++i) {
159
if (m_maze->getCell(i, curCallerCol).getType() != Cell::CORRIDOR) {
163
// If not, the other Character is in the line sight
167
// If the two Characters are not on the same row or column, they are not in the line of sight
171
Cell Character::getNextCell() {
173
// Get the current cell coordinates from the character coordinates
174
int curCellRow = m_maze->getRowFromY(m_y);
175
int curCellCol = m_maze->getColFromX(m_x);
177
// Get the next cell function of the character direction
179
nextCell = m_maze->getCell(curCellRow, curCellCol + 1);
180
} else if (m_xSpeed < 0) {
181
nextCell = m_maze->getCell(curCellRow, curCellCol - 1);
182
} else if (m_ySpeed > 0) {
183
nextCell = m_maze->getCell(curCellRow + 1, curCellCol);
184
} else if (m_ySpeed < 0) {
185
nextCell = m_maze->getCell(curCellRow - 1, curCellCol);
191
bool Character::onCenter() {
192
// Get the current cell center coordinates
193
qreal centerX = (m_maze->getColFromX(m_x) + 0.5) * Cell::SIZE;
194
qreal centerY = (m_maze->getRowFromY(m_y) + 0.5) * Cell::SIZE;
195
bool willGoPast = false;
197
// Will the character go past the center of the cell it's on ?
200
willGoPast = (m_x <= centerX && m_x + m_xSpeed >= centerX);
203
else if (m_xSpeed < 0) {
204
willGoPast = (m_x >= centerX && m_x + m_xSpeed <= centerX);
207
else if (m_ySpeed > 0) {
208
willGoPast = (m_y <= centerY && m_y + m_ySpeed >= centerY);
211
else if (m_ySpeed < 0) {
212
willGoPast = (m_y >= centerY && m_y + m_ySpeed <= centerY);
216
willGoPast = (m_x == centerX && m_y == centerY);
222
void Character::moveOnCenter() {
223
setX((m_maze->getColFromX(m_x) + 0.5) * Cell::SIZE);
224
setY((m_maze->getRowFromY(m_y) + 0.5) * Cell::SIZE);