Game Object Creator

Collision Detection

  • Collision Detection

Written by: Andy Odle
Date: Nov 16, 2010

      This tutorial builds upon the Input Handling tutorial. Please complete the
Input Handling tutorial before continuing with this tutorial, if you have not done so all ready.

This tutorial covers how to detect:


          When a paddle collides with a window's edge.

          When a ball collides with a window edge.

          Moving the ball around the screen.

          Keeping the Ball Inside the Window.

          When a ball collides with a paddle.

Paddle and Boundary Collsion Detection:

1.) Open GOC.h in CodeLite.

2.) Add a int maxPlayerPosition_m variable.

3.) Open main.cpp in Codelite.

4.) Initialize maxPlayerPosition_m's value to be the window height minus
      playerOne_m's height in the GOC::Initialize funciton.

Initialize Maximum Player Position

                    // The maximum amount to move the paddle and still 
                    // be inside the window.
                    maxPlayerPosition_m = GetWindowHeight() - playerOne_m->GetHeight();
                    

5.) Change playerOne_m's input checks in GOC::Update function to
     include boundary checking.

Player One's Paddle Boundary Checking

                        // New keyboard input Handling for moveing the paddle up.
                        if(input_p->IsKeyOrButtonPressed (KeysAndButtons::UP_KEYBOARD) && playerOne_m->GetYcor() > 0) 
                        {
                            //Move Paddle Up Code
                        }
                        
                        // New Keyboard input Handling for moveing the paddle down.
                        if(input_p->IsKeyOrButtonPressed (KeysAndButtons::DOWN_KEYBOARD) && playerOne_m->GetYcor() < maxPlayerPosition_m)
                        {
                            //Move Paddle Down Code
                        }
                    

6.) Replace playerTwo_m's input handling code and add boundary checking.

Player Two's Paddle Boundary Checking

                        // New Mouse Handling for moving the paddle 
                        // down and up.
                        if(input_p->YCordinate() < maxPlayerPosition_m)
                        {
                            playerTwo_m->SetYCor(input_p->YCordinate());
                        }
                        else
                        {   
                            playerTwo_m->SetYCor(maxPlayerPosition_m);
                        }                            
                    

7.) Click Build -> Build and Run Project in CodeLite.

Ball Collision Detection:

1.) Open GOC.h in CodeLite.

2.) Add two integer variables called maxBallX_m and maxBallY_m.

3.) Open main.cpp in CodeLite.

4.) Initialize maxBallX_m's value to be the window width minus ball_m's width
     in the GOC::Initialize function.

5.) Initialize maxBallY_m's value to be the window height minus ball_m's
     height in the GOC::Initialize function.

Maximum Ball's x-cor and y-cor

                        maxBallX_m = GetWindowWidth() - ball_m->GetWidth();
                        maxBallY_m = GetWindowHeight() - ball_m->GetHeight();
                    

6.) Check to see if the ball has collided with the top window's edge in       GOC::Update.

7.) Check to see if the ball has collided with the bottom window's edge       GOC::Update.

8.) Check to see if the ball has collided with the left window's edge       GOC::Update.

9.) Check to see if the ball has collided with the right window's edge       GOC::Update.

Ball and Window Edge Collision Checks

                        // Top Screen Edge Has been reached.
                        if(ball_m->GetYcor() <= 0)
                        {
                            //...
                        }
                        
                        // Bottom Screen Edge Has been reached.
                        if(ball_m->GetYcor() >= maxBallY_m)
                        {
                            //...
                        }
                        
                        // Right Screen Edge Has been reached.
                        if(ball_m->GetXcor() >= maxBallX_m)
                        {
                            // Player One Scored.
                            //...
                        }
                        
                        // Left Screen Edge Has been reached.
                        if(ball_m->GetXcor() <= 0)
                        {
                            // Player Two Scored.
                            //... 
                        }
                    

10.) Click Build -> Build and Run Project in CodeLite.

Moving the Ball Around:

1.) Open GOC.h in CodeLite.

2.) Add three float variables ballVelocityX_m, ballVelocityY_m and
      ballAngle_m.

3.) Add a int ballSpeed_m variable.

4.) Open Main.cpp in Codelite.

5.) Initialize ballSpeed_m to 10 in GOC::Initialize.

6.) Initialize ballAngle_m to 60 in GOC::Initialize.

7.) Initialize ballVelocityX_m to the ballSpeed_m times the cos of the
      ballAngle_m in GOC::Initialize.

8.) Initialize ballVelocityY_m to the ballSpeed_m times the sin of the
      ballAngle_m in GOC::Initialize.

BallSpeed, BallAngle and Ball Velocity

                        ballSpeed_m = 10;
                        ballAngle_m = 60;

                        ballVelocityX_m = ballSpeed_m * cos( ballAngle_m );
                        ballVelocityY_m = ballSpeed_m * sin( ballAngle_m );                                    
                    

9.) Set the ball_m's x-cor equal to the ball_m's current x-cor pluss
      ballVelocityX_m in GOC::Update.

10.) Set the ball_m's y-cor equal to the ball_m's current y-cor pluss
       ballVelocityY_m in GOC::Update.

Upate Ball's Position Each Frame

                        // Move the ball a little bit each frame.
                        ball_m->SetXCor(ball_m->GetXcor() + ballVelocityX_m );
                        ball_m->SetYCor(ball_m->GetYcor() + ballVelocityY_m );                                
                    

11.) Click Build -> Build and Run Project in CodeLite.

Collision Resoultion

1.) Open main.cpp in CodeLite.

2.) Locate the GOC::Update function.

3.) Negate ballVelocityY_m inside of the //Top of Screen Edge's if check.

4.) Set the ball_m's y-cor to 0 inside of the //Top of Screen Edge's if check.

5.) Negate ballVelocityY_m inside of the // Bottom Screen Edge's if check.

6.) Set the ball_m's y-cor to maxBallY_m inside of the // Bottom Screen
      Edge
's if check.

7.) Negate ballVelocityX_m inside of the // Right Screen Edge's if check.

8.) Set the ball_m's x-cor to maxBallX_m inside of the // Right Screen Edge's
     if check.

9.) Negate ballVelocityX_m inside of the // Left Screen Edge's if check.

10.) Set the ball_m's x-cor to 0 inside of the // Left Screen Edge's if check.

Reslove Collisions

                        // Top Screen Edge Has been reached.
                        if(ball_m->GetYcor() <= 0)
                        {
                            ballVelocityY_m = -ballVelocityY_m;
                            ball_m->SetYCor(0);
                        }
                        
                        // Bottom Screen Edge Has been reached.
                        if(ball_m->GetYcor() >= maxBallY_m)
                        {
                            ballVelocityY_m = -ballVelocityY_m;
                            ball_m->SetYCor(maxBallY_m);
                        }
                        
                        // Right Screen Edge Has been reached.
                        if(ball_m->GetXcor() >= maxBallX_m)
                        {
                            // Player One Scored.
                            ballVelocityX_m = -ballVelocityX_m;
                            ball_m->SetXCor(maxBallX_m);  
                        }
                        
                        // Left Screen Edge Has been reached.
                        if(ball_m->GetXcor() <= 0)
                        {
                            // Player Two Scored.
                            ballVelocityX_m = -ballVelocityX_m;
                            ball_m->SetXCor(0); 
                        }                                
                    

11.) Click Build -> Build and Run Project in CodeLite.

Ball and Paddle Collision Detection:

1.) Open main.cpp in CodeLite.

2.) Locate the GOC::Update function.

3.) Check to see if ball_m has collided with playerOne_m's right side.

4.) Negate ballVelocityX_m inside the ball_m and playerOne_m's collision
     check.

5.) Set ball_m's x-cor to 31 inside the ball_m and playerOne_m's collision
     check.

6.) Check to see if ball_m has collided with playerTwo_m's left side.

7.) Negate ballVelocityX_m inside the ball_m and playerTwo_m's collision
     check.

8.) Set ball_m's x-cor to maxBallX_m - 31 inside the ball_m and
      playerOne_m's collision check.

Paddle and Ball Collisions

                        // Ball collied with PlayerOne.
                        if(playerOne_m->HasCollidedRight(ball_m) == CollidedSide::RIGHT_COLLISION)
                        {
                            ballVelocityX_m = -ballVelocityX_m;
                            ball_m->SetXCor(31);
                        }
                        
                        // Ball collied with PlayerTwo.
                        if(playerTwo_m->HasCollidedLeft(ball_m) == CollidedSide::LEFT_COLLISIOIN)
                        {
                            ballVelocityX_m = -ballVelocityX_m;
                            ball_m->SetXCor(maxBallX_m - 31);
                        }                                 
                    

9.) Change ball_m's visibilty to true in GOC::Initialize function.

10.) Click Build -> Build and Run Project in CodeLite.

(Back to "Windows® " or "Ubuntu® " Tutorials)

Collision Detection Complete Example:


       You can get the complete example source code here.
			            /*
				            File Name: GOC.h
				            Date: Nov 16, 2010
			            */

                        #ifndef GOC_h
                        #define GOC_h

                        #include "./source/PlatformSpecific/inc/ErrorReport.h"
                        #include "./source/inc/TimeGOC.h"
                        #include "./source/inc/InputEngine.h"

                        /* Add new include files here */
                        #include "./source/PlatformSpecific/inc/Sprite.h"
                        #include "./source/inc/MathGOC.h"
                        #include "./source/PlatformSpecific/inc/DeviceInput.h"

                        class GOC
                        {
                            public:
                                
                                // Initialize the developer's game.
                                virtual void Initialize();
                                
                                // Updates the developer's game state.
                                virtual void Update(TimeGOC *timeGOC_p, InputEngine *input_p);
                                virtual void IndepedentUpdate(TimeGOC *timeGOC_p, InputEngine *input_p);
                                
                                // Ceans up the developer's game.
                                virtual void Destroy();
                                
                                // This is how you interact with the GOC.
                                // 
                                // Output:
                                //         Returns the Game Object Creator instance pointer.
                                static GOC *goc_i();

                                // Get the window's width and height.
                                int GetWindowWidth();
                                int GetWindowHeight();
                                
                                // Start the setup of the Game Object Creator.
                                #ifdef _WIN32
                                    void LoadGOC(HINSTANCE &hinstance_p);
                                #else
                                    void LoadGOC();
                                #endif
                                
                                // Clean up the Game Object Creator.
                                void UnloadGOC();
                                
                                ErrorReport *GetErrorReport();        

                            private:
                            
                                GOC();
                                ~GOC();
                                GOC(GOC const&){};
                                GOC &operator=(GOC const&){};
                                        
                            private:

                                /* Add private variables here. */
                                Sprite *ball_m;
                                
                                Sprite *playerOne_m;
                                Sprite *playerTwo_m;
                                
                                int maxPlayerPosition_m;
                                
                                int maxBallX_m;
                                int maxBallY_m;
                                
                                float ballVelocityX_m;
                                float ballVelocityY_m;
                                
                                int ballSpeed_m;
                                float ballAngle_m;       
                        };

                        #endif
			        

                                
                        /* 
                            FileName: main.cpp
                            Date: Nov 16, 2010
                            
                            Collision Detection Example 
                        */
                        
                        #include "./source/PlatformSpecific/inc/GOC.h"

                        void GOC::Initialize()
                        {
                         /* 
                          Initialize your game scene, and game variables here. 
                         */
                            
                            // Initilize ball.
                            PointGOC ballPosition_l = { GetWindowWidth() / 2,
                                                        GetWindowHeight() / 2,
                                                        0.0f};

                            ball_m = new Sprite();
                            
                            ball_m->Set2DPosition(ballPosition_l,
                                                  24,
                                                  24);
                            ball_m->GetTexture()->LoadTexture("./images/Ball.png");
                            
                            ball_m->SetVisible(true);
                            
                            
                            // Initilize player one.
                            PointGOC playerOnePosition_l = { 15,
                                                             15,
                                                             0.0f};
                            playerOne_m = new Sprite();
                            
                            playerOne_m->Set2DPosition( playerOnePosition_l,
                                                       15,
                                                       200 );
                            playerOne_m->GetTexture()->LoadTexture( "./images/Padle.png" );
                            
                            playerOne_m->SetVisible(true);
                            
                            // Initilize player two.
                            
                            PointGOC playerTwoPosition_l = { GetWindowWidth() - 30,
                                                             15,
                                                             0.0f };
                            playerTwo_m = new Sprite();
                            
                            playerTwo_m->Set2DPosition( playerTwoPosition_l, 
                                                       15,
                                                       200 );
                            playerTwo_m->GetTexture()->LoadTexture( "./images/Padle.png" );
                            
                            playerTwo_m->SetVisible(true);
                            
                            maxPlayerPosition_m = GetWindowHeight() - playerOne_m->GetHeight();
                            
                            maxBallX_m = GetWindowWidth() - ball_m->GetWidth();
                            maxBallY_m = GetWindowHeight() - ball_m->GetHeight();
                            
                            ballSpeed_m = 10;
                            ballAngle_m = 60;
                            
                            ballVelocityX_m = ballSpeed_m * cos(ballAngle_m);
                            ballVelocityY_m = ballSpeed_m * sin(ballAngle_m);    
                        }

                        void GOC::Update(TimeGOC *timeGOC_p, InputEngine *input_p)
                        {
                            /* 
                          Update your game scenes, check for collisions, check for input
                          and play sounds here.
                         */
                            
                            // Move the ball a little bit each frame.
                            ball_m->SetXCor(ball_m->GetXcor() + ballVelocityX_m );
                            ball_m->SetYCor(ball_m->GetYcor() + ballVelocityY_m );
                            
                            // Top Screen Edge Has been reached.
                            if(ball_m->GetYcor() <= 0)
                            {
                                ballVelocityY_m = -ballVelocityY_m;
                                ball_m->SetYCor(0);
                            }
                            
                            // Bottom Screen Edge Has been reached.
                            if(ball_m->GetYcor() >= maxBallY_m)
                            {
                                ballVelocityY_m = -ballVelocityY_m;
                                ball_m->SetYCor(maxBallY_m);
                            }
                            
                            // Right Screen Edge Has been reached.
                            if(ball_m->GetXcor() >= maxBallX_m)
                            {
                                // Player One Scored.
                                ballVelocityX_m = -ballVelocityX_m;
                                ball_m->SetXCor(maxBallX_m);  
                            }
                            
                            // Left Screen Edge Has been reached.
                            if(ball_m->GetXcor() <= 0)
                            {
                                // Player Two Scored.
                                ballVelocityX_m = -ballVelocityX_m;
                                ball_m->SetXCor(0); 
                            }
                            
                            // Ball collied with PlayerOne.
                            if(playerOne_m->HasCollidedRight(ball_m) == CollidedSide::RIGHT_COLLISION)
                            {
                                ballVelocityX_m = -ballVelocityX_m;
                                ball_m->SetXCor(31);
                            }
                            
                            // Ball collied with PlayerTwo.
                            if(playerTwo_m->HasCollidedLeft(ball_m) == CollidedSide::LEFT_COLLISIOIN)
                            {
                                ballVelocityX_m = -ballVelocityX_m;
                                ball_m->SetXCor(maxBallX_m - 31);
                            }    
                            
                            if(input_p->YCordinate() < maxPlayerPosition_m)
                            {
                                playerTwo_m->SetYCor( input_p->YCordinate() );
                            }
                            else
                            {   
                                playerTwo_m->SetYCor(maxPlayerPosition_m);
                            }
                            
                            if(input_p->IsKeyOrButtonPressed( KeysAndButtons::UP_KEYBOARD ) && playerOne_m->GetYcor() > 0)
                            {
                                playerOne_m->SetYCor(playerOne_m->GetYcor() - 20);
                            }
                            
                            if(input_p->IsKeyOrButtonPressed( KeysAndButtons::DOWN_KEYBOARD ) && playerOne_m->GetYcor() < maxPlayerPosition_m)
                            {
                                playerOne_m->SetYCor(playerOne_m->GetYcor() + 20);
                            }
                        }

                        void GOC::IndependentUpdate(TimeGOC *timeGOC_p, InputEngine *input_p)

                        {
                            /* 
                          Update your game scenes, check for collisions, check for input
                          and play sounds here.
                         */
                        }

                        void GOC::Destroy()
                        {
                         /* 
                          Clean up after your game here.
                         */
                            
                            delete ball_m;
                            
                            delete playerOne_m;
                            delete playerTwo_m;
                        }

                        #ifdef _WIN32
                            // Define the windows main funciton.
                            int WINAPI WinMain(HINSTANCE hInstance, 
                                               HINSTANCE hPrevInstance, 
                                               LPSTR lpCmdLine, 
                                               int nCmdShow)
                        #else
                            // Define the ubutnu main function.
                            int main(int argc, char **argv)
                        #endif
                            {
                                #ifdef _WIN32
                                    // Start the GOC on windows.
                                    GOC::goc_i()->LoadGOC(hInstance);
                                #else
                                    // Start the GOC on ubuntu.
                                    GOC::goc_i()->LoadGOC();
                                #endif
                           
                                return 0;
                            }                               
                        



Legal Info  About GOC  Contact Us