如何使两个键同时响应?

2024-06-28 19:56:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python制作一个乒乓球游戏:

enter image description here

然而,假设球在粉红色的地方来了,而黄色的家伙决定用他的ws键。然后他的球拍会开始移动(好的),但是粉红色的会停止(不好)。在

python可以同时监听两个事件键吗?在

代码如下:

import pygame, sys
from pygame.locals import *
pygame.init()

DISPLAYSURF = pygame.display.set_mode((1439, 790))
YELLOW = (255, 255, 0)
PINK = (255, 0, 255)
BLUE = (120, 214, 208)
y1, y2 = (0, 0)
circx, circy = (1439//2, 790//2)
diffx, diffy = (15, 15)
pygame.key.set_repeat(1, 10)
while True:
        if (0 <= circy <= 780) == False:
                diffy*=-1
        if circx <= 60 and y1-10 <= circy <= y1+75:
                diffx*=-1
        if circx >= 1439-60 and y2-10 <= circy <= y2+75:
                diffx*=-1
        if (0 <= circx <= 1439) == False:
                circx, circy = (720, 395)
        DISPLAYSURF.fill((0, 0, 0))
        pygame.draw.rect(DISPLAYSURF, YELLOW, (50, y1, 10, 75))
        pygame.draw.rect(DISPLAYSURF, PINK, (1439-60, y2, 10, 75))
        pygame.draw.circle(DISPLAYSURF, BLUE, (circx, circy), 10)
        circx+=diffx
        circy+=diffy
        try:
                for event in pygame.event.get():
                        if event.type == QUIT or event.key == pygame.K_ESCAPE or event.key == pygame.K_q:
                                pygame.quit()
                                sys.exit()
                        if event.key == pygame.K_w:
                                y1-=15
                        if event.key == pygame.K_s:
                                y1+=15
                        if event.key == pygame.K_UP:
                                y2-=15
                        if event.key == pygame.K_DOWN:
                                y2+=15
        except AttributeError:
                pass
        pygame.display.flip()

如果同时有两个按键,如何使其独立处理?在


Tags: keyimporteventifsyspygamedrawdiffx
3条回答

我同意SilasRay的观点,即这几乎肯定不是线程阻塞的问题,但是如果是的话:这应该可以解决它(因此,如果不是的话,这是Silas提到的键盘或SDL层的问题)。不管怎样,用你的球拍来制作物体是很重要的,所以无论如何要考虑做这个部分。线程部分位于paddlelisten()。在

import threading

class Paddle(object):
    def __init__(self, posx, color):
        self.posx = posx
        self.posy = 0
        self.color = color
    @property
    def pos():
        return (self.posx, self.posy, 10, 75)

def main():
    # the logic for the program
    p1_paddle = Paddle(50, YELLOW)
    p2_paddle = Paddle(1439-60, PINK)
    def paddlelisten(paddle, upkey, downkey):
        if event.key == upkey:
            paddle.posy -= 15
        if event.key == pygame.downkey:
            paddle.posy += 15
    t1 = threading.Thread(target=lambda: paddlelisten(p1_paddle, pygame.K_w, pygame.K_s))
    t2 = threading.Thread(target=lambda: paddlelisten(p2_paddle, pygame.K_UP, pygame.K_DOWN))
    for t in [t1, t2]:
        t.daemon = True
        t.start()
    while True:
        # game loop
        pygame.draw.rect(DISPLAYSURF, p1_paddle.color, p1_paddle.pos)
        pygame.draw.rect(DISPLAYSURF, p2_paddle.color, p2_paddle.pos)

经过一些研究,我认为这实际上是一个SDL事件队列溢出问题。SDL是一个C事件库,PyGame的事件系统就是在这个库之上构建的。从我所读到的,事件队列有128个事件限制,之后添加的新事件将被丢弃,直到队列被刷新。在

你的渲染逻辑不是很有效,你已经将你的输入轮询率绑定到你的渲染逻辑上(你在每一个游戏循环中重新渲染整个屏幕、球拍和球,然后轮询事件队列,因此清空事件队列的速度不能快于从头开始渲染整个帧的速度)。我认为你需要做的是改进你的渲染逻辑(看看你如何可以删除/重画一个精灵的一部分,而不是刷新整个缓冲区),并通过将渲染放在一个单独的线程中来解除渲染事件轮询的绑定。在

我认为你需要使用线程,否则程序总是顺序的。在

检查此示例:

Make 2 functions run at the same time

尝试将while True放在每个线程的函数中,以便两个线程都响应命令。在

相关问题 更多 >