如何计算弹跳角度?

时间:2009-02-21 14:11:37

标签: c# xna physics

我玩了一会儿,但我根本想不出来。

我制造了一个发射导弹的坦克,当导弹击中墙壁时,我希望它们反弹,但我希望它们能够以正确的角度反弹。

现在我没有任何障碍,当导弹越过viewportRectangle之外时导弹就会反弹。

我正在寻找的解决方案是否相当先进?

有相对简单的方法吗?

10 个答案:

答案 0 :(得分:185)

您可能会认为,因为您的墙与坐标轴对齐,因此编写特殊情况代码是有意义的(对于垂直墙,否定速度的x坐标;对于水平墙,否定y坐标的速度)。然而,一旦你让游戏在垂直和水平墙壁上运行良好,你可能接下来会想到的是,“任意角度的墙壁怎么样?”因此,从一开始就值得考虑一般情况。

在一般情况下,假设你的导弹的速度 v 并击中表面法线 n 的墙壁。

Missile with vector v about to obliquely hit a wall with surface normal n.

v 拆分为垂直于墙的 u 组件,并与 w 平行。

Right-angled triangle with hypotenuse for v, short side u parallel to wall and long side w parallel to wall.

其中:

=( v · n / n · n )< strong> n
w = v -

此处, v · n 是向量 v n dot product。请参阅链接以获取有关如何计算它的说明。点积 n · n 计算法线向量长度的平方;如果你总是以unit vectors然后 n · n = 1的形式保持你的法线,你就可以省略除法。

弹跳后,平行于墙壁的运动分量受到摩擦 f 的影响,垂直于墙壁的分量受弹性影响,弹性可以{{{ 3}} r

因此碰撞后的速度 v' = f w - r u < / strong>即可。在一个完全弹性,无摩擦的碰撞中, v' = w - u ;也就是说,运动反映在碰撞点的法线上,如比尔答案中给出的图表。

这种方法在三个维度上也是一样的。

(显然这是一个非常简化的弹跳概念;它不考虑角动量或变形。但对于许多种类的视频游戏来说,这种简化是完全足够的。)

答案 1 :(得分:66)

我认为更简单的方法是使用导弹的速度而不是计算角度。假设你的导弹有xVelocityyVelocity水平和垂直表示它的运动。这些速度可以是正的,也可以是负的,表示左,右,上或下。

  • 如果导弹击中顶部或底部边界,则反转yVelocity
  • 的符号
  • 如果导弹击中左侧或右侧边界,则反转xVelocity
  • 的标志

这将使相反轴的运动保持不变。

借用ChrisF's answer的图像,假设导弹从位置I开始。

Angle of Reflection

xVelocityyVelocity均为正(在2D图形中右下方通常为正),导弹将沿指示的方向行进。我们只需指定

的值
xVelocity = 3
yVelocity = 4

当导弹在 C 位置撞击墙壁时,其xVelocity不应改变,但其yVelocity应该反转为-4,以便它返回到向上的方向,但一直向右。

这种方法的好处是你只需要跟踪导弹的xPositionyPositionxVelocityyVelocity。仅使用这四个组件和游戏的更新速率,导弹将始终重新绘制在正确的位置。一旦你遇到更加复杂的障碍物,这些障碍物不是直角或正在移动,使用X和Y速度比使用角度更容易。

答案 2 :(得分:9)

对于完美的粒子(和光),反射角等于入射角,如此图所示(来自commons.wikimedia.org)。

Angle of Reflection

在Google中搜索“反射角度”(不带引号)。

当你考虑物体的弹性和材料以及障碍物时会有点复杂;)

答案 3 :(得分:6)

我遇到了这个问题,我找到的唯一方法是分离碰撞轴!

试一试:

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; 
}

我希望这可以帮到你!

答案 4 :(得分:5)

除了您要问的特定物理问题外,我还会推荐Wendy Stahler撰写的“为游戏程序员开始数学和物理”一书。我发现它对我的游戏/物理编程项目非常有用。

本书附带的代码是C ++,但如果您了解C#,那么进行转换将非常容易。

有一个好的!

答案 5 :(得分:3)

根本不复杂 - 伪代码:

angleObjectHitWall = a;
bounceAngle = 180-a;

当然这是一个非常简单的计算,一旦你开始考虑材料,重力,不直的墙等因素,它们就完全无关了......

答案 6 :(得分:3)

180-a在所有情况下都不起作用,除非你只是在X增加时在顶部表面上反弹。

一个方向是XNA论坛或拿起XNA示例代码。它是C#,用于构建游戏。我并不是说你想在XNA中构建你的游戏,但它是一个很棒的工具,它是免费的。

答案 7 :(得分:0)

这实际上是一个物理问题,所以如果你不是一个物理学家(因为你问的是这个问题,我会认为你不是这个问题)它需要大量的阅读和头脑风暴来获得它对。

我建议您阅读this维基百科条目,以获得有关问题深度的基本概念。

如果你只是想让它“看起来似乎有道理”,那么我就不会太担心它并使用比尔蜥蜴的答案,但是如果你想要做对,你会有相当的冒险不要让这吓到你!祝你好运!

答案 8 :(得分:0)

a = 2w - b

其中:
a =>结果角度
w =>墙壁或地板或天花板的角度
b =>球角

这是我试图找到最简单的公式来计算仅球在墙壁,天花板和地板上弹起的角度后得出的结果。结果可能会超出+360或-360度,但它们仍是等效角度。

例如,如果顶角为270deg且球角度为30deg,则所得角度为510deg,相当于+150度或-210度如果将90deg用作天花板而不是270deg,则结果仍然是150deg。

答案 9 :(得分:-4)

if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}

它有效且简单,祝你好运。