I am making a simple game with the pygame library. I noticed a strange bug where if I tap one of the arrow keys for direction to move my character, it sticks it moving in one direction. Key down triggers a positive acceleration in the direction you press, and key up resets the acceleration to zero. Checking these values, the acceleration stays positive despite key up occurring. Looking at all of the events, it registers a key down and key up, but pygame doesn't run the code associated with that key up event. It could be a signal problem with my keyboard, but it seems like it might be event handling in pygame. Here is my code:
import pygame
pygame.init()
display_x = 1024
display_y = 512
game_display = pygame.display.set_mode((display_x, display_y))
clock = pygame.time.Clock()
fps = 30
font = pygame.font.SysFont(None, 25)
max_velocity = 16
acceleration = 4
def print_to_screen(text, color, x, y):
screen_text = font.render(text, True, color)
game_display.blit(screen_text, [x, y])
def game_loop():
game_exit = False
lead_x = display_x/2
lead_y = display_y/2
vel_x = 0
vel_y = 0
acc_x = 0
acc_y = 0
tile_size = 32
while not game_exit:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
game_exit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
acc_x = -acceleration
if event.key == pygame.K_RIGHT:
acc_x = acceleration
if event.key == pygame.K_UP:
acc_y = -acceleration
if event.key == pygame.K_DOWN:
acc_y = acceleration
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT and vel_x < 0:
acc_x = 0
if event.key == pygame.K_RIGHT and vel_x > 0:
acc_x = 0
if event.key == pygame.K_UP and vel_y < 0:
acc_y = 0
if event.key == pygame.K_DOWN and vel_y > 0:
acc_y = 0
if -max_velocity < vel_x < max_velocity: # if velocity isn't max, adds acceleration to velocity
vel_x += acc_x
if -max_velocity < vel_y < max_velocity:
vel_y += acc_y
if vel_x < 0: # velocity decay, if vel is less than 0, adds one. no input = slowed down cube
vel_x += 1
elif vel_x > 0:
vel_x -= 1
if vel_y < 0:
vel_y += 1
elif vel_y > 0:
vel_y -= 1
if (lead_x + vel_x) < 0: # looks into future: if past border in next frame, sets x coord to 0, stops motion
vel_x = 0
acc_x = 0
lead_x = 0
elif (lead_x + vel_x) > (display_x - tile_size):
vel_x = 0
acc_x = 0
lead_x = (display_x - tile_size)
if (lead_y + vel_y) < 0:
vel_y = 0
acc_y = 0
lead_y = 0
elif (lead_y + vel_y) > (display_y - tile_size):
vel_y = 0
acc_y = 0
lead_y = (display_y - tile_size)
lead_x += vel_x
lead_y += vel_y
game_display.fill((255, 255, 255))
pygame.draw.rect(game_display, (255, 0, 0), [lead_x, lead_y, tile_size, tile_size])
print_to_screen(str(int(lead_x)) + ", " + str(int(lead_y)), (0, 0, 0), 0, 0)
if vel_x > max_velocity or vel_y > max_velocity:
print_to_screen(str(int(vel_x)) + ", " + str(int(vel_y)), (255, 0, 0), 0, 16)
else:
print_to_screen(str(int(vel_x)) + ", " + str(int(vel_y)), (0, 0, 0), 0, 16)
if acc_x > acceleration or acc_y > acceleration:
print_to_screen(str(int(acc_x)) + ", " + str(int(acc_y)), (255, 0, 0), 0, 32)
else:
print_to_screen(str(int(acc_x)) + ", " + str(int(acc_y)), (0, 0, 0), 0, 32)
pygame.display.update()
clock.tick(fps)
game_loop()
pygame.quit()
quit()
Here is the event data from the quick tap:
<Event(2-KeyDown {'unicode': '', 'key': 276, 'mod': 0, 'scancode': 75})>
<Event(3-KeyUp {'key': 276, 'mod': 0, 'scancode': 75})>
It shows a key up and key down event, not sure why the key up won't register.