我目前正在使用python进行乒乓球游戏:
然而,说球是粉红色的,黄色的家伙决定发送他的w
和s
密钥。然后他的桨将开始移动(精细),但随后粉红色将停止(不是很好)。
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()
如果有两个同时按键,如何让它独立处理每个按键?
答案 0 :(得分:1)
我同意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)
答案 1 :(得分:1)
经过一番研究,我认为这实际上是一个SDL事件队列溢出问题。 SDL是一个C事件库,PyGame的事件系统建立在它之上。根据我的阅读,事件队列有一个128事件限制,之后只需删除添加的新事件,直到刷新队列。
您的渲染逻辑效率不高,并且您已将输入轮询速率限制为渲染逻辑(您在每个游戏循环中重新渲染整个屏幕,拨片和球,然后轮询事件队列,所以你不能以比从头开始渲染整个框架更快的速度清空事件队列。我认为你需要做的是改进渲染逻辑(看看如何擦除/重绘精灵的部分而不是刷新整个缓冲区)并通过将渲染放在一个单独的线程中解除渲染事件轮询。
答案 2 :(得分:0)
我认为你需要使用线程,否则程序总是顺序的。
检查此示例:
Make 2 functions run at the same time
尝试将while True
放在每个线程的函数中,以便两者都响应命令。
答案 3 :(得分:0)
正如我上面所说,我只使用了pygame.key.set_repeat(1, 10)
,所以即使按下按键,事件也会发生。
我发现了另一种方法,使用pygame.key.get_pressed()[pygame.DESIRED_KEY]
。
pygame.key.get_pressed()
返回一个元组,如下所示:
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
当按下特定键时,0
变为1
,使我们能够使用if pygame.key.get_pressed()[pygame.DESIRED_KEY]
。
以下是您编辑的代码:
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 pygame.key.get_pressed()[pygame.K_UP]:
y1-=15
if pygame.key.get_pressed()[pygame.K_DOWN]:
y1+=15
if pygame.key.get_pressed()[pygame.K_w]:
y2-=15
if pygame.key.get_pressed()[pygame.K_s]:
y2+=15
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()
except AttributeError:
pass
pygame.display.flip()
答案 4 :(得分:0)
在我制作的游戏中,角色可以在各个方向上移动,我这样做是为了当你按下一个键,而不是直接改变角色的sx和y时,它只会使其中一个变量moveLeft,moveRight,moveUp或moveDown(取决于按下的键)True。然后你必须制作一个单独的东西,当钥匙被抬起时将其关闭。稍后在循环中检查每个变量是否为True,并根据按下的键移动字符。另外,我不明白为什么Try循环就在那里。
您可以将主循环更改为:
p1moveup = False
p1movedown = False
p2moveup = False
p2movedown = False
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
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.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
p1moveup = True
if event.key == pygame.K_s:
p1movedown = True
if event.key == pygame.K_UP:
p2moveup = True
if event.key == pygame.K_DOWN:
p2movedown = True
if event.type === pygame.KEYUP:
if event.key == pygame.K_w:
p1moveup = False
if event.key == pygame.K_s:
p1movedown = False
if event.key == pygame.K_UP:
p2moveup = False
if event.key == pygame.K_DOWN:
p2movedown = False
if p1moveup == True:
y1-=15
if p1movedown == True:
y1+=15
if p2moveup == True:
y2-=15
if p2movedown == True:
y2+=15
pygame.display.flip()