我创建了一个碰撞类来检测使用像素的碰撞。在我的课堂上,我还开发了一些用于确定collsion角度的函数。基于此,我创建了一些例子:
http://megaswf.com/serve/25437/
http://megaswf.com/serve/25436/
(改变重力的空间,左/右以给予球速一些速度。)
你可能会注意到,有些奇怪的事情会发生:
collision 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};
}
这是计算新速度矢量的方法......
我的问题是,有没有人遇到过这种问题或对如何避免这种情况有所了解?
答案 0 :(得分:3)
如果没有看到您的代码,这是我能提供的最佳代码。
碰撞物理应该有一些被认为是“停止”的速度阈值。也就是说,一旦速度变得足够小,您应该明确地将对象标记为已停止并将其从碰撞代码中豁免。这有助于稳定缓慢移动的物体。良好的阈值需要试错。
当碰撞发生时,至少要尝试纠正任何相互渗透是很重要的。这很可能是切线碰撞表现奇怪的原因。尝试以合理的方式移动碰撞对象远离碰撞对象。
您确定正常的方法应该可以正常工作。游戏物理学就是在欺骗(以一种看起来仍然很好的方式作弊)。我认为轮换和摩擦不是你想要的一部分吗?
试试这个。你的联系方式正常。当您检测到碰撞时,计算穿透深度并沿着法线移动物体,使其不再穿透。您可以使用已计算的两个点来获得一个穿透点,但您需要计算另一个点。对于圆圈来说,它很容易(中心点+正常方向的半径)。有更复杂的方法可以解决这个问题,但看看简单的方法是否适合你。
我已阅读并推荐此书:Game Physics Engine Development
答案 1 :(得分:1)
我做了一些类似的事情并遇到了类似的问题。 我所做的是当弹跳物体(你的情况下是一个球)的像素与障碍物的像素重叠时,你需要将球移出障碍物,使它们不重叠。
假设球在障碍物上滚动,在再次渲染球之前,您需要将球移回“重叠”的数量。如果你知道球撞到障碍物的角度,只需沿着那个角度向外移动。
你还需要增加一些阻尼,否则球永远不会停止。取一个(非常)小的值,如果球速度低于该值,则将速度设置为0。
答案 2 :(得分:0)
你可以尝试一件我觉得非常有效的事情。
您可以在游戏对象中创建诸如getNextX()和getNextY()(当然在下次更新后协调其位置)等功能,并根据对象的下一个位置而不是当前位置检查对象的碰撞。
这样,物体永远不会重叠,你会知道它们何时发生碰撞并优雅地应用你的碰撞物理学!