2011-07-03 58 views
0

嗯,我有一个二维框冲突代码,基本上循环遍历列表中的每个块名为“块”,它检查我是否靠近两侧和什么。C++ 2D Box-Collision,是吗?

它工作得很好,除了块的底部。当我向底部跳跃时,我希望我的玩家只是“反弹”。它这样做,但它非常糟糕。这很难解释,所以我希望你们可以发现我的底部碰撞代码有什么问题。

这里就是整个事情(这是在一个循环中运行):

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; 
     } 
    } 
    }  
} 
+0

[2D Box Collision - This is right?]的可能重复(http://stackoverflow.com/questions/6561341/2d-box-collision-is-this-right) –

回答

0

我不知道你会得到它像这样工作。我会解释一下我认为的碰撞检测和反弹运行平稳的解决方案。记录上次检查碰撞和调整位置的时间间隔。如果Xplayer+Vplayer*deltaT>Xtarget(如果玩家会重叠目标),那么计算它将触及目标的实际时间deltaTtouch=(Xtarget-Xplayer)/Vplayer。现在将玩家弹回Xplayer=Xtarget-Vplayer*(deltaT-deltaTtouch)。在向前,向后,向上,向下移动时,你必须弄清所有情况。
LE:你也可以实现引力,这包括求解一个二次方程来找出deltaTtouch

0

那么我可以看到几个小细节:

1)在这一行检查老位置时hspeed是相当多余的,最好将其删除的清晰度。

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的小偏移量有点混乱,我认为你试图实现一个小的缓冲区,以便需要少量的重叠。特别是这条线,你已经使用了<的<代替=你使用的每一个东西:

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相匹配,否则您将错过碰撞。我想这可能是你的问题来自哪里。

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

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

如果速度大于b.height更高和y COORDS类似于在这些行中的第二检查将是假的。

希望有助于一些。