如何在python/pygame中创建按钮?

时间:2021-07-05 13:51:06

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.

我在pygame做游戏,在第一个屏幕上,我想让你按下按钮(I)启动游戏,(ii)用指令加载一个新屏幕,然后(iii)退出程序。

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.

我在网上找到了这个代码,但我并不真正理解它(我不擅长面向对象编程)。如果我能解释一下它的作用,那就太好了。而且,当我使用它并尝试在我的计算机上使用文件路径打开一个文件时,我得到了错误sh: filepath:权限被拒绝,我不知道该如何解决。

#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 个解决方案

#1


12  

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. 创建一个PyGame表面,无论是图像或填充矩形。
    3. Render text on it with the Font.Render stuff in Pygame
    4. 用字体渲染文本。在Pygame呈现的东西
  2. 创建一个Button类,将文本按下按钮作为构造函数的参数创建一个PyGame表面,或者是一个图像或填充的Rect在其上使用字体显示文本。在Pygame呈现的东西
  3. Blit to game screen, save that rect.
  4. Blit到游戏屏幕,保存这个rect。
  5. 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.
  6. 在鼠标单击时,查看mouse.get_pos()与在rect中匹配的一个coord,它由按钮的blit返回到主界面。

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

这与您的示例所做的类似,尽管不同。

#2


0  

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:

因此,buttonify加载将在按钮上的图像。此图像必须是.jpg文件或与代码相同的目录中的任何其他图片文件。图片就是它的名称。名称必须有。jpg或其他任何东西,名称必须是引号。Buttonify的coords参数是屏幕或窗口的右上方的坐标,这是由pygame打开的。表面是这样的:

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.

所以它的功能是“image”,这是一个pygame的表面,它把一个矩形放在它的周围,叫做“imag勃起”(在一个位置上设置它,在blitting的时候设置第二个参数),然后它设置它的位置,然后在倒数第二个到最后一行。

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

下一段代码使“Image”(图像)成为“Image”和“imag”的tuple。

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.

最后一个代码是if事件。类型== MOUSEBUTTONDOWN和事件。按钮== 1:这基本上意味着如果按下鼠标左键。这段代码必须在pygame.event.get中进行。下一行使鼠标成为鼠标位置的元组。最后一行检查鼠标是否与图像[1]相冲突,如我们所知,这是“图像竖立”。代码如下。

Tell me if I need to explain further.

请告诉我是否需要进一步解释。

#3


0  

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

所以你必须创建一个名为button的函数,它接收8个参数。(1)按钮2)左上角的X位置,左上角的Y位置左上角的按钮,按钮的宽度,按钮的高度不活动的颜色(背景色),主动的颜色(当你悬停时的颜色),你想要做的动作的名字。

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" )

按钮(“开始”,600,120,120,25,蓝色,青色,“开始”)

#4


0  

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!

这是我很久以前做的一个按钮的类:https://www.dropbox.com/s/iq5djllnz0tncc1/button.py?在我记忆中,这个按钮是windows 7风格的,我最近还没能测试它,因为我在使用的电脑上没有pygame。希望这可以帮助!

#1


12  

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. 创建一个PyGame表面,无论是图像或填充矩形。
    3. Render text on it with the Font.Render stuff in Pygame
    4. 用字体渲染文本。在Pygame呈现的东西
  2. 创建一个Button类,将文本按下按钮作为构造函数的参数创建一个PyGame表面,或者是一个图像或填充的Rect在其上使用字体显示文本。在Pygame呈现的东西
  3. Blit to game screen, save that rect.
  4. Blit到游戏屏幕,保存这个rect。
  5. 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.
  6. 在鼠标单击时,查看mouse.get_pos()与在rect中匹配的一个coord,它由按钮的blit返回到主界面。

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

这与您的示例所做的类似,尽管不同。

#2


0  

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:

因此,buttonify加载将在按钮上的图像。此图像必须是.jpg文件或与代码相同的目录中的任何其他图片文件。图片就是它的名称。名称必须有。jpg或其他任何东西,名称必须是引号。Buttonify的coords参数是屏幕或窗口的右上方的坐标,这是由pygame打开的。表面是这样的:

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.

所以它的功能是“image”,这是一个pygame的表面,它把一个矩形放在它的周围,叫做“imag勃起”(在一个位置上设置它,在blitting的时候设置第二个参数),然后它设置它的位置,然后在倒数第二个到最后一行。

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

下一段代码使“Image”(图像)成为“Image”和“imag”的tuple。

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.

最后一个代码是if事件。类型== MOUSEBUTTONDOWN和事件。按钮== 1:这基本上意味着如果按下鼠标左键。这段代码必须在pygame.event.get中进行。下一行使鼠标成为鼠标位置的元组。最后一行检查鼠标是否与图像[1]相冲突,如我们所知,这是“图像竖立”。代码如下。

Tell me if I need to explain further.

请告诉我是否需要进一步解释。

#3


0  

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

所以你必须创建一个名为button的函数,它接收8个参数。(1)按钮2)左上角的X位置,左上角的Y位置左上角的按钮,按钮的宽度,按钮的高度不活动的颜色(背景色),主动的颜色(当你悬停时的颜色),你想要做的动作的名字。

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" )

按钮(“开始”,600,120,120,25,蓝色,青色,“开始”)

#4


0  

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!

这是我很久以前做的一个按钮的类:https://www.dropbox.com/s/iq5djllnz0tncc1/button.py?在我记忆中,这个按钮是windows 7风格的,我最近还没能测试它,因为我在使用的电脑上没有pygame。希望这可以帮助!