2

我创建了一个碰撞类来使用像素检测碰撞。在我的课堂上,我还开发了一些用于确定碰撞角度的函数。基于此,我创建了一些示例:

http://megaswf.com/serve/25437/

http://megaswf.com/serve/25436/

(改变重力的空间,右/左给球一些速度。)

您可能会注意到,会发生一些奇怪的事情:

  • 当球速很低时
  • 当球的方向几乎与障碍物相切时。

碰撞 http://img514.imageshack.us/img514/4059/colisao.png

上图显示了我如何计算碰撞角度。我称红点为关键点。我搜索最大数量的关键点(通常为 4 个)。如果我发现超过 2 个关键点,我选择最远的 2 个(如蓝色对象之一所示)。这就是我如何找到物体碰撞表面位置的法线角度。我不知道这是否是一种过时的做事方式。

基于该角度,我旋转速度矢量来进行弹跳。

进行数学运算的代码如下:

static public function newSpeedVector(speedX: Number, speedY: Number, normalAngle: Number): Object{
            var vector_angle: Number = Math.atan2(speedY, speedX) * (180/Math.PI);
            var rotating_angle: Number = (2*(normalAngle - vector_angle) + 180) % 360;
            var cos_ang: Number = Math.cos(rotating_angle/DEGREES_OF_1RAD);
            var sin_ang: Number = Math.sin(rotating_angle/DEGREES_OF_1RAD);
            var final_speedX: Number = speedX * cos_ang - speedY * sin_ang;
            var final_speedY: Number = speedX * sin_ang + speedY * cos_ang;

            return {x_speed: final_speedX, y_speed: final_speedY};
        }

这就是计算新速度矢量的方式......

我的问题是,有没有人遇到过这种问题,或者对如何避免这种情况有一些想法?

4

3 回答 3

3

在没有看到您的代码的情况下,这是我能提供的最好的。

碰撞物理应该有一些被认为是“停止”的速度阈值。也就是说,一旦速度变得足够小,您应该明确地将对象标记为停止并将其从碰撞代码中排除。这将有助于稳定缓慢移动的物体。良好的阈值需要反复试验。

当发生碰撞时,重要的是至少尝试纠正任何相互渗透。这很可能是切线碰撞行为异常的原因。尝试以合理的方式将碰撞的物体从它撞击的物体上移开。

您确定正常值的方法应该可以正常工作。游戏物理就是作弊(以一种看起来还不错的方式作弊)。我认为旋转和摩擦不是你想要的一部分吗?

试试这个。你有正常的联系。当您检测到碰撞时,计算穿透深度并沿着法线移动您的对象,这样就不再穿透了。您可以使用您已经计算的两个点来获得一个穿透点,但您需要计算另一个。对于圆很容易(中心点+法线方向的半径)。有更复杂的方法可以解决这个问题,但看看简单的方法是否适合你。

我已阅读并推荐这本书: 游戏物理引擎开发

于 2010-07-15T23:15:54.550 回答
1

我做了一些类似的事情并遇到了类似的问题。我所做的是,当弹跳物体(在您的情况下为球)的像素与障碍物的像素重叠时,您需要将球移出障碍物,以免它们重叠。

假设球在障碍物上滚动,在再次渲染球之前,您需要将球向后移动“重叠”的量。如果您知道球以什么角度撞击障碍物,只需将其沿该角度移出即可。

您还需要添加一些阻尼,否则球将永远不会停止。取一个(非常)小的值,如果球速度低于该值,则将速度设置为 0。

于 2010-07-15T23:27:13.083 回答
0

你可以再尝试一件事,我认为这是非常有效的。

您可以在游戏对象中创建诸如 getNextX() 和 getNextY() 之类的函数(这当然会在下次更新后协调它们的位置),并根据对象的下一个位置而不是当前位置检查对象的碰撞。

这样,对象将永远不会重叠,您将知道它们何时将发生碰撞并优雅地应用您的碰撞后物理!

于 2016-08-05T12:58:45.313 回答