Collision Code Help

Hi, I was looking for some help in regards to some code that I have written for a replica Pong Game. I have managed to create a border around the game using rectangleshape, as well as a paddle and ball.

I have also added code that allows the paddle to move up and down but where I am stuck is that I would like the paddle to stop when reaching the top or bottom rectangle but not sure how.

If somebody could please advise.

Part of my code

Event event; // allows the game window to be closed using the x button or esc key
while (window.pollEvent(event))
{
if ( (event.type == Event::Closed) ||
((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )
window.close();
else
{
if (event.type == Event::KeyPressed)
{
switch(event.key.code)
{
case Keyboard::Up: paddle.move(0,-10);
break;
case Keyboard::Down: paddle.move(0,10);
break;
}
}
}
}
}

The top and bottom border are named toprectangle and bottom rectangle.

Any advice or tips would be really appreciated.
Last edited on
You could have right after move(up)
IF top < paddle.posy THEN paddle.posy = top;
(except that your "up" seems to use negative value, so adjust the < or >).

Similarly for the bottom.


The alternative is to adjust the move amount before the move so that you never cross the borders -- and do not even call move(0,0) unnecessarily.
1
2
3
auto diff = top - posy;
auto step = std::min( diff, 10 );
if ( 0 < step ) paddle.move( 0, step );
Thanks keskiverto, i adjusted the code to give me the following:

switch(event.key.code)
{
case Keyboard::Up: paddle.move(0,-10);
if toprectangle < paddle.posy then paddle.posy = toprectangle;
break;

but when i run the code then I get an error message with build errors even if i adjust the < with > with the following:

error C2061: syntax error : identifier 'toprectangle'

Btw thanks for your response.
Last edited on
Did you consider telling us what the error messages are? It's pretty hard to fix build errors if we don't know what they are.

However, I will try.

if toprectangle < paddle.posy then paddle.posy = toprectangle;
This looks like BASIC code (if I remember my early programming from decades ago). Try using C++ constructs. if (...) ...;
@doug4
Don't confuse pseudocode with actual code. I'm sure OP knows the difference.

@aftabn10
It looks like you are trying to compare a class/struct (toprectangle) with a number (paddle.posy).
Is there a toprectangle.bottom or something like that?
(If you're using an SDL_Rect, it would be toprectangle.y + toprectangle.h.)

Hope this helps.
doug4, Duoas, thanks for your replies. apologies noticed that I hadnt put the error message which i later edited and added onto the post.

What I have is 5 RectangleShapes (4 are borders around the window and the 1 being the paddle that moves up or down).

An example of 1 of the RectangleShapes is shown below:

RectangleShape toprectangle;
toprectangle.setPosition(0, 0);
toprectangle.setSize(Vector2f(716, 33));

What I am trying to do is to make sure the paddle stops as soon as it collides with the toprectangle rather than overlapping and continuing to move up and the same if its being moved down.

So the code @keskiverto posted im guessing wont work as the toprectangle is not defined as a class rather drawn when the window.isOpen.

Hope that makes sense, apologies for the confusion.
What?

The toprectangle is clearly on object with properties. Do you seriously claim that the public interface of RectangleShape has no "get" methods?
You've got to use a little algebra here, since your ball moves in discrete "jumps".

Check to see if the line (from the ball's previous position to the next position) intersects with the edge of the paddle.

If it does, calculate the new trajectory and place the ball '1 jump' position away from the paddle.

Since paddles are horizontal (not vertical?), the algebra is easy enough. Find X where the line crosses the Y position of the paddle's edge. If (paddle left ≤ X ≤ paddle right) then you had a collision.

Remember that y = mx + b.
The slope is given by m = (y2 - y1) / (x2 - x1).
Assuming y1 < Y < y2, then take b = 0 at x2 and set X = x2 + (y2 - Y) / m.

You don't need much more math than that. You don't even have to calculate angles. Just negate the ball's x and y increments, place the ball at the paddle, and 'jump' it forward one.

Hope this helps.
keskiverto, apologies i wasnt claiming anything. Just a novice and only started to write code in c++ since yesterday and just trying to get an understanding of how it all works.

Duoas, thanks for that. At present I have a static ball and paddle that moves up and down, am i right in guessing that i need to sort the ball movement before I would try and tackle this problem.

Apologies, i guess doesnt make it easier without my code being shown.
am i right in guessing that i need to sort the ball movement before I would try and tackle this problem.

No. The paddle movement is separate and simpler. Start with that.

What I wrote initially still stands: you have three objects that each have y-coordinate. You do modify the y of the paddle object. The other two objects define valid range for paddle.y's value.

The fact that the objects have size too rather than being just a point or line merely adds a tiny bit to the calculation. You probably don't want the paddle to go inside the border, so the bottom edge of the top border is the maximum y-pos that the top edge of the paddle should go and the y-pos of the paddle is thus limited even lower, by the distance form top edge of paddle to y-pos of paddle (i.e. the size).

The definition of class RectangleShape should reveal how to use a RectangleShape object. Is it from some library, or written by you? If it is from library, does the library have online documentation?
TC appears to be using SFML.
http://www.sfml-dev.org/documentation/2.3.1/classsf_1_1RectangleShape.php

@TC: What you may want to do is after movement, check if the paddle's top is above the bottom of the upper rectangle, and if so, manually place it so they touch. Similarly for the bottom. This is perhaps one of the simpler options to implement.
Thanks guys for your responses. I probably need to do a bit of reading in my c++ book and other sources as at present I was ok writing the code for the windowsize, borders around and paddle and ball. Need to make sure i know what i am writing before I start as trying to get my head around the algebra (not my strongest point)

Thanks for all your help and advise, as never written code in c++ before.
Last edited on
Collision objects are a lot simpler than the objects they represent.

A paddle's collision object only needs to be a line. The ball only needs to be a circle (a point and a radius). The math to find the intersection of these things is trivial, and a lot of it can be precomputed even.

You're asking the right questions, which means you are on the right track.
Topic archived. No new replies allowed.