Pygame 个按钮未创建工作按钮

Pygame buttons not creating working buttons

我正在尝试在 pygame 中制作刽子手游戏,但在从事件创建按钮后(在我的情况下,在按下 enter 后)我无法让按钮工作,它们出现在屏幕上但是不工作(翻转或激活事件),请帮助!

from pygame.locals import *
import pygame, sys, eztext
import time

pygame.init()

Black      = (  0,   0,   0)
Grey       = (100, 100, 100)
DarkGrey   = (70,   70,  70)
White      = (255, 255, 255)
Blue       = (  0,   0, 255)
NavyBlue   = ( 60,  60, 100)
Cyan       = (  0, 255, 255)
Purple     = (255,   0, 255)
Red        = (255,   0,   0)
DarkRed    = (180,   0,   0)
Orange     = (255, 128,   0)
Yellow     = (255, 255,   0)
Green      = (  0, 255,   0)
DarkGreen  = (  0, 180,   0)
LightBlue  = ( 90, 164, 213)
Magenta    = (153,   0,  76)

screen = pygame.display.set_mode((1000,600),0,32)
screen.fill(Orange)
txtbx = eztext.Input(maxlength=45, color=(0,0,0), prompt='Enter username: ')

def text_objects(text, font):
    textSurface = font.render(text, True, Black)
    return textSurface, textSurface.get_rect()
smallText = pygame.font.Font("freesansbold.ttf",20)

def button(msg,x,y,w,h,ic,ac,action=None):
    if x+w > mouse[0] > x and y+h > mouse[1] > y:  
        pygame.draw.rect(screen, ac,(x, y, w, h))     
        if click [0] == 1 and action!= None:          
            if action == "Quit":
                pygame.quit() 
            if action == "Single player":
                pygame.draw.rect(screen, Green,(10, 10, 500, 500))

    else:
        pygame.draw.rect(screen, ic,(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))) 
    screen.blit(textSurf, textRect)
    
while True:
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    
    string1 = txtbx.value
    pygame.display.update()
    time.sleep(0.02)
        
    pygame.draw.rect(screen, Green,(10, 100, 500, 50))
    
    clock = pygame.time.Clock()   
    clock.tick(30)
    
    events = pygame.event.get()
    
    txtbx.set_pos(10,110)

    label = smallText.render("Enter you user name and then press enter!", 1, (0,0,0)) 
    screen.blit(label, (10, 10))                                 

    for event in events:
   
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_KP_ENTER or event.key == pygame.K_RETURN:
                button("Single player",10, 400, 150, 50, Green, DarkGreen,"Single player")
                if string1 in open('Users.txt').read():
                    username = string1
                    Welcomeold1 = smallText.render('Welcome back', 1, (0,0,0))
                    screen.blit(Welcomeold1, (10, 200))
                    Welcomeold2 = smallText.render(username, 1, (0,0,0))
                    screen.blit(Welcomeold2, (160, 200))

                else:
                    username = string1
                    f = open('Users.txt','a')
                    string1 = txtbx.value
                    f.write(string1)
                    f.write('\n')                                           
                    f.close()
                    Welcomenew1 = smallText.render('Welcome to my game', 1, (0,0,0))
                    screen.blit(Welcomenew1, (10, 200))
                    Welcomenew2 = smallText.render(username, 1, (0,0,0))
                    screen.blit(Welcomenew2, (230, 200))
            if event.key == pygame.K_BACKSPACE:
                screen.fill(Orange)
                                                   
    txtbx.update(events)
    txtbx.draw(screen)
    pygame.display.flip()

if __name__ == '__main__': main()

button函数在event.key里面,所以只有当RETURN被按下,松开,再按下,再松开,等等

您应该使用方法 drawhandle_event 创建 class 以在不同位置的主循环中使用此方法。您可以在 event.key 中创建按钮,但您必须检查在不同位置按下的按钮。

-

简单的按钮。完整的工作示例。

当您按下按钮功能时 do_it 被调用并且背景颜色改变。

#
# pygame (simple) template - by furas
#

# ---------------------------------------------------------------------

import pygame
import pygame.gfxdraw
import random

# === CONSTANS === (UPPER_CASE names)

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

RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

CYAN    = (  0, 255, 255)
MAGENTA = (255,   0, 255)
YELLOW  = (255, 255,   0)

SCREEN_WIDTH  = 800
SCREEN_HEIGHT = 600

# === CLASSES === (CamelCase names)

class Button():

    def __init__(self, text, x, y, width, height, on_click=None, fg_color=RED, bg_color=WHITE, font_size=35):
        self.text = text

        font = pygame.font.SysFont(None, font_size)

        # rectangle - without position, to put text in correct place
        self.rect = pygame.Rect(0, 0, width, height)

        # normal button - fill background
        self.normal_image = pygame.surface.Surface( self.rect.size )
        self.normal_image.fill(bg_color)

        # normal button - add text
        text_image = font.render(text, True, fg_color)
        text_rect = text_image.get_rect(center=self.rect.center)
        self.normal_image.blit(text_image, text_rect)

        # hover button - fill background
        self.hover_image = pygame.surface.Surface( self.rect.size )
        self.hover_image.fill(fg_color)

        # hover button - add text
        text_image = font.render(text, True, bg_color)
        text_rect = text_image.get_rect(center=self.rect.center)
        self.hover_image.blit(text_image, text_rect)

        # set position 
        self.rect.x = x
        self.rect.y = y

        # other 
        self.on_click = on_click
        self.hover = False

    def draw(self, surface):
        # draw normal or hover image
        if self.hover:
            surface.blit(self.hover_image, self.rect)
        else:
            surface.blit(self.normal_image, self.rect)

    def event_handler(self, event):
        # is mouse over button ?
        if event.type == pygame.MOUSEMOTION:
            self.hover = self.rect.collidepoint(event.pos)

        # is mouse clicked ? run function.
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.hover and self.on_click:
                self.on_click()

# === FUNCTIONS === (lower_case names)

def do_it():
    global background_color

    if background_color == BLACK:
        background_color = RED
    elif background_color == RED:
        background_color = GREEN
    else:
        background_color = BLACK

    print("Button pressed")


# === MAIN ===

# --- init ---

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()

# --- objects ---

# create button
button = Button('CHANGE COLOR', 0, 0, 300, 50, on_click=do_it)

# add function later
#button_quit.on_click = do_it

# center button
button.rect.center = screen_rect.center

# default bacground color - changed in do_it()
background_color = BLACK

# --- mainloop ---

clock = pygame.time.Clock()
is_running = True

while is_running:

    # --- events ---

    for event in pygame.event.get():

        # --- global events ---

        if event.type == pygame.QUIT:
            is_running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                is_running = False

        # --- objects events ---

        button.event_handler(event)

    # --- updates ---

        # empty

    # --- draws ---

    # clear buffer
    screen.fill(background_color)

    # draw all objects - widgets (buttons, labels)

    button.draw(screen)

    clock.tick(25)

    # send buffer to video card 
    pygame.display.update()

# --- the end ---

pygame.quit()