Reputation: 3
I'm fairly new to coding (like 3 weeks in) and I've been trying to make a turn-based RPG battle system using pygame. I've encountered a problem involving pygame's key.get_pressed. I'm making a dropdown menu thing where if you press ENTER, a smaller black box should appear and when you press ENTER again, the box should disappear. Unfortunately, the black box appears but disappears almost immediately. I used the print function as a debug to find the error and it seems that the program registers the second ENTER press (the one that should close the box) without it ever being pressed. Any help would be greatly appreciated. I am also using windows 10 and python 3.6
import pygame
pygame.init()
win = pygame.display.set_mode((820,567))
pygame.display.set_caption('Basic battle')
drop_menu_attack = pygame.image.load('drop menu attack.png')
health_pp = pygame.image.load('hp and pp.png')
menu_img = pygame.image.load('menu.png')
attack_img = pygame.image.load('attack.png')
defend_img = pygame.image.load('defend.png')
bag_img = pygame.image.load('bag.png')
background_img = pygame.image.load('rpg background.gif')
Snake_enemy_img = pygame.image.load('pixil-frame-0.png')
clock = pygame.time.Clock()
class player(object):
def __init__ (self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.cursor_state = 1
self.attack_x = 100
self.defend_x = 325
self.bag_x = 575
self.top_menu_y = 70
class drop_menu(object):
def __init__ (self, x, y):
self.x = x
self.y = y
self.drop_menu_state = False
def cursor_position():
if c_p.cursor_state == 1:
print ('it should be on attack')
c_p.x = c_p.attack_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state == 2:
print ('it hould be on defend')
c_p.x = c_p.defend_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state == 3:
print ('it should be on bag')
c_p.x = c_p.bag_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state > 3:
c_p.cursor_state = 3
print ('it should be on bag')
c_p.x = c_p.bag_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state < 1:
c_p.cursor_state = 1
print ('it should be on attack')
c_p.x = c_p.attack_x
c_p.y = c_p.top_menu_y
def select():
if c_p.cursor_state == 1:
d_m.drop_menu_state = True
print (d_m.y)
while d_m.drop_menu_state:
pygame.time.delay(150)
win.blit (drop_menu_attack, (d_m.x, d_m.y))
pygame.display.update()
print ('dooooog')
keys = pygame.key.get_pressed()
if d_m.drop_menu_state == True:
if keys[pygame.K_RETURN]:
d_m.drop_menu_state = False
print('SSSSSS')
pygame.event.pump()
def redraw_gamewindow():
win.blit (background_img, (0,0))
win.blit (Snake_enemy_img, (300, 174))
win.blit (menu_img, (25, 425 ))
win.blit (menu_img, (25, 10))
win.blit (health_pp, (70, 450))
win.blit (attack_img, (c_p.attack_x + 30, c_p.top_menu_y - 15))
win.blit (defend_img, (c_p.defend_x + 30, c_p.top_menu_y - 15))
win.blit (bag_img, (c_p.bag_x + 30, c_p.top_menu_y - 15))
pygame.draw.rect(win, (255, 255, 255), (c_p.x, c_p.y, 7 , 7))
pygame.display.update()
d_m = drop_menu(25, 125)
print (d_m.x)
c_p = player(100, 70, 7,7)
run = True
while run:
clock.tick(27)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
c_p.cursor_state = c_p.cursor_state + 1
cursor_position()
pygame.time.delay(150)
if keys[pygame.K_LEFT]:
c_p.cursor_state = c_p.cursor_state -1
cursor_position()
pygame.time.delay(150)
if keys[pygame.K_RETURN]:
select()
pygame.time.delay(500)
redraw_gamewindow()
Upvotes: 0
Views: 73
Reputation: 370
So what's happening is that you're holding the ENTER button. In the while
loop, when you press enter, it calls the select()
function, which then detects the ENTER that is still being pressed. Let me draw a visual-ish:
ENTER is pressed -> select() is called, drop_menu_state
turns True -> select() detects ENTER still being pressed -> drop_menu_state
turns false
You may be asking, how does it detect? Well the frames are running at a wanted 27 frames per second. So it will change the state of drop menu state every 1/27 of a second while the ENTER key is being pressed. If you are able to press and release the ENTER key for less than 1/27 of a second, it will work properly.
There are 3 solutions. Either bind the closing of the menu to another key, add a short timer, or use an event loop. My style of programming would be to add a timer.
import time
pre_time = time.time()
def select():
... # code in select()
if d_m.drop_menu_state and pre_time + 5 > time.time() and keys[pygame.K_RETURN]:
pre_time = time.time()
d_m.drop_menu_state = False
I simplified your code a bit (no == True) What the pre_time + 5 > time.time()
is saying is has it been five seconds since the last time pre_time has been defined as the current time.
I hope this helps!
Upvotes: 1