Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make buttons in python/pygame?

I'm making a game in pygame and on the first screen I want there to be buttons that you can press to (i) start the game, (ii) load a new screen with instructions, and (iii) exit the program.

I've found this code online for button making, but I don't really understand it (I'm not that good at object oriented programming). If I could get some explanation as to what it's doing that would be great. Also, when I use it and try to open a file on my computer using the file path, I get the error sh: filepath :Permission denied, which I don't know how to solve.

#load_image is used in most pygame programs for loading images
def load_image(name, colorkey=None):
    fullname = os.path.join('data', name)
    try:
        image = pygame.image.load(fullname)
    except pygame.error, message:
        print 'Cannot load image:', fullname
        raise SystemExit, message
    image = image.convert()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0,0))
        image.set_colorkey(colorkey, RLEACCEL)
    return image, image.get_rect()
class Button(pygame.sprite.Sprite):
    """Class used to create a button, use setCords to set 
        position of topleft corner. Method pressed() returns
        a boolean and should be called inside the input loop."""
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image('button.png', -1)

    def setCords(self,x,y):
        self.rect.topleft = x,y

    def pressed(self,mouse):
        if mouse[0] > self.rect.topleft[0]:
            if mouse[1] > self.rect.topleft[1]:
                if mouse[0] < self.rect.bottomright[0]:
                    if mouse[1] < self.rect.bottomright[1]:
                        return True
                    else: return False
                else: return False
            else: return False
        else: return False
def main():
    button = Button() #Button class is created
    button.setCords(200,200) #Button is displayed at 200,200
    while 1:
        for event in pygame.event.get():
            if event.type == MOUSEBUTTONDOWN:
                mouse = pygame.mouse.get_pos()
                if button.pressed(mouse):   #Button's pressed method is called
                    print ('button hit')
if __name__ == '__main__': main()

Thank you to anyone who can help me.

like image 666
user1334014 Avatar asked Apr 16 '12 03:04

user1334014


3 Answers

I don't have a code example for you, but how I would do it is to:

  1. Make a Button class, with the text to go on the button as a constructor argument
    1. Create a PyGame surface, either of an image or filled Rect
    2. Render text on it with the Font.Render stuff in Pygame
  2. Blit to game screen, save that rect.
  3. Check, on mouse click, to see the mouse.get_pos() matches a coord in the rect that it returned by the blit of the button to the main surface.

That is similar to what your example is doing, although different still.

like image 147
TankorSmash Avatar answered Oct 24 '22 20:10

TankorSmash


Another good way to create buttons on pygame (in Python) is by installing the package called pygame_widgets (pip3 install pygame_widgets).

# Importing modules
import pygame as pg
import pygame_widgets as pw

# Creating screen
pg.init()
screen = pg.display.set_mode((800, 600))
running = True
button = pw.Button(
    screen, 100, 100, 300, 150, text='Hello',
    fontSize=50, margin=20,
    inactiveColour=(255, 0, 0),
    pressedColour=(0, 255, 0), radius=20,
    onClick=lambda: print('Click')
)

While running:

events = pg.event.get()
for event in events:
    if event.type == pg.QUIT:
        running = False
button.listen(events)
button.draw()
pg.display.update()
like image 22
PranavKarthik Avatar answered Oct 24 '22 21:10

PranavKarthik


The 'code' you have found online is not that good. All you need to make a button is this. Put this near the beginning of your code:

def Buttonify(Picture, coords, surface):
    image = pygame.image.load(Picture)
    imagerect = image.get_rect()
    imagerect.topright = coords
    surface.blit(image,imagerect)
    return (image,imagerect)

Put the following in your game loop. Also somewhere in your game loop:

Image = Buttonify('YOUR_PICTURE.png',THE_COORDS_OF_THE_BUTTON'S_TOP_RIGHT_CORNER, THE_NAME_OF_THE_SURFACE)

Also put this in your game loop wherever you have done for event in pygame.event.get

if event.type == MOUSEBUTTONDOWN and event.button == 1:
     mouse = pygame.mouse.getpos
     if Image[1].collidrect(mouse):
        #code if button is pressed goes here

So, buttonify loads the image that will be on the button. This image must be a .jpg file or any other PICTURE file in the same directory as the code. Picture is its name. The name must have .jpg or anything else after it and the name must be in quotation marks. The coords parameter in Buttonify is the top-right coordinate on your screen or window that opens from pygame. The surface is this thing:

blahblahblah = pygame.surface.set_mode((WindowSize))
 /|\
  |
  Surface's Name

So it the function makes something called 'image' which is a pygame surface, it puts a rectangle around it called 'imagerect' (to set it at a location and for the second parameter when blitting,) and then it sets it's location, and blits it on the second to last last line.

The next bit of code makes 'Image' a tuple of both 'image' and 'imagerect.'

The last code has if event.type == MOUSEBUTTONDOWN and event.button == 1: which basically means if the left mouse button is pressed. This code MUST be in for event in pygame.event.get. The next line makes mouse a tuple of the mouses position. The last line checks if the mouse collided with Image[1] which as we know is 'imagerect.' The code follows that.

Tell me if I need to explain further.

like image 28
SnootierBaBoon Avatar answered Oct 24 '22 21:10

SnootierBaBoon