我已经使用Python和Pyglet库组装了基于等距磁贴的RPG。但是,我遇到了以下问题:
我的播放器移动基于由瓷砖组成的三维阵列上的位置。为了限制移动速度,我使用了一个全局变量:TILE_TO_TILE_DELAY = 200。
TILE_TO_TILE_DELAY应该是玩家从一个磁贴移动到另一个磁贴所需的时间量(以毫秒为单位)。在此期间,他们不应该进行新的运动。
我一直在使用的系统是我有一个计时器类,如下所示:
import time
def GetSystemTimeInMS(): #Return system time in milliseconds
systime = round((time.clock()*1000), 0)
return systime
class Timer:
def __init__(self,time):
#time = time for which the timer runs
self.time = time
self.start_time = 0
self.stop_time = 0
def StartTimer(self):
#start_time = time at which the timer was started
self.start_time = GetSystemTimeInMS()
self.stop_time = self.start_time + self.time
def TimerIsStopped(self):
if GetSystemTimeInMS() >= self.stop_time:
return True
else:
return False
玩家类有一个Timer对象:
self.MoveTimer = Timer(TILE_TO_TILE_DELAY)
当玩家按下W键时,会调用一个函数来检查player.MoveTimer.TimerIsStopped()。如果它返回True,则调用player.MoveTimer.StartTimer()并开始新的移动到下一个位置。
在偶数循环中,更新(dt)功能设置为每秒发生30次:
def update(dt):
if player.MoveTimer.TimerIsStopped()
player.UpdatePosition()
pyglet.clock.schedule_interval(update, 1/30)
现在,根据我的逻辑,更新(dt)应该每秒检查30次是否有足够的时间来保证玩家有新的移动事件。但是,出于某种原因,玩家在较低的FPS下移动得更快。
当我的FPS大约为30时,玩家的移动速度比瓦片精灵较少的区域要快得多,将帧速率提高到60.在FPS高的区域,玩家确实通过我的测量速度几乎慢了两倍。
我无法弄明白,经过一天的搜索,我也没有在网上找到任何东西。一些帮助将非常感激。
编辑:启动MoveTimer的代码:
def StartMovement(self, new_next_pos):
self.RequestedMovement = False
if self.GetCanMoveAgain():
self.SetNextPos(new_next_pos)
self.SetMoveDirection(self.GetDirection())
#Start the timer for the movement
self.MoveTimer.StartTimer()
self.SetIsMoving(True)
self.SetStartedMoving(True)
self.SetWalking(True)
self.SetNeedUpdate(True)
self.MOVE_EVENT_HANDLER.CreateMoveEvent()
GetCanMoveAgain()返回player.can_move_again的值,由update(dt)中的UpdatePosition()设置回True
答案 0 :(得分:0)
好吧,我解决了这个问题,但我仍然不确定是什么导致了这个问题。也许这是一种以毫秒为单位的舍入误差,当FPS较高时,需要对时钟进行更多检查。无论如何,解决方案:
我没有使用系统时钟,而是决定使用Pyglet自己的" dt"更新函数中的参数:
dt参数给出秒数(由于延迟,负载和计时器准备,这可能略微多于或少于请求的间隔)。
新计时器如下所示:
class dtTimer: #A timer based on the dt-paremeter of the pyglet event loop
def __init__(self,time):
self.time = time
self.time_passed = 0
def StartTimer(self):
self.time_passed = 0
def UpdateTimer(self, dt):
self.time_passed += dt*1000
def GetTime(self):
return self.time
def GetTimePassed(self):
if not self.TimerIsStopped():
return self.time_passed
else:
return 0
def TimerIsStopped(self):
if self.time_passed > self.time:
return True
else:
return False
当循环尝试更新玩家的位置时,如果TimerIsStopped返回false,则简单地将dt添加到Timer的self.time_passed中。这解决了这个问题:玩家移动所需的时间现在是不变的。
感谢您查看我的问题。