木匣子

Web/Game/Programming/Life etc.

使用欧拉方法模拟的物理运动

在游戏中模拟物理运动的方法有很多,很多游戏开发的书籍都会引用物理课本上介绍的牛顿运动方程。并给游戏中的物体定义位置(s)、速度(v)、加速度(a)、质量(m)以及所受到的力(F)。

以2D游戏为例,给一个对象设置初始位置 \(s:=(x_0, y_0)\)(:=为赋值符号,下同),然后计算施加在对象上的作用力 F,并使用以下公式来更新经过一段时间 t 后各个物理量的值:

加速度

$$ \left\{\begin{matrix} a_x:=F_x/m \\ a_y:=F_y/m \end{matrix}\right. $$

速度

$$ \left\{\begin{matrix} v_x:=v_x+a_xt \\ v_y:=v_y+a_yt \end{matrix}\right. $$

位移

$$ \left\{\begin{matrix} s_x:=s_x+v_xt\ s_y:=s_y+v_yt \end{matrix}\right. $$

以上过程不断循环,使得物体的位置不断变化,这就是所谓的欧拉方法

在数学和计算机科学中,欧拉方法,命名自它的发明者莱昂哈德·欧拉,是一种一阶数值方法,用以对给定初值的常微分方程(即初值问题)求解。它是一种解决数值常微分方程的最基本的一类显型方法(Explicit method)。

因为对于物体的位移来说,初值就是当前位置,而位称关于时间的常微分方程就是速度。于是在很短的时间内(通常是 1/FPS 秒,FPS为游戏的帧速,以60为佳),我们可以用速度乘以时间累加到当前位置上得到新的位置。同理速度的微分又是加速度,可以用加速度更新当前速度。这样只要求出作用力,得到加速度,更新速度,更新位移,就得到了新的位置。

这里有一个使用欧拉方法模拟粒子运动的演示:Move with the vector

局限

欧拉方法并非是一种精确的物理模拟方法,它的精度取决于步长,也就是游戏里两帧之间的时间间隔,如果时间越短,欧拉方法工作得越好。在 FPS=60 的游戏中已经足够来模拟大多物理效果了。如果需要精度更高的物理模拟,试试龙格-库塔方法吧,不过这不在我们的讨论范围之内。这个方法需要更多的计算量,但请相信我,玩家根本看不出两者之间的区别。事实上大多游戏都使用 s-v 欧拉方法来移动物体

此外,欧拉方法常常把一个物体看作一个质点,作用力施加在其质心上,整体一起移动。使用欧拉方法制作的游戏,碰撞检测通常是基于矩形或圆形的。这使得模拟复杂的刚体运动变得十分困难;

更多

即使有一些局限,很多游戏还是用欧拉方法做出一非常赞的物理效果。如果想更详细学习欧拉方法,推荐阅读一下 Keith Peters 的 Foundation ActionScript 3 Animation: Making Things Move! (中文书名《Flash ActionScript 3.0 动画教程》,这么好的一本书被这译名弄得掉价好多,Orz)的第二部分:基本运动。这本书虽然是基于 ActionScript 的,但是里面的思想是普适的,实际上我把里面的所有例子用 Processing 重写过,运行得非常好。


在游戏中常用的另一种方法,叫韦尔莱积分法,我会在另一篇日志介绍。