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

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);