Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed N5110 ShiftReg PinDetect
Game.cpp
00001 #include "Game.h " 00002 00003 /// @file Game.cpp 00004 00005 Game::~Game() 00006 { 00007 clearAll(); 00008 } 00009 00010 void Game::clearAll() 00011 { 00012 // Free allocated memory from bullets 00013 for (std::vector<Point*>::iterator it = gameProperty.bullets.begin(); it != gameProperty.bullets.end(); ++it) 00014 delete *it; 00015 00016 gameProperty.bullets.clear(); 00017 00018 // Free allocated memory from enemies 00019 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it) 00020 delete *it; 00021 00022 gameProperty.enemies.clear(); 00023 00024 // Set initial values for the player 00025 gameProperty.player.width = gameProperty.player.height = 5; 00026 00027 gameProperty.player.vx = 0; 00028 gameProperty.player.vy = 0; 00029 00030 gameProperty.player.dead = false; 00031 00032 gameProperty.player.facingLeft = false; 00033 } 00034 00035 void Game::init() 00036 { 00037 if (gameProperty.currentLayer == 1){ 00038 Global::score = 0; 00039 gameProperty.paused = false; 00040 gameProperty.livesLeft = 3; 00041 memcpy(&mapProperty,&mapProperty1,sizeof(mapProperty1)); 00042 } 00043 else 00044 { 00045 clearAll(); 00046 switch(gameProperty.currentLayer) 00047 { 00048 case 2: 00049 memcpy(&mapProperty,&mapProperty2,sizeof(mapProperty2)); 00050 break; 00051 case 3: 00052 00053 break; 00054 case 4: 00055 00056 break; 00057 } 00058 00059 } 00060 const int seven_seg_array [] = { 00061 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71 00062 }; 00063 shift.write(seven_seg_array[gameProperty.livesLeft]); 00064 00065 respawnPlayer(); 00066 00067 spawnEnemy(); 00068 } 00069 00070 00071 00072 void Game::spawnEnemy() 00073 { 00074 00075 // Get random spawn point 00076 int r = rand() % 3; 00077 int x = mapProperty.enermyPosition[r][0]; 00078 int y = mapProperty.enermyPosition[r][1]; 00079 00080 // Spawn random enemy 00081 int randPercent = (rand() % 100); 00082 Enemy::Type type; 00083 00084 if (randPercent >= 40) // 60% probability 00085 type = Enemy::JUMPER; 00086 else if (randPercent >= 15) // 25% probablitiy 00087 type = Enemy::SIMPLE; 00088 else // 15 % probability 00089 type = Enemy::RUNNER; 00090 00091 // Create enemy 00092 Enemy *enemy = new Enemy(x, y, true, type); 00093 gameProperty.enemies.push_back(enemy); 00094 } 00095 00096 // Functions 00097 void Game::update(float dt) 00098 { 00099 // Pause button input 00100 if (input->read(Input::ButtonC)) 00101 { 00102 if (releasedBtnC) 00103 { 00104 gameProperty.paused = !gameProperty.paused; 00105 releasedBtnC = false; 00106 } 00107 } 00108 else 00109 releasedBtnC = true; 00110 00111 // Skip the rest if paused 00112 if (gameProperty.paused) return; 00113 00114 // if successfully reach the end 00115 if (gameProperty.player.x == mapProperty.succeedPosition[0] && gameProperty.player.y == mapProperty.succeedPosition[1]) 00116 { 00117 gameProperty.currentLayer += 1; 00118 init(); 00119 } 00120 00121 // if respawn new enermy 00122 if ((rand() % 100) < mapProperty.spawnRate && !gameProperty.player.dead && gameProperty.enemies.size() <= mapProperty.maxEnermy) 00123 spawnEnemy(); 00124 00125 00126 // Handle input, should be its own function 00127 switch(input->joystick->getDirection()) 00128 { 00129 case LEFT: 00130 gameProperty.player.vx = -1; 00131 gameProperty.player.facingLeft = true; 00132 break; 00133 case UP_LEFT: 00134 gameProperty.player.vx = -1; 00135 gameProperty.player.vy = -1; 00136 gameProperty.player.facingLeft = true; 00137 break; 00138 case DOWN_LEFT: 00139 gameProperty.player.vx = -1; 00140 gameProperty.player.vy = 1; 00141 gameProperty.player.facingLeft = true; 00142 break; 00143 case RIGHT: 00144 gameProperty.player.vx = 1; 00145 gameProperty.player.facingLeft = false; 00146 break; 00147 case UP_RIGHT: 00148 gameProperty.player.vx = 1; 00149 gameProperty.player.vy = -1; 00150 gameProperty.player.facingLeft = false; 00151 break; 00152 case DOWN_RIGHT: 00153 gameProperty.player.vx = 1; 00154 gameProperty.player.vy = 1; 00155 gameProperty.player.facingLeft = false; 00156 break; 00157 case UP: 00158 gameProperty.player.vy = -1; 00159 gameProperty.player.facingLeft = false; 00160 break; 00161 case DOWN: 00162 gameProperty.player.vy = 1; 00163 gameProperty.player.facingLeft = false; 00164 break; 00165 case CENTER: 00166 gameProperty.player.vx = 0; 00167 gameProperty.player.vy = 0; 00168 break; 00169 } 00170 00171 if (!gameProperty.player.dead) 00172 { 00173 switch(gameProperty.currentLayer) 00174 { 00175 case 1: 00176 moveWithCollisionTest(&gameProperty.player, map1); 00177 break; 00178 case 2: 00179 moveWithCollisionTest(&gameProperty.player, map2); 00180 break; 00181 } 00182 } 00183 else // move without testing collision agains the map 00184 { 00185 gameProperty.player.x += gameProperty.player.vx; 00186 gameProperty.player.y += 4; 00187 } 00188 00189 moveEnemies(); 00190 00191 // Check if bullet should be fired 00192 if (input->read(Input::ButtonB) && releasedBtnB && !gameProperty.player.dead) 00193 { 00194 // Create a new bullet and give it initial values 00195 Point* bullet = new Point; 00196 bullet->x = (int)(gameProperty.player.x + (gameProperty.player.width / 2)); 00197 bullet->y = gameProperty.player.y + 2; 00198 bullet->vx = (gameProperty.player.facingLeft) ? -4 : 4; 00199 bullet->vy = 0; 00200 00201 gameProperty.bullets.push_back(bullet); 00202 releasedBtnB = false; 00203 00204 // Play sound 00205 // sound->playNote(SFX::BULLET_FIRED); 00206 } 00207 else if (!input->read(Input::ButtonB)) 00208 releasedBtnB = true; 00209 00210 // Loop through bullets and move them + collision test 00211 for (std::vector<Point*>::iterator it = gameProperty.bullets.begin(); it != gameProperty.bullets.end();) 00212 { 00213 Point* bullet = *it; 00214 00215 int x0; // left border of collision rect 00216 int x1; // right border of collision rect 00217 00218 int oldX = bullet->x; 00219 int newX = bullet->x + bullet->vx; 00220 00221 x0 = min(oldX, newX); 00222 x1 = max(oldX, newX); 00223 00224 // Collision rect for bullet in this time step 00225 Rectangle bulletColRect(x0, bullet->y, (x1-x0)+1, 1); 00226 00227 bool col = false; 00228 // Delete if outside screen 00229 switch(gameProperty.currentLayer) 00230 { 00231 case 1: 00232 if (newX < 0 || newX > WIDTH || bulletHitMap(bulletColRect, map1)) // if outside screen 00233 col = true; 00234 else 00235 { 00236 // loop through all enemies 00237 for (std::vector<Enemy*>::iterator ite = gameProperty.enemies.begin(); ite != gameProperty.enemies.end(); ++ite) 00238 { 00239 Enemy *enemy = *ite; 00240 00241 // If bullet hits enemy 00242 //if (!enemy->dead && bullet->x >= enemy->x && bullet->x <= enemy->getRight() && bullet->y >= enemy->y && bullet->y <= enemy->getBottom()) 00243 00244 Rectangle enemyColRect(enemy->x, enemy->y, enemy->width, enemy->height); // collision rectangle for enemy 00245 00246 if (!enemy->dead && hitTestRect(bulletColRect, enemyColRect)) 00247 { 00248 col = true; 00249 00250 enemy->dead = true; 00251 enemy->vx = bullet->vx / 2; // sends the dead enemy in the same direction as the incoming bullet 00252 enemy->vy = -3; // sends the dead enemy upwards in the air, because of impact 00253 00254 Global::score += 5 * enemy->difficulty; // increase the score 00255 00256 // sound->playNote(SFX::ENEMY_DEAD); 00257 } 00258 } 00259 } 00260 break; 00261 case 2: 00262 if (newX < 0 || newX > WIDTH || bulletHitMap(bulletColRect, map2)) // if outside screen 00263 col = true; 00264 else 00265 { 00266 // loop through all enemies 00267 for (std::vector<Enemy*>::iterator ite = gameProperty.enemies.begin(); ite != gameProperty.enemies.end(); ++ite) 00268 { 00269 Enemy *enemy = *ite; 00270 00271 // If bullet hits enemy 00272 //if (!enemy->dead && bullet->x >= enemy->x && bullet->x <= enemy->getRight() && bullet->y >= enemy->y && bullet->y <= enemy->getBottom()) 00273 00274 Rectangle enemyColRect(enemy->x, enemy->y, enemy->width, enemy->height); // collision rectangle for enemy 00275 00276 if (!enemy->dead && hitTestRect(bulletColRect, enemyColRect)) 00277 { 00278 col = true; 00279 00280 enemy->dead = true; 00281 enemy->vx = bullet->vx / 2; // sends the dead enemy in the same direction as the incoming bullet 00282 enemy->vy = -3; // sends the dead enemy upwards in the air, because of impact 00283 00284 Global::score += 5 * enemy->difficulty; // increase the score 00285 00286 // sound->playNote(SFX::ENEMY_DEAD); 00287 } 00288 } 00289 } 00290 break; 00291 } 00292 00293 00294 if (!col) 00295 { 00296 ++it; // go to next element 00297 bullet->x += bullet->vx; // update position 00298 } 00299 else 00300 { 00301 delete bullet; 00302 it = gameProperty.bullets.erase(it); // go to next element 00303 } 00304 } 00305 00306 // Check if player hits enemy 00307 Rectangle playerRect(gameProperty.player.x, gameProperty.player.y, gameProperty.player.width, gameProperty.player.height); 00308 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it) 00309 { 00310 Enemy *enemy = *it; 00311 00312 if (enemy->dead) continue; // only test against living enemies 00313 00314 Rectangle enemyRect(enemy->x, enemy->y, enemy->width, enemy->height); 00315 00316 if (hitTestRect(playerRect, enemyRect)) 00317 { 00318 gameProperty.player.dead = true; 00319 gameProperty.player.vx = 0; 00320 gameProperty.player.vy = 4; 00321 --gameProperty.livesLeft; 00322 // Show the livesleft 00323 int seven_seg_array [] = { 00324 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71 00325 }; 00326 shift.write(seven_seg_array[gameProperty.livesLeft]); 00327 00328 // sound->playNote(SFX::PLAYER_DEAD); 00329 break; 00330 } 00331 } 00332 00333 if (gameProperty.player.dead) 00334 { 00335 // remove all enemies (let them fall off) 00336 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it) 00337 { 00338 Enemy *enemy = *it; 00339 enemy->dead = true; 00340 enemy->vy = 4; 00341 } 00342 00343 if (gameProperty.player.y >= HEIGHT && !gameProperty.enemies.size()) // when all enemies are removed 00344 { 00345 if (gameProperty.livesLeft) 00346 { 00347 respawnPlayer(); // Respawn player if it still have lives left 00348 spawnEnemy(); // Spawn an enemy right away 00349 } 00350 else 00351 { 00352 if (Global::score > Global::highscores[2].score) // If new high score 00353 requestStateChange(SUBMIT_HIGHSCORE); 00354 else 00355 requestStateChange(GAME_OVER); 00356 } 00357 } 00358 } 00359 } 00360 00361 void Game::render() 00362 { 00363 00364 if (!gameProperty.player.dead) 00365 { 00366 // Draw map 00367 switch(gameProperty.currentLayer) 00368 { 00369 case 1: 00370 drawImage(map1); 00371 break; 00372 case 2: 00373 drawImage(map2); 00374 break; 00375 case 3: 00376 drawImage(map_chest); 00377 break; 00378 case 4: 00379 drawImage(map_big1); 00380 break; 00381 } 00382 // Draw ladder 00383 drawImage(Image::Ladder, mapProperty.succeedPosition[0], mapProperty.succeedPosition[1], false, false, false); 00384 00385 // Draw respawnCircle 00386 drawImage(Image::RespawnSign, mapProperty.respawnPosition[0], mapProperty.respawnPosition[1], false, false, false); 00387 00388 // Draw player 00389 drawImage(Image::Player, gameProperty.player.x, gameProperty.player.y, false, !gameProperty.player.facingLeft, gameProperty.player.dead); 00390 00391 // Draw enemies 00392 00393 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ++it) 00394 { 00395 Enemy *enemy = *it; 00396 00397 switch (enemy->type) 00398 { 00399 case Enemy::SIMPLE: 00400 drawImage(Image::EnemySimple, enemy->x, enemy->y, false, !enemy->facingLeft, enemy->dead); 00401 break; 00402 00403 case Enemy::JUMPER: 00404 drawImage(Image::EnemyJumper, enemy->x, enemy->y, false, !enemy->facingLeft, enemy->dead); 00405 break; 00406 00407 case Enemy::RUNNER: 00408 drawImage(Image::EnemyRunner, enemy->x, enemy->y, false, !enemy->facingLeft, enemy->dead); 00409 break; 00410 00411 default: 00412 ; // should not happen, don't render 00413 } 00414 } 00415 00416 00417 // Render bullets 00418 for (std::vector<Point*>::iterator it = gameProperty.bullets.begin(); it != gameProperty.bullets.end(); ++it) 00419 { 00420 int x, y; 00421 x = (*it)->x; 00422 y = (*it)->y; 00423 00424 if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT) // Boundary check 00425 lcd->setPixel(x,y); 00426 } 00427 } 00428 else 00429 { 00430 // Print lives left 00431 std::stringstream ss; 00432 ss << "Lives left: " << gameProperty.livesLeft; 00433 lcd->printString(ss.str().c_str(), 4, 2); 00434 } 00435 00436 00437 // Draw pause 00438 if (gameProperty.paused) 00439 { 00440 lcd->drawRect(25, 14, 35, 13, 1); // create shadow at the bottom layer 00441 lcd->drawRect(24, 13, 35, 13, 0); // outline 00442 lcd->drawRect(25, 14, 33, 11, 2); // white fill 00443 lcd->printString("Pause", 27, 2); // text 00444 } 00445 00446 // GUI 00447 // renderScore(); 00448 } 00449 00450 // Collision test between entites and map 00451 void Game::moveWithCollisionTest(Entity* entity, const bool map[HEIGHT][WIDTH]) 00452 { 00453 int x = entity->x; 00454 int y = entity->y; 00455 int steps = abs(entity->vx); // how many units (pixels) the entity should move in said direction 00456 bool collision; // true if colliding 00457 00458 // Check x-axis 00459 if (entity->vx > 0) // moving right 00460 { 00461 int entityRight = x + entity->width - 1; // Need to check right border of entity, since it is moving right 00462 00463 while(steps--) // While it still have more movement left 00464 { 00465 collision = false; 00466 00467 // Wrapping 00468 if (entityRight+1 >= WIDTH) 00469 entityRight = -1;// wants entityRight = -1, so next check is entityRight 0*/ 00470 00471 for (int i = 0; i < entity->height; ++i) // Loop through all vertical points on the right hand side of the entity (y+i) 00472 { 00473 if (map[y+i][entityRight+1]) // If moving to the right leads to collision for given y+i 00474 { 00475 // Slope + allows player to climb to top of platform by going right if it hits close to top of wall. 00476 if (!map[y+i-1][entityRight+1]) 00477 { 00478 entity->vy = -1; 00479 } 00480 else 00481 { 00482 collision = true; // Then collision is true 00483 break; // Skip the for loop, no need for further testing 00484 } 00485 00486 } 00487 } 00488 00489 if (collision) // If collision 00490 break; // skip the while loop, entity can not move further, even though its velocity is higher 00491 else 00492 ++entityRight; // Move entity one px to the right 00493 } 00494 00495 // If wrap didn't work, make sure entity is on the correct side of the map 00496 if (entityRight < 0) 00497 entityRight = WIDTH-1; 00498 00499 entity->x = entityRight - (entity->width - 1); // Update entity's position. Need to set upper-left pixel. 00500 } 00501 else // moving left 00502 { 00503 while(steps--) // While still movement left 00504 { 00505 collision = false; 00506 00507 // Wrap around map 00508 if (x-1 < 0) 00509 x = WIDTH; // causes x-1 in the next check to be WIDTH - 1 00510 00511 // Check for all y-positions 00512 for (int i = 0; i < entity->height; ++i) 00513 { 00514 00515 if (map[y+i][x-1]) // If solid block 00516 { 00517 if (!map[y+i-1][x-1]) // If slope or close to top of wall (=> can climb by going left). 00518 { 00519 entity->vy = -1; 00520 } 00521 else 00522 { 00523 collision = true; 00524 break; // Collision detected, no further testing required 00525 } 00526 } 00527 } 00528 00529 if (collision) 00530 break; 00531 else 00532 --x; // Move to the left if no collision is detected 00533 } 00534 00535 x %= WIDTH; // In case wrapping caused entity to crash with wall on other side, x should be 0 instead of WIDTH (invalid). 00536 00537 entity->x = x; // update position 00538 } 00539 00540 // Check collision with map in y-direction - works the same way as the x-axis, except for other axis 00541 x = entity->x; 00542 y = entity->y; 00543 steps = abs(entity->vy); 00544 00545 if (entity->vy > 0) // downwards 00546 { 00547 int entityBottom = y + entity->height - 1; // Need to check if bottom part collides 00548 while(steps--) // Still movement left 00549 { 00550 collision = false; 00551 00552 for (int i = 0; i < entity->width; ++i) // Loop through all x-position on lower part of entity 00553 { 00554 if (map[(entityBottom+1) % HEIGHT][x+i]) // If moving the entity one step down for a given (x+i)-position gives a collision 00555 { 00556 collision = true; 00557 break; // No further testing required 00558 } 00559 } 00560 00561 if (collision) // If collision 00562 { 00563 entity->vy = 0; // Set vertical velocity to 0 (playe 00564 break; // Skip the while loop as the entity can not move further downwards 00565 } 00566 else // Can safely move entity without collision 00567 { 00568 ++entityBottom; // Move entity one step down 00569 } 00570 } 00571 00572 // Wrapping 00573 y = (entityBottom - (entity->height - 1)); 00574 if (y >= HEIGHT) // if completely outside map 00575 y = -entity->height; // wrap to top of map 00576 00577 entity->y = y; // (entityBottom - (entity->height - 1)); // Update position when done moving, remember that entity.y refers to upper part of the entity 00578 } 00579 else // moving up, check collision from top 00580 { 00581 while(steps--) // Still movement left 00582 { 00583 collision = false; 00584 00585 for (int i = 0; i < entity->width; ++i) // Check for all x-positions 00586 { 00587 int y1 = ((y-1) + HEIGHT) % HEIGHT; // In case negative, because of wrapping 00588 00589 if (map[y1][x+i]) // If moving upwards gives collision for a given x+i 00590 { 00591 collision = true; // Then we have a collision 00592 break; // No further testing needed, skip for loop 00593 } 00594 } 00595 00596 if (collision) // If collision was detected 00597 { 00598 entity->vy = 0; // Set vertical velocity to zero 00599 break; // Skip while loop as entity can not move further up 00600 } 00601 else // If safe to move for all x-values 00602 --y; // Move entity one step up 00603 } 00604 00605 // Wrapping 00606 if (y + (entity->height - 1) < 0) // completely outside map (bottom of entity over top of map) 00607 y = HEIGHT-1 - entity->height - 1; // Sets the altitude. 00608 00609 entity->y = y; // Update vertical position of entity 00610 } 00611 } 00612 00613 bool Game::hitTestRect(Rectangle r1, Rectangle r2) 00614 { 00615 return ((r1.x + r1.width > r2.x) // r1's right edge to the right of r2's left edge 00616 && (r1.x < r2.x + r2.width) // r1's left edge to the left of r2's right edge 00617 && (r1.y + r2.height > r2.y) // r1's bottom lower than r2's top 00618 && (r1.y < r2.y + r2.height)); // r1's top higher than r2's bottom 00619 00620 } 00621 00622 bool Game::bulletHitMap(Rectangle &bulletColRect, const bool map[HEIGHT][WIDTH]) 00623 { 00624 for (int j = 0; j < bulletColRect.width; ++j) 00625 { 00626 if (map[bulletColRect.y][bulletColRect.x + j]) 00627 return true; 00628 } 00629 00630 return false; 00631 } 00632 00633 void Game::moveEnemies() 00634 { 00635 for (std::vector<Enemy*>::iterator it = gameProperty.enemies.begin(); it != gameProperty.enemies.end(); ) 00636 { 00637 Enemy *enemy = *it; 00638 00639 if (!enemy->dead) 00640 { 00641 // Random movement for enemies 00642 if ((rand() % 100) < 20) // 20% chance 00643 { 00644 enemy->vy = -1; 00645 } 00646 else if ((rand() % 100) > 90) // 10% chance 00647 { 00648 // switch direction 00649 enemy->vx *= -1; 00650 enemy->facingLeft = (enemy->vx < 0); 00651 } 00652 00653 switch(gameProperty.currentLayer) 00654 { 00655 case 1: 00656 moveWithCollisionTest(enemy, map1); 00657 break; 00658 case 2: 00659 moveWithCollisionTest(enemy, map2); 00660 break; 00661 } 00662 00663 00664 // Enemy AI 00665 if (enemy->y >= 0) 00666 { 00667 int nextRight = enemy->getRight() + 1; // Next position of right edge if enemy moves to the right 00668 nextRight %= WIDTH; // wrapping 00669 bool flag = true; 00670 for (int i = 0; i < enemy->height && flag; ++i) // Check for all heights 00671 { 00672 // Check if crashing if moving right or left. Bounds should already be limited by moveWithCollisionTest! 00673 switch(gameProperty.currentLayer) 00674 { 00675 case 1: 00676 if (map1[enemy->y + i][nextRight] || map1[enemy->y + i][enemy->x - 1]) 00677 { 00678 enemy->vx *= -1; // move in opposite direction 00679 enemy->facingLeft = !enemy->facingLeft; // toggle direction 00680 flag = false; // no further testing required 00681 } 00682 break; 00683 case 2: 00684 if (map2[enemy->y + i][nextRight] || map2[enemy->y + i][enemy->x - 1]) 00685 { 00686 enemy->vx *= -1; // move in opposite direction 00687 enemy->facingLeft = !enemy->facingLeft; // toggle direction 00688 flag = false; // no further testing required 00689 } 00690 break; 00691 } 00692 } 00693 } 00694 00695 ++it; // go to next enemy 00696 } 00697 else // if enemy is dead 00698 { 00699 enemy->y += enemy->vy; 00700 enemy->x += enemy->vx; 00701 00702 if (enemy->y >= HEIGHT) // if outside map (and dead) 00703 { 00704 delete enemy; 00705 it = gameProperty.enemies.erase(it); // remove and go to next enemy 00706 } 00707 else 00708 ++it; // go to next enemy 00709 } 00710 } 00711 } 00712 00713 void Game::renderScore() 00714 { 00715 int s = (Global::score < 100000) ? Global::score : 99999; // Max possible score is 99999. 00716 00717 // Read digits 00718 int digits[5]; // max five 00719 // Count the number of digits in the score 00720 int numDigits = 0; 00721 do 00722 { 00723 digits[numDigits] = s % 10; 00724 s /= 10; 00725 ++numDigits; 00726 } while (s != 0 && numDigits < 5); 00727 00728 00729 // Draw score 00730 int xStart = 79; 00731 int xStep = 4; // width + 1 00732 int y = 2; 00733 int x; 00734 00735 for (int i = 0; i < numDigits; ++i) 00736 { 00737 x = xStart - i * xStep; 00738 00739 switch (digits[i]) 00740 { 00741 case 1: 00742 drawImage(Number::One, x, y); 00743 break; 00744 00745 case 2: 00746 drawImage(Number::Two, x, y); 00747 break; 00748 00749 case 3: 00750 drawImage(Number::Three, x, y); 00751 break; 00752 00753 case 4: 00754 drawImage(Number::Four, x, y); 00755 break; 00756 00757 case 5: 00758 drawImage(Number::Five, x, y); 00759 break; 00760 00761 case 6: 00762 drawImage(Number::Six, x, y); 00763 break; 00764 00765 case 7: 00766 drawImage(Number::Seven, x, y); 00767 break; 00768 00769 case 8: 00770 drawImage(Number::Eight, x, y); 00771 break; 00772 00773 case 9: 00774 drawImage(Number::Nine, x, y); 00775 break; 00776 00777 case 0: 00778 default: 00779 drawImage(Number::Zero, x, y); 00780 break; 00781 } 00782 00783 } 00784 } 00785 00786 void Game::respawnPlayer() 00787 { 00788 gameProperty.player.x = mapProperty.respawnPosition[0]; 00789 gameProperty.player.y = mapProperty.respawnPosition[1]; 00790 00791 gameProperty.player.vx = gameProperty.player.vy = 0; 00792 gameProperty.player.facingLeft = true; 00793 gameProperty.player.dead = false; 00794 }
Generated on Tue Jul 12 2022 21:30:55 by
