LeoJolo2112
LeoJolo2112

Reputation: 3

Pygame.key.get_pressed recognized when not pressed

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

Answers (1)

Ethanol
Ethanol

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

Related Questions