A complex 2D-dungeon game on LPC1768 in SWJTU-Leeds Joint School XJEL2645 project. Referenced from the framework contributed by https://os.mbed.com/users/Siriagus/code/SimplePlatformGame/

Dependencies:   mbed N5110 ShiftReg PinDetect

Committer:
hugohu
Date:
Thu Mar 25 03:56:22 2021 +0000
Branch:
BRAVEHEART
Revision:
21:e19709a07756
Parent:
19:89c3eeb3761b
Combined some files, removed codes for my personal needs, created new maps, new ways to play.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Siriagus 7:678873947b29 1 #include "Game.h"
Siriagus 7:678873947b29 2
Siriagus 17:d6a3b29cab31 3 /// @file Game.cpp
Siriagus 17:d6a3b29cab31 4
Siriagus 17:d6a3b29cab31 5 Game::~Game()
Siriagus 17:d6a3b29cab31 6 {
hugohu 19:89c3eeb3761b 7 clearAll();
hugohu 19:89c3eeb3761b 8 }
hugohu 19:89c3eeb3761b 9
hugohu 19:89c3eeb3761b 10 void Game::clearAll()
hugohu 19:89c3eeb3761b 11 {
Siriagus 17:d6a3b29cab31 12 // Free allocated memory from bullets
hugohu 19:89c3eeb3761b 13 for (std::vector<Point*>::iterator it = gameProperty.bullets.begin(); it != gameProperty.bullets.end(); ++it)
Siriagus 17:d6a3b29cab31 14 delete *it;
Siriagus 17:d6a3b29cab31 15
hugohu 19:89c3eeb3761b 16 gameProperty.bullets.clear();
Siriagus 17:d6a3b29cab31 17
Siriagus 17:d6a3b29cab31 18 // Free allocated memory from enemies
hugohu 19:89c3eeb3761b 19 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it)
Siriagus 17:d6a3b29cab31 20 delete *it;
Siriagus 17:d6a3b29cab31 21
hugohu 19:89c3eeb3761b 22 gameProperty.enemies.clear();
hugohu 19:89c3eeb3761b 23
hugohu 19:89c3eeb3761b 24 // Set initial values for the player
hugohu 19:89c3eeb3761b 25 gameProperty.player.width = gameProperty.player.height = 5;
hugohu 19:89c3eeb3761b 26
hugohu 19:89c3eeb3761b 27 gameProperty.player.vx = 0;
hugohu 19:89c3eeb3761b 28 gameProperty.player.vy = 0;
hugohu 19:89c3eeb3761b 29
hugohu 19:89c3eeb3761b 30 gameProperty.player.dead = false;
hugohu 19:89c3eeb3761b 31
hugohu 19:89c3eeb3761b 32 gameProperty.player.facingLeft = false;
hugohu 19:89c3eeb3761b 33 }
Siriagus 8:9ac6a428fa26 34
Siriagus 8:9ac6a428fa26 35 void Game::init()
Siriagus 16:caf613d5b85e 36 {
hugohu 19:89c3eeb3761b 37 if (gameProperty.currentLayer == 1){
hugohu 19:89c3eeb3761b 38 Global::score = 0;
hugohu 19:89c3eeb3761b 39 gameProperty.paused = false;
hugohu 19:89c3eeb3761b 40 gameProperty.livesLeft = 3;
hugohu 19:89c3eeb3761b 41 memcpy(&mapProperty,&mapProperty1,sizeof(mapProperty1));
hugohu 19:89c3eeb3761b 42 }
hugohu 19:89c3eeb3761b 43 else
hugohu 19:89c3eeb3761b 44 {
hugohu 19:89c3eeb3761b 45 clearAll();
hugohu 19:89c3eeb3761b 46 switch(gameProperty.currentLayer)
hugohu 19:89c3eeb3761b 47 {
hugohu 19:89c3eeb3761b 48 case 2:
hugohu 19:89c3eeb3761b 49 memcpy(&mapProperty,&mapProperty2,sizeof(mapProperty2));
hugohu 19:89c3eeb3761b 50 break;
hugohu 19:89c3eeb3761b 51 case 3:
hugohu 19:89c3eeb3761b 52
hugohu 19:89c3eeb3761b 53 break;
hugohu 19:89c3eeb3761b 54 case 4:
hugohu 19:89c3eeb3761b 55
hugohu 19:89c3eeb3761b 56 break;
hugohu 19:89c3eeb3761b 57 }
Siriagus 15:d5eb13c4c1c6 58
hugohu 19:89c3eeb3761b 59 }
hugohu 19:89c3eeb3761b 60 const int seven_seg_array [] = {
hugohu 19:89c3eeb3761b 61 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
hugohu 19:89c3eeb3761b 62 };
hugohu 19:89c3eeb3761b 63 shift.write(seven_seg_array[gameProperty.livesLeft]);
hugohu 19:89c3eeb3761b 64
Siriagus 17:d6a3b29cab31 65 respawnPlayer();
hugohu 19:89c3eeb3761b 66
Siriagus 17:d6a3b29cab31 67 spawnEnemy();
Siriagus 16:caf613d5b85e 68 }
Siriagus 16:caf613d5b85e 69
hugohu 19:89c3eeb3761b 70
Siriagus 17:d6a3b29cab31 71
Siriagus 16:caf613d5b85e 72 void Game::spawnEnemy()
Siriagus 16:caf613d5b85e 73 {
hugohu 19:89c3eeb3761b 74
Siriagus 17:d6a3b29cab31 75 // Get random spawn point
Siriagus 17:d6a3b29cab31 76 int r = rand() % 3;
hugohu 19:89c3eeb3761b 77 int x = mapProperty.enermyPosition[r][0];
hugohu 19:89c3eeb3761b 78 int y = mapProperty.enermyPosition[r][1];
Siriagus 17:d6a3b29cab31 79
Siriagus 17:d6a3b29cab31 80 // Spawn random enemy
Siriagus 17:d6a3b29cab31 81 int randPercent = (rand() % 100);
Siriagus 17:d6a3b29cab31 82 Enemy::Type type;
Siriagus 17:d6a3b29cab31 83
Siriagus 17:d6a3b29cab31 84 if (randPercent >= 40) // 60% probability
Siriagus 17:d6a3b29cab31 85 type = Enemy::JUMPER;
Siriagus 17:d6a3b29cab31 86 else if (randPercent >= 15) // 25% probablitiy
Siriagus 17:d6a3b29cab31 87 type = Enemy::SIMPLE;
Siriagus 17:d6a3b29cab31 88 else // 15 % probability
Siriagus 17:d6a3b29cab31 89 type = Enemy::RUNNER;
Siriagus 17:d6a3b29cab31 90
Siriagus 17:d6a3b29cab31 91 // Create enemy
Siriagus 17:d6a3b29cab31 92 Enemy *enemy = new Enemy(x, y, true, type);
hugohu 19:89c3eeb3761b 93 gameProperty.enemies.push_back(enemy);
Siriagus 8:9ac6a428fa26 94 }
Siriagus 8:9ac6a428fa26 95
Siriagus 8:9ac6a428fa26 96 // Functions
Siriagus 7:678873947b29 97 void Game::update(float dt)
Siriagus 16:caf613d5b85e 98 {
Siriagus 15:d5eb13c4c1c6 99 // Pause button input
Siriagus 15:d5eb13c4c1c6 100 if (input->read(Input::ButtonC))
Siriagus 15:d5eb13c4c1c6 101 {
Siriagus 15:d5eb13c4c1c6 102 if (releasedBtnC)
Siriagus 15:d5eb13c4c1c6 103 {
hugohu 19:89c3eeb3761b 104 gameProperty.paused = !gameProperty.paused;
Siriagus 15:d5eb13c4c1c6 105 releasedBtnC = false;
Siriagus 15:d5eb13c4c1c6 106 }
Siriagus 15:d5eb13c4c1c6 107 }
Siriagus 15:d5eb13c4c1c6 108 else
Siriagus 15:d5eb13c4c1c6 109 releasedBtnC = true;
Siriagus 15:d5eb13c4c1c6 110
Siriagus 15:d5eb13c4c1c6 111 // Skip the rest if paused
hugohu 19:89c3eeb3761b 112 if (gameProperty.paused) return;
Siriagus 15:d5eb13c4c1c6 113
hugohu 19:89c3eeb3761b 114 // if successfully reach the end
hugohu 19:89c3eeb3761b 115 if (gameProperty.player.x == mapProperty.succeedPosition[0] && gameProperty.player.y == mapProperty.succeedPosition[1])
hugohu 19:89c3eeb3761b 116 {
hugohu 19:89c3eeb3761b 117 gameProperty.currentLayer += 1;
hugohu 19:89c3eeb3761b 118 init();
hugohu 19:89c3eeb3761b 119 }
hugohu 19:89c3eeb3761b 120
hugohu 19:89c3eeb3761b 121 // if respawn new enermy
hugohu 19:89c3eeb3761b 122 if ((rand() % 100) < mapProperty.spawnRate && !gameProperty.player.dead && gameProperty.enemies.size() <= mapProperty.maxEnermy)
Siriagus 16:caf613d5b85e 123 spawnEnemy();
hugohu 19:89c3eeb3761b 124
Siriagus 16:caf613d5b85e 125
Siriagus 8:9ac6a428fa26 126 // Handle input, should be its own function
Siriagus 8:9ac6a428fa26 127 switch(input->joystick->getDirection())
Siriagus 8:9ac6a428fa26 128 {
Siriagus 8:9ac6a428fa26 129 case LEFT:
hugohu 19:89c3eeb3761b 130 gameProperty.player.vx = -1;
hugohu 19:89c3eeb3761b 131 gameProperty.player.facingLeft = true;
hugohu 19:89c3eeb3761b 132 break;
Siriagus 8:9ac6a428fa26 133 case UP_LEFT:
hugohu 19:89c3eeb3761b 134 gameProperty.player.vx = -1;
hugohu 19:89c3eeb3761b 135 gameProperty.player.vy = -1;
hugohu 19:89c3eeb3761b 136 gameProperty.player.facingLeft = true;
hugohu 19:89c3eeb3761b 137 break;
Siriagus 8:9ac6a428fa26 138 case DOWN_LEFT:
hugohu 19:89c3eeb3761b 139 gameProperty.player.vx = -1;
hugohu 19:89c3eeb3761b 140 gameProperty.player.vy = 1;
hugohu 19:89c3eeb3761b 141 gameProperty.player.facingLeft = true;
Siriagus 8:9ac6a428fa26 142 break;
Siriagus 8:9ac6a428fa26 143 case RIGHT:
hugohu 19:89c3eeb3761b 144 gameProperty.player.vx = 1;
hugohu 19:89c3eeb3761b 145 gameProperty.player.facingLeft = false;
hugohu 19:89c3eeb3761b 146 break;
Siriagus 8:9ac6a428fa26 147 case UP_RIGHT:
hugohu 19:89c3eeb3761b 148 gameProperty.player.vx = 1;
hugohu 19:89c3eeb3761b 149 gameProperty.player.vy = -1;
hugohu 19:89c3eeb3761b 150 gameProperty.player.facingLeft = false;
hugohu 19:89c3eeb3761b 151 break;
Siriagus 8:9ac6a428fa26 152 case DOWN_RIGHT:
hugohu 19:89c3eeb3761b 153 gameProperty.player.vx = 1;
hugohu 19:89c3eeb3761b 154 gameProperty.player.vy = 1;
hugohu 19:89c3eeb3761b 155 gameProperty.player.facingLeft = false;
Siriagus 8:9ac6a428fa26 156 break;
hugohu 19:89c3eeb3761b 157 case UP:
hugohu 19:89c3eeb3761b 158 gameProperty.player.vy = -1;
hugohu 19:89c3eeb3761b 159 gameProperty.player.facingLeft = false;
hugohu 19:89c3eeb3761b 160 break;
hugohu 19:89c3eeb3761b 161 case DOWN:
hugohu 19:89c3eeb3761b 162 gameProperty.player.vy = 1;
hugohu 19:89c3eeb3761b 163 gameProperty.player.facingLeft = false;
hugohu 19:89c3eeb3761b 164 break;
Siriagus 8:9ac6a428fa26 165 case CENTER:
hugohu 19:89c3eeb3761b 166 gameProperty.player.vx = 0;
hugohu 19:89c3eeb3761b 167 gameProperty.player.vy = 0;
Siriagus 8:9ac6a428fa26 168 break;
Siriagus 8:9ac6a428fa26 169 }
Siriagus 7:678873947b29 170
hugohu 19:89c3eeb3761b 171 if (!gameProperty.player.dead)
Siriagus 8:9ac6a428fa26 172 {
hugohu 19:89c3eeb3761b 173 switch(gameProperty.currentLayer)
hugohu 19:89c3eeb3761b 174 {
hugohu 19:89c3eeb3761b 175 case 1:
hugohu 19:89c3eeb3761b 176 moveWithCollisionTest(&gameProperty.player, map1);
hugohu 19:89c3eeb3761b 177 break;
hugohu 19:89c3eeb3761b 178 case 2:
hugohu 19:89c3eeb3761b 179 moveWithCollisionTest(&gameProperty.player, map2);
hugohu 19:89c3eeb3761b 180 break;
hugohu 19:89c3eeb3761b 181 }
Siriagus 8:9ac6a428fa26 182 }
Siriagus 17:d6a3b29cab31 183 else // move without testing collision agains the map
Siriagus 17:d6a3b29cab31 184 {
hugohu 19:89c3eeb3761b 185 gameProperty.player.x += gameProperty.player.vx;
hugohu 19:89c3eeb3761b 186 gameProperty.player.y += 4;
Siriagus 17:d6a3b29cab31 187 }
Siriagus 11:adb68da98262 188
Siriagus 17:d6a3b29cab31 189 moveEnemies();
Siriagus 8:9ac6a428fa26 190
Siriagus 11:adb68da98262 191 // Check if bullet should be fired
hugohu 19:89c3eeb3761b 192 if (input->read(Input::ButtonB) && releasedBtnB && !gameProperty.player.dead)
Siriagus 8:9ac6a428fa26 193 {
Siriagus 11:adb68da98262 194 // Create a new bullet and give it initial values
Siriagus 8:9ac6a428fa26 195 Point* bullet = new Point;
hugohu 19:89c3eeb3761b 196 bullet->x = (int)(gameProperty.player.x + (gameProperty.player.width / 2));
hugohu 19:89c3eeb3761b 197 bullet->y = gameProperty.player.y + 2;
hugohu 19:89c3eeb3761b 198 bullet->vx = (gameProperty.player.facingLeft) ? -4 : 4;
Siriagus 9:da608ae65df9 199 bullet->vy = 0;
Siriagus 8:9ac6a428fa26 200
hugohu 19:89c3eeb3761b 201 gameProperty.bullets.push_back(bullet);
Siriagus 9:da608ae65df9 202 releasedBtnB = false;
Siriagus 17:d6a3b29cab31 203
Siriagus 17:d6a3b29cab31 204 // Play sound
hugohu 19:89c3eeb3761b 205 // sound->playNote(SFX::BULLET_FIRED);
Siriagus 8:9ac6a428fa26 206 }
Siriagus 9:da608ae65df9 207 else if (!input->read(Input::ButtonB))
Siriagus 9:da608ae65df9 208 releasedBtnB = true;
Siriagus 8:9ac6a428fa26 209
Siriagus 15:d5eb13c4c1c6 210 // Loop through bullets and move them + collision test
hugohu 19:89c3eeb3761b 211 for (std::vector<Point*>::iterator it = gameProperty.bullets.begin(); it != gameProperty.bullets.end();)
Siriagus 8:9ac6a428fa26 212 {
Siriagus 15:d5eb13c4c1c6 213 Point* bullet = *it;
Siriagus 15:d5eb13c4c1c6 214
Siriagus 15:d5eb13c4c1c6 215 int x0; // left border of collision rect
Siriagus 15:d5eb13c4c1c6 216 int x1; // right border of collision rect
Siriagus 15:d5eb13c4c1c6 217
Siriagus 15:d5eb13c4c1c6 218 int oldX = bullet->x;
Siriagus 15:d5eb13c4c1c6 219 int newX = bullet->x + bullet->vx;
Siriagus 15:d5eb13c4c1c6 220
Siriagus 15:d5eb13c4c1c6 221 x0 = min(oldX, newX);
Siriagus 15:d5eb13c4c1c6 222 x1 = max(oldX, newX);
Siriagus 15:d5eb13c4c1c6 223
Siriagus 15:d5eb13c4c1c6 224 // Collision rect for bullet in this time step
Siriagus 15:d5eb13c4c1c6 225 Rectangle bulletColRect(x0, bullet->y, (x1-x0)+1, 1);
Siriagus 9:da608ae65df9 226
Siriagus 15:d5eb13c4c1c6 227 bool col = false;
Siriagus 15:d5eb13c4c1c6 228 // Delete if outside screen
hugohu 19:89c3eeb3761b 229 switch(gameProperty.currentLayer)
Siriagus 9:da608ae65df9 230 {
hugohu 19:89c3eeb3761b 231 case 1:
hugohu 19:89c3eeb3761b 232 if (newX < 0 || newX > WIDTH || bulletHitMap(bulletColRect, map1)) // if outside screen
hugohu 19:89c3eeb3761b 233 col = true;
hugohu 19:89c3eeb3761b 234 else
Siriagus 16:caf613d5b85e 235 {
hugohu 19:89c3eeb3761b 236 // loop through all enemies
hugohu 19:89c3eeb3761b 237 for (std::vector<Enemy*>::iterator ite = gameProperty.enemies.begin(); ite != gameProperty.enemies.end(); ++ite)
hugohu 19:89c3eeb3761b 238 {
hugohu 19:89c3eeb3761b 239 Enemy *enemy = *ite;
hugohu 19:89c3eeb3761b 240
hugohu 19:89c3eeb3761b 241 // If bullet hits enemy
hugohu 19:89c3eeb3761b 242 //if (!enemy->dead && bullet->x >= enemy->x && bullet->x <= enemy->getRight() && bullet->y >= enemy->y && bullet->y <= enemy->getBottom())
hugohu 19:89c3eeb3761b 243
hugohu 19:89c3eeb3761b 244 Rectangle enemyColRect(enemy->x, enemy->y, enemy->width, enemy->height); // collision rectangle for enemy
hugohu 19:89c3eeb3761b 245
hugohu 19:89c3eeb3761b 246 if (!enemy->dead && hitTestRect(bulletColRect, enemyColRect))
hugohu 19:89c3eeb3761b 247 {
hugohu 19:89c3eeb3761b 248 col = true;
hugohu 19:89c3eeb3761b 249
hugohu 19:89c3eeb3761b 250 enemy->dead = true;
hugohu 19:89c3eeb3761b 251 enemy->vx = bullet->vx / 2; // sends the dead enemy in the same direction as the incoming bullet
hugohu 19:89c3eeb3761b 252 enemy->vy = -3; // sends the dead enemy upwards in the air, because of impact
hugohu 19:89c3eeb3761b 253
hugohu 19:89c3eeb3761b 254 Global::score += 5 * enemy->difficulty; // increase the score
hugohu 19:89c3eeb3761b 255
hugohu 19:89c3eeb3761b 256 // sound->playNote(SFX::ENEMY_DEAD);
hugohu 19:89c3eeb3761b 257 }
hugohu 19:89c3eeb3761b 258 }
hugohu 19:89c3eeb3761b 259 }
hugohu 19:89c3eeb3761b 260 break;
hugohu 19:89c3eeb3761b 261 case 2:
hugohu 19:89c3eeb3761b 262 if (newX < 0 || newX > WIDTH || bulletHitMap(bulletColRect, map2)) // if outside screen
Siriagus 16:caf613d5b85e 263 col = true;
hugohu 19:89c3eeb3761b 264 else
hugohu 19:89c3eeb3761b 265 {
hugohu 19:89c3eeb3761b 266 // loop through all enemies
hugohu 19:89c3eeb3761b 267 for (std::vector<Enemy*>::iterator ite = gameProperty.enemies.begin(); ite != gameProperty.enemies.end(); ++ite)
hugohu 19:89c3eeb3761b 268 {
hugohu 19:89c3eeb3761b 269 Enemy *enemy = *ite;
hugohu 19:89c3eeb3761b 270
hugohu 19:89c3eeb3761b 271 // If bullet hits enemy
hugohu 19:89c3eeb3761b 272 //if (!enemy->dead && bullet->x >= enemy->x && bullet->x <= enemy->getRight() && bullet->y >= enemy->y && bullet->y <= enemy->getBottom())
hugohu 19:89c3eeb3761b 273
hugohu 19:89c3eeb3761b 274 Rectangle enemyColRect(enemy->x, enemy->y, enemy->width, enemy->height); // collision rectangle for enemy
hugohu 19:89c3eeb3761b 275
hugohu 19:89c3eeb3761b 276 if (!enemy->dead && hitTestRect(bulletColRect, enemyColRect))
hugohu 19:89c3eeb3761b 277 {
hugohu 19:89c3eeb3761b 278 col = true;
hugohu 19:89c3eeb3761b 279
hugohu 19:89c3eeb3761b 280 enemy->dead = true;
hugohu 19:89c3eeb3761b 281 enemy->vx = bullet->vx / 2; // sends the dead enemy in the same direction as the incoming bullet
hugohu 19:89c3eeb3761b 282 enemy->vy = -3; // sends the dead enemy upwards in the air, because of impact
hugohu 19:89c3eeb3761b 283
hugohu 19:89c3eeb3761b 284 Global::score += 5 * enemy->difficulty; // increase the score
hugohu 19:89c3eeb3761b 285
hugohu 19:89c3eeb3761b 286 // sound->playNote(SFX::ENEMY_DEAD);
hugohu 19:89c3eeb3761b 287 }
hugohu 19:89c3eeb3761b 288 }
Siriagus 16:caf613d5b85e 289 }
hugohu 19:89c3eeb3761b 290 break;
Siriagus 15:d5eb13c4c1c6 291 }
Siriagus 15:d5eb13c4c1c6 292
hugohu 19:89c3eeb3761b 293
Siriagus 15:d5eb13c4c1c6 294 if (!col)
Siriagus 15:d5eb13c4c1c6 295 {
Siriagus 15:d5eb13c4c1c6 296 ++it; // go to next element
Siriagus 15:d5eb13c4c1c6 297 bullet->x += bullet->vx; // update position
Siriagus 15:d5eb13c4c1c6 298 }
Siriagus 15:d5eb13c4c1c6 299 else
Siriagus 15:d5eb13c4c1c6 300 {
Siriagus 15:d5eb13c4c1c6 301 delete bullet;
hugohu 19:89c3eeb3761b 302 it = gameProperty.bullets.erase(it); // go to next element
Siriagus 9:da608ae65df9 303 }
Siriagus 17:d6a3b29cab31 304 }
Siriagus 17:d6a3b29cab31 305
Siriagus 17:d6a3b29cab31 306 // Check if player hits enemy
hugohu 19:89c3eeb3761b 307 Rectangle playerRect(gameProperty.player.x, gameProperty.player.y, gameProperty.player.width, gameProperty.player.height);
hugohu 19:89c3eeb3761b 308 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it)
Siriagus 17:d6a3b29cab31 309 {
Siriagus 17:d6a3b29cab31 310 Enemy *enemy = *it;
Siriagus 8:9ac6a428fa26 311
Siriagus 17:d6a3b29cab31 312 if (enemy->dead) continue; // only test against living enemies
Siriagus 17:d6a3b29cab31 313
Siriagus 17:d6a3b29cab31 314 Rectangle enemyRect(enemy->x, enemy->y, enemy->width, enemy->height);
Siriagus 17:d6a3b29cab31 315
Siriagus 17:d6a3b29cab31 316 if (hitTestRect(playerRect, enemyRect))
Siriagus 17:d6a3b29cab31 317 {
hugohu 19:89c3eeb3761b 318 gameProperty.player.dead = true;
hugohu 19:89c3eeb3761b 319 gameProperty.player.vx = 0;
hugohu 19:89c3eeb3761b 320 gameProperty.player.vy = 4;
hugohu 19:89c3eeb3761b 321 --gameProperty.livesLeft;
hugohu 19:89c3eeb3761b 322 // Show the livesleft
hugohu 19:89c3eeb3761b 323 int seven_seg_array [] = {
hugohu 19:89c3eeb3761b 324 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
hugohu 19:89c3eeb3761b 325 };
hugohu 19:89c3eeb3761b 326 shift.write(seven_seg_array[gameProperty.livesLeft]);
Siriagus 17:d6a3b29cab31 327
hugohu 19:89c3eeb3761b 328 // sound->playNote(SFX::PLAYER_DEAD);
Siriagus 17:d6a3b29cab31 329 break;
Siriagus 17:d6a3b29cab31 330 }
Siriagus 17:d6a3b29cab31 331 }
Siriagus 17:d6a3b29cab31 332
hugohu 19:89c3eeb3761b 333 if (gameProperty.player.dead)
Siriagus 17:d6a3b29cab31 334 {
Siriagus 17:d6a3b29cab31 335 // remove all enemies (let them fall off)
hugohu 19:89c3eeb3761b 336 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it)
Siriagus 17:d6a3b29cab31 337 {
Siriagus 17:d6a3b29cab31 338 Enemy *enemy = *it;
Siriagus 17:d6a3b29cab31 339 enemy->dead = true;
hugohu 19:89c3eeb3761b 340 enemy->vy = 4;
Siriagus 17:d6a3b29cab31 341 }
Siriagus 17:d6a3b29cab31 342
hugohu 19:89c3eeb3761b 343 if (gameProperty.player.y >= HEIGHT && !gameProperty.enemies.size()) // when all enemies are removed
Siriagus 17:d6a3b29cab31 344 {
hugohu 19:89c3eeb3761b 345 if (gameProperty.livesLeft)
Siriagus 17:d6a3b29cab31 346 {
Siriagus 17:d6a3b29cab31 347 respawnPlayer(); // Respawn player if it still have lives left
Siriagus 17:d6a3b29cab31 348 spawnEnemy(); // Spawn an enemy right away
Siriagus 17:d6a3b29cab31 349 }
Siriagus 17:d6a3b29cab31 350 else
Siriagus 17:d6a3b29cab31 351 {
Siriagus 17:d6a3b29cab31 352 if (Global::score > Global::highscores[2].score) // If new high score
Siriagus 17:d6a3b29cab31 353 requestStateChange(SUBMIT_HIGHSCORE);
Siriagus 17:d6a3b29cab31 354 else
Siriagus 17:d6a3b29cab31 355 requestStateChange(GAME_OVER);
Siriagus 17:d6a3b29cab31 356 }
Siriagus 17:d6a3b29cab31 357 }
Siriagus 8:9ac6a428fa26 358 }
Siriagus 7:678873947b29 359 }
Siriagus 7:678873947b29 360
Siriagus 7:678873947b29 361 void Game::render()
Siriagus 7:678873947b29 362 {
Siriagus 17:d6a3b29cab31 363
hugohu 19:89c3eeb3761b 364 if (!gameProperty.player.dead)
Siriagus 17:d6a3b29cab31 365 {
Siriagus 17:d6a3b29cab31 366 // Draw map
hugohu 19:89c3eeb3761b 367 switch(gameProperty.currentLayer)
hugohu 19:89c3eeb3761b 368 {
hugohu 19:89c3eeb3761b 369 case 1:
hugohu 19:89c3eeb3761b 370 drawImage(map1);
hugohu 19:89c3eeb3761b 371 break;
hugohu 19:89c3eeb3761b 372 case 2:
hugohu 19:89c3eeb3761b 373 drawImage(map2);
hugohu 19:89c3eeb3761b 374 break;
hugohu 19:89c3eeb3761b 375 case 3:
hugohu 19:89c3eeb3761b 376 drawImage(map_chest);
hugohu 19:89c3eeb3761b 377 break;
hugohu 19:89c3eeb3761b 378 case 4:
hugohu 19:89c3eeb3761b 379 drawImage(map_big1);
hugohu 19:89c3eeb3761b 380 break;
hugohu 19:89c3eeb3761b 381 }
hugohu 19:89c3eeb3761b 382 // Draw ladder
hugohu 19:89c3eeb3761b 383 drawImage(Image::Ladder, mapProperty.succeedPosition[0], mapProperty.succeedPosition[1], false, false, false);
hugohu 19:89c3eeb3761b 384
hugohu 19:89c3eeb3761b 385 // Draw respawnCircle
hugohu 19:89c3eeb3761b 386 drawImage(Image::RespawnSign, mapProperty.respawnPosition[0], mapProperty.respawnPosition[1], false, false, false);
hugohu 19:89c3eeb3761b 387
hugohu 19:89c3eeb3761b 388 // Draw player
hugohu 19:89c3eeb3761b 389 drawImage(Image::Player, gameProperty.player.x, gameProperty.player.y, false, !gameProperty.player.facingLeft, gameProperty.player.dead);
hugohu 19:89c3eeb3761b 390
hugohu 19:89c3eeb3761b 391 // Draw enemies
hugohu 19:89c3eeb3761b 392
hugohu 19:89c3eeb3761b 393 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it)
hugohu 19:89c3eeb3761b 394 {
hugohu 19:89c3eeb3761b 395 Enemy *enemy = *it;
hugohu 19:89c3eeb3761b 396
hugohu 19:89c3eeb3761b 397 switch (enemy->type)
hugohu 19:89c3eeb3761b 398 {
hugohu 19:89c3eeb3761b 399 case Enemy::SIMPLE:
hugohu 19:89c3eeb3761b 400 drawImage(Image::EnemySimple, enemy->x, enemy->y, false, !enemy->facingLeft, enemy->dead);
hugohu 19:89c3eeb3761b 401 break;
hugohu 19:89c3eeb3761b 402
hugohu 19:89c3eeb3761b 403 case Enemy::JUMPER:
hugohu 19:89c3eeb3761b 404 drawImage(Image::EnemyJumper, enemy->x, enemy->y, false, !enemy->facingLeft, enemy->dead);
hugohu 19:89c3eeb3761b 405 break;
hugohu 19:89c3eeb3761b 406
hugohu 19:89c3eeb3761b 407 case Enemy::RUNNER:
hugohu 19:89c3eeb3761b 408 drawImage(Image::EnemyRunner, enemy->x, enemy->y, false, !enemy->facingLeft, enemy->dead);
hugohu 19:89c3eeb3761b 409 break;
hugohu 19:89c3eeb3761b 410
hugohu 19:89c3eeb3761b 411 default:
hugohu 19:89c3eeb3761b 412 ; // should not happen, don't render
hugohu 19:89c3eeb3761b 413 }
hugohu 19:89c3eeb3761b 414 }
hugohu 19:89c3eeb3761b 415
hugohu 19:89c3eeb3761b 416
hugohu 19:89c3eeb3761b 417 // Render bullets
hugohu 19:89c3eeb3761b 418 for (std::vector<Point*>::iterator it = gameProperty.bullets.begin(); it != gameProperty.bullets.end(); ++it)
hugohu 19:89c3eeb3761b 419 {
hugohu 19:89c3eeb3761b 420 int x, y;
hugohu 19:89c3eeb3761b 421 x = (*it)->x;
hugohu 19:89c3eeb3761b 422 y = (*it)->y;
hugohu 19:89c3eeb3761b 423
hugohu 19:89c3eeb3761b 424 if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT) // Boundary check
hugohu 19:89c3eeb3761b 425 lcd->setPixel(x,y);
hugohu 19:89c3eeb3761b 426 }
Siriagus 17:d6a3b29cab31 427 }
Siriagus 17:d6a3b29cab31 428 else
Siriagus 17:d6a3b29cab31 429 {
Siriagus 17:d6a3b29cab31 430 // Print lives left
Siriagus 17:d6a3b29cab31 431 std::stringstream ss;
hugohu 19:89c3eeb3761b 432 ss << "Lives left: " << gameProperty.livesLeft;
Siriagus 17:d6a3b29cab31 433 lcd->printString(ss.str().c_str(), 4, 2);
Siriagus 17:d6a3b29cab31 434 }
Siriagus 11:adb68da98262 435
Siriagus 15:d5eb13c4c1c6 436
Siriagus 15:d5eb13c4c1c6 437 // Draw pause
hugohu 19:89c3eeb3761b 438 if (gameProperty.paused)
Siriagus 15:d5eb13c4c1c6 439 {
hugohu 19:89c3eeb3761b 440 lcd->drawRect(25, 14, 35, 13, 1); // create shadow at the bottom layer
hugohu 19:89c3eeb3761b 441 lcd->drawRect(24, 13, 35, 13, 0); // outline
hugohu 19:89c3eeb3761b 442 lcd->drawRect(25, 14, 33, 11, 2); // white fill
hugohu 19:89c3eeb3761b 443 lcd->printString("Pause", 27, 2); // text
Siriagus 15:d5eb13c4c1c6 444 }
Siriagus 17:d6a3b29cab31 445
Siriagus 17:d6a3b29cab31 446 // GUI
hugohu 19:89c3eeb3761b 447 // renderScore();
Siriagus 13:7ab71c7c311b 448 }
Siriagus 13:7ab71c7c311b 449
Siriagus 13:7ab71c7c311b 450 // Collision test between entites and map
hugohu 19:89c3eeb3761b 451 void Game::moveWithCollisionTest(Entity* entity, const bool map[HEIGHT][WIDTH])
Siriagus 13:7ab71c7c311b 452 {
Siriagus 13:7ab71c7c311b 453 int x = entity->x;
Siriagus 13:7ab71c7c311b 454 int y = entity->y;
Siriagus 13:7ab71c7c311b 455 int steps = abs(entity->vx); // how many units (pixels) the entity should move in said direction
Siriagus 13:7ab71c7c311b 456 bool collision; // true if colliding
Siriagus 13:7ab71c7c311b 457
Siriagus 13:7ab71c7c311b 458 // Check x-axis
Siriagus 13:7ab71c7c311b 459 if (entity->vx > 0) // moving right
Siriagus 13:7ab71c7c311b 460 {
Siriagus 13:7ab71c7c311b 461 int entityRight = x + entity->width - 1; // Need to check right border of entity, since it is moving right
Siriagus 13:7ab71c7c311b 462
Siriagus 13:7ab71c7c311b 463 while(steps--) // While it still have more movement left
Siriagus 13:7ab71c7c311b 464 {
Siriagus 13:7ab71c7c311b 465 collision = false;
Siriagus 16:caf613d5b85e 466
Siriagus 16:caf613d5b85e 467 // Wrapping
Siriagus 16:caf613d5b85e 468 if (entityRight+1 >= WIDTH)
Siriagus 16:caf613d5b85e 469 entityRight = -1;// wants entityRight = -1, so next check is entityRight 0*/
Siriagus 16:caf613d5b85e 470
Siriagus 13:7ab71c7c311b 471 for (int i = 0; i < entity->height; ++i) // Loop through all vertical points on the right hand side of the entity (y+i)
Siriagus 13:7ab71c7c311b 472 {
Siriagus 13:7ab71c7c311b 473 if (map[y+i][entityRight+1]) // If moving to the right leads to collision for given y+i
Siriagus 13:7ab71c7c311b 474 {
Siriagus 15:d5eb13c4c1c6 475 // Slope + allows player to climb to top of platform by going right if it hits close to top of wall.
hugohu 19:89c3eeb3761b 476 if (!map[y+i-1][entityRight+1])
Siriagus 15:d5eb13c4c1c6 477 {
Siriagus 15:d5eb13c4c1c6 478 entity->vy = -1;
Siriagus 15:d5eb13c4c1c6 479 }
Siriagus 15:d5eb13c4c1c6 480 else
Siriagus 15:d5eb13c4c1c6 481 {
Siriagus 15:d5eb13c4c1c6 482 collision = true; // Then collision is true
Siriagus 15:d5eb13c4c1c6 483 break; // Skip the for loop, no need for further testing
Siriagus 15:d5eb13c4c1c6 484 }
Siriagus 15:d5eb13c4c1c6 485
Siriagus 13:7ab71c7c311b 486 }
Siriagus 13:7ab71c7c311b 487 }
Siriagus 13:7ab71c7c311b 488
Siriagus 13:7ab71c7c311b 489 if (collision) // If collision
Siriagus 13:7ab71c7c311b 490 break; // skip the while loop, entity can not move further, even though its velocity is higher
Siriagus 13:7ab71c7c311b 491 else
Siriagus 13:7ab71c7c311b 492 ++entityRight; // Move entity one px to the right
Siriagus 13:7ab71c7c311b 493 }
Siriagus 13:7ab71c7c311b 494
Siriagus 16:caf613d5b85e 495 // If wrap didn't work, make sure entity is on the correct side of the map
Siriagus 16:caf613d5b85e 496 if (entityRight < 0)
Siriagus 16:caf613d5b85e 497 entityRight = WIDTH-1;
Siriagus 16:caf613d5b85e 498
Siriagus 13:7ab71c7c311b 499 entity->x = entityRight - (entity->width - 1); // Update entity's position. Need to set upper-left pixel.
Siriagus 13:7ab71c7c311b 500 }
Siriagus 13:7ab71c7c311b 501 else // moving left
Siriagus 13:7ab71c7c311b 502 {
Siriagus 13:7ab71c7c311b 503 while(steps--) // While still movement left
Siriagus 13:7ab71c7c311b 504 {
Siriagus 13:7ab71c7c311b 505 collision = false;
Siriagus 13:7ab71c7c311b 506
Siriagus 16:caf613d5b85e 507 // Wrap around map
Siriagus 16:caf613d5b85e 508 if (x-1 < 0)
Siriagus 16:caf613d5b85e 509 x = WIDTH; // causes x-1 in the next check to be WIDTH - 1
Siriagus 13:7ab71c7c311b 510
Siriagus 16:caf613d5b85e 511 // Check for all y-positions
Siriagus 16:caf613d5b85e 512 for (int i = 0; i < entity->height; ++i)
Siriagus 13:7ab71c7c311b 513 {
Siriagus 16:caf613d5b85e 514
Siriagus 13:7ab71c7c311b 515 if (map[y+i][x-1]) // If solid block
Siriagus 13:7ab71c7c311b 516 {
hugohu 19:89c3eeb3761b 517 if (!map[y+i-1][x-1]) // If slope or close to top of wall (=> can climb by going left).
Siriagus 15:d5eb13c4c1c6 518 {
Siriagus 15:d5eb13c4c1c6 519 entity->vy = -1;
Siriagus 15:d5eb13c4c1c6 520 }
Siriagus 15:d5eb13c4c1c6 521 else
Siriagus 15:d5eb13c4c1c6 522 {
Siriagus 15:d5eb13c4c1c6 523 collision = true;
Siriagus 15:d5eb13c4c1c6 524 break; // Collision detected, no further testing required
Siriagus 15:d5eb13c4c1c6 525 }
Siriagus 13:7ab71c7c311b 526 }
Siriagus 13:7ab71c7c311b 527 }
Siriagus 13:7ab71c7c311b 528
Siriagus 13:7ab71c7c311b 529 if (collision)
Siriagus 13:7ab71c7c311b 530 break;
Siriagus 13:7ab71c7c311b 531 else
Siriagus 13:7ab71c7c311b 532 --x; // Move to the left if no collision is detected
Siriagus 13:7ab71c7c311b 533 }
Siriagus 13:7ab71c7c311b 534
Siriagus 16:caf613d5b85e 535 x %= WIDTH; // In case wrapping caused entity to crash with wall on other side, x should be 0 instead of WIDTH (invalid).
Siriagus 16:caf613d5b85e 536
Siriagus 16:caf613d5b85e 537 entity->x = x; // update position
Siriagus 13:7ab71c7c311b 538 }
Siriagus 13:7ab71c7c311b 539
Siriagus 13:7ab71c7c311b 540 // Check collision with map in y-direction - works the same way as the x-axis, except for other axis
Siriagus 13:7ab71c7c311b 541 x = entity->x;
Siriagus 13:7ab71c7c311b 542 y = entity->y;
Siriagus 13:7ab71c7c311b 543 steps = abs(entity->vy);
Siriagus 13:7ab71c7c311b 544
Siriagus 13:7ab71c7c311b 545 if (entity->vy > 0) // downwards
Siriagus 13:7ab71c7c311b 546 {
Siriagus 13:7ab71c7c311b 547 int entityBottom = y + entity->height - 1; // Need to check if bottom part collides
Siriagus 13:7ab71c7c311b 548 while(steps--) // Still movement left
Siriagus 13:7ab71c7c311b 549 {
Siriagus 13:7ab71c7c311b 550 collision = false;
Siriagus 16:caf613d5b85e 551
Siriagus 13:7ab71c7c311b 552 for (int i = 0; i < entity->width; ++i) // Loop through all x-position on lower part of entity
Siriagus 16:caf613d5b85e 553 {
Siriagus 16:caf613d5b85e 554 if (map[(entityBottom+1) % HEIGHT][x+i]) // If moving the entity one step down for a given (x+i)-position gives a collision
Siriagus 13:7ab71c7c311b 555 {
Siriagus 13:7ab71c7c311b 556 collision = true;
Siriagus 13:7ab71c7c311b 557 break; // No further testing required
Siriagus 13:7ab71c7c311b 558 }
Siriagus 13:7ab71c7c311b 559 }
Siriagus 13:7ab71c7c311b 560
Siriagus 13:7ab71c7c311b 561 if (collision) // If collision
Siriagus 13:7ab71c7c311b 562 {
Siriagus 13:7ab71c7c311b 563 entity->vy = 0; // Set vertical velocity to 0 (playe
Siriagus 13:7ab71c7c311b 564 break; // Skip the while loop as the entity can not move further downwards
Siriagus 13:7ab71c7c311b 565 }
Siriagus 13:7ab71c7c311b 566 else // Can safely move entity without collision
Siriagus 15:d5eb13c4c1c6 567 {
Siriagus 13:7ab71c7c311b 568 ++entityBottom; // Move entity one step down
Siriagus 15:d5eb13c4c1c6 569 }
Siriagus 13:7ab71c7c311b 570 }
Siriagus 13:7ab71c7c311b 571
Siriagus 16:caf613d5b85e 572 // Wrapping
Siriagus 16:caf613d5b85e 573 y = (entityBottom - (entity->height - 1));
Siriagus 16:caf613d5b85e 574 if (y >= HEIGHT) // if completely outside map
Siriagus 16:caf613d5b85e 575 y = -entity->height; // wrap to top of map
Siriagus 16:caf613d5b85e 576
Siriagus 16:caf613d5b85e 577 entity->y = y; // (entityBottom - (entity->height - 1)); // Update position when done moving, remember that entity.y refers to upper part of the entity
Siriagus 13:7ab71c7c311b 578 }
Siriagus 13:7ab71c7c311b 579 else // moving up, check collision from top
Siriagus 13:7ab71c7c311b 580 {
Siriagus 13:7ab71c7c311b 581 while(steps--) // Still movement left
Siriagus 13:7ab71c7c311b 582 {
Siriagus 13:7ab71c7c311b 583 collision = false;
Siriagus 16:caf613d5b85e 584
Siriagus 13:7ab71c7c311b 585 for (int i = 0; i < entity->width; ++i) // Check for all x-positions
Siriagus 13:7ab71c7c311b 586 {
Siriagus 16:caf613d5b85e 587 int y1 = ((y-1) + HEIGHT) % HEIGHT; // In case negative, because of wrapping
Siriagus 16:caf613d5b85e 588
Siriagus 16:caf613d5b85e 589 if (map[y1][x+i]) // If moving upwards gives collision for a given x+i
Siriagus 13:7ab71c7c311b 590 {
Siriagus 13:7ab71c7c311b 591 collision = true; // Then we have a collision
Siriagus 13:7ab71c7c311b 592 break; // No further testing needed, skip for loop
Siriagus 13:7ab71c7c311b 593 }
Siriagus 13:7ab71c7c311b 594 }
Siriagus 13:7ab71c7c311b 595
Siriagus 13:7ab71c7c311b 596 if (collision) // If collision was detected
Siriagus 13:7ab71c7c311b 597 {
Siriagus 13:7ab71c7c311b 598 entity->vy = 0; // Set vertical velocity to zero
Siriagus 13:7ab71c7c311b 599 break; // Skip while loop as entity can not move further up
Siriagus 13:7ab71c7c311b 600 }
Siriagus 13:7ab71c7c311b 601 else // If safe to move for all x-values
Siriagus 13:7ab71c7c311b 602 --y; // Move entity one step up
Siriagus 13:7ab71c7c311b 603 }
Siriagus 13:7ab71c7c311b 604
Siriagus 16:caf613d5b85e 605 // Wrapping
Siriagus 16:caf613d5b85e 606 if (y + (entity->height - 1) < 0) // completely outside map (bottom of entity over top of map)
Siriagus 16:caf613d5b85e 607 y = HEIGHT-1 - entity->height - 1; // Sets the altitude.
Siriagus 16:caf613d5b85e 608
Siriagus 13:7ab71c7c311b 609 entity->y = y; // Update vertical position of entity
Siriagus 13:7ab71c7c311b 610 }
Siriagus 15:d5eb13c4c1c6 611 }
Siriagus 15:d5eb13c4c1c6 612
Siriagus 15:d5eb13c4c1c6 613 bool Game::hitTestRect(Rectangle r1, Rectangle r2)
Siriagus 15:d5eb13c4c1c6 614 {
Siriagus 15:d5eb13c4c1c6 615 return ((r1.x + r1.width > r2.x) // r1's right edge to the right of r2's left edge
Siriagus 15:d5eb13c4c1c6 616 && (r1.x < r2.x + r2.width) // r1's left edge to the left of r2's right edge
Siriagus 15:d5eb13c4c1c6 617 && (r1.y + r2.height > r2.y) // r1's bottom lower than r2's top
Siriagus 15:d5eb13c4c1c6 618 && (r1.y < r2.y + r2.height)); // r1's top higher than r2's bottom
hugohu 19:89c3eeb3761b 619
Siriagus 15:d5eb13c4c1c6 620 }
Siriagus 15:d5eb13c4c1c6 621
hugohu 19:89c3eeb3761b 622 bool Game::bulletHitMap(Rectangle &bulletColRect, const bool map[HEIGHT][WIDTH])
Siriagus 15:d5eb13c4c1c6 623 {
Siriagus 15:d5eb13c4c1c6 624 for (int j = 0; j < bulletColRect.width; ++j)
Siriagus 15:d5eb13c4c1c6 625 {
Siriagus 15:d5eb13c4c1c6 626 if (map[bulletColRect.y][bulletColRect.x + j])
Siriagus 15:d5eb13c4c1c6 627 return true;
Siriagus 15:d5eb13c4c1c6 628 }
Siriagus 15:d5eb13c4c1c6 629
Siriagus 15:d5eb13c4c1c6 630 return false;
Siriagus 16:caf613d5b85e 631 }
Siriagus 16:caf613d5b85e 632
Siriagus 16:caf613d5b85e 633 void Game::moveEnemies()
Siriagus 16:caf613d5b85e 634 {
hugohu 19:89c3eeb3761b 635 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); )
Siriagus 16:caf613d5b85e 636 {
Siriagus 16:caf613d5b85e 637 Enemy *enemy = *it;
Siriagus 16:caf613d5b85e 638
Siriagus 16:caf613d5b85e 639 if (!enemy->dead)
Siriagus 16:caf613d5b85e 640 {
Siriagus 17:d6a3b29cab31 641 // Random movement for enemies
hugohu 19:89c3eeb3761b 642 if ((rand() % 100) < 20) // 20% chance
Siriagus 17:d6a3b29cab31 643 {
hugohu 19:89c3eeb3761b 644 enemy->vy = -1;
Siriagus 17:d6a3b29cab31 645 }
hugohu 19:89c3eeb3761b 646 else if ((rand() % 100) > 90) // 10% chance
Siriagus 17:d6a3b29cab31 647 {
Siriagus 17:d6a3b29cab31 648 // switch direction
Siriagus 17:d6a3b29cab31 649 enemy->vx *= -1;
Siriagus 17:d6a3b29cab31 650 enemy->facingLeft = (enemy->vx < 0);
Siriagus 17:d6a3b29cab31 651 }
Siriagus 17:d6a3b29cab31 652
hugohu 19:89c3eeb3761b 653 switch(gameProperty.currentLayer)
hugohu 19:89c3eeb3761b 654 {
hugohu 19:89c3eeb3761b 655 case 1:
hugohu 19:89c3eeb3761b 656 moveWithCollisionTest(enemy, map1);
hugohu 19:89c3eeb3761b 657 break;
hugohu 19:89c3eeb3761b 658 case 2:
hugohu 19:89c3eeb3761b 659 moveWithCollisionTest(enemy, map2);
hugohu 19:89c3eeb3761b 660 break;
hugohu 19:89c3eeb3761b 661 }
hugohu 19:89c3eeb3761b 662
Siriagus 16:caf613d5b85e 663
Siriagus 16:caf613d5b85e 664 // Enemy AI
Siriagus 17:d6a3b29cab31 665 if (enemy->y >= 0)
Siriagus 16:caf613d5b85e 666 {
Siriagus 17:d6a3b29cab31 667 int nextRight = enemy->getRight() + 1; // Next position of right edge if enemy moves to the right
Siriagus 17:d6a3b29cab31 668 nextRight %= WIDTH; // wrapping
hugohu 19:89c3eeb3761b 669 bool flag = true;
hugohu 19:89c3eeb3761b 670 for (int i = 0; i < enemy->height && flag; ++i) // Check for all heights
Siriagus 16:caf613d5b85e 671 {
Siriagus 17:d6a3b29cab31 672 // Check if crashing if moving right or left. Bounds should already be limited by moveWithCollisionTest!
hugohu 19:89c3eeb3761b 673 switch(gameProperty.currentLayer)
hugohu 19:89c3eeb3761b 674 {
hugohu 19:89c3eeb3761b 675 case 1:
hugohu 19:89c3eeb3761b 676 if (map1[enemy->y + i][nextRight] || map1[enemy->y + i][enemy->x - 1])
hugohu 19:89c3eeb3761b 677 {
hugohu 19:89c3eeb3761b 678 enemy->vx *= -1; // move in opposite direction
hugohu 19:89c3eeb3761b 679 enemy->facingLeft = !enemy->facingLeft; // toggle direction
hugohu 19:89c3eeb3761b 680 flag = false; // no further testing required
hugohu 19:89c3eeb3761b 681 }
hugohu 19:89c3eeb3761b 682 break;
hugohu 19:89c3eeb3761b 683 case 2:
hugohu 19:89c3eeb3761b 684 if (map2[enemy->y + i][nextRight] || map2[enemy->y + i][enemy->x - 1])
hugohu 19:89c3eeb3761b 685 {
hugohu 19:89c3eeb3761b 686 enemy->vx *= -1; // move in opposite direction
hugohu 19:89c3eeb3761b 687 enemy->facingLeft = !enemy->facingLeft; // toggle direction
hugohu 19:89c3eeb3761b 688 flag = false; // no further testing required
hugohu 19:89c3eeb3761b 689 }
hugohu 19:89c3eeb3761b 690 break;
Siriagus 17:d6a3b29cab31 691 }
Siriagus 16:caf613d5b85e 692 }
Siriagus 16:caf613d5b85e 693 }
Siriagus 17:d6a3b29cab31 694
Siriagus 17:d6a3b29cab31 695 ++it; // go to next enemy
Siriagus 16:caf613d5b85e 696 }
Siriagus 17:d6a3b29cab31 697 else // if enemy is dead
Siriagus 16:caf613d5b85e 698 {
Siriagus 16:caf613d5b85e 699 enemy->y += enemy->vy;
Siriagus 16:caf613d5b85e 700 enemy->x += enemy->vx;
Siriagus 17:d6a3b29cab31 701
Siriagus 17:d6a3b29cab31 702 if (enemy->y >= HEIGHT) // if outside map (and dead)
Siriagus 17:d6a3b29cab31 703 {
Siriagus 17:d6a3b29cab31 704 delete enemy;
hugohu 19:89c3eeb3761b 705 it = gameProperty.enemies.erase(it); // remove and go to next enemy
Siriagus 17:d6a3b29cab31 706 }
Siriagus 17:d6a3b29cab31 707 else
Siriagus 17:d6a3b29cab31 708 ++it; // go to next enemy
Siriagus 16:caf613d5b85e 709 }
Siriagus 16:caf613d5b85e 710 }
Siriagus 17:d6a3b29cab31 711 }
Siriagus 17:d6a3b29cab31 712
Siriagus 17:d6a3b29cab31 713 void Game::renderScore()
Siriagus 17:d6a3b29cab31 714 {
Siriagus 17:d6a3b29cab31 715 int s = (Global::score < 100000) ? Global::score : 99999; // Max possible score is 99999.
Siriagus 17:d6a3b29cab31 716
Siriagus 17:d6a3b29cab31 717 // Read digits
Siriagus 17:d6a3b29cab31 718 int digits[5]; // max five
Siriagus 17:d6a3b29cab31 719 // Count the number of digits in the score
Siriagus 17:d6a3b29cab31 720 int numDigits = 0;
Siriagus 17:d6a3b29cab31 721 do
Siriagus 17:d6a3b29cab31 722 {
Siriagus 17:d6a3b29cab31 723 digits[numDigits] = s % 10;
Siriagus 17:d6a3b29cab31 724 s /= 10;
Siriagus 17:d6a3b29cab31 725 ++numDigits;
Siriagus 17:d6a3b29cab31 726 } while (s != 0 && numDigits < 5);
Siriagus 17:d6a3b29cab31 727
Siriagus 17:d6a3b29cab31 728
Siriagus 17:d6a3b29cab31 729 // Draw score
Siriagus 17:d6a3b29cab31 730 int xStart = 79;
Siriagus 17:d6a3b29cab31 731 int xStep = 4; // width + 1
Siriagus 17:d6a3b29cab31 732 int y = 2;
Siriagus 17:d6a3b29cab31 733 int x;
Siriagus 17:d6a3b29cab31 734
Siriagus 17:d6a3b29cab31 735 for (int i = 0; i < numDigits; ++i)
Siriagus 17:d6a3b29cab31 736 {
Siriagus 17:d6a3b29cab31 737 x = xStart - i * xStep;
Siriagus 17:d6a3b29cab31 738
Siriagus 17:d6a3b29cab31 739 switch (digits[i])
Siriagus 17:d6a3b29cab31 740 {
Siriagus 17:d6a3b29cab31 741 case 1:
Siriagus 17:d6a3b29cab31 742 drawImage(Number::One, x, y);
Siriagus 17:d6a3b29cab31 743 break;
Siriagus 17:d6a3b29cab31 744
Siriagus 17:d6a3b29cab31 745 case 2:
Siriagus 17:d6a3b29cab31 746 drawImage(Number::Two, x, y);
Siriagus 17:d6a3b29cab31 747 break;
Siriagus 17:d6a3b29cab31 748
Siriagus 17:d6a3b29cab31 749 case 3:
Siriagus 17:d6a3b29cab31 750 drawImage(Number::Three, x, y);
Siriagus 17:d6a3b29cab31 751 break;
Siriagus 17:d6a3b29cab31 752
Siriagus 17:d6a3b29cab31 753 case 4:
Siriagus 17:d6a3b29cab31 754 drawImage(Number::Four, x, y);
Siriagus 17:d6a3b29cab31 755 break;
Siriagus 17:d6a3b29cab31 756
Siriagus 17:d6a3b29cab31 757 case 5:
Siriagus 17:d6a3b29cab31 758 drawImage(Number::Five, x, y);
Siriagus 17:d6a3b29cab31 759 break;
Siriagus 17:d6a3b29cab31 760
Siriagus 17:d6a3b29cab31 761 case 6:
Siriagus 17:d6a3b29cab31 762 drawImage(Number::Six, x, y);
Siriagus 17:d6a3b29cab31 763 break;
Siriagus 17:d6a3b29cab31 764
Siriagus 17:d6a3b29cab31 765 case 7:
Siriagus 17:d6a3b29cab31 766 drawImage(Number::Seven, x, y);
Siriagus 17:d6a3b29cab31 767 break;
Siriagus 17:d6a3b29cab31 768
Siriagus 17:d6a3b29cab31 769 case 8:
Siriagus 17:d6a3b29cab31 770 drawImage(Number::Eight, x, y);
Siriagus 17:d6a3b29cab31 771 break;
Siriagus 17:d6a3b29cab31 772
Siriagus 17:d6a3b29cab31 773 case 9:
Siriagus 17:d6a3b29cab31 774 drawImage(Number::Nine, x, y);
Siriagus 17:d6a3b29cab31 775 break;
Siriagus 17:d6a3b29cab31 776
Siriagus 17:d6a3b29cab31 777 case 0:
Siriagus 17:d6a3b29cab31 778 default:
Siriagus 17:d6a3b29cab31 779 drawImage(Number::Zero, x, y);
Siriagus 17:d6a3b29cab31 780 break;
Siriagus 17:d6a3b29cab31 781 }
Siriagus 17:d6a3b29cab31 782
Siriagus 17:d6a3b29cab31 783 }
Siriagus 17:d6a3b29cab31 784 }
Siriagus 17:d6a3b29cab31 785
Siriagus 17:d6a3b29cab31 786 void Game::respawnPlayer()
Siriagus 17:d6a3b29cab31 787 {
hugohu 19:89c3eeb3761b 788 gameProperty.player.x = mapProperty.respawnPosition[0];
hugohu 19:89c3eeb3761b 789 gameProperty.player.y = mapProperty.respawnPosition[1];
hugohu 19:89c3eeb3761b 790
hugohu 19:89c3eeb3761b 791 gameProperty.player.vx = gameProperty.player.vy = 0;
hugohu 19:89c3eeb3761b 792 gameProperty.player.facingLeft = true;
hugohu 19:89c3eeb3761b 793 gameProperty.player.dead = false;
Siriagus 7:678873947b29 794 }