Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Collision detection(Pong game)  (Read 8681 times)

0 Members and 1 Guest are viewing this topic.

kintantee

  • Newbie
  • *
  • Posts: 10
    • View Profile
Collision detection(Pong game)
« on: February 08, 2012, 05:35:47 pm »
Hi folks, I need your help with collision detection with my little sfml pong game.

First I can detect the collision with walls(window boundaries) however I can't do the same with rackets.  I just don't get where the mistake is...

as a background information, my ball is a square.

fallowing lines belong to collision detection function. Firstly I'm trying to understand if ball is going left and did it hit the racket horizontally. Then I control if it's indeed hit the racket by checking the coordinate vertically.

Code: [Select]

int Ball::detectCollision(Racket &leftRacket, Racket &rightRacket)
{
sf::Vector2f bouncerPosition = geometry_.GetPosition();
sf::Vector2f leftRacketPosition = leftRacket.getRacketPosition();
sf::Vector2f rightRacketPosition = rightRacket.getRacketPosition();

float racketWidth = leftRacket.getRacketWidth();
float racketHeight = leftRacket.getRacketHeight();



if(bouncerPosition.x <= leftRacketPosition.x + racketWidth && velocity_.x < 0.0f)
{
if(bouncerPosition.y + ballHeight_ >= leftRacketPosition.y && bouncerPosition.y <= leftRacketPosition.y + racketHeight)
{
return COLLIDING_WITH_LEFT_PADDLE;
}
}

else if(bouncerPosition.x + ballWidth_ >= rightRacketPosition.x && velocity_.x > 0.0f)
{
if(bouncerPosition.y + ballHeight_ >= rightRacketPosition.y && bouncerPosition.y <= rightRacketPosition.y + racketHeight)
{
return COLLIDING_WITH_RIGHT_PADDLE;
}
}

else
{
return NO_COLLISION;
}
}


and here is my process function for collision. In essence, what I'm trying to do is firstly changing the x velocity and then altering the ball position for possible infinite strucks in paddle.

Code: [Select]

void Ball::processCollision(const int collisionInformation, Racket &leftRacket, Racket &rightRacket)
{
sf::Vector2f bouncerPosition = geometry_.GetPosition();
sf::Vector2f leftRacketPosition = leftRacket.getRacketPosition();
sf::Vector2f rightRacketPosition = rightRacket.getRacketPosition();

float racketWidth = leftRacket.getRacketWidth();

float fraction = 0.0f;

if(collisionInformation == COLLIDING_WITH_LEFT_PADDLE)
{
velocity_.x = -velocity_.x;


fraction = -(bouncerPosition.x - leftRacketPosition.x + racketWidth);
bouncerPosition.x += fraction;
geometry_.SetPosition(bouncerPosition);
}

else if(collisionInformation == COLLIDING_WITH_RIGHT_PADDLE)
{
velocity_.x = -velocity_.x;

fraction = -(bouncerPosition.x + ballWidth_ - leftRacketPosition.x);
bouncerPosition.x += fraction;
geometry_.SetPosition(bouncerPosition);
}
}


and enumartion for collision types:
Code: [Select]

enum COLLISION_INFORMATION
{
NO_COLLISION,

COLLIDING_WITH_UPPER_WALL,
COLLIDING_WITH_LOWER_WALL,
COLLIDING_WITH_LEFT_WALL,
COLLIDING_WITH_RIGHT_WALL,

COLLIDING_WITH_LEFT_PADDLE,
COLLIDING_WITH_RIGHT_PADDLE
};


Finally my driving code in the main game loop:

Code: [Select]

bouncer.calculateDisplacement(deltaTime);


if(collidingEdge = bouncer.detectCollision(leftRacket, rightRacket))
{
bouncer.processCollision(collidingEdge, leftRacket, rightRacket);
bouncer.accelerate();
}

else
{
bouncer.bounce();
bouncer.tailAnimation();
}
}




Thank you in advance!

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Collision detection(Pong game)
« Reply #1 on: February 08, 2012, 07:06:17 pm »
Quote
I just don't get where the mistake is...
What exactly is going wrong? Does the ball go too far?


I think your fraction is wrong with the left panel. I think you have to add racketWidth instead of subtracting it.
Code: [Select]
fraction = leftRacketPosition.x + racketWidth - bouncerPosition.x;


Why are you adding 1 when colliding with the left paddle? You don't substract 1 when colliding with the right paddle.
TGUI: C++ SFML GUI

kintantee

  • Newbie
  • *
  • Posts: 10
    • View Profile
Collision detection(Pong game)
« Reply #2 on: February 08, 2012, 08:00:33 pm »
Quote from: "texus"
What exactly is going wrong? Does the ball go too far?


It's not detecting the paddles

Quote from: "texus"

I think your fraction is wrong with the left panel. I think you have to add racketWidth instead of subtracting it.
Code: [Select]
fraction = leftRacketPosition.x + racketWidth - bouncerPosition.x;



What I'm trying to acheieve there is that getting the fraction that is inside the racket. Since my ball is a square I'm extracting the left side of ball(assuming it's inside or atleast at the same coordinate) from the right side of the racket which is leftRacketPosition.x + racketWidth

something like this :


Quote from: "texus"

Why are you adding 1 when colliding with the left paddle? You don't substract 1 when colliding with the right paddle.


that was an experiment and didn't work. I'll fix it

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Collision detection(Pong game)
« Reply #3 on: February 08, 2012, 08:29:30 pm »
I still think that your formula is wrong. Lets just use numbers as an example.
leftRacketPosition.x = 10
bouncerPosition.x = 12
racketWidth = 5

If I understand it correctly then the fraction would have to be 3.
You are doing 12 - 10 + 5 = 7   (bouncerPosition.x - leftRacketPosition.x + racketWidth)
My code does 10 + 5 - 12 = 3   (leftRacketPosition.x + racketWidth - bouncerPosition.x)
TGUI: C++ SFML GUI

kintantee

  • Newbie
  • *
  • Posts: 10
    • View Profile
Collision detection(Pong game)
« Reply #4 on: February 08, 2012, 09:34:58 pm »
Quote from: "texus"
I still think that your formula is wrong. Lets just use numbers as an example.
leftRacketPosition.x = 10
bouncerPosition.x = 12
racketWidth = 5

If I understand it correctly then the fraction would have to be 3.
You are doing 12 - 10 + 5 = 7   (bouncerPosition.x - leftRacketPosition.x + racketWidth)
My code does 10 + 5 - 12 = 3   (leftRacketPosition.x + racketWidth - bouncerPosition.x)



I think I should put paranteses:

like fallowing:

-(12 - (10 + 5)) = 3

however, the major problem is I can not detect collision.

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Collision detection(Pong game)
« Reply #5 on: February 08, 2012, 10:21:38 pm »
Quote
It's not detecting the paddles

Sorry, I misunderstood your sentence. I thought you meant that the problem did not lie with detecting the paddles.


Quote
the major problem is I can not detect collision.

You should be able to locate the problem a little better.
Debug your program: Is the detectCollision function returning NO_COLLISION? If so then check the values of the variables while performing the check.
TGUI: C++ SFML GUI

kintantee

  • Newbie
  • *
  • Posts: 10
    • View Profile
Collision detection(Pong game)
« Reply #6 on: February 08, 2012, 10:29:25 pm »
Quote from: "texus"
Quote
It's not detecting the paddles

Sorry, I misunderstood your sentence. I thought you meant that the problem did not lie with detecting the paddles.


Quote
the major problem is I can not detect collision.

You should be able to locate the problem a little better.
Debug your program: Is the detectCollision function returning NO_COLLISION? If so then check the values of the variables while performing the check.


It's only detecting the collision with right racket if vy < 0 and if it hits the upper side of the racket and vice versa for left racket : detects the collision if vy > 0 and if it hits the upper sides of the racket.

kamui

  • Sr. Member
  • ****
  • Posts: 291
    • View Profile
Collision detection(Pong game)
« Reply #7 on: February 09, 2012, 10:47:52 am »
Hello,

I don't think it's a problem with parenteses :

with operators priority...

Code: [Select]

 if((bouncerPosition.x <= (leftRacketPosition.x + racketWidth)) && (velocity_.x < 0.0f))
   {
      if(((bouncerPosition.y + ballHeight_) >= leftRacketPosition.y) && (bouncerPosition.y <= (leftRacketPosition.y + racketHeight)))


...that's good.

you should check collision with anticipation (look after next time if collision will be detected) because you maybe think the ball collide with a wall, but it's just that you say "stop" too late to your ball colliding with paddles :

Code: [Select]

        if (velocity.x<0)//check leftPaddle
        {
            if (leftRacketPosition.x >= (bouncerPosition.x + velocity.x)) //the ball is going to be in the left paddleX area
            {
               if ((BouncerPosition.y>=LeftRacketPosition.y)
               && (bouncerPosition.y<=leftracketPosition.y+Height)) //the ball is going to be in the left PaddleY area
              {
                     return COLLIDING_WITH_LEFT_PADDLE;
              }
           }
        }
        else//check RightRacket
        {//etc...}

kintantee

  • Newbie
  • *
  • Posts: 10
    • View Profile
Collision detection(Pong game)
« Reply #8 on: February 09, 2012, 08:05:56 pm »
Okay guys I found the problem and thank you for your help!

The problem occured because of the shape of my ball which is square. I was comparing the top left y-coordinate of the ball(for both vy > 0 and vy <0), however, I should have compared like fallowing:

if(vy > 0)
    compare lower-left corner(bouncerPosition.y + ballHeight_)

else if(vy < 0)
    compare top-left corner(bouncerPosition.y)

here is my code for solution:

Code: [Select]

if(velocity_.x < 0.0f)
{
if(bouncerPosition.x <= leftRacketPosition.x + racketWidth)
{
if(velocity_.y < 0.0f)
{
if(bouncerPosition.y <= leftRacketPosition.y + racketHeight &&
bouncerPosition.y >= leftRacketPosition.y)
{
return COLLIDING_WITH_LEFT_PADDLE;
}
}

else
{
if(bouncerPosition.y + ballHeight_ >= leftRacketPosition.y &&
  bouncerPosition.y + ballHeight_ <= leftRacketPosition.y + racketHeight)
{
return COLLIDING_WITH_LEFT_PADDLE;
}
}
}
}

else if(velocity_.x > 0.0f)
{
if(bouncerPosition.x + ballWidth_ >= rightRacketPosition.x)
{
if(velocity_.y < 0.0f)
{
if(bouncerPosition.y <= rightRacketPosition.y + racketHeight &&
  bouncerPosition.y >= rightRacketPosition.y)
{
return COLLIDING_WITH_RIGHT_PADDLE;
}
}

else
{
if(bouncerPosition.y + ballHeight_ >= rightRacketPosition.y &&
  bouncerPosition.y + ballHeight_ <= rightRacketPosition.y + racketHeight)
{
return COLLIDING_WITH_RIGHT_PADDLE;
}
}
}
}


Thank you again!

Serapth

  • Full Member
  • ***
  • Posts: 105
    • View Profile
Collision detection(Pong game)
« Reply #9 on: February 10, 2012, 03:35:54 pm »
Just a suggestion, but if you used sf::Rect's instead of vectors, you could reduce your code down to like 2 lines.


if(ballRect.Intersects(paddle1Rect) return PADDLE1HIT;
if(ballRect.Intersects(paddle2Rect) return PADDLE2HIT;

 

anything