gpt4 book ai didi

button - 在 PyGame 中创建按钮

转载 作者:行者123 更新时间:2023-12-04 15:13:18 31 4
gpt4 key购买 nike

我正在制作一个自动时间表的程序,我已经设法创建了一个标题,但我想添加一个登录和注册按钮,进入一个新页面。我还想在这些新页面上添加一个返回按钮。我正在使用programmingpixels.com 来提供帮助,但我仍然无法做我想做的事情。我是使用 PyGame 的新手,所以我可能没有像我本可以做的那样编写有效的代码,并且可能有很多错误。我的标题屏幕以前可以工作,但是当我尝试添加这些按钮时,它是空白的,不会让我退出屏幕。任何帮助都会很棒。谢谢你。

import pygame

import pygame.freetype

from pygame.sprite import Sprite

from pygame.rect import Rect

from enum import Enum

PINK = (250, 100, 100)

WHITE = (255, 255, 255)

BLACK = (0,0,0)

def create_surface_with_text(text, font_size, text_rgb, bg_rgb):

font = pygame.freetype.SysFont("Arial", font_size, bold=True)

surface, _ = font.render(text=text, fgcolor=text_rgb, bgcolor=bg_rgb)

return surface.convert_alpha()


class UIElement(Sprite):

def __init__(self, center_position, text, font_size, bg_rgb, text_rgb, action=None):

self.mouse_over = False

# what happens when the mouse is not over the element
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb, bg_rgb=bg_rgb
)

# what happens when the mouse is over the element
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.1, text_rgb=text_rgb, bg_rgb=bg_rgb
)

self.images = [default_image, highlighted_image]

self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]

self.action = action

super().__init__()

@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]

@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]

def update(self, mouse_pos, mouse_up):
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
else:
self.mouse_over = False

def draw(self, surface):
surface.blit(self.image, self.rect)


def main():
pygame.init()

screen = pygame.display.set_mode((800, 600))
game_state = GameState.LOGIN

while True:
if game_state == GameState.LOGIN:
game_state = log_in(screen)

if game_state == GameState.SIGNUP:
game_state = sign_up(screen)

if game_state == GameState.RETURN:
game_state = title_screen(screen)

if game_state == GameState.QUIT:
pygame.quit()
return

def title_screen(screen):

login_btn = UIElement(

center_position=(400,300),

font_size=30,

bg_rgb=WHITE,

text_rgb=BLACK,

text="Log In",

action=GameState.LOGIN,

)

signup_btn = UIElement(
center_position=(400,200),
font_size=30,
bg_rgb=WHITE,
text_rgb=BLACK,
text="Log In",
action=GameState.LOGIN,
)

uielement = UIElement(
center_position=(400, 100),
font_size=40,
bg_rgb=PINK,
text_rgb=BLACK,
text="Welcome to the Automated Timetable Program",
action=GameState.QUIT,
)

buttons = [login_btn, signup_btn]

while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
elif event.type == pygame.QUIT:
pygame.quit()
sys.exitIO
screen.fill(PINK)

for button in buttons:
ui_action = button.update(pygame.mouse.get_pos(),mouse_up)
if ui_action is not None:
return ui_action
button.draw(screen)

pygame.display.flip()

def log_in(screen):

return_btn = UIElement(

center_position=(140, 570),

font_size=20,

bg_rgb=WHITE,

text_rgb=BLACK,

text="Return to main menu",

action=GameState.TITLE,

)

while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
screen.fill(PINK)

ui_action = return_btn.update(pygame.mouse.get_pos(),mouse_up)
if ui_action is not None:
return ui_action
return_btn.draw(screen)

pygame.display.flip()

class GameState(Enum):

LOGIN = -1

SIGNUP = 0

RETURN = 1

QUIT = 2


if __name__ == "__main__":

main()

最佳答案

对于初学者 GameState丢失 TITLE值(value)。

class GameState(Enum):
# ...
TITLE = 3
添加它会使代码运行。 log_in()函数不处理正在关闭的窗口。您必须处理 pygame.QUIT事件,在每个事件循环中。例如:
def log_in( screen ):
# ...

while True:
mouse_up = False
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
pygame.event.post( pygame.event.Event( pygame.QUIT ) ) # re-send the quit event to the next loop
return GameState.QUIT
elif ( event.type == pygame.MOUSEBUTTONUP and event.button == 1 ):
mouse_up = True # Mouse button 1 weas released

ui_action = return_btn.update( pygame.mouse.get_pos(), mouse_up )
if ui_action is not None:
print( "log_in() - returning action" )
return ui_action

screen.fill(PINK)
return_btn.draw(screen)
pygame.display.flip()
UIElement.update()看起来它应该返回 self.action当鼠标按钮在控件上释放时。但是,在现有代码中,没有返回任何内容。可能它需要是这样的:
class UIElement( Sprite ):
# ...
def update(self, mouse_pos, mouse_up):
""" Track the mouse, setting the self.mouse_over. Also check
if the mouse-button was clicked while over this control
returning the pre-defined self.action, if so. """

result = None # No click => no action
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
if ( mouse_up ):
result = self.action # Mouse was clicked on element, add action
else:
self.mouse_over = False
return result
在这些更改之后,您的脚本运行正常,然后在单击按钮时进入外部循环。外循环也不能正确处理退出,但可能只是再次进行相同的更改。
最好只有一个用户输入处理循环。拥有这些单独的事件循环会在多个位置导致相同的问题。找出一种方法来拥有单个事件处理功能,然后调整您的 UI 代码以使用它。这将使您的代码更容易编写和调试。
引用:所有代码
import pygame

import pygame.freetype

from pygame.sprite import Sprite

from pygame.rect import Rect

from enum import Enum

PINK = (250, 100, 100)

WHITE = (255, 255, 255)

BLACK = (0,0,0)

def create_surface_with_text(text, font_size, text_rgb, bg_rgb):

font = pygame.freetype.SysFont("Arial", font_size, bold=True)

surface, _ = font.render(text=text, fgcolor=text_rgb, bgcolor=bg_rgb)

return surface.convert_alpha()


class UIElement(Sprite):

def __init__(self, center_position, text, font_size, bg_rgb, text_rgb, action=None):

self.mouse_over = False

# what happens when the mouse is not over the element
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb, bg_rgb=bg_rgb
)

# what happens when the mouse is over the element
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.1, text_rgb=text_rgb, bg_rgb=bg_rgb
)

self.images = [default_image, highlighted_image]

self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]

self.action = action

super().__init__()

@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]

@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]

def update(self, mouse_pos, mouse_up):
""" Track the mouse, setting the self.mouse_over. Also check
if the mouse-button was clicked while over this control
returning the pre-defined self.action, if so. """

result = None # No click => no action
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
if ( mouse_up ):
result = self.action # Mouse was clicked on element, add action
else:
self.mouse_over = False
return result


def draw(self, surface):
surface.blit(self.image, self.rect)


def main():
pygame.init()

screen = pygame.display.set_mode((800, 600))
game_state = GameState.LOGIN

while True:
if game_state == GameState.LOGIN:
game_state = log_in(screen)

if game_state == GameState.SIGNUP:
game_state = sign_up(screen)

if game_state == GameState.RETURN:
game_state = title_screen(screen)

if game_state == GameState.QUIT:
pygame.quit()
return

def title_screen(screen):

login_btn = UIElement(
center_position=(400,300),
font_size=30,
bg_rgb=WHITE,
text_rgb=BLACK,
text="Log In",
action=GameState.LOGIN,
)

signup_btn = UIElement(
center_position=(400,200),
font_size=30,
bg_rgb=WHITE,
text_rgb=BLACK,
text="Log In",
action=GameState.LOGIN,
)

uielement = UIElement(
center_position=(400, 100),
font_size=40,
bg_rgb=PINK,
text_rgb=BLACK,
text="Welcome to the Automated Timetable Program",
action=GameState.QUIT,
)

buttons = [login_btn, signup_btn]

while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
elif event.type == pygame.QUIT:
pygame.quit()
sys.exitIO
screen.fill(PINK)

for button in buttons:
ui_action = button.update(pygame.mouse.get_pos(),mouse_up)
if ui_action is not None:
return ui_action
button.draw(screen)

pygame.display.flip()

def log_in(screen):

return_btn = UIElement(
center_position=(140, 570),
font_size=20,
bg_rgb=WHITE,
text_rgb=BLACK,
text="Return to main menu",
action=GameState.TITLE,
)

while True:
mouse_up = False
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
pygame.event.post( pygame.event.Event( pygame.QUIT ) ) # re-send the quit event to the next loop
return GameState.QUIT
elif ( event.type == pygame.MOUSEBUTTONUP and event.button == 1 ):
mouse_up = True # Mouse button 1 weas released

ui_action = return_btn.update( pygame.mouse.get_pos(), mouse_up )
if ui_action is not None:
print( "log_in() - returning action" )
return ui_action

screen.fill(PINK)
return_btn.draw(screen)
pygame.display.flip()



class GameState(Enum):

LOGIN = -1
SIGNUP = 0
RETURN = 1
QUIT = 2
TITLE=3


if __name__ == "__main__":

main()

关于button - 在 PyGame 中创建按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64802223/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com