开发者

2D Box Collision - Is this right?

开发者 https://www.devze.com 2023-03-17 10:02 出处:网络
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.

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)

)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号