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
Diff: Game.cpp
- Revision:
- 11:adb68da98262
- Parent:
- 9:da608ae65df9
- Child:
- 12:8178fad5e660
--- a/Game.cpp Fri May 08 14:39:36 2015 +0000 +++ b/Game.cpp Fri May 08 22:10:54 2015 +0000 @@ -2,12 +2,11 @@ Serial pc(USBTX, USBRX); // TO DELETE - DEBUGGING ONLY -// BUG: Registrer jo bare btn press, må være en bedre måte, men er trøtt nå - void Game::init() { // Player - player.x = player.y = 10; + player.x = 40; + player.y = 5; player.width = player.height = 5; onGround = false; } @@ -18,19 +17,18 @@ // Handle input, should be its own function switch(input->joystick->getDirection()) { - case LEFT: case UP_LEFT: case DOWN_LEFT: player.vx = -2; - player.goingLeft = true; + player.facingLeft = true; break; case RIGHT: case UP_RIGHT: case DOWN_RIGHT: player.vx = 2; - player.goingLeft = false; + player.facingLeft = false; break; @@ -46,29 +44,148 @@ break; } + // Ground, temporary solution, to be fixed with real map + player.vy += 1; - if (player.y < HEIGHT-10) player.vy += 1; // gravity - else if (player.vy > 0) {player.vy = 0; onGround = true;} - - - if (input->read(Input::ButtonA) && onGround) // && player.onGround) + // Check if player is trying to jump. Player can only jump if it's on the ground + if (input->read(Input::ButtonA) && onGround) { player.vy = -4; onGround = false; } + // Terminal velocity 3 px/update if (player.vy > 3) player.vy = 3; - player.x += player.vx; - player.y += player.vy; + // Update player position - should be done step wise! TODO!! + + // Find direction of player + + // Collision player with map + + int x = player.x; + int y = player.y; + int steps = abs(player.vx); // how many units (pixels) the player should move in said direction + bool collision; // true if colliding + + // Check x-axis + if (player.vx > 0) // moving right + { + int playerRight = x + player.width - 1; // Need to check right border of player, since it is moving right + + while(steps--) // While it still have more movement left + { + collision = false; + for (int i = 0; i < player.height; ++i) // Loop through all vertical points on the right hand side of the player (y+i) + { + if (map[y+i][playerRight+1]) // If moving to the right leads to collision for given y+i + { + collision = true; // Then collision is true + break; // Skip the for loop, no need for further testing + } + } + + if (collision) // If collision + break; // skip the while loop, player can not move further, even though its velocity is higher + else + ++playerRight; // Move player one px to the right + } + + player.x = playerRight - (player.width - 1); // Update player's position. Need to set upper-left pixel. + } + else // moving left + { + while(steps--) // While still movement left + { + collision = false; + + + for (int i = 0; i < player.height; ++i) // Check for all y-positions + { + if (map[y+i][x-1]) // If solid block + { + collision = true; + break; // Collision detected, no further testing required + } + } + + if (collision) + break; + else + --x; // Move to the left if no collision is detected + } + + player.x = x; + } - // Bullets - TODO: Give the bullets a direction - need to delete them when they go off the screen + // Check collision with map in y-direction - works the same way as the x-axis, except for other axis + + x = player.x; + y = player.y; + steps = abs(player.vy); + + if (player.vy > 0) // downwards + { + int playerBottom = y + player.height - 1; // Need to check if bottom part collides + while(steps--) // Still movement left + { + collision = false; + for (int i = 0; i < player.width; ++i) // Loop through all x-position on lower part of player + { + if (map[playerBottom+1][x+i]) // If moving the player one step down for a given (x+i)-position gives a collision + { + collision = true; + break; // No further testing required + } + } + + if (collision) // If collision + { + player.vy = 0; // Set vertical velocity to 0 (playe + onGround = true; // Player has hit ground + break; // Skip the while loop as the player can not move further downwards + } + else // Can safely move player without collision + ++playerBottom; // Move player one step down + } + + player.y = playerBottom - (player.height - 1); // Update position when done moving, remember that player.y refers to upper part of the player + } + else // moving up, check collision from top + { + while(steps--) // Still movement left + { + collision = false; + + for (int i = 0; i < player.width; ++i) // Check for all x-positions + { + if (map[y-1][x+i]) // If moving upwards gives collision for a given x+i + { + collision = true; // Then we have a collision + break; // No further testing needed, skip for loop + } + } + + if (collision) // If collision was detected + { + player.vy = 0; // Set vertical velocity to zero + break; // Skip while loop as player can not move further up + } + else // If safe to move for all x-values + --y; // Move player one step up + } + + player.y = y; // Update vertical position of player + } + + // Check if bullet should be fired if (input->read(Input::ButtonB) && releasedBtnB) { + // Create a new bullet and give it initial values Point* bullet = new Point; - bullet->x = player.x-1; + bullet->x = (player.facingLeft) ? (player.x-1) : (player.x + player.width); bullet->y = player.y + 2; - bullet->vx = (player.goingLeft) ? -4 : 4; + bullet->vx = (player.facingLeft) ? -4 : 4; bullet->vy = 0; bullets.push_back(bullet); @@ -99,6 +216,9 @@ void Game::render() { + // Draw map + drawImage(map); + // Draw player - TODO: Make this a part of sprite class (so they can draw themselves) int x0, x1, y0, y1; x0 = (player.x < 0) ? 0 : player.x; // x0 = max(0,x); @@ -111,7 +231,7 @@ for (int j = x0; j < x1; ++j) { // If player is going right, obtain data from sprite in reverse order => render in reverse - int xIndex = (player.goingLeft) ? (j-x0) : (player.width - 1 - (j-x0)); + int xIndex = (player.facingLeft) ? (j-x0) : (player.width - 1 - (j-x0)); if (Image::Player[i-y0][xIndex]) lcd->setPixel(j,i);