【问题标题】:How to implement button interaction for Main Menu (Pygame)如何实现主菜单的按钮交互(Pygame)
【发布时间】:2019-01-05 21:21:30
【问题描述】:

我一直在看一堆教程,并且是 pygame 和一般编码的新手。我看过的教程都没有帮助我解决这个问题。我的目标是当用户将鼠标悬停在按钮上时按钮将按钮更改为不同的颜色。下面是我到目前为止的主菜单的全部代码。

import pygame
import time
import random

pygame.init()

size = (800, 600)
screen = pygame.display.set_mode(size)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)


pygame.display.set_caption("Basketball Shootout")
clock = pygame.time.Clock()

#GAME INTRO

def game_intro():

    intro = True

    while intro:
        for event in pygame.event.get():
            #print(event)
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

#Font's and text
font = pygame.font.SysFont ("Times New Norman", 60)
text = font.render ("", True, WHITE)

#Background Image
background_images = pygame.image.load("greybackground.jpg").convert()
screen.blit(background_images, [0,0])
screen.blit(text, (150, 50))

#Background Music
pygame.mixer.music.load('game.ogg')
pygame.mixer.music.set_endevent(pygame.constants.USEREVENT)
pygame.mixer.music.play()
pygame.display.update()
clock.tick(15)

#BUTTONS
screen.blit(text, (150, 50))
pygame.draw.rect(screen,(0,0,0),(300,300,205,80));
pygame.draw.rect(screen,(0,0,0),(300,400,205,80));
pygame.draw.rect(screen,(0,0,0),(300,500,205,80));

font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("START", True, WHITE)
screen.blit(text, (340, 320))
font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("OPTIONS", True, WHITE)
screen.blit(text, (340, 420))
font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("ABOUT", True, WHITE)
screen.blit(text, (340, 520))

pygame.display.flip();

#Quit Pygame
game_intro()
pygame.quit

【问题讨论】:

    标签: python button menu pygame main


    【解决方案1】:

    我建议将按钮数据(文本表面、矩形、颜色)存储在列表列表中。当鼠标移动时,pygame.MOUSEMOTION 事件被添加到事件队列中。在事件循环中,检查鼠标是否移动,然后遍历您的按钮并将colliding buttons 的颜色设置为悬停颜色,将其他按钮重置为黑色。也在 for 循环中对矩形和文本表面进行 Blit。

    import pygame
    
    
    pygame.init()
    
    screen = pygame.display.set_mode((800, 600))
    clock = pygame.time.Clock()
    
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    HOVER_COLOR = (50, 70, 90)
    # Don't define new font objects in your while loop (that's inefficient).
    FONT = pygame.font.SysFont ("Times New Norman", 60)
    # If the text surfaces and button rects don't change,
    # you can define them once outside of the while loop.
    text1 = FONT.render("START", True, WHITE)
    text2 = FONT.render("OPTIONS", True, WHITE)
    text3 = FONT.render("ABOUT", True, WHITE)
    rect1 = pygame.Rect(300,300,205,80)
    rect2 = pygame.Rect(300,400,205,80)
    rect3 = pygame.Rect(300,500,205,80)
    # The buttons consist of a text surface, a rect and a color.
    buttons = [
        [text1, rect1, BLACK],
        [text2, rect2, BLACK],
        [text3, rect3, BLACK],
        ]
    
    def game_intro():
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return
                elif event.type == pygame.MOUSEMOTION:
                    for button in buttons:
                        # button[1] is the rect. Use its collidepoint method with
                        # the `event.pos` (mouse position) to detect collisions.
                        if button[1].collidepoint(event.pos):
                            # Set the button's color to the hover color.
                            button[2] = HOVER_COLOR
                        else:
                            # Otherwise reset the color to black.
                            button[2] = BLACK
    
            screen.fill((20, 50, 70))
    
            # Draw the buttons with their current colors at their rects.
            # You can unpack the button lists directly in the head of the loop.
            for text, rect, color in buttons:
                pygame.draw.rect(screen, color, rect)
                screen.blit(text, rect)
    
            pygame.display.flip()
            clock.tick(15)
    
    
    game_intro()
    pygame.quit()
    

    我实际上建议定义一个Button 类,但我不确定您是否已经熟悉类/面向对象编程。

    按钮还需要回调函数来实际执行某些操作。看看我的回答:https://stackoverflow.com/a/47664205/6220679

    【讨论】:

    • 感谢您的回答,虽然我在更改背景图像时遇到了麻烦,但它帮助很大。当我尝试将您的代码实现到我自己的源代码中时,它只会显示背景图像而不会显示按钮。
    • 您可能必须重新排列代码的绘图部分。首先对背景进行 Blit,然后是按钮,最后调用 pygame.display.flip()。对了,你只需要每帧调用一次pygame.display.flippygame.display.update
    • 感谢它终于起作用了,我开始使用回调函数了
    【解决方案2】:

    我建议为此创建一个函数:

        mouse = pygame.mouse.get_pos()
        click = pygame.mouse.get_pressed()
    
        if x + w > mouse[0] > x and y + h > mouse[1] > y:
            gameDisplay.blit(active, (x, y))
        else:
            gameDisplay.blit(inactive, (x, y))
    

    然后在你的游戏介绍中调用你这样的函数:

    def game_intro():
    
        intro = True
    
        while intro:
            for event in pygame.event.get():
                #print(event)
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
    
            # For example
            button(100, 350, 195, 80, startBtn, startBtn_Hover)
    

    这是每个参数的含义:

    • x:按钮的 x 坐标
    • y:按钮的 y 坐标
    • w: 按钮宽度
    • h: 按钮高度
    • 活动:鼠标悬停在按钮上时的图片
    • 不活动:按钮空闲时的图片

    【讨论】:

      猜你喜欢
      • 2019-01-08
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-07
      • 1970-01-01
      相关资源
      最近更新 更多