我花了一些时间来尝试,但我仍然无法理解。
我制作了一个可以发射导弹的坦克,当导弹击中墙壁时,我想让它们弹开,但我希望它们能够弹到正确的角度。
目前我还没有遇到任何障碍,当导弹超出我创建的viewportRectangle
视口矩形时,它们就会弹回。
我正在寻找的解决方案是否相当高级?
有没有相对简单的方法可以实现?
在此处:
u = (v · n / n · n) n
w = v − u
这里,v · n 是向量 v 和 n 的点积。请参见链接以了解如何计算它。点积 n · n 评估法线向量长度的平方; 如果您始终保持法线向量为单位向量形式,则 n · n = 1,您可以省略除法。
弹跳后,平行于墙壁运动的分量受到摩擦力 f 的影响,垂直于墙壁的分量受到弹性的影响,可以用恢复系数r来表示。
所以碰撞后的速度为v' = fw - ru。在完全弹性、无摩擦的碰撞中,v' = w - u;也就是说,在碰撞点处,运动沿法线反射,就像Bill的答案中给出的图示一样。这种方法在三维中同样适用。xVelocity
和 yVelocity
以表示它的水平和垂直运动。这些速度可以是正数或负数,以表示向左、向右、向上或向下。
yVelocity
的符号。xVelocity
的符号。xVelocity
和 yVelocity
均为正数时(在2D图形中右和下通常为正数),导弹将沿所示方向移动。让我们假定赋值为:xVelocity = 3
yVelocity = 4
当导弹击中位置为C的墙壁时,它的xVelocity
不应该改变,但是它的yVelocity
应该被反转为-4,这样它就会向上方反弹,但仍然朝右移动。
使用这种方法的好处是,您只需要跟踪导弹的xPosition
、yPosition
、xVelocity
和yVelocity
。使用这四个组件和游戏的更新速率,导弹将始终以正确的位置重绘。一旦涉及到不在直角或移动的更复杂的障碍物,使用X和Y速度比使用角度更容易处理。
我曾经遇到过这个问题,唯一的解决方法是分离碰撞轴!
试一下:
x += velocity * Math.cos(angle * Math.PI /180);
y += velocity * Math.sin(angle * Math.PI /180);
if (x < 0 || x > canvas.width) {
angle = 180 - angle;
}
else if (y < 0 ||y > canvas.height) {
angle = 360 - angle;
}
对于完美的粒子(和光),反射角等于入射角,如这个图示所示(来自commons.wikimedia.org)。
反射的维基百科页面 很好地解释了它的工作原理。
当考虑到物体和障碍物的弹性和材料时,这会变得有点复杂,但对于大多数应用程序来说,这可能已经足够了。
180-a并非在所有情况下都有效,除非您只是在顶部表面上弹跳时X增加。
一个方向是前往XNA论坛或获取XNA示例代码。它是用于构建游戏的C#。我并不是说您想在XNA中构建游戏,但它是一个很好的工具,而且是免费的。
a = 2w - b
其中:
a => 结果角度
w => 墙壁或地板或天花板的角度
b => 球的角度
这是我尝试寻找最简单的公式来计算球在墙壁、天花板和地板上反弹后的结果角度。结果可能超过+360度或-360度,但它们仍然是等效的角度。
例如,如果天花板角度为270度,球的角度为30度,则结果角度为510度,相当于+150度或-210度。如果您将天花板角度改为90度而不是270度,则结果仍为150度。
非常简单 - 伪代码:
angleObjectHitWall = a;
bounceAngle = 180-a;
当然,这只是一个非常简单的计算,一旦考虑到诸如材料、重力、不直的墙壁等因素,它就完全不相关了...
这实际上是一个物理问题,所以如果你不是物理学家(而且由于你提出了这个问题,我会认为你不是),需要大量阅读和头脑风暴才能得到正确的答案。
我建议阅读this维基百科条目,以了解你的问题的深度。
如果你只想让它“看起来可信”,那么我不会太担心它,可以使用Bill the Lizard的答案,但是如果你想做对,你将会有一次相当的冒险。不要被吓到!祝你好运!
if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}
它能够正常工作且简单易用,祝你好运。