C++ 2D Box-Collision,是吗?
嗯,我有一个二维框冲突代码,基本上循环遍历列表中的每个块名为“块”,它检查我是否靠近两侧和什么。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;
}
}
}
}
我不知道你会得到它像这样工作。我会解释一下我认为的碰撞检测和反弹运行平稳的解决方案。记录上次检查碰撞和调整位置的时间间隔。如果Xplayer+Vplayer*deltaT>Xtarget
(如果玩家会重叠目标),那么计算它将触及目标的实际时间deltaTtouch=(Xtarget-Xplayer)/Vplayer
。现在将玩家弹回Xplayer=Xtarget-Vplayer*(deltaT-deltaTtouch)
。在向前,向后,向上,向下移动时,你必须弄清所有情况。
LE:你也可以实现引力,这包括求解一个二次方程来找出deltaTtouch
。
那么我可以看到几个小细节:
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类似于在这些行中的第二检查将是假的。
希望有助于一些。
[2D Box Collision - This is right?]的可能重复(http://stackoverflow.com/questions/6561341/2d-box-collision-is-this-right) –