Pygame事件:不松开按键触发事件
Pygame event: key up event triggering without releasing key
我正在尝试制作俄罗斯方块游戏,下面是我让方块移动的代码。我希望方块在按住箭头键时继续移动,并在释放时停止。但是当我 运行 代码时,即使没有释放键,它也会停止块。
def set_keyboard_dirs(cur_block, width, height, events): # events stores pygame.event.get() as I use it multiple times in my code
global move_timer # only moves block one time per set number of frames
cur_block.reset_collisions(height)
for event in events:
if event.type == pygame.KEYDOWN: # sets magnitude and direction of movement
if event.key == pygame.K_RIGHT:
cur_block.dir = (cur_block.length, 0)
elif event.key == pygame.K_LEFT:
cur_block.dir = (-cur_block.length, 0)
elif event.key == pygame.K_DOWN:
cur_block.dir = (0, cur_block.length)
elif event.key == pygame.K_UP:
cur_block.rotate(height, width)
elif event.key == pygame.K_SPACE: # just moves the block instantly to the bottom of the screen by equating it to a 'projection' already there.
cur_block.shape = deepcopy(cur_block.projection)
elif event.type == pygame.KEYUP: # stops block from moving
print(event.key) # I called this to see what's happening, and event.key is printed event when I didn't release the key.
cur_block.dir = (0, 0)
cur_block.move()
由于上述原因,方块一次移动一步,而不是像我想要的那样连续移动(只要他们拿着它)。请问我该如何解决?游戏的其余部分有效,所以我真的希望它也有效。非常感谢。
编辑:
我还尝试使用 pygame.key.get_pressed() 设置控件,如下所示:
def set_keyboard_dirs(cur_block, width, height):
global move_timer, keys
cur_block.reset_collisions(height)
cur_block.dir = (0, 0)
if keys[pygame.K_UP] or keys[pygame.K_w]:
cur_block.rotate(height, width)
elif keys[pygame.K_SPACE]:
cur_block.shape = deepcopy(cur_block.projection)
elif (keys[pygame.K_DOWN] or keys[pygame.K_s]) and 2 not in cur_block.collisions: # 1, 2, 3 are collisions in left, down and right directions
cur_block.dir = (0, cur_block.length)
elif (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and 1 not in cur_block.collisions:
cur_block.dir = (cur_block.length, 0)
elif (keys[pygame.K_LEFT] or keys[pygame.K_a]) and 3 not in cur_block.collisions:
cur_block.dir = (-cur_block.length, 0)
else:
print('ran reset') # this statement print even as i'm holding down a key for some reason
cur_block.dir = (0, 0)
if cur_block.dir != (0, 0) and move_timer == 0:
cur_block.move()
move_timer = 7
在前一种情况下,如果我删除了 KEYUP 事件,而在后一种情况下,如果我删除了 else 语句,块会连续移动(但不能停止),这也表明正是这些语句导致了问题,我想。这是我定义 cur_block.dir 的代码中唯一的地方。
这可能是因为您的 for 循环每帧运行 1 次,所以如果您按住按钮,它会在您在该特定帧按下 1 次时计数,与 KEYUP 事件相同。
您可以尝试在主循环之外创建两个变量 left=False 和 right=False
在您当前的 for 循环之外,您检查是否按下了任何按钮。
#these are outside of the mainloop
left=False
right=False
keys = pygame.key.get_pressed() # checks for key events (put this outside of the for loop, but still be inside your mainloop)
if keys[pygame.K_LEFT]:
right = False
left = True
elif keys[pygame.K_RIGHT]:
left = False
right = True
# if none of those buttons pressed, it sets the values back to False
else:
right = False
left = False
# using the left value, if its true, it will do your action every frame,
#(you can adjust the speed of your block later)
if left:
# do something
cur_block.dir = (-cur_block.length, 0)
if right:
# do something else
然后如果你按 LEFT 键,例如,Left 的值将为真,然后你可以检查:如果这些值中的任何一个为真 > 做某事。
根据您的示例代码,这是我唯一能想到的。希望有用。
在您的代码中,如果释放任何键,块的移动将被取消,如果释放特殊键则不会。如果释放了一个光标键,则必须实施特殊情况:
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
# [...]
elif event.key == pygame.K_LEFT:
# [...]
# [...]
我建议根据pygame.key.get_pressed()
返回的按键状态设置移动方向:
def set_keyboard_dirs(cur_block, width, height, events):
global move_timer
cur_block.reset_collisions(height)
keys = pygame.key.get_pressed()
cur_block = [0, 0]
if key[pygame.K_RIGHT]:
cur_block.dir[0] += cur_block.length
if key[pygame.K_LEFT]:
cur_block.dir[0] -= cur_block.length
if key[pygame.K_DOWN]:
cur_block.dir[1] += cur_block.length
if key[pygame.K_UP]:
cur_block.rotate(height, width)
if key[pygame.K_SPACE]:
cur_block.shape = deepcopy(cur_block.projection)
cur_block.move()
我正在尝试制作俄罗斯方块游戏,下面是我让方块移动的代码。我希望方块在按住箭头键时继续移动,并在释放时停止。但是当我 运行 代码时,即使没有释放键,它也会停止块。
def set_keyboard_dirs(cur_block, width, height, events): # events stores pygame.event.get() as I use it multiple times in my code
global move_timer # only moves block one time per set number of frames
cur_block.reset_collisions(height)
for event in events:
if event.type == pygame.KEYDOWN: # sets magnitude and direction of movement
if event.key == pygame.K_RIGHT:
cur_block.dir = (cur_block.length, 0)
elif event.key == pygame.K_LEFT:
cur_block.dir = (-cur_block.length, 0)
elif event.key == pygame.K_DOWN:
cur_block.dir = (0, cur_block.length)
elif event.key == pygame.K_UP:
cur_block.rotate(height, width)
elif event.key == pygame.K_SPACE: # just moves the block instantly to the bottom of the screen by equating it to a 'projection' already there.
cur_block.shape = deepcopy(cur_block.projection)
elif event.type == pygame.KEYUP: # stops block from moving
print(event.key) # I called this to see what's happening, and event.key is printed event when I didn't release the key.
cur_block.dir = (0, 0)
cur_block.move()
由于上述原因,方块一次移动一步,而不是像我想要的那样连续移动(只要他们拿着它)。请问我该如何解决?游戏的其余部分有效,所以我真的希望它也有效。非常感谢。
编辑: 我还尝试使用 pygame.key.get_pressed() 设置控件,如下所示:
def set_keyboard_dirs(cur_block, width, height):
global move_timer, keys
cur_block.reset_collisions(height)
cur_block.dir = (0, 0)
if keys[pygame.K_UP] or keys[pygame.K_w]:
cur_block.rotate(height, width)
elif keys[pygame.K_SPACE]:
cur_block.shape = deepcopy(cur_block.projection)
elif (keys[pygame.K_DOWN] or keys[pygame.K_s]) and 2 not in cur_block.collisions: # 1, 2, 3 are collisions in left, down and right directions
cur_block.dir = (0, cur_block.length)
elif (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and 1 not in cur_block.collisions:
cur_block.dir = (cur_block.length, 0)
elif (keys[pygame.K_LEFT] or keys[pygame.K_a]) and 3 not in cur_block.collisions:
cur_block.dir = (-cur_block.length, 0)
else:
print('ran reset') # this statement print even as i'm holding down a key for some reason
cur_block.dir = (0, 0)
if cur_block.dir != (0, 0) and move_timer == 0:
cur_block.move()
move_timer = 7
在前一种情况下,如果我删除了 KEYUP 事件,而在后一种情况下,如果我删除了 else 语句,块会连续移动(但不能停止),这也表明正是这些语句导致了问题,我想。这是我定义 cur_block.dir 的代码中唯一的地方。
这可能是因为您的 for 循环每帧运行 1 次,所以如果您按住按钮,它会在您在该特定帧按下 1 次时计数,与 KEYUP 事件相同。 您可以尝试在主循环之外创建两个变量 left=False 和 right=False 在您当前的 for 循环之外,您检查是否按下了任何按钮。
#these are outside of the mainloop
left=False
right=False
keys = pygame.key.get_pressed() # checks for key events (put this outside of the for loop, but still be inside your mainloop)
if keys[pygame.K_LEFT]:
right = False
left = True
elif keys[pygame.K_RIGHT]:
left = False
right = True
# if none of those buttons pressed, it sets the values back to False
else:
right = False
left = False
# using the left value, if its true, it will do your action every frame,
#(you can adjust the speed of your block later)
if left:
# do something
cur_block.dir = (-cur_block.length, 0)
if right:
# do something else
然后如果你按 LEFT 键,例如,Left 的值将为真,然后你可以检查:如果这些值中的任何一个为真 > 做某事。
根据您的示例代码,这是我唯一能想到的。希望有用。
在您的代码中,如果释放任何键,块的移动将被取消,如果释放特殊键则不会。如果释放了一个光标键,则必须实施特殊情况:
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
# [...]
elif event.key == pygame.K_LEFT:
# [...]
# [...]
我建议根据pygame.key.get_pressed()
返回的按键状态设置移动方向:
def set_keyboard_dirs(cur_block, width, height, events):
global move_timer
cur_block.reset_collisions(height)
keys = pygame.key.get_pressed()
cur_block = [0, 0]
if key[pygame.K_RIGHT]:
cur_block.dir[0] += cur_block.length
if key[pygame.K_LEFT]:
cur_block.dir[0] -= cur_block.length
if key[pygame.K_DOWN]:
cur_block.dir[1] += cur_block.length
if key[pygame.K_UP]:
cur_block.rotate(height, width)
if key[pygame.K_SPACE]:
cur_block.shape = deepcopy(cur_block.projection)
cur_block.move()