66

我玩了一段时间,但我根本无法弄清楚。

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

现在我没有任何障碍物,导弹在viewportRectangle我制造的外面时会反弹。

我正在寻找的解决方案是否非常先进?

有没有相对简单的方法来做到这一点?

4

10 回答 10

199
于 2009-02-21T15:17:49.797 回答
70

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

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

这将保持相反轴上的运动相同。

借用ChrisF 的回答中的图像,假设导弹从位置 I 开始。

反射角

和都为正(在二维图形中xVelocityyVelocity右和下通常为正),导弹将沿指示的方向行进。让我们分配值

xVelocity = 3
yVelocity = 4

当导弹在位置C撞到墙上时,它xVelocity不应该改变,但它yVelocity应该被反转到 -4 以便它在向上的方向上返回,但继续向右移动。

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

于 2009-02-21T14:25:09.813 回答
8

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

反射角

关于反射的维基百科页面非常擅长解释它是如何工作的。

当您考虑到物体的弹性和材料以及障碍物时,它会稍微复杂一些,但这对于大多数应用程序来说可能已经足够了。

于 2009-02-21T14:18:12.637 回答
6

除了您要问的具体物理问题,我会推荐 Wendy Stahler 的《游戏程序员的数学和物理入门》一书。我发现它对我的游戏/物理编程项目非常有用。

本书随附的代码是 C++,但如果您了解 C#,则很容易进行转换。

祝你有个好的一天!

于 2009-02-21T15:51:55.080 回答
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; 
}

我希望这可以帮助你!

于 2015-06-18T01:43:51.707 回答
4

180-a 并非在所有情况下都有效,除非您只是在 X 增加时在顶部表面上进行反弹。

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

于 2009-02-21T14:27:37.687 回答
2

一点也不复杂——伪代码:

angleObjectHitWall = a;
bounceAngle = 180-a;

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

于 2009-02-21T14:14:08.827 回答
0

这确实是一个物理问题,所以如果你不是物理学家(既然你问这个问题,我会认为你不是)它需要大量的阅读和头脑风暴才能得到正确的答案。

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

如果您只想让它“看起来合理”,那么我不会太担心它并使用蜥蜴比尔的答案,但是如果您想让它正确,您将有相当大的冒险。不要让这吓到你!祝你好运!

于 2009-02-21T14:45:10.687 回答
0

a = 2w - b

其中:
a => 合成角度
w => 墙壁或地板或天花板角度
b => 球角度

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

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

于 2020-10-19T04:37:00.420 回答
-5
if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}

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

于 2015-07-08T21:18:23.323 回答