2012-12-02 85 views
1

我发现了一个解决方案,当您按住某个按键时,精灵会移动。问题在于它强制编写难看的重复代码。我发现的当前解决方案是:pygame - 按住按钮

 for event in pygame.event.get(): 
      if event.type == KEYDOWN: 
       keystate = pygame.key.get_pressed() 
       while keystate[K_RIGHT]: 
        screen.fill((255,255,255)) 
        pygame.event.get() 

        for sprite in sprites: 
         rimage = sprite[1].getimage() 

         if sprite[2] is None: 
          x+=3 
          sprite[1].update(time) 
          screen.blit(rimage, (x,y)) 
          if sprite[1].isfinished() == True: 
           sprite[1].reset() 
          last_dir = "right" 
          if x >= screen_width - rimage.get_width(): 
           x = screen_width - rimage.get_width() 

        #update player sprite movement 
        #update player sprite animation 
        #update rest of game map 

        keystate = pygame.key.get_pressed() 
        time = pygame.time.get_ticks() 


        pygame.display.update() 

问题是,while keystate块。必须对每个方向重复一次,并且游戏世界需要在每个块中更新。这是五个地方需要重复相同的代码.... 4个方向加上,如果没有按下一个键。我可以将它包装在一个函数中,但我想知道是否有更好的方法来处理在pygame中按住按钮。

回答

5

pygame中的常用方式是使用事件来更新方向,然后在事件之外写入更新位置代码,这样你就不需要复制代码。

clock = pygame.time.Clock() 

direction = (0,0) 

while True: # main loop 

    for event in pygame.event.get(): 

     if event.type == KEYDOWN: 
      if event.key == K_RIGHT: 
       direction = (3, 0) 
      elif event.key == K_LEFT: 
       direction = (-3, 0) 
      elif event.key == K_UP: 
       direction = (0, 3) 
      elif event.key == K_DOWN: 
       direction = (0, -3) 
      else: 
       print "Unrecognized key" 

     if event.type == KEYUP: 
      direction = (0, 0) 

    screen.fill((255,255,255)) 

    for sprite in sprites: 
     rimage = sprite[1].getimage() 

     if sprite[2] is None: 

      # Check if new position is inside the screen 
      new_pos = x + direction[0], y + direction[1] 
      if new_pos[0] + rimage.get_width() < screen_width: 
       x = new_pos[0] 
      if new_pos[1] + rimage.get_height() < screen_height: 
       y = new_pos[1] 

      # Draw the sprite 
      sprite[1].update(time) 
      screen.blit(rimage, (x,y)) 
      if sprite[1].isfinished() == True: 
       sprite[1].reset() 
       last_dir = direction 

    #update player sprite movement 
    #update player sprite animation 
    #update rest of game map 

    time = pygame.time.get_ticks() 

    pygame.display.update() 

    clock.tick(40) # Keep game running at 40 fps 

如果你愿意,你可以实现与keystate一样,在这种情况下,你不需要过程中的关键事件。

+1

您忘记了重置方向回到(0,0) –

+0

您是绝对正确的,已更新。 – pmoleri

+0

是的,但我认为keystate是不同的,只是检测到一个按键。我正在检测按钮被按下。这就是为什么在keystate时有一个循环:按住按钮的同时记录方向?我如何知道退出循环?循环是必要的吗? –

1

Pygame的建议或暗示的程序划分为3个部分:

的事件处理,更新和绘图。正如pmoleri已经说过的,你只需改变运动的方向即可。 在更新函数中,您应该传入一个增量时间参数,以便根据传递的时间移动所有精灵。这是非常重要的,因为其他技术不考虑处理器的可变速度。 DOS中的游戏已经这样做了,所以现在我们需要模拟器来人为地减慢处理器速度。绘制部分只是绘制所有的精灵。

通过这种方式,您可以在游戏中的这三个不同部分之间划分清楚:玩家输入,游戏逻辑(移动,碰撞,动作等)和绘图。

+0

如果你使用clock.tick(),你将不会遇到DOS问题。您可能遇到的问题是,如果程序运行速度慢,无法跟上您想要的FPS。无论哪种方式,德尔塔时间是一个很好的建议,所以你可以独立地改变游戏速度和FPS。游戏逻辑/绘图分离是另一个好建议,关于精灵的更多信息请参见:www.pygame.org/docs/ – pmoleri