我正在用pygame编写游戏,当时在徘徊什么是处理多个玩家键输入的最佳方法,例如在乒乓游戏中,您可以为一个玩家处理“ w,s”键的键输入和另一个的箭头键。
我现在的操作方式是在Player类中使用一个名为“ control_type”的变量,该变量在初始化每个播放器时分配。然后在Player类中,我检查变量是否等于'wasd'或'arrows',然后相应地检查键输入。它可以工作,但有时似乎滞后并跳过了一些帧。是这样做的好方法还是更好的处理方法?
答案 0 :(得分:3)
您可以这样做,但是如果您说
但有时似乎会滞后并跳过一些帧
记住一件事(因为这是一个常见的错误):
每帧只能调用一次pygame.event.get()
。如果按下某个键并将事件添加到队列中,并且您呼叫pygame.event.get()
并且不处理该事件,则该事件将丢失,并且对pygame.event.get()
的另一次调用将不会收到该事件。>
我使用的一种常见模式是将一帧的所有事件存储在列表中,并在多个位置使用该列表来检查当前代码感兴趣的事件。使用Sprite
类时,您可以简单地将该列表传递到您的Group
,以将其向下传递到精灵。
简化示例:
...
sprites = pygame.sprite.Group()
while True:
events = pygame.event.get()
for e in events:
... handle "global" events like QUIT
sprites.update(events) # pass events to all sprites
然后在sprite类中
class Foo(pygame.sprite.Sprite):
...
def update(self, events):
for e in events:
... handle other events
需要注意的另一件事:在类似Pong的游戏中,您按住某个键进行移动,您可能对单个键事件不感兴趣,而对键的当前状态感兴趣(是否按下了键?) 。因此,您想调用pygame.key.get_pressed()
来获取键盘的状态。多次拨打pygame.key.get_pressed()
很好。
另一个简化的伪示例:
class Paddle(pygame.sprite.Sprite):
def __init__(self, pos, up_key, down_key, *grps):
super().__init__(*grps)
self.image = ...
self.rect = ...
self.up_key = up_key
self.down_key = down_key
def update(self):
pressed = pygame.key.get_pressed()
if pressed[self.up_key]: self.rect.move_ip(0, -1)
if pressed[self.up_down]: self.rect.move_ip(0, 1)
并初始化多个玩家,例如:
sprites = pygame.sprite.Group()
Player(p1, pygame.K_w, pygame.K_s, sprites)
Player(p2, pygame.K_UP, pygame.K_DOWN, sprites)
答案 1 :(得分:0)
我成功使用的一种方法是每当调用pygame.event.get()时,如果需要在其他地方拉出事件,只需将其放回队列即可。例如
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
handle_up()
# Check for all your other relevant keys...
elif event.key == pygame.K_w: # Or any key you need elsewhere
pygame.event.post(event) # Put it back on the queue
您需要注意这一点,因为将过多的内容放回队列可能导致队列填满。但是,如果您放回队列中的所有内容肯定会在其他地方使用,那么您就很好了。