C ++ 2D Box-Collision,这是对的吗?

时间:2011-07-03 06:43:08

标签: c++ 2d collision

嗯,我有一个2D盒子碰撞代码,它基本上遍历名为“Blocks”的列表中的每个块,并检查我是否靠近两侧等等。

除了块的底部之外,它的效果非常好。当我向上跳跃时,我希望我的玩家只是“反弹”。它这样做,但它是非常小故障。这很难解释所以我希望你们能够发现我的底部碰撞代码有什么问题。

这是整个事情(这是循环运行):

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 = 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;
        }
     }
  }    
}

2 个答案:

答案 0 :(得分:0)

我不确定你能不能像这样工作。我将解释一个我想到的解决方案,它可以解决碰撞检测和弹跳问题。记录上次检查碰撞和调整位置的时间间隔。如果Xplayer+Vplayer*deltaT>Xtarget(如果玩家与目标重叠),则计算触及目标deltaTtouch=(Xtarget-Xplayer)/Vplayer的实际时间。现在将玩家退回Xplayer=Xtarget-Vplayer*(deltaT-deltaTtouch)。向前,向后,向上,向下移动时,你必须弄清楚所有的情况 LE:你也可以实现引力,这涉及求解二次方程以找出deltaTtouch

答案 1 :(得分:0)

我可以看到一些小细节:

1)在这一行中,检查旧位置时的速度是多余的,最好将其删除以便清晰。

if(x + hspeed <= b.worldX+b.width-1  && x + hspeed > b.worldX+b.width + hspeed-2)

变为:

if(x + hspeed <= b.worldX + b.width - 1  && x > b.worldX + b.width - 2)

其他类似的行也一样。

2) -2和-1的小偏移有点令人困惑我认为你试图获得一个小缓冲区,这样就需要轻微的重叠。特别是你用过&lt;而不是&lt; =你已经使用了其他所有东西:

if(x + hspeed <= b.worldX+b.width-1  && x + hspeed > b.worldX+b.width + hspeed-2)

为了与程序的其余部分保持一致,我可能会写:

if(x + hspeed <= b.worldX + b.width - 1  && x >= b.worldX + b.width - 1)

3)您似乎在Vert检查中遗漏了一些小偏差:

首先检查一下:

if(y + height + vspeed >= b.worldY && y + height + vspeed <= b.worldY + vspeed + 1 && jumpstate=="falling")

你似乎忘记了你的小偏移:

if(y + height + vspeed >= b.worldY + 1 && y + height <= b.worldY + 1 && jumpstate=="falling")

然后第二次检查:

if(y + vspeed <= b.worldY + b.height && y + vspeed >= b.worldY + b.height + vspeed - 1 && jumpstate=="jumping")

再次抵消:

if(y + vspeed <= b.worldY + b.height - 1 && y >= b.worldY + b.height - 1 && jumpstate=="jumping")

4)你需要非常小心,vspeed和jumpstate始终保持同步,因为vspeed的标志需要始终匹配jumpstate,否则你会错过碰撞。我想这可能是你问题的来源。

5)如果速度超过块大小,则在两个方向上,您将跳过碰撞检测并在块中触发。

if(y + height + vspeed >= b.worldY+2 && y + vspeed <= b.worldY+b.height)

如果速度高于b.height且y坐标相似,则这些行中的第二次检查将为false。

希望有所帮助。