我试图让一个敌人角色射击子弹然后下一个子弹顺时针旋转40度并以相同的速度射击,但出于某种原因,在更高的帧速率下它不会来实际上,对称的是帧越高,它就越不对称。我的代码看起来像这样。当它准备开火时,它会这样做
if self.kind == "RapidSpinner":
self.attackY = math.cos(self.angle) * 150
self.attackX = math.sin(self.angle) * 150
self.angle -= math.pi / 9
其中" RapidSpinner"指的是敌人的类型,self.angle是为下次调用而改变的,自我。攻击X和Y指的是子弹的运动,自我。攻击X和Y转换为一般自我。然后dx然后是子弹运动是这样定义的。
self.rect.y += self.dy * dt
self.rect.x += self.dx * dt
和dt定义如下
dt = clock.tick(30)
dt = dt/1000.
我的代码出现了什么问题?这些奇怪的模式是以高帧率制作而不是完美的螺旋?高,我的意思是超过15看起来很奇怪,即使在15,它也不完美。
答案 0 :(得分:0)
self.angle
每帧更改固定数量,不依赖于每秒的帧数:
self.angle -= math.pi / 9
但dt
(因此dx
和dy
)每秒更改固定金额:
dt = clock.tick(30)
dt = dt/1000.
如果您的帧速率恰好是30fps,完美到纳秒,这将没有任何区别,您将获得完美的数字化螺旋。*
但是如果你的帧速率变化,即使它的频率接近平均30fps,你也会在某些角度移动比其他角度更长的段,这会给你一个奇怪的,不完美的螺旋。 / p>
例如,假设你旋转π/ 9然后移动35个单位,然后旋转π/ 9并移动31个单位,然后旋转π/ 9并移动34个单位等等。这看起来不像移动33.3每次+单位。帧率越高,你得到的变化就越大。
即使变化较小,**也可以看到左侧螺旋已经突变:
要解决此问题,您可以:
dt = 1/30.
代替dt = clock.tick(30)/1000
,每个刻度线只需1 / fps。angle
结果的clock.tick
更新,使用每个刻度的实际值,与dt
的方式相同。前者有点简单,但是如果计算机无法跟上所需的帧速率(或者说,如果计算机进入睡眠状态而不暂停游戏)。第一个解决方案意味着随着游戏的滞后,一切都会变慢;第二个意味着一切都将继续全速运行,但会让用户看起来像“传送”一样。
*当然,这与实际的完美螺旋不同,但我假设你已经知道了。
**我以30fps的速度写出了100个刻度,而什么都没做,然后在最小值和最大值之间使用三角形分布,以30fps作为模式,然后使用turtle
模块模拟输出。 /子>