File indexing completed on 2023-10-01 08:02:04
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 Thomas Gallinari <tg8187@yahoo.fr> 0003 SPDX-FileCopyrightText: 2007-2008 Pierre-BenoƮt Besse <besse.pb@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "character.h" 0009 0010 #include <KgDifficulty> 0011 0012 const qreal Character::LOW_SPEED = 3.75; 0013 const qreal Character::MEDIUM_SPEED = 4.5; 0014 const qreal Character::HIGH_SPEED = 5.25; 0015 const qreal Character::LOW_SPEED_INC = 0.005; 0016 const qreal Character::MEDIUM_SPEED_INC = 0.01; 0017 const qreal Character::HIGH_SPEED_INC = 0.02; 0018 0019 Character::Character(qreal p_x, qreal p_y, Maze *p_maze) 0020 : Element(p_x, p_y, p_maze) 0021 , m_xSpeed(0) 0022 , m_ySpeed(0) 0023 { 0024 initSpeed(); 0025 m_maxSpeed = m_normalSpeed; // To avoid bugs, but will be overridden in the Ghost and Kapman constructors 0026 } 0027 0028 Character::~Character() = default; 0029 0030 void Character::move() 0031 { 0032 // Take care of the Maze borders 0033 if (m_maze->getColFromX(m_x + m_xSpeed) == 0) { // First column 0034 m_x = (m_maze->getNbColumns() - 1.5) * Cell::SIZE; 0035 } else if (m_maze->getColFromX(m_x + m_xSpeed) == m_maze->getNbColumns() - 1) { // Last column 0036 m_x = 1.5 * Cell::SIZE; 0037 } else if (m_maze->getRowFromY(m_y + m_ySpeed) == 0) { // First row 0038 m_y = (m_maze->getNbRows() - 1.5) * Cell::SIZE; 0039 } else if (m_maze->getRowFromY(m_y + m_ySpeed) == m_maze->getNbRows() - 1) { // Last row 0040 m_y = 1.5 * Cell::SIZE; 0041 } 0042 // Move the Character 0043 m_x += m_xSpeed; 0044 m_y += m_ySpeed; 0045 Q_EMIT moved(m_x, m_y); 0046 } 0047 0048 void Character::die() 0049 { 0050 Q_EMIT eaten(); 0051 } 0052 0053 qreal Character::getXSpeed() const 0054 { 0055 return m_xSpeed; 0056 } 0057 0058 qreal Character::getYSpeed() const 0059 { 0060 return m_ySpeed; 0061 } 0062 0063 qreal Character::getSpeed() const 0064 { 0065 return m_speed; 0066 } 0067 0068 qreal Character::getNormalSpeed() const 0069 { 0070 return m_normalSpeed; 0071 } 0072 0073 void Character::setXSpeed(qreal p_xSpeed) 0074 { 0075 m_xSpeed = p_xSpeed; 0076 } 0077 0078 void Character::setYSpeed(qreal p_ySpeed) 0079 { 0080 m_ySpeed = p_ySpeed; 0081 } 0082 0083 void Character::initSpeed() 0084 { 0085 // Kapman speed increase when level up 0086 switch ((int)Kg::difficultyLevel()) { 0087 case KgDifficultyLevel::Easy: 0088 m_normalSpeed = Character::LOW_SPEED; 0089 break; 0090 case KgDifficultyLevel::Medium: 0091 m_normalSpeed = Character::MEDIUM_SPEED; 0092 break; 0093 case KgDifficultyLevel::Hard: 0094 m_normalSpeed = Character::HIGH_SPEED; 0095 break; 0096 } 0097 m_speed = m_normalSpeed; 0098 } 0099 0100 void Character::increaseCharactersSpeed() 0101 { 0102 m_normalSpeed += m_normalSpeed * m_speedIncrease; 0103 // Do not have a speed over the max allowed speed 0104 if (m_normalSpeed > m_maxSpeed) { 0105 m_normalSpeed = m_maxSpeed; 0106 } 0107 m_speed = m_normalSpeed; 0108 } 0109 0110 bool Character::isInLineSight(Character *p_character) 0111 { 0112 int curCallerRow; // The current row of the Character 0113 int curCallerCol; // The current column of the Character 0114 int curCharacterRow; // The current row of the other Character 0115 int curCharacterCol; // The current column of the other Character 0116 0117 curCallerRow = m_maze->getRowFromY(m_y); 0118 curCallerCol = m_maze->getColFromX(m_x); 0119 curCharacterRow = m_maze->getRowFromY(p_character->getY()); 0120 curCharacterCol = m_maze->getColFromX(p_character->getX()); 0121 0122 // If the two Characters are on the same row 0123 if (curCallerRow == curCharacterRow) { 0124 // If The Character is on the right of the other one and goes to the left 0125 if (curCallerCol > curCharacterCol && m_xSpeed < 0) { 0126 // Check there is a wall between them 0127 for (int i = curCharacterCol; i < curCallerCol; ++i) { 0128 if (m_maze->getCell(curCallerRow, i).getType() != Cell::CORRIDOR) { 0129 return false; 0130 } 0131 } 0132 // If not, the other Character is in the line sight 0133 return true; 0134 // If the Character is on the left of the other one and goes to the right 0135 } else if (curCallerCol < curCharacterCol && m_xSpeed > 0) { 0136 // Check there is a wall between them 0137 for (int i = curCallerCol; i < curCharacterCol; ++i) { 0138 if (m_maze->getCell(curCallerRow, i).getType() != Cell::CORRIDOR) { 0139 return false; 0140 } 0141 } 0142 // If not, the other Character is in the line sight 0143 return true; 0144 } 0145 // If the two Characters are on the same column 0146 } else if (curCallerCol == curCharacterCol) { 0147 // If The Character is on the bottom of the other one and goes up 0148 if (curCallerRow > curCharacterRow && m_ySpeed < 0) { 0149 // Check there is a wall between them 0150 for (int i = curCharacterRow; i < curCallerRow; ++i) { 0151 if (m_maze->getCell(i, curCallerCol).getType() != Cell::CORRIDOR) { 0152 return false; 0153 } 0154 } 0155 // If not, the other Character is in the line sight 0156 return true; 0157 // If the Character is on the top of the other one and goes down 0158 } else if (curCallerRow < curCharacterRow && m_ySpeed > 0) { 0159 // Check there is a wall between them 0160 for (int i = curCallerRow; i < curCharacterRow; ++i) { 0161 if (m_maze->getCell(i, curCallerCol).getType() != Cell::CORRIDOR) { 0162 return false; 0163 } 0164 } 0165 // If not, the other Character is in the line sight 0166 return true; 0167 } 0168 } 0169 // If the two Characters are not on the same row or column, they are not in the line of sight 0170 return false; 0171 } 0172 0173 Cell Character::getNextCell() 0174 { 0175 Cell nextCell; 0176 // Get the current cell coordinates from the character coordinates 0177 int curCellRow = m_maze->getRowFromY(m_y); 0178 int curCellCol = m_maze->getColFromX(m_x); 0179 0180 // Get the next cell function of the character direction 0181 if (m_xSpeed > 0) { 0182 nextCell = m_maze->getCell(curCellRow, curCellCol + 1); 0183 } else if (m_xSpeed < 0) { 0184 nextCell = m_maze->getCell(curCellRow, curCellCol - 1); 0185 } else if (m_ySpeed > 0) { 0186 nextCell = m_maze->getCell(curCellRow + 1, curCellCol); 0187 } else if (m_ySpeed < 0) { 0188 nextCell = m_maze->getCell(curCellRow - 1, curCellCol); 0189 } 0190 0191 return nextCell; 0192 } 0193 0194 bool Character::onCenter() 0195 { 0196 // Get the current cell center coordinates 0197 qreal centerX = (m_maze->getColFromX(m_x) + 0.5) * Cell::SIZE; 0198 qreal centerY = (m_maze->getRowFromY(m_y) + 0.5) * Cell::SIZE; 0199 bool willGoPast = false; 0200 0201 // Will the character go past the center of the cell it's on ? 0202 // If goes right 0203 if (m_xSpeed > 0) { 0204 willGoPast = (m_x <= centerX && m_x + m_xSpeed >= centerX); 0205 } 0206 // If goes left 0207 else if (m_xSpeed < 0) { 0208 willGoPast = (m_x >= centerX && m_x + m_xSpeed <= centerX); 0209 } 0210 // If goes down 0211 else if (m_ySpeed > 0) { 0212 willGoPast = (m_y <= centerY && m_y + m_ySpeed >= centerY); 0213 } 0214 // If goes up 0215 else if (m_ySpeed < 0) { 0216 willGoPast = (m_y >= centerY && m_y + m_ySpeed <= centerY); 0217 } 0218 // If does not moe 0219 else { 0220 willGoPast = (m_x == centerX && m_y == centerY); 0221 } 0222 0223 return willGoPast; 0224 } 0225 0226 bool Character::isOnCenter() 0227 { 0228 // Get the current cell center coordinates 0229 qreal centerX = (m_maze->getColFromX(m_x) + 0.5) * Cell::SIZE; 0230 qreal centerY = (m_maze->getRowFromY(m_y) + 0.5) * Cell::SIZE; 0231 0232 return m_x == centerX && m_y == centerY; 0233 } 0234 0235 void Character::moveOnCenter() 0236 { 0237 setX((m_maze->getColFromX(m_x) + 0.5) * Cell::SIZE); 0238 setY((m_maze->getRowFromY(m_y) + 0.5) * Cell::SIZE); 0239 } 0240 0241 #include "moc_character.cpp"