我玩了一会儿,但我简直无法理解.
我制造了一个发射导弹的坦克,当导弹击中墙壁时,我希望它们反弹,但我希望它们能够以正确的角度反弹.
现在我没有任何障碍,当导弹越过viewportRectangle
我制造的时候导弹就会反弹.
我正在寻找的解决方案是否相当先进?
有相对简单的方法吗?
您可能会认为,因为您的墙与坐标轴对齐,因此编写特殊情况代码是有意义的(对于垂直墙,否定速度的x坐标;对于水平墙,否定速度的y坐标) ).然而,一旦你让游戏在垂直和水平墙壁上运行良好,你可能接下来会想到的是,"任意角度的墙壁怎么样?" 所以从一开始就值得考虑一般情况.
在一般情况下,假设您的导弹具有速度v并且击中具有表面法线n的墙壁.
分裂v成成分ù垂直于壁和瓦特平行.
哪里:
u =(v · n/n · n)n
w = v - u
这里,v · n是向量v和n的点积.请参阅链接以获取有关如何计算它的说明.点积n · n评估法向量长度的平方; 如果你总是以单位向量的形式保持法线,则n · n = 1,你可以省略除法.
在弹跳之后,平行于壁的运动分量受到摩擦力f的影响,并且垂直于壁的分量受到弹性的影响,弹性可以以恢复系数 r的形式给出.
所以碰撞后的速度是v' = f w - r u.在一个完全弹性,无摩擦的碰撞中,v' = w - u ; 也就是说,运动反映在碰撞点的法线上,如比尔答案中给出的图表所示.
这种方法在三个维度上的工作方式也相同.
(显然这是一个非常简化的弹跳概念;它不考虑角动量或变形.但对于许多种类的视频游戏来说,这种简化是完全足够的.)
我认为更简单的方法是使用导弹的速度而不是计算角度.假设你的导弹具有xVelocity
并且yVelocity
可以水平和垂直地表示其运动.这些速度可以是正的或负的,以表示左,右,上或下.
如果导弹击中顶部或底部边界反转的标志yVelocity
.
如果导弹击中左侧或右侧边界,则反转该标志xVelocity
.
这将使相反轴的运动保持不变.
从ChrisF的回答中借用图像,让我们说导弹从位置I开始.
与xVelocity
和yVelocity
两者均为正(在2D图形向右和向下通常为正)的导弹将在所指示的方向行进.让我们只分配值
xVelocity = 3 yVelocity = 4
当导弹击中位置C处的墙壁时,它xVelocity
不应该改变,但是它yVelocity
应该反转到-4,以便它向上行进,但是向右移动.
这种方法的好处是,你只需要跟踪导弹的的xPosition
,yPosition
,xVelocity
,和yVelocity
.仅使用这四个组件和游戏的更新速率,导弹将始终重新绘制在正确的位置.一旦你进入更加复杂的障碍物,这些障碍物不是直角或正在移动,使用X和Y速度比使用角度更容易.
对于完美的粒子(和光),反射角等于入射角,如该图所示(来自commons.wikimedia.org).
在Google中搜索"反射角度"(不带引号).
当你考虑到物体的弹性和材料以及障碍物时,它会有点复杂;)
我遇到了这个问题,我发现的唯一方法是分离碰撞轴!
试试吧:
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; }
我希望这可以帮助你!
除了您要问的特定物理问题外,我还会推荐Wendy Stahler撰写的"为游戏程序员开始数学和物理"一书.我发现它对我的游戏/物理编程项目非常有用.
本书附带的代码是C++,但如果您了解C#,那么进行转换将非常容易.
祝你有个好的一天!