2D Box Collision - Is this right?
Well I've got a 2D box collision code that basically loops through every block in a list called "Blocks" and it checks if I'm near the sides and whatnot.
It works very well except for the bottom of the block. When I'm jumping up towards the bottom I want my player to simply "bounce" off. It does this, but it is very glitchy. It's hard to explain so I was hoping you guys could possibly spot out what's wrong with my bottom collision code.
Here's the entire thing:
for(unsigned int i = 0; i<blocks.size(); i++){
Block &b = blocks.at(i);
if(!b.passable==true){
//Check if we are on the sides
if(y + height + vspeed >= b.worldY+2 && y + vspeed <= b.worldY+b.height)
{
//Right side
if(x + hspeed <= b.worldX+b.width-1 && x + hspeed > b.worldX+b.width + hspeed-2)
{
x = b.worldX + b.width; hspeed = 0;
}
//Left side
if(x + width + hspeed >= b.worldX +1 && x + width + hspeed <= b.worldX + hspeed + 2)
{
x = b.worldX - width; hspeed =开发者_StackOverflow中文版 0;
}
}
//Check if we are on the top or the bottom
if(x + width + hspeed >= b.worldX+2 && x + hspeed <= b.worldX+b.width-2)
{
if(y + height + vspeed >= b.worldY && y + height + vspeed <= b.worldY + vspeed + 1 && jumpstate=="falling")
{
y = b.worldY - height; jumpstate.assign("ground"); vspeed = 0;
}
if(y + vspeed <= b.worldY + b.height && y + vspeed >= b.worldY + b.height + vspeed - 1 && jumpstate=="jumping")
{
y = b.worldY + b.height; jumpstate.assign("falling"); vspeed = 0;
}
}
}
}
My guess is that you should set vspeed = -vspeed;
instead of vspeed = 0
. Fully elastic bouncing means that the velocity gets mirrored in the box's side.
If you set it to zero, depending on the order in which you perform your updates, you might not move during a frame. And since you use <=
and >=
for bounds checking, you'll still be inside the box on the next frame, invoke the bouncing behaviour again, and get stuck with your head glued to the block.
My guess at your problem would be negative numbers in your inequality checks. For example, when going down, I guess vspeed
will be negative. Depending on where you have set the origin of your box, this could mean that the condition
y + vspeed <= b.worldY + b.height
is always true.
As an aside, by adding a distance to a speed, you have assumed a magic dimension for the unit time. This makes your code brittle because if you change this magic number, then your equations will be wrong.
Try,
y + vspeed*unit_time <= b.worldY + b.height
If you want to handle the units at compile-time (and not pay for that multiplication), then use boost.units
.
Additionally,
x + hspeed > b.worldX+b.width + hspeed-2
can be simplified to
x > b.worldX+b.width-2
And the significance of this magic number 2 is anyones guess. (why for instance do you have
//Check if we are on the sides
if(y + vspeed <= b.worldY+b.height)
but have a -2
in
//Check if we are on the top or the bottom
if( x + hspeed <= b.worldX+b.width-2)
)
精彩评论