Pygame: 如何在用户点击某个区域时显示一个新框,并在用户再次点击时关闭该框

Pygame: How to display a new box when user clicks an area, and close the box when the user clicks again

我是 python 和 pygame 的新手,我正在开发一个天气应用程序作为一个项目来学习这两者。

我想在用户单击屏幕的某个区域(=按钮)时显示一个新矩形。新矩形应该一直可见,直到用户再次单击,这次是在屏幕上的任意位置。

我在绘制屏幕的地方有我的主循环,然后检查事件 MOUSEBUTTONUP 并使用 collidepoint 检查鼠标是否在按钮上,然后更新变量 newscreenTrue

然后我有一个新循环,它应该是 运行,直到用户再次点击屏幕上的任意位置。 问题是一旦移动鼠标,新的 while 循环就会中断。它看起来也像第一个条件,检查用户是否单击按钮,在每次迭代中返回 true,直到移动鼠标。为什么这不仅返回 true 一次?

这可以在没有第二个 while 循环的情况下完成吗?

import pygame
import pygame.freetype
from pygame.locals import *
pygame.init()

SIZE = 500, 200
RED = (75, 0, 0)
NOTGREY = (75, 150, 150)

#set up the screen
screen = pygame.display.set_mode([800, 480])

# create rectangle
#Rect(position from left, position from top, width in pixels, height in pixels)
rect = Rect(50, 20, 200, 80)
rect2 = Rect(50,200, 200, 300)


running = True
newscreen = False
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_ESCAPE:
            pygame.quit()
            running = False

    screen.fill(NOTGREY)
    pygame.draw.rect(screen, RED, rect)

    # If user is clicking (on release of click) on the rectangle area update newscreen to true
    if event.type == pygame.MOUSEBUTTONUP:
        if event.button == 1:  # Left mouse button.
            if rect.collidepoint(event.pos):
                newscreen = True
                print("Clicking area")

    while newscreen == True:
        pygame.draw.rect(screen, RED, rect2)
        pygame.display.flip()
        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:  # Left mouse button.
                print("now you clicked again")
                newscreen = False

    pygame.display.flip()

您必须根据 newscreen 的状态绘制矩形:

if newscreen:
    pygame.draw.rect(screen, RED, rect2)
else: 
    pygame.draw.rect(screen, RED, rect)

所有事件都需要在一个事件循环中处理。单击按钮 (newscreen = not newscreen) 时切换 newscreen 的状态:

if event.type == pygame.MOUSEBUTTONUP:
    if event.button == 1:  # Left mouse button.
        if newscreen or rect.collidepoint(event.pos):
            newscreen = not newscreen

完整示例:

import pygame
import pygame.freetype
from pygame.locals import *
pygame.init()

SIZE = 500, 200
RED = (75, 0, 0)
NOTGREY = (75, 150, 150)

#set up the screen
screen = pygame.display.set_mode([800, 480])

# create rectangle
#Rect(position from left, position from top, width in pixels, height in pixels)
rect = Rect(50, 20, 200, 80)
rect2 = Rect(50,200, 200, 300)

running = True
newscreen = False
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                running = False
        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:  # Left mouse button.
                if newscreen or rect.collidepoint(event.pos):
                    newscreen = not newscreen

    screen.fill(NOTGREY)
    if newscreen:
       pygame.draw.rect(screen, RED, rect2)
    else: 
       pygame.draw.rect(screen, RED, rect)
    pygame.display.flip()

典型的 PyGame 应用程序循环必须:

我可能不会使用第二个 while 循环:

 while running:
        # keep loop running at the right speed
        clock.tick(30) // Frame per second
        screen.fill(BLACK) // never forget this line of code, especially when you work with animation
        pos = pygame.mouse.get_pos()
        # Process input (events)
        for event in pygame.event.get():
            # check for closing window
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                click = True

            if click:
                show_new_screen()
                click = False

如上所述,通过将所有事件添加到一个事件循环中解决了问题。我仍然希望在单击屏幕上的任意位置时关闭第二个框。通过为 MOUSEBUTTONDOWN 添加另一个事件检查来解决。再次举办 MOUSEBUTTONUP 活动无效。

running = True
newscreen = False
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                running = False
        # If user is clicking (on release of click) on the rectangle area update newscreen to true
        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:  # Left mouse button.
                if rect.collidepoint(event.pos):
                    newscreen = True
                    print("Clicking area")
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # Left mouse button.
                newscreen = False
                print("now you clicked again")

    screen.fill(NOTGREY)
    pygame.draw.rect(screen, RED, rect)

    if newscreen:
        pygame.draw.rect(screen, RED, rect2)

    pygame.display.flip()