Python Forum
[PyGame] Mouse.get_pressed() Overlapping Buttons
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Mouse.get_pressed() Overlapping Buttons
#1
Hi there.

I'm having trouble creating various menus with Pygame, since some of the menu buttons, although on different menu screens, share the same coordinates. So once one gets pressed, the next screen detects the button still being pressed and automatically triggers as well.

I'm wondering whether the variable imbued with .get_pressed() could be reset to it's original state, aka no buttons active?
I've tried to set a delay, but the issue persists through it, and changing the mouse position after the first press would seem like an unsuitable solution from the viewpoint of the Player - a simplistic menu that has to reset mouse position after every press?

As a note, the different menu screens are in the same general function, split between parts of it, to make navigating easier.
Reply
#2
(Dec-28-2016, 09:04 AM)KHendrikson Wrote: As a note, the different menu screens are in the same general function, split between parts of it, to make navigating easier.
Hard to say without seeing code, but this worries me.

I think you should look into how to design a multi scene program before continuing.
https://github.com/Mekire/pygame-mutisce...with-movie
Reply
#3
(Dec-28-2016, 09:12 AM)Mekire Wrote:
(Dec-28-2016, 09:04 AM)KHendrikson Wrote: As a note, the different menu screens are in the same general function, split between parts of it, to make navigating easier.
Hard to say without seeing code, but this worries me.

I think you should look into how to design a multi scene program before continuing.
https://github.com/Mekire/pygame-mutisce...with-movie

The code itself is pretty simple, since I'm new to Pygame. The screens share a similar background and thus the whole screen doesn't need to be updated each time, rather the contents of the menus, so I thought it would be easier to keep it within the same function. Do you think splitting it between functions would solve the issue?

menu = 'menu'
while True:
   mouse = pygame.mouse.get_pos()
   click = pygame.mouse.get_pressed()
   if menu == 'menu':
       # Displays main options menu
       # Looks for key presses to navigate through options (works great)
       # Looks for mouse position and presses:
       if x < mouse[0] < x+i and y < mouse[1] < y+j:
           if click[0] == 1:
               menu = 'attack'
       elif ...:
           if click[0] == 1:
               menu = 'item'
       elif ...:
           ...
   if menu == 'attack':
       # Displays the different attacks menu
       # Since the attack screen shares some button coordinates,
       # after switching menu = 'attack' it starts scanning for new input
       # relating to the new coordinates. And since the coordinates are
       # the same, and it still detects the button being pressed, it activates
       # the next button.

       # If you want to go back to the previous menu you'd just switch menu = 'menu' again
   if menu == 'item':
       # Displays the Item menu
       # ...
   pygame.display.update()
   clock.tick(30)


I've now also tried to split the menu between different functions, setting new variables for get_pos() and get_pressed() in them, but that has also failed to work.
Reply
#4
(Dec-28-2016, 09:25 AM)KHendrikson Wrote: Do you think splitting it between functions would solve the issue?
It really is necessary. You are going to end up with a global mess like this. Also you should be using rects for collision, and as far as I can tell you don't have an event loop.

Here is a basic template for what even the simplest pygame should look like:
https://gist.github.com/Mekire/f67d83087...0fb2939796

Beyond that you should look into how to make a button in a more Object Oriented fashion:
https://github.com/Mekire/pygame-button

Finally as I said, you should investigate a scene manager of sorts if you plan on having multiple different pages/scenes to your program.

Do you have a working version of your program you could link so that we can run it and see the exact problem?
Fixing your immediate problem may be easy enough but eventually you will need to address the above points.
Reply
#5
I'm sorry, we  do not help via PMs.

Quoting content so that others can assist:
Quote:The part of the program I'm currently working on is just a test to see how the menus could be set up. Keep in mind that I'm new to Pygame and thus the overall program management is quite messy :/ This particular piece of code returns the player's desired action.

It works fine with the arrow keys, but not with the mouse.

I've linked the .rar file containing the code file and images related to it.

I tried to split the code between functions.

https://www.dropbox.com/s/jjnj3jxxhwzofq...t.rar?dl=0

And the code:  

Quote:
import sys, pygame
pygame.init()
pygame.font.init()

def Actionz():
    myfont = pygame.font.SysFont("courier", 29, True)
    myfonttitle = pygame.font.SysFont("courier", 32, True)

    display_width = 1280
    display_height = 720

    gameDisplay = pygame.display.set_mode((display_width, display_height))
    pygame.display.set_caption('RPG')
    clock = pygame.time.Clock()

    backgroundimg = pygame.image.load('Background.jpg')
    actionbox = pygame.image.load('FightBox.png')
    cursor = pygame.image.load('MenuCursor.png')


    def Background(x, y):
        gameDisplay.blit(backgroundimg, (x, y))

    def ActionBox():
        gameDisplay.blit(actionbox, (0, display_height-214))

    def Cursor(x, y):
        gameDisplay.blit(cursor, (x, y))

    Background(0, 0)
    ActionBox()

    lasthovered = 'attack'
    menu = 'menu'

    while True:
        if menu == 'menu':
            ActionBox()
            mouse = pygame.mouse.get_pos()
            click = pygame.mouse.get_pressed()
            for event in pygame.event.get():
                mouse = pygame.mouse.get_pos()
                click = pygame.mouse.get_pressed()
                if event.type == pygame.KEYDOWN:
                    if lasthovered == 'attack':
                        if event.key == pygame.K_DOWN:
                            lasthovered = 'item'
                        elif event.key == pygame.K_RIGHT:
                            lasthovered = 'block'
                        elif event.key == pygame.K_RETURN:
                            menu = 'attack'
                            lasthovered = 'slash'
                    elif lasthovered == 'block':
                        if event.key == pygame.K_DOWN:
                            lasthovered = 'escape'
                        elif event.key == pygame.K_LEFT:
                            lasthovered = 'attack'
                        elif event.key == pygame.K_RETURN:
                            return 'block'
                    elif lasthovered == 'item':
                        if event.key == pygame.K_UP:
                            lasthovered = 'attack'
                        elif event.key == pygame.K_RIGHT:
                            lasthovered = 'escape'
                        elif event.key == pygame.K_RETURN:
                            menu = 'item'
                            lasthovered = 'yes'
                    elif lasthovered == 'escape':
                        if event.key == pygame.K_UP:
                            lasthovered = 'block'
                        elif event.key == pygame.K_LEFT:
                            lasthovered = 'item'
                        elif event.key == pygame.K_RETURN:
                            return 'escape'
                if event.type == pygame.QUIT:
                    exit()
            if lasthovered == 'attack':
                Cursor(display_width*0.3 - 40, display_height*0.82 - 16)
            elif lasthovered == 'block':
                Cursor(display_width*0.6 - 40, display_height*0.82 - 16)
            elif lasthovered == 'item':
                Cursor(display_width*0.3 - 40, display_height*0.909 - 14)
            elif lasthovered == 'escape':
                Cursor(display_width*0.6 - 40, display_height*0.909 - 14)
            if 320 < mouse[0] < 500 and 550 < mouse[1] < 600:
                lasthovered = 'attack'
                if click[0] == 1:
                    menu = 'attack'
                    lasthovered = 'slash'
            elif 770 < mouse[0] < 900 and 550 < mouse[1] < 600:
                lasthovered = 'block'
                if click[0] == 1:
                    return 'block'
            elif 400 < mouse[0] < 500 and 625 < mouse[1] < 675:
                lasthovered = 'item'
                if click[0] == 1:
                    menu = 'item'
                    lasthovered = 'yes'
            elif 775 < mouse[0] < 900 and 625 < mouse[1] < 675:
                lasthovered = 'escape'
                if click[0] == 1:
                    return 'escape'
        elif menu == 'item':
            option = Menu_Item()
            if option == 'back':
                menu = 'menu'
                lasthovered = 'attack'
            else:
                return option
        elif menu == 'attack':
            option = Menu_Attack()
            if option == 'back':
                menu = 'menu'
                lasthovered = 'attack'
            else:
                return option
        pygame.display.update()
        clock.tick(60)

def Menu_Item():
    gameDisplay = pygame.display.get_surface()

    myfontpotion = pygame.font.SysFont("courier", 36, True)
    cursor = pygame.image.load('MenuCursor.png')
    itembox = pygame.image.load('ItemBox.png')
    clock = pygame.time.Clock()

    display_width = 1280
    display_height = 720
    lasthovered = 'yes'

    def Cursor(x, y):
        gameDisplay.blit(cursor, (x, y))

    def ItemBox():
        gameDisplay.blit(itembox, (0, display_height-214))

    while True:
        ItemBox()
        mouse = pygame.mouse.get_pos()
        click = pygame.mouse.get_pressed()
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if lasthovered == 'yes':
                    if event.key == pygame.K_RIGHT:
                        lasthovered = 'no'
                    elif event.key == pygame.K_RETURN:
                        return 'item'
                elif lasthovered == 'no':
                    if event.key == pygame.K_LEFT:
                        lasthovered = 'yes'
                    elif event.key == pygame.K_RETURN:
                        return 'back'
                if event.key == pygame.K_BACKSPACE or event.key == pygame.K_ESCAPE:
                    menu = 'menu'
                    lasthovered = 'attack'
            if event.type == pygame.QUIT:
                exit()
        textsurfacename2 = myfontpotion.render('1', False, (106, 97, 81))
        gameDisplay.blit(textsurfacename2, (display_width * 0.5, display_height * 0.73 + 32))
        if lasthovered == 'yes':
            Cursor(display_width * 0.4 - 40, display_height * 0.909 - 16)
        elif lasthovered == 'no':
            Cursor(display_width * 0.5 - 28, display_height * 0.909 - 16)
        if 500 < mouse[0] < 575 and 625 < mouse[1] < 665:
            lasthovered = 'yes'
            if click[0] == 1:
                return 'item'
        elif 625 < mouse[0] < 700 and 625 < mouse[1] < 665:
            lasthovered = 'no'
            if click[0] == 1:
                return 'back'
        pygame.display.update()
        clock.tick(60)

def Menu_Attack():
    gameDisplay = pygame.display.get_surface()

    cursor = pygame.image.load('MenuCursor.png')
    fightbox = pygame.image.load('FightBoxes.png')
    clock = pygame.time.Clock()
    display_width = 1280
    display_height = 720
    lasthovered = 'slash'

    def Cursor(x, y):
        gameDisplay.blit(cursor, (x, y))

    def FightBox():
        gameDisplay.blit(fightbox, (0, display_height-214))

    while True:
        FightBox()
        mouse = pygame.mouse.get_pos()
        click = pygame.mouse.get_pressed()
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if lasthovered == 'slash':
                    if event.key == pygame.K_DOWN:
                        lasthovered = 'stab'
                    elif event.key == pygame.K_RIGHT:
                        lasthovered = 'chop'
                    elif event.key == pygame.K_RETURN:
                        return 'aslash'
                elif lasthovered == 'chop':
                    if event.key == pygame.K_DOWN:
                        lasthovered = 'back'
                    elif event.key == pygame.K_LEFT:
                        lasthovered = 'slash'
                    elif event.key == pygame.K_RETURN:
                        return 'achop'
                elif lasthovered == 'stab':
                    if event.key == pygame.K_UP:
                        lasthovered = 'slash'
                    elif event.key == pygame.K_RIGHT:
                        lasthovered = 'back'
                    elif event.key == pygame.K_RETURN:
                        return 'astab'
                elif lasthovered == 'back':
                    if event.key == pygame.K_UP:
                        lasthovered = 'chop'
                    elif event.key == pygame.K_LEFT:
                        lasthovered = 'stab'
                    elif event.key == pygame.K_RETURN:
                        return 'back'
                if event.key == pygame.K_BACKSPACE or event.key == pygame.K_ESCAPE:
                    menu = 'menu'
                    lasthovered = 'attack'
            elif event.type == pygame.QUIT:
                exit()
        if lasthovered == 'slash':
            Cursor(display_width * 0.3 - 40, display_height * 0.82 - 16)
        elif lasthovered == 'chop':
            Cursor(display_width * 0.6 - 40, display_height * 0.82 - 16)
        elif lasthovered == 'stab':
            Cursor(display_width * 0.3 - 40, display_height * 0.909 - 14)
        elif lasthovered == 'back':
            Cursor(display_width * 0.6 - 40, display_height * 0.909 - 14)
        if 380 < mouse[0] < 500 and 570 < mouse[1] < 600:
            lasthovered = 'slash'
            if click[0] == 1:
                return 'aslash'
        elif 800 < mouse[0] < 875 and 570 < mouse[1] < 600:
            lasthovered = 'chop'
            if click[0] == 1:
                return 'achop'
        elif 400 < mouse[0] < 475 and 630 < mouse[1] < 660:
            lasthovered = 'stab'
            if click[0] == '1':
                return 'astab'
        elif 800 < mouse[0] < 875 and 630 < mouse[1] < 660:
            lasthovered = 'back'
            if click[0] == 1:
                return 'back'
        pygame.display.update()
        clock.tick(60)

print(Actionz())

Not to be too harsh, but this is a bit of a mess.  However, I can tell you that what you are doing does not call for mouse.get_pressed().  You are trying to react to a mouse click, not a mouse hold.  You should be using pygame.MOUSEBUTTONDOWN events instead, just as you are doing for keys.
Reply
#6
(Dec-28-2016, 10:58 AM)Mekire Wrote: However, I can tell you that what you are doing does not call for mouse.get_pressed().  You are trying to react to a mouse click, not a mouse hold.  You should be using pygame.MOUSEBUTTONDOWN events instead, just as you are doing for keys.

Thanks a lot! I got it to work via MOUSEBUTTONDOWN.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020