Problem: Hi, I'm running into an issue where I'm trying to update my player (mario)'s position with the keyboard arrow keys (K_LEFT, K_RIGHT, etc.). The movements work as intended but the movements erratically get "stuck" in that my player can't move anymore unless I hit the key again. My player again resumes normal movement in the 4 arrow directional moves but then gets stuck again randomly soon after unless I double-hit the same key (or another key) to make it move again.
Contextual Info: I incorporated the "self.pause" because I wanted a way to stop the player rect from continuing to move after a KEYUP and I release the arrow keyboard key. The "self.move_left", "self.move_right", etc. are all boolean variables and the "self.move_rate" is an arbitrary numerical value.
Debugging so far: I wrote some print statements to figure out what was going on (and removed some of them to avoid clutter). I see that the branches within the code snippets go as expected. For example, I might be pressing K_DOWN to go down and then it would get "stuck" but my print statement would tell me that my boolean "self.move_down" is True and "self.pause" is False (meaning I can move) and that I'm currently within the branch underneath "if self.move_down" in the move() function.
Thank you for your help
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
mario.pause = False
if event.key == K_LEFT:
mario.move_left, mario.move_right, mario.move_up, mario.move_down = True, False, False, False
elif event.key == K_RIGHT:
mario.move_left, mario.move_right, mario.move_up, mario.move_down = False, True, False, False
elif event.key == K_UP:
mario.move_left, mario.move_right, mario.move_up, mario.move_down = False, False, True, False
elif event.key == K_DOWN:
mario.move_left, mario.move_right, mario.move_up, mario.move_down = False, False, False, True
elif event.type == KEYUP:
# if event.key == K_LEFT:
# mario.move_left = False
# if event.key == K_RIGHT:
# mario.move_right == False
# if event.key == K_UP:
# mario.move_up == False
# if event.key == K_DOWN:
# move_down == False
mario.pause = True
And the other relevant code snippet
def move(self, window_surface):
if not self.pause:
#print(f"""status: pause->{self.pause} up -> {self.move_up}, down -> {self.move_down} left -> {self.move_left} right -> {self.move_right}""")
if self.move_left:
#self.body.left -= self.move_rate
self.body.move_ip(-1 * self.move_rate, 0)
if self.move_right:
#self.body.left += self.move_rate
self.body.move_ip(self.move_rate, 0)
if self.move_up:
#self.body.top -= self.move_rate
self.body.move_ip(0, -1 * self.move_rate)
if self.move_down:
#self.body.top += self.move_rate
self.body.move_ip(0, self.move_rate)
self.body.clamp_ip(window_surface.get_rect())
If you want to implement continuous movement, use pygame.key.get_pressed()
, rather than the keyboard events:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
keys = pygame.key.get_pressed()
mario.move_left = keys[K_LEFT] and not keys[K_RIGHT]
mario.move_right = keys[K_RIGHT] and not keys[K_LEFT]
mario.move_up = keys[K_UP] and not keys[K_DOWN]
mario.move_down = keys[K_DOWN] and not keys[K_UP]
# [...]