如何让一个动作在 Python / Pygame 中只发生一次
How To Make An Action Happen Only Once In Python / Pygame
我正在 Python / Pygame 编写游戏代码。目前我正在研究玩家的移动,但我已经意识到,如果我按住 space 条(即激活我的跳跃移动的按钮),它会一直上升并且永远不会下降。我已经实现了重力,但它只在我按下按钮一次时发生。我希望这样我只能跳一次而且我的角色不会一直飞。
这是我的代码(请帮忙!)
# This is my player file
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = pygame.Surface((32,64))
self.image.fill('red')
self.rect = self.image.get_rect(topleft = pos)
# Player Movement
self.direction = pygame.math.Vector2(0, 0)
self.speed = 7
self.gravity = 0.7
self.jump_speed = -14
# player status
self.status = 'idle'
self.facing_right = True
self.on_ground = False
self.on_ceiling = False
self.on_left = False
self.on_right = False
# Key Pressed
def get_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.direction.x = 1
elif keys[pygame.K_LEFT]:
self.direction.x = -1
else:
self.direction.x = 0
if keys[pygame.K_SPACE]:
self.jump()
# Gravity
def apply_gravity(self):
self.direction.y += self.gravity
self.rect.y += self.direction.y
# Jumping
def jump(self):
self.direction.y = self.jump_speed
# Updating The Player
def update(self):
self.get_input()
self.apply_gravity()
处理单个按键的最佳方法是使用 pygame
的 event
模块。在主游戏循环中使用 pygame.event.get()
。
这让你可以用单个 'events' 做一些事情,比如按下或释放一个键。
您可以通过添加一个 space_is_pressed
变量来解决此问题] 发布时)。然后只有在
keys[pygame.K_SPACE]
是 True
,但 space_is_pressed
是 False
。
我只建议你在无法实现 pygame.event.get()
方法时这样做。
首先为什么你不只允许在 self.on_ground
时跳转?
class Player(pygame.sprite.Sprite):
# [...]
def get_input(self):
# [...]
if keys[pygame.K_SPACE] and self.on_ground:
self.jump()
无论如何,你必须使用 KEYDOWN
事件而不是 pygame.key.get_pressed()
pygame.key.get_pressed()
returns a list with the state of each key. If a key is held down, the state for the key is True
, otherwise False
. Use pygame.key.get_pressed()
评估按钮的当前状态并获得连续移动。
键盘事件(参见 pygame.event 模块)仅在键状态改变时发生一次。 KEYDOWN
事件在每次按下一个键时发生一次。 KEYUP
每松开一个键就会出现一次。使用键盘事件进行单个操作或逐步移动。
class Player(pygame.sprite.Sprite):
# [...]
def get_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.direction.x = 1
elif keys[pygame.K_LEFT]:
self.direction.x = -1
else:
self.direction.x = 0
for event in event_list:
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
self.jump()
# application loop
while run:
#event loop
event_list = pgame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
run = False
# [...]
注意,pygame.event.get()
获取所有消息并将它们从队列中删除。请参阅文档:
This will get all the messages and remove them from the queue. [...]
如果在多个事件循环中调用pygame.event.get()
,则只有一个循环接收事件,而不是所有循环都接收所有事件。因此,有些事件似乎被遗漏了。
见。
或者,您可以使用状态属性防止连续多次跳转:
class Player(pygame.sprite.Sprite):
def __init__(self, pos):
# [...]
self.is_jumping = False
def get_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.direction.x = 1
elif keys[pygame.K_LEFT]:
self.direction.x = -1
else:
self.direction.x = 0
space_pressed = keys[pygame.K_SPACE]:
if space_pressed and not self.is_jumping:
self.jump()
self.is_jumping = space_pressed
只要按键被按下,事件'key pressed'就为真。而 'key down' 事件仅在键按下时发生。
这不是解决问题的方法吗?
我正在 Python / Pygame 编写游戏代码。目前我正在研究玩家的移动,但我已经意识到,如果我按住 space 条(即激活我的跳跃移动的按钮),它会一直上升并且永远不会下降。我已经实现了重力,但它只在我按下按钮一次时发生。我希望这样我只能跳一次而且我的角色不会一直飞。 这是我的代码(请帮忙!)
# This is my player file
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = pygame.Surface((32,64))
self.image.fill('red')
self.rect = self.image.get_rect(topleft = pos)
# Player Movement
self.direction = pygame.math.Vector2(0, 0)
self.speed = 7
self.gravity = 0.7
self.jump_speed = -14
# player status
self.status = 'idle'
self.facing_right = True
self.on_ground = False
self.on_ceiling = False
self.on_left = False
self.on_right = False
# Key Pressed
def get_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.direction.x = 1
elif keys[pygame.K_LEFT]:
self.direction.x = -1
else:
self.direction.x = 0
if keys[pygame.K_SPACE]:
self.jump()
# Gravity
def apply_gravity(self):
self.direction.y += self.gravity
self.rect.y += self.direction.y
# Jumping
def jump(self):
self.direction.y = self.jump_speed
# Updating The Player
def update(self):
self.get_input()
self.apply_gravity()
处理单个按键的最佳方法是使用 pygame
的 event
模块。在主游戏循环中使用 pygame.event.get()
。
这让你可以用单个 'events' 做一些事情,比如按下或释放一个键。
您可以通过添加一个 space_is_pressed
变量来解决此问题] 发布时)。然后只有在
keys[pygame.K_SPACE]
是 True
,但 space_is_pressed
是 False
。
我只建议你在无法实现 pygame.event.get()
方法时这样做。
首先为什么你不只允许在 self.on_ground
时跳转?
class Player(pygame.sprite.Sprite):
# [...]
def get_input(self):
# [...]
if keys[pygame.K_SPACE] and self.on_ground:
self.jump()
无论如何,你必须使用 KEYDOWN
事件而不是 pygame.key.get_pressed()
pygame.key.get_pressed()
returns a list with the state of each key. If a key is held down, the state for the key is True
, otherwise False
. Use pygame.key.get_pressed()
评估按钮的当前状态并获得连续移动。
键盘事件(参见 pygame.event 模块)仅在键状态改变时发生一次。 KEYDOWN
事件在每次按下一个键时发生一次。 KEYUP
每松开一个键就会出现一次。使用键盘事件进行单个操作或逐步移动。
class Player(pygame.sprite.Sprite):
# [...]
def get_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.direction.x = 1
elif keys[pygame.K_LEFT]:
self.direction.x = -1
else:
self.direction.x = 0
for event in event_list:
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
self.jump()
# application loop
while run:
#event loop
event_list = pgame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
run = False
# [...]
注意,pygame.event.get()
获取所有消息并将它们从队列中删除。请参阅文档:
This will get all the messages and remove them from the queue. [...]
如果在多个事件循环中调用pygame.event.get()
,则只有一个循环接收事件,而不是所有循环都接收所有事件。因此,有些事件似乎被遗漏了。
见
或者,您可以使用状态属性防止连续多次跳转:
class Player(pygame.sprite.Sprite):
def __init__(self, pos):
# [...]
self.is_jumping = False
def get_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.direction.x = 1
elif keys[pygame.K_LEFT]:
self.direction.x = -1
else:
self.direction.x = 0
space_pressed = keys[pygame.K_SPACE]:
if space_pressed and not self.is_jumping:
self.jump()
self.is_jumping = space_pressed
只要按键被按下,事件'key pressed'就为真。而 'key down' 事件仅在键按下时发生。 这不是解决问题的方法吗?