Add collision
authorwatkinsr <ryanwatkins54@gmail.com>
Thu, 18 Jun 2020 11:53:26 +0000 (12:53 +0100)
committerwatkinsr <ryanwatkins54@gmail.com>
Thu, 18 Jun 2020 11:53:26 +0000 (12:53 +0100)
game.cpp [moved from 31_scrolling_backgrounds.cpp with 82% similarity]

similarity index 82%
rename from 31_scrolling_backgrounds.cpp
rename to game.cpp
index e0bcbeefc4cb6a876429ae4dc8fb5316a8f79286..106a40e63df472eda5051ffe8f7779fd93eb8b65 100755 (executable)
+++ b/game.cpp
@@ -57,6 +57,13 @@ class LTexture
                int mHeight;
 };
 
+//A circle stucture
+struct Circle
+{
+  int x, y;
+  int r;
+};
+
 //The dot that will move around on the screen
 class Dot
 {
@@ -66,15 +73,16 @@ class Dot
                static const int DOT_VEL = 10;
 
                //Initializes the variables
-               Dot();
-    Dot(Uint16 x, Uint16 y, Uint8 velX, Uint8 velY, Uint8 w, Uint8 h);
+    Dot(Uint16 x, Uint16 y, int8_t velX, int8_t velY, Uint8 w, Uint8 h);
 
                //Moves the dot
-               void move();
+               void move( SDL_Rect& paddle1 );
 
                //Shows the dot on the screen
                void render();
 
+               Circle& getCollider();
+
     private:
                //The X and Y offsets of the dot
                int mPosX, mPosY;
@@ -85,6 +93,10 @@ class Dot
                
          int mWidth;
          int mHeight;
+
+         Circle mCollider;
+
+         void shiftColliders();
 };
 
 class Paddle
@@ -103,6 +115,8 @@ class Paddle
                void move();
                void render();
 
+               SDL_Rect& getCollider();
+
     private:
     
          SDL_Rect p;
@@ -125,6 +139,9 @@ SDL_Window* gWindow = NULL;
 //The window renderer
 SDL_Renderer* gRenderer = NULL;
 
+//Circle/Box collision detector
+bool checkCollision( Circle& a, SDL_Rect& b );
+
 //Scene textures
 LTexture gDotTexture;
 
@@ -279,21 +296,7 @@ int LTexture::getHeight()
        return mHeight;
 }
 
-Dot::Dot()
-{
-    //Initialize the offsets
-    mPosX = 0;
-    mPosY = 0;
-
-    //Initialize the velocity
-    mVelX = 0;
-    mVelY = 0;
-
-    mWidth = 10;
-    mHeight = 10;
-}
-
-Dot::Dot(Uint16 x, Uint16 y, Uint8 velX, Uint8 velY, Uint8 w, Uint8 h)
+Dot::Dot(Uint16 x, Uint16 y, int8_t velX, int8_t velY, Uint8 w, Uint8 h)
 {
     //Initialize the offsets
     mPosX = x;
@@ -303,37 +306,103 @@ Dot::Dot(Uint16 x, Uint16 y, Uint8 velX, Uint8 velY, Uint8 w, Uint8 h)
     mVelX = velX;
     mVelY = velY;
 
+    mCollider.r = w / 2;
+
     mWidth = w;
     mHeight = h;
+
+    shiftColliders();
 }
 
-void Dot::move()
+void Dot::move( SDL_Rect& paddle1)
 {
-    //Move the dot left or right
-    mPosX += mVelX;
+  //Move the dot left or right
+  mPosX += mVelX;
+  shiftColliders();
+
+  //If the dot collided or went too far to the left or right
+  if( ( mPosX - mCollider.r < 0 ) || ( mPosX + mCollider.r > SCREEN_WIDTH ) || checkCollision( mCollider, paddle1 ))
+  {
+    //Move back
+    mPosX -= mVelX;
+    shiftColliders();
+  }
+
+  //Move the dot up or down
+  mPosY += mVelY;
+  shiftColliders();
+
+  //If the dot collided or went too far up or down
+  if( ( mPosY - mCollider.r < 0 ) || ( mPosY + mCollider.r > SCREEN_HEIGHT ) || checkCollision( mCollider, paddle1 ))
+  {
+    //Move back
+    mPosY -= mVelY;
+    shiftColliders();
+  }
+}
 
-    //If the dot went too far to the left or right
-    if( ( mPosX < 0 ) || ( mPosX + mWidth > SCREEN_WIDTH ) )
-    {
-        //Move back
-        mPosX -= mVelX;
-    }
+void Dot::render()
+{
+  //Show the dot
+  gDotTexture.render( mPosX - mCollider.r, mPosY - mCollider.r );
+}
 
-    //Move the dot up or down
-    mPosY += mVelY;
+void Dot::shiftColliders()
+{
+       //Align collider to center of dot
+       mCollider.x = mPosX;
+       mCollider.y = mPosY;
+}
 
-    //If the dot went too far up or down
-    if( ( mPosY < 0 ) || ( mPosY + mHeight > SCREEN_HEIGHT ) )
-    {
-        //Move back
-        mPosY -= mVelY;
-    }
+double distanceSquared( int x1, int y1, int x2, int y2 )
+{
+  int deltaX = x2 - x1;
+  int deltaY = y2 - y1;
+  return deltaX*deltaX + deltaY*deltaY;
 }
 
-void Dot::render()
+bool checkCollision( Circle& a, SDL_Rect& b )
 {
-  //Show the dot
-  gDotTexture.render( mPosX, mPosY );
+  //Closest point on collision box
+  int cX, cY;
+
+  //Find closest x offset
+  if( a.x < b.x )
+  {
+    cX = b.x;
+  }
+  else if( a.x > b.x + b.w )
+  {
+    cX = b.x + b.w;
+  }
+  else
+  {
+    cX = a.x;
+  }
+
+  //Find closest y offset
+  if( a.y < b.y )
+  {
+    cY = b.y;
+  }
+  else if( a.y > b.y + b.h )
+  {
+    cY = b.y + b.h;
+  }
+  else
+  {
+    cY = a.y;
+  }
+
+  //If the closest point is inside the circle
+  if( distanceSquared( a.x, a.y, cX, cY ) < a.r * a.r )
+  {
+    //This box and the circle have collided
+    return true;
+  }
+
+  //If the shapes have not collided
+  return false;
 }
 
 Paddle::Paddle(Uint16 x, Uint16 y, Uint8 velX, Uint8 velY, Uint8 w, Uint8 h)
@@ -349,6 +418,11 @@ Paddle::Paddle(Uint16 x, Uint16 y, Uint8 velX, Uint8 velY, Uint8 w, Uint8 h)
     mVelY = velY;
 }
 
+SDL_Rect& Paddle::getCollider()
+{
+  return p;
+}
+
 void Paddle::handleEvent( SDL_Event& e )
 {
     //If a key was pressed
@@ -507,7 +581,7 @@ int main( int argc, char* args[] )
                        //The dot that will be moving around on the screen
                        Paddle paddle = Paddle(10, SCREEN_HEIGHT/2, 0, 0, 8, 40);
 
-                       Dot ball = Dot(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, 2, 1, 10, 10);
+                       Dot ball = Dot(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, -1, 1, 10, 10);
                        gDotTexture.setColor(0xFF, 0xFF, 0xFF);
 
                        //While application is running
@@ -528,7 +602,7 @@ int main( int argc, char* args[] )
 
                                //Move the dot
                                paddle.move();
-                               ball.move();
+                               ball.move(paddle.getCollider());
 
                                //Clear screen
                                SDL_SetRenderDrawColor( gRenderer, 0x00, 0x00, 0x00, 0xFF );