How to make buttons in python/pygame?

2019-02-13 20:20发布

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.

4条回答
Root(大扎)
2楼-- · 2019-02-13 20:26

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.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-02-13 20:34

Here is a class for a button I made ages ago: https://www.dropbox.com/s/iq5djllnz0tncc1/button.py?dl=0 The button is windows 7 style as far as I can remember, and I havent been able to test it recently because I do not have pygame on the computer I am using. Hope this helps!

查看更多
Animai°情兽
4楼-- · 2019-02-13 20:36

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.

查看更多
Ridiculous、
5楼-- · 2019-02-13 20:45

So you have to make a function named button which receives 8 parameters. 1)Message of button 2)X position of left top corner of the button 3)Y position of left top corner of the button 4)Width of the button 5)Height of button 6)Inactive color(background color) 7)Active color(color when you hover) 8)Name of the action you want to perfom

def button (msg, x, y, w, h, ic, ac, action=None ):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if (x+w > mouse[0] > x) and (y+h > mouse[1] > y):
        pygame.draw.rect(watercycle, CYAN, (x, y, w, h))
        if (click[0] == 1 and action != None):
            if  (action == "Start"):
                game_loop()
            elif  (action == "Load"):
                 ##Function that makes the loading of the saved file##
            elif  (action == "Exit"):
                pygame.quit()

    else:
        pygame.draw.rect(watercycle, BLUE, (x, y, w, h))
        smallText = pygame.font.Font("freesansbold.ttf", 20)
        textSurf, textRect = text_objects(msg, smallText)
        textRect.center = ( (x+(w/2)), (y+(h/2)) )
        watercycle.blit(textSurf, textRect)

So when you create your game loop and you call the button function:

button ("Start", 600, 120, 120, 25, BLUE, CYAN, "Start" )

查看更多
登录 后发表回答