【发布时间】:2010-10-09 01:18:56
【问题描述】:
我玩了一段时间,但我就是想不通。
我做了一个可以发射导弹的坦克,当导弹击中墙壁时,我希望它们反弹,但我希望它们反弹到正确的角度。
现在我没有任何障碍物,导弹只是在我制造的viewportRectangle之外弹开。
我正在寻找的解决方案是否相当先进?
有没有相对简单的方法?
【问题讨论】:
-
这是一个问题,如果你去打台球,这个问题的解决方案可能会立即变得显而易见。
我玩了一段时间,但我就是想不通。
我做了一个可以发射导弹的坦克,当导弹击中墙壁时,我希望它们反弹,但我希望它们反弹到正确的角度。
现在我没有任何障碍物,导弹只是在我制造的viewportRectangle之外弹开。
我正在寻找的解决方案是否相当先进?
有没有相对简单的方法?
【问题讨论】:
对于完美粒子(和光),反射角等于入射角,如下图所示(来自 commons.wikimedia.org)。
Wikipedia page on reflection 非常擅长解释其工作原理。
如果考虑到物体的弹性和材料以及障碍物,情况会稍微复杂一些,但这对于大多数应用程序来说可能已经足够了。
【讨论】:
a = 2w - b
其中:
a => 结果角度
w => 墙壁或地板或天花板角度
b => 球角度
这是我在尝试找到最简单的公式来计算球在墙壁、天花板和地板上反弹的角度后得出的结论。结果可能超出 +360 或 -360 度,但它们仍然是等效角度。
例如,如果天花板角度为 270 度,球角度为 30 度,则结果角度为 510 度,相当于 +150 度或 -210 度。如果天花板使用 90 度而不是 270 度,结果仍然是 150 度。
【讨论】:
if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}
它很有效,很简单,祝你好运。
【讨论】:
我遇到过这个问题,我发现的唯一方法就是分离碰撞轴!
试试看:
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;
}
希望对你有帮助!
【讨论】:
您可能会认为,由于您的墙壁与坐标轴对齐,因此编写特殊情况代码是有意义的(对于垂直墙壁,否定速度的 x 坐标;对于水平墙壁,否定 y 坐标的速度)。然而,一旦你让游戏在垂直和水平墙壁上运行良好,你可能会想到的下一个问题是,“任意角度的墙壁怎么样?”所以从一开始就值得考虑一般情况。
在一般情况下,假设您的导弹速度为 v,并以表面法线 n 击中墙壁。
将v分割成垂直于墙壁的u和平行于墙壁的w分量。
地点:
u = (v · n / n · n) n
w = v - u
这里,v · n 是向量 v 和 n 的dot product。有关如何计算它的说明,请参阅链接。点积 n · n 求值为法向量长度的平方;如果您始终以unit vectors 的形式保留法线,则 n · n = 1,您可以省略除法。
弹起后,平行于壁的运动分量受摩擦影响f,垂直于壁的分量受弹性影响,可以以@987654323的形式给出@r.
所以碰撞后的速度是v′ = f w - r u。在完全弹性、无摩擦的碰撞中,v′ = w - u;也就是说,运动反映在碰撞点的法线附近,如比尔回答中给出的图表所示。
这种方法在三个维度上也同样有效。
(显然这是一个非常简化的弹跳概念;它没有考虑角动量或变形。但对于许多类型的视频游戏来说,这种简化是完全足够的。)
【讨论】:
ux = (dotproduct(v,n)) * n、uy、wx 和 wy。
我认为更简单的方法是使用导弹的速度而不是计算角度。假设你有一个导弹,它有xVelocity 和yVelocity 来表示它的水平和垂直运动。这些速度可以是正数或负数,以表示左、右、上或下。
yVelocity 的符号。xVelocity 的符号。这将使相反轴的运动保持不变。
借用ChrisF's answer的图片,假设导弹从位置I开始。
xVelocity 和 yVelocity 都为正值(在 2D 图形中,右下方通常为正值),导弹将沿指示的方向行进。让我们分配值
xVelocity = 3
yVelocity = 4
当导弹在位置C击中墙壁时,它的xVelocity 不应该改变,但它的yVelocity 应该被反转为-4,以便它朝上方向返回,但一直向右。
这种方法的好处是您只需要跟踪导弹的xPosition、yPosition、xVelocity 和yVelocity。仅使用这四个组件和游戏的更新率,导弹总是会在正确的位置重新绘制。一旦遇到更复杂的障碍物(不是直角或移动),使用 X 和 Y 速度比使用角度要容易得多。
【讨论】:
除了您所问的具体物理问题之外,我推荐 Wendy Stahler 的《游戏程序员的数学和物理入门》一书。我发现它对我的游戏/物理编程项目非常有用。
本书随附的代码是 C++,但如果您了解 C#,则很容易进行转换。
祝你好运!
【讨论】:
这确实是一个物理问题,所以如果你不是物理学家(既然你问这个问题,我会认为你不是)它需要大量阅读和头脑风暴才能得到它正确的。
我建议阅读this 维基百科条目以了解有关您问题深度的基本概念。
如果你只是想让它“看起来合理”,那么我不会太担心它并使用 Bill the Lizard 的答案,但是如果你想让它正确,你将拥有相当一次冒险。不要让这吓到你!祝你好运!
【讨论】:
180-a 并非在所有情况下都有效,除非您只是在 X 增加时在顶面上进行反弹。
一个方向是 XNA 论坛或获取 XNA 示例代码。它是 C#,用于构建游戏。我并不是说你想在 XNA 中构建你的游戏,但它是一个很棒的工具,而且它是免费的。
【讨论】:
一点也不复杂——伪代码:
angleObjectHitWall = a;
bounceAngle = 180-a;
当然,这是一个非常简单的计算,一旦你开始考虑材料、重力、不直的墙壁等因素,就完全无关紧要了......
【讨论】: