【问题标题】:Python and tile based game: limiting player movement speed基于 Python 和瓷砖的游戏:限制玩家移动速度
【发布时间】:2015-08-01 01:02:51
【问题描述】:

我一直在使用 Python 和 Pyglet 库制作一个基于等距图块的 RPG。但是,我遇到了以下问题:

我的玩家移动基于由图块组成的 3 维数组上的位置。为了限制移动速度,我使用了一个全局变量: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() 并开始新的移动到下一个位置。

在偶数循环中,update(dt) 函数设置为每秒发生 30 次:

def update(dt):
    if player.MoveTimer.TimerIsStopped()
        player.UpdatePosition()

pyglet.clock.schedule_interval(update, 1/30)

现在,按照我的逻辑,update(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

【问题讨论】:

  • 能否包含调用 StartTimer() 的代码?
  • 请将此代码添加到您的问题中
  • 添加了启动计时器的代码。

标签: python pyglet


【解决方案1】:

好的,我解决了这个问题,但我仍然不确定是什么原因造成的。也许这是某种以毫秒为单位的舍入误差,与当 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 中。这解决了问题:玩家移动所需的时间现在是恒定的。

感谢您查看我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    相关资源
    最近更新 更多