在游戏中平稳运动的玩家

时间:2010-12-13 14:38:06

标签: pygame

我正在使用pygame库。以下是我为玩家处理事件的伪代码:

#generates multiple events for keys that are held down
pygame.key.set_repeat(30,30)

for event in pygame.event.get()

   nextPos = currentPos

   if(keyUp):
       if event.key == w :
         key_w = false
       #do the same for s, a and d

   if(keyDown):
       if event.key == w:
         key_w = true
       #same for s,a and d

   if(key_w):
      #update nextPos

   #do same for key_s, key_a and key_d

   currentPos = nextPos

问题在于,有时当我在屏幕上移动鼠标,并且我同时按下某个键时,在处理鼠标事件时,键的事件排队等候,这些多个按键一起执行,以便玩家似乎跳得很远。

如果我根本不移动鼠标,则不会导致此问题。

4 个答案:

答案 0 :(得分:1)

更新我的回答:

我检查了我的游戏代码,看看我是如何处理每一帧的密钥,似乎我没有从事件中获取关键信息但是使用pygame.key.get_pressed():

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gl.loop_main_loop = False # exit main loop and terminate 
    keys = pygame.key.get_pressed()
    for key, state in enumerate(keys):
        if (key in self.key_handlers) and state:
            self.key_handlers[key]() # call key handler proc

这意味着我每帧只处理一次相关的密钥。鼠标可以按照我在下面描述的方式阅读。

如果您的游戏没有固定的帧速率,请记住在移动向量计算中使用增量时间。


也许更好的想法是在每个进程中首先执行所有键盘事件并构建自己的键状态表示,即一种告诉您哪些重要的键(例如WSAD)向上或向下的结构。在该帧中处理完所有事件后,使用您的密钥状态数据运行移动代码。

不要使用mousemotion事件来跟踪鼠标,而是使用pygame.mouse.get_pos()和pygame.mouse.get_pressed()直接读取位置和按钮。

您的移动代码还应考虑到您的游戏以可变帧速率运行的事实(除非您强制pygame保持帧速率不变)并在移动向量计算中使用时间增量。

答案 1 :(得分:1)

我使用以下方法...

我初始化cooridinate变量......

x = 300
y = 300
pX = 0
pY = 0

在这种情况下,x和y是玩家精灵使用的实际坐标,而事件处理程序使用pX和pY。

然后我在事件处理程序中使用以下代码...

for event in pygame.event.get(): 
    if event.type == pygame.QUIT: 
        sys.exit(0)

    if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
        pX -= 2
    if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
        pX += 2
    if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
        pY -= 2
    if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
        pY += 2       

    if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
        pX += 2
    if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
        pX -= 2
    if event.type == pygame.KEYUP and event.key == pygame.K_UP:
        pY += 2
    if event.type == pygame.KEYUP and event.key == pygame.K_DOWN:
        pY -= 2

最后,在处理玩家坐标的主游戏循环中,我放了......

x += pX
y += pY

答案 2 :(得分:0)

也许事件队列不是最好的解决方案,相反,每帧轮询一次会更好?

答案 3 :(得分:0)

我不会使用pygame.event.get()

在我看来,玩家移动的最佳输入是pygame.key.get_pressed()

我会这样格式化:

while True:
    keys = pygame.key.get_pressed()
    if keys[K_a]:
        player.pos.x -= 10
    if keys[K_d]:
        player.pos.x += 10
    if keys[K_w]:
        player.pos.y -= 10
    if keys[K_s]:
        player.pos.y += 10

这样系统将检查每一帧上的按下键。