I've made a pong clone (using 4 bats)
I have made 4 Rectangles, and a ball rectangle.
I'm trying to make the ball bounce of the bats, this works fine when the speed isn't incremented, but when it is my collisions just fuck up... any ideas?
Collision Code
[code]
#region Collisions
if (elapsed == 0)
{
if (ballbox.Intersects(bat1box))
{
vBallpos.Y += 2 * playerScore;
velocity.X *= -1;
playerScore++;
}
else if (ballbox.Intersects(bat2box))
{
vBallpos.Y -= 2 * playerScore;
velocity.X *= -1;
playerScore++;
}
if (ballbox.Intersects(bat3box))
{
vBallpos.X -= 2 * playerScore;
velocity.X *= -1;
playerScore++;
}
else if (ballbox.Intersects(bat4box))
{
vBallpos.X += 2 * playerScore;
velocity.X *= -1;
playerScore++;
}
}
#endregion
[/code]
we'll probably need to see more code
is it possible that speeding it up causes the ball to jump over the paddles so it never actually touches them?
Maybe, instead of doing those rectangle intersects, you could check if the ball is outside the defendable rect (blue):
[IMG]http://i47.tinypic.com/1rdk4p.png[/IMG]
then if so, check if the paddle has the right X or Y (not both) position to block it, if that makes sense. You should only need to check at max five conditions.
Where are the bats rectangles being updated?
[QUOTE=Jimmylaw;22926162]Where are the bats rectangles being updated?[/QUOTE]
This is probably your problem...
inside the update method...
[QUOTE=Loli;22931742]inside the update method...[/QUOTE]
Where? the only rectangle I see that's being updated is the bat rectangle.
Perhaps you could update the x and y multiple times per frame and check the collisons multiple times per frame?
Or perhaps you could fire a trace every frame in the direction of where the ball is heading and see if a collision is approaching.
[QUOTE=NovembrDobby;22922849]we'll probably need to see more code
is it possible that speeding it up causes the ball to jump over the paddles so it never actually touches them?[/QUOTE]
I think that could possibly be the problem.
Would the easiest method be to have the start position for the frame and the end position and then go through each individual step between that and check for collisions?
[QUOTE=andersonmat;22943739]I think that could possibly be the problem.
Would the easiest method be to have the start position for the frame and the end position and then go through each individual step between that and check for collisions?[/QUOTE]
I have no idea...
I don't quite understand what you're saying, however, I think this is the problem...
he means instead of checking one frame then the next frame for collisions, every frame you check a few positions in between like this:
[code]
Vector2 newPos = vBallpos + velocity * (float)playerScore;
for(float i = 0; i < 1; i += 0.1f)
{
ballbox = new Rectangle(
(int)MathHelper.Lerp(vBallpos.X, newPos.X, i),
(int)MathHelper.Lerp(vBallpos.Y, newPos.Y, i),
tBall.Width, tBall.Height);
//check intersects with each paddle blah blah
}
vBallpos += velocity * (float)playerScore;
[/code]
hmm, give it a try...
I think he illustrated it pretty well with code however, here is the concept I was going for:
[img]http://anyhub.net/file/collision.png[/img]
Eureka... You've struck gold. I'm going to try and implement this stuff now...
[editline]09:21PM[/editline]
That method only works for the bat at the top... I'm fresh outta ideas.
[img]http://imgur.com/ANpyq.png[/img]
Here is a diagram showing a single frame of a ball (a particle to simplify things for now).
In this single frame, the ball travels from [I]Before[/I] to [I]After[/I] and penetrates the paddle (It doesn't matter is the [I]After[/I] position is INSIDE the paddle or not). What we want is the [I]Resolve Collision[/I] point where the green distance [I]d[/I] is the same length as the black distance [I]d[/I].
Firstly to check that the ball has infact penetrated the paddle, we can check if x > 0
[cpp]
Ball.Pos += Ball.Velocity
// Assume Paddle.X is the X co-ordinate of the thick line
// IE: Paddle has 0 width
x = Paddle.X - Ball.X
if(x > 0)
// collision
[/cpp]
Now if X is greater than zero then the ball has passed the line but not necessarily collided in the Y axis.
To do this properly you would want to check the actual intersection point of the line of velocity and the paddle ([I]Orange[/I] dot on my diagram). You can do this with school-level mathematics y=mx+c, where x = Paddle.X
However, I was lazy and I cut some corners and just compared
[cpp]
if(Ball.Y > Paddle.Y && Ball.Y < Paddle.Y + Paddle.Height)
[/cpp]
This is pretty much okay because we're dealing with small values.
Now to find the [I]Resolved Collision[/I] position, all we have to do is:
[cpp]
resolved = Ball.Pos + 2 * x
[/cpp]
You may notice that we may not see the ball actually touch the paddle but this is a good thing because the ball travels exactly the same distance as it would have done if the paddle was not there ([I]c[/I]+[I]d[/I] on the diagram)
All this is done with a particle in mind but the maths is the same with a circle instead. The only difference is that [I]x[/I] is the distance between [B]The side of the ball that will hit the paddle[/B] and the paddle. so:
[cpp]
x = Paddle.X - (Ball.X - Ball.Radius)
[/cpp]
[img]http://imgur.com/FtVzV.png[/img]
This method will work for solid walls, horizontal paddles etc. You can probably create a generalised function for it.
Edit: I didn't take into account the small sides of the paddles because this gets much harder when the ball intersects the corner. In my experience it seems okay to leave this out.
[QUOTE=Loli;22957991]Eureka... You've struck gold. I'm going to try and implement this stuff now...
[editline]09:21PM[/editline]
That method only works for the bat at the top... I'm fresh outta ideas.[/QUOTE]
It was generalized, vampired has a more elaborate solution.
Gonna start over. Using OOP this time might help me :P Why did I not use it previously?
Sorry, you need to Log In to post a reply to this thread.