如何计算反弹angular度?
我玩了一段时间,但我根本无法弄清楚。
我制造了一个能发射导弹的坦克,当导弹击中墙壁时,我希望它们反弹,但我希望它们反弹到正确的angular度。
现在我没有任何障碍,导弹刚从我做的viewportRectangle
外面反弹viewportRectangle
。
我正在寻找相当先进的解决scheme吗?
有一个相对简单的方法来做到这一点?
我认为更简单的方法是使用导弹的速度而不是计算angular度。 假设你有一个有xVelocity
和yVelocity
的导弹来表示它的水平和垂直运动。 这些速度可以正面或负面代表左,右,上,下。
- 如果导弹击中顶部或底部的边界,则反转
yVelocity
的符号。 - 如果导弹击中左或右边界,则反转
xVelocity
的符号。
这将保持相反轴的运动相同。
从ChrisF的回答中借用图像,假设导弹从位置I开始。
由于xVelocity
和yVelocity
都是正向的(在2Dgraphics中,右侧和下侧通常是正向的),导弹将按照指示的方向行进。 我们只是分配值
xVelocity = 3 yVelocity = 4
当导弹击中C位置的墙壁时,其yVelocity
不应该变化,但其yVelocity
应该反转到-4,使其向上返回,而是继续向右。
这种方法的好处是你只需要跟踪一个导弹的xPosition
, yPosition
, xVelocity
和yVelocity
。 使用这四个组件和您的游戏的更新率,导弹将始终在正确的位置重绘。 一旦进入更加复杂的非直angular或正在移动的障碍物,使用X和Y速度比使用angular度要容易得多。
你可能会认为,因为你的墙与坐标轴alignment,所以写出特殊情况代码是有意义的(对于垂直墙来说,否定速度的x坐标;对于水平墙来说,否定速度的y坐标)。 但是,一旦你的游戏在垂直和水平的墙壁上运行良好,你可能会想到的另一件事情是:“墙angular是什么angular度?” 所以从一开始就值得思考一般情况。
在一般情况下,假设你的导弹的速度为v ,击中了一个表面法线n的墙。
将v分成垂直于墙壁的部件u并平行于墙壁。
哪里:
u =( v · n / n · n ) n
w = v – u
这里, v · n是vectorv和n的点积 。 请参阅链接了解如何计算它。 点乘n · n计algorithm向量长度的平方; 如果你总是以单位向量的forms保持你的法线,那么n · n = 1,你可以省略除法。
在弹跳之后,与墙平行的运动分量受到摩擦力f的影响,垂直于墙的分量受弹性的影响,其可以以恢复系数 r的forms给出。
所以碰撞后的速度是v' = f w – r u 。 在一个完美的弹性,无摩擦的碰撞中, v' = w – u ; 也就是说,这个动作是反映在碰撞点的正常情况,正如在Bill的答案中给出的图表一样。
这种方法在三个方面也是一样的。
(显然这是一个非常简单的弹跳概念,它不考虑angular动量或变形,但是对于多种video游戏来说,这种简化是完全合适的)。
对于完美的粒子(&光),reflectionangular等于入射angular,如此图(来自commons.wikimedia.org)所示。
在Google中search“reflectionangular度”(不带引号)。
考虑到物体的弹性和材质以及障碍物,会稍微复杂一点;)
除了你提到的具体物理问题之外,我还会推荐Wendy Stahler的书“游戏程序员的math和物理开始”。 我发现它对我的游戏/物理编程项目非常有用。
本书附带的代码是C ++,但是如果您了解C#,那么进行转换就相当容易。
祝你有个好的一天!
我遇到过这个问题,唯一的办法就是把碰撞的轴线分开。
尝试一下:
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; }
我希望这可以帮助你!
根本不复杂 – 伪代码:
angleObjectHitWall = a; bounceAngle = 180-a;
当然,这是一个非常简单的计算,一旦你开始考虑材料,重力,不直的墙等因素,这是完全不相关的。
180-a在任何情况下都不起作用,除非在X增加的时候你只是在顶面上反弹。
一个方向是XNA论坛或拿起XNA示例代码。 它是C#,用于构build游戏。 我并不是说你想用XNA构build你的游戏,但它是一个很棒的工具,它是免费的。
这实际上是一个物理问题,所以如果你不是一个物理学家(因为你问这个问题,我会认为你不是),它需要大量的阅读和头脑风暴,才能把它做好。
我build议阅读这个维基百科条目,以获得关于你的问题的深度的基本想法。
如果你只是想让它“看起来似乎合理”,那么我不会太担心它,并使用比尔蜥蜴的答案,但是如果你想要正确的话,你将有一个冒险。 不要让这个吓到你! 祝你好运!
if(!Collide(Missle, Mainchar)){ (Velocity.x)*-1; (Velocity.y)*-1; }
它的工作原理很简单,祝你好运。