如何检测碰撞的一面?

时间:2014-02-16 20:19:28

标签: java libgdx

我正在尝试重拍突破,我的球偶尔会完全跳过牌,或者不正确地反弹。我想我发现问题在于我的代码检测球是从顶部,底部还是侧面来的,并没有考虑到球的“阶梯”大小可以使其落在一个内部的事实。瓦。我试过的唯一能阻止这些错误发生的事情就是减小步长,但这会让球的移动速度比我想要的要慢。那么,我怎样才能保持球的速度不变,同时仍能准确地检测出哪一侧碰撞?

Vector2 ballCenter = new Vector2();
                Vector2 tileCenter = new Vector2();
                ballCenter = ball.getHitbox().getCenter(ballCenter);
                tileCenter = tiles.get(i-1).getHitbox().getCenter(tileCenter);



                if(ballCenter.y-ball.sprite.getHeight()/2>tileCenter.y){
                    ball.velocity.y = Math.max((-1*ball.velocity.y)+2,10);
                }
                else if(ballCenter.y+ball.sprite.getHeight()/2<tileCenter.y){
                    ball.velocity.y = Math.max((-1*ball.velocity.y)-1,-10);
                }
                else
                    ball.velocity.x *=-1;

1 个答案:

答案 0 :(得分:0)

通过它的外观,您的代码会检测球在步骤发生时当前是否与磁贴碰撞。问题在于,除非你有非常小的步长,否则恰好在恰当的时间与步骤重合的碰撞发生的可能性是最小的。由于您在步骤之间发生碰撞,因此您可以通过磁贴跳过磁贴并完全忽略它们。

解决此问题的一个方法是更改​​进行碰撞检测的方式。此时,您需要检查球是否在当前步骤与之前步骤之间的任何时间点击中了磁贴,而不是检查球是否在此时击中了磁贴。

由于你同时拥有球的位置和速度,并且我假设是静态牌,你可以将其建模为找到从球的旧位置到球的新位置的线的交点(旧位置) +速度假设没有碰撞)。

然后,如果存在交叉点(碰撞),您可以采用更复杂的处理。

因此,伪代码看起来像这样:

// use some basic geometry to find intersections between the ball's motion vector 
// and the tiles bounding square
if (isCollision(ball, tile)) 
{
   // If there is a collision then find out how far through the step it occurred
   // i.e.: 0 = start, 1 = end, 0.5 = half way through
   collision_time = findCollisionTime(ball, tile); 

   //process the part of the step before the collision
   ball.x = ball.x + (ball.velocity.x * collision_time);
   ball.y = ball.y + (ball.velocity.y * collision_time);
   //or however you want to do it.

   //update the velocity to for the collision
   ball.velocity.x = ...
   ball.velocity.y = ...

   //process the part of the step after the collision
   ball.x = ball.x + (ball.velocity.x * (1-collision_time));
   ball.y = ball.y + (ball.velocity.y * (1-collision_time));
}

注意:我上面展示的方法假设只有球移动,并且它不会在一个步骤中与多个瓦片碰撞。应该很容易通过一些自适应和一个while循环允许多次碰撞。允许非静态碰撞需要更多思考。

或者,您可以查看物理引擎来为您完成所有这些操作。