如何在 pygame 窗口和函数之间转换



更新的代码:

import pygame
pygame.init()
width = 700
height = 700
running = True
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Dijkstra's Path-Finding Algorithm Solver")
icon = pygame.image.load('icon.jpg')
pygame.display.set_icon(icon)
def title_main():
title_font = pygame.font.Font('TrajanPro-Regular.otf', 40)
text_font = pygame.font.SysFont("comicsans", 30, bold=True)
Dijkstra_img = pygame.image.load('Dijkstra.jpg')
text1_display = title_font.render("Dijkstra's Path-Finding", True, (255, 255, 255))
text2_display = title_font.render('Algorithm', True, (255, 255, 255))
text3_display = text_font.render('Press any key to continue...', True, (255, 255, 255))
screen.blit(Dijkstra_img, (225, 40))
screen.blit(text1_display, (75, 400))
screen.blit(text2_display, (225, 460))
screen.blit(text3_display, (190, 550))
def title_game():
title_font = pygame.font.Font('TrajanPro-Regular.otf', 35)
title_display = title_font.render('Dijkstra Path-Finding Algorithm', True, (255, 255, 255))
screen.blit(title_display, (12, 15))
def title_underline():
rect = pygame.Rect(0, 60, 800, 3)
rect_display = pygame.draw.rect(screen, [255, 255, 255], rect)
title_font = pygame.font.Font('TrajanPro-Regular.otf', 100)
title_display = title_font.render('', True, (255, 255, 255))
screen.blit(title_display, (270, 198))
def grid():
grid_x = 0
grid_y = 63
blockSize = 20
for x in range(width):
for y in range(height):
rect = pygame.Rect(x*blockSize + grid_x, y*blockSize + grid_y, blockSize, blockSize)
pygame.draw.rect(screen, (200,200,200), rect, 1)
def game_loop():
game_is_active = True
while game_is_active:
for game_event in pygame.event.get():
if game_event.type == pygame.QUIT:
game_is_active = False
if game_event.type == pygame.MOUSEBUTTONDOWN:
start = print(pygame.mouse.get_pos())
print(start)
screen.fill((0, 0, 0))
title_game()
title_underline()
grid()
pygame.display.update()
while running:
for event in pygame.event.get():
screen.fill((0, 0, 0))
title_main()
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
running = game_loop()
pygame.display.update()

我已经在启动 GUI 时运行的功能下为我的项目创建了一个标题页,但我想做的是当用户按下任何键时,我想不再显示 title_main(( 函数,而只显示我的主应用程序。我使用 KEYDOWN 尝试执行此操作,但由于某种原因,它非常慢且无响应,并且仍然显示 title_main(( 函数。

@Cribber解释了现有循环不起作用的原因。

我想提供一个只使用单个事件循环的答案,因为我相信拥有一个简单的主循环是事件驱动程序(即:所有 PyGame 程序(的最佳架构。

您的程序分为两种状态,显示"标题页"和"主应用程序"。 我会将此状态保留在一个变量中,并基于它确定在主循环中采用的路径。 在绘制→输入→更新周期的每一步,检查状态(是否需要(并根据值进行操作。

# Function definitions as per question
# States the app can be in
TITLE_PAGE = 10   # TODO: maybe use an Enumerated Type
MAIN_APP   = 20
app_state = TITLE_PAGE  # start with the titles
while running:
# Handle user input
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if ( app_state == TITLE_PAGE ):
# user dismissed title page, switch to app-mode
app_state = MAIN_APP
# Update the screen
screen.fill((0, 0, 0))
if ( app_state == TITLE_PAGE ):   # In Title-page mode?
title_main()
elif ( app_state == MAIN_APP ):   # In Main-Application mode?
title_game()
title_underline()
grid()
pygame.display.update()

当然,当它像这样非常简单时,它的实现方式并不是什么大问题。 但随着程序变得越来越复杂,它有助于通过简单的步骤布置逻辑流程。 没有重复的事件循环代码块或屏幕绘制,因此(例如(如果存在用户输入错误,则它只能在一个位置。

编辑:处理第一次和第二次鼠标点击

处理两次鼠标点击非常容易。 只需要记住点击次数和"上一次"点击的位置。

这可以通过存储单个初始化变量first_click来实现,但从值None开始。 "无"很重要,因为它表示尚未单击。 因此,它会跟踪第一次/第二次点击,以及第一次点击的位置。

所以。。。

  • 如果用户尚未点击first_click == None
  • 如果first_click != None→ 第一个单击"确定",等待第二个。

在您的代码中,first_click称为start。 它只需要初始化为"无"。

start = None   # no clicks yet
def game_loop():
game_is_active = True
while game_is_active:
for game_event in pygame.event.get():
if game_event.type == pygame.QUIT:
game_is_active = False
if game_event.type == pygame.MOUSEBUTTONDOWN:
# Mouse has been clicked
if ( start == None ):             # Is this a first click?
# Save the First click 
start = pygame.mouse.get_pos()      
else:
# This is a second click, process both
handleTwoClicks( start, pygame.mouse.get_pos() )
# reset back to no-clicks-made
start = None

if event.type == pygame.KEYDOWN:下面块中的行只有在按下按钮时才会被执行 - 并且每个 KEYDOWN 只能执行一次!

由于在初始 pygame 之后没有单独的循环。KEYDOWN,您的while running:在执行一次title_game()title_underline()grid()功能后继续。然后循环重新开始,函数title_main()也会再次执行(这就是它仍然显示的原因(。

我认为您可能希望在注册 KEYDOWN 后实现另一个循环。

您还必须单独捕获此循环中的输入,因为您不会"返回"while running:循环中的for event in pygame.event.get():

我包含了更多清理版本的代码,并在显示您的title_main()后实现了游戏循环,因为我了解您的问题。

while running:  # your loop - display the title and wait for a button to be pressed
for event in pygame.event.get():  
screen.fill((0, 0, 0))
title_main()
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN: 
# start the actual game upon pressing a button for the first time
running = game_loop() # stop the loop if the game returns with False
pygame.display.update()

def game_loop():
game_is_active = True
while game_is_active :
for game_event in pygame.event.get():
if game_event.type == pygame.QUIT:
return False  # return to your outer loop
# game logic - display the title, the underline and the grid: 
screen.fill((0, 0, 0))
title_game()
title_underline()
grid()
pygame.display.update() # update screen

最新更新