我玩了一会儿,但我根本想不出来。
我制造了一个发射导弹的坦克,当导弹击中墙壁时,我希望它们反弹,但我希望它们能够以正确的角度反弹。现在我没有任何障碍,当导弹越过viewportRectangle
之外时导弹就会反弹。
我正在寻找的解决方案是否相当先进?
有相对简单的方法吗?
答案 0 :(得分:185)
您可能会认为,因为您的墙与坐标轴对齐,因此编写特殊情况代码是有意义的(对于垂直墙,否定速度的x坐标;对于水平墙,否定y坐标的速度)。然而,一旦你让游戏在垂直和水平墙壁上运行良好,你可能接下来会想到的是,“任意角度的墙壁怎么样?”因此,从一开始就值得考虑一般情况。
在一般情况下,假设你的导弹的速度 v 并击中表面法线 n 的墙壁。
将 v 拆分为垂直于墙的 u 组件,并与 w 平行。
其中:
你 =( 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)
我认为更简单的方法是使用导弹的速度而不是计算角度。假设你的导弹有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速度比使用角度更容易。
答案 2 :(得分:9)
对于完美的粒子(和光),反射角等于入射角,如此图所示(来自commons.wikimedia.org)。
在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;
}
它有效且简单,祝你好运。