简体   繁体   English

在 pygame 中处理多个玩家键输入的最有效方法是什么?

[英]What is the most efficient way to handle multiple players key inputs in pygame?

I'm programming a game with pygame and was wandering what is the best way to handle multiple players key inputs in it, like in a pong game where you can handle key inputs from the 'w, s' keys for one player and the arrow keys for the other.我正在使用 pygame 编写游戏,并且正在徘徊什么是处理其中多个玩家键输入的最佳方法,例如在乒乓球游戏中,您可以处理来自一个玩家的“w,s”键和箭头的键输入对方的钥匙。

The way I'm doing it now is by using a variable called 'control_type' in my Player class that is assigned when each player is initialized.我现在这样做的方式是在我的播放器 class 中使用一个名为“control_type”的变量,该变量在每个播放器初始化时分配。 Then inside the Player class I check if the variable is equal to 'wasd' or 'arrows' and then check the key inputs accordingly.然后在播放器 class 中检查变量是否等于“wasd”或“箭头”,然后相应地检查键输入。 It works, but sometimes it seems to lag and skip some frames.它有效,但有时它似乎滞后并跳过一些帧。 Is this a good way to do it or is there a better way to handle it?这是一个好方法还是有更好的方法来处理它?

You can do this, but if you say你可以这样做,但如果你说

but sometimes it seems to lag and skip some frames但有时它似乎滞后并跳过一些帧

remember one thing (because that's a common mistake):记住一件事(因为这是一个常见的错误):

Only ever call pygame.event.get() once per frame.每帧只调用一次pygame.event.get() If a key is pressed and the event is added to the queue, and you call pygame.event.get() and don't handle that event, it is lost, and another call to pygame.event.get() will not recieve it.如果按下某个键并将事件添加到队列中,并且您调用pygame.event.get()并且不处理该事件,它就会丢失,并且对pygame.event.get()的另一个调用将不会收到它。

A common pattern I use is to store all events of a frame in a list, and use that list in multiple places to check for events that the current piece of code is interested in. When using the Sprite class, you can simple pass that list to your Group to pass it down to the sprites.我使用的一种常见模式是将帧的所有事件存储在列表中,并在多个位置使用该列表来检查当前代码感兴趣的事件。使用Sprite class 时,您可以简单地传递该列表到您的Group以将其传递给精灵。

Simplified example:简化示例:

...
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

Then in a sprite class然后在精灵 class

class Foo(pygame.sprite.Sprite):
   ...
   def update(self, events):
       for e in events:
           ... handle other events

Another thing to note: in a game like Pong, where you move by holding a key, you're probably not interested in the individual key events, but rather the current state of the key (is it pressed or not?).另一件需要注意的事情:在像乒乓球这样的游戏中,您通过按住一个键来移动,您可能对单个键事件不感兴趣,而是对键的当前 state(是否按下?)感兴趣。 So you want to call pygame.key.get_pressed() to get the state of the keyboard.所以你想调用pygame.key.get_pressed()来获取键盘的 state。 Calling pygame.key.get_pressed() multiple times is fine.多次调用pygame.key.get_pressed()就可以了。

Another simplified pseudo example:另一个简化的伪示例:

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)

and initialize multiple players like:并初始化多个播放器,例如:

sprites = pygame.sprite.Group()
Player(p1, pygame.K_w, pygame.K_s, sprites)
Player(p2, pygame.K_UP, pygame.K_DOWN, sprites)

A method I've used successfully is whenever a call to pygame.event.get() is made, if the event pulled is needed elsewhere, just put it back on the queue.我成功使用的一种方法是每当调用 pygame.event.get() 时,如果在其他地方需要提取的事件,只需将其放回队列中即可。 For example例如

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

You'll need to be careful about this as putting too many things back on the queue can cause the queue to fill up.您需要注意这一点,因为将太多东西放回队列会导致队列填满。 But if everything you put back on the queue is definitely going to be used elsewhere, then you're good.但是,如果您放回队列中的所有内容肯定会在其他地方使用,那么您很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用一个键将多个键的字典相加的最有效方法是什么? - What is the most efficient way to sum a dict with multiple keys by one key? 在 pygame 中,重置每个精灵位置的最有效方法是什么? - In pygame, what is the most efficient way of resetting every sprite's position? 使用多个子元素的最有效方法是什么? - What is the most efficient way to work with multiple subelements? Python3:处理条形分隔文件的最有效方法是什么? - Python3: What is the most efficient way to handle bar delimited files? 在python中字典中最有效的方法是什么? - What is the most efficient way to a multiple variable in dictionary in python? 更新数据库中的多行并记录它的最有效方法是什么? - What is the most efficient way update multiple rows in a database and log it? 如果某些条件是有条件的,那么进行多重或比较的最有效方法是什么 - What is the most efficient way to do multiple or comparisons if some are conditional 连接具有相同索引/列的多个表的最有效方法是什么? - What is the most efficient way to join multiple tables with the same index/col? 刮除多个单一和分支OID的最有效方法是什么? - What is the most efficient way to scrape multiple single and branch OIDs? 在Python中跨多个文件连接MySQL的最有效方法是什么? - What is the most efficient way to connect to MySQL across multiple files in Python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM