单击以触发功能时,如何使代码工作并使用图像?

How do i make the code to work and use a image when clicked to trigger a function?

当我进入第二个 window 或带有图像的 window 时,我需要一个方法,它显示了 3 个汉堡图像,但我无法找到一种方法来点击图像和触发一个功能,让我可以询问他们是否想要菜单中的其他东西。

节目的图片在这里

# Imports
import pygame
from threading import Timer

# start the game
pygame.init()

w, h = 200, 300

# making the windows
window = pygame.display.set_mode((1280, 720))
window2 = pygame.display.set_mode((1280, 720))
window3 = pygame.display.set_mode((1280, 720))
# set up the games name
pygame.display.set_caption("Ordering Simulator")

# Variables
pyX = 1280
pyY = 720
nextWindow = 0
# sprites
beefSprite = pygame.image.load("Hamburger.png").convert_alpha()
beefSprite.convert()
rectBeef = beefSprite.get_rect()
rectBeef.center = w // 2, h // 2
# Set up the text
font = pygame.font.Font('freesansbold.ttf', 64)
font2 = pygame.font.Font('freesansbold.ttf', 30)
white = (255, 255, 255)
black = (0, 0, 0)
# Text
text = font.render("Welcome to Cesar's ordering sim", True, black, white)
text2 = font2.render("What would you like? We have beef, chicken and tofu sandwich.", True, white, black)
text3 = font2.render("So you have chosen.", True, white, black)
# icon
icon = pygame.image.load("cheeseburger.png")
pygame.display.set_icon(icon)
# setup text pt2
textRect = text.get_rect()
textRect2 = text2.get_rect()
textRect3 = text3.get_rect()
textRect.center = (pyX // 2, pyY // 2)
textRect2.midtop = (pyX // 2, pyY - 600)
textRect3.midtop = (pyX // 2, pyY - 600)
# add a background
bg = pygame.image.load("restaurant.jpg")
bg = pygame.transform.scale(bg, (1280, 720))


# define the background and the selection menu
def image():
    window2.blit(bg, (0, 0))
    window2.blit(beefSprite, (200, 300))
    window2.blit(text2, textRect2)


def selection1():
    window3.blit(text3, textRect3)


# timer setup
timer = Timer(3.0, image)
timerLoop = 0

# loop for game window
running = True
running2 = True
running3 = True
while running:
    window.blit(text, textRect)
    if timerLoop == 0:
        timer.start()
        timerLoop = timerLoop + 1
        nextWindow = nextWindow + 1
    else:
        running2 = True
        running = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            running2 = False
            running3 = False
    pygame.display.update()

# Second screen which starts the game
while running2:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            running2 = False
            running3 = False
        if nextWindow == 1:
            if event.type == pygame.MOUSEBUTTONDOWN:
                mousePos = pygame.mouse.get_pos()
                if beefSprite.get_rect().collidepoint(mousePos):
                    selection1()
                    nextWindow = nextWindow + 1
        else:
            running = False
            running2 = False
            running3 = True
pygame.display.update()

# third screen
while running3:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running3 = False
pygame.display.update()

我发现汉堡图片有两个问题

第一个:

您在 beefSprite 中有图像,并且在开始时您在 rectBeef

中设置了位置
rectBeef = beefSprite.get_rect()
rectBeef.center = w // 2, h // 2

但稍后您将鼠标位置与 beefSprite.get_rect()

进行比较
if beefSprite.get_rect().collidepoint(mousePos):

总是给出 (x,y) = (0,0) - 所以你与错误的矩形进行比较。

您应该使用 rectBeef 而不是 beefSprite.get_rect()

if rectBeef.collidepoint(mousePos):

第二个:

您显示图像使用的位置(200, 300)

window2.blit(beefSprite, (200, 300))

但你将鼠标位置与 rectBeef 进行比较,后者可能具有不同的位置

你应该再次使用 rectBeef

window2.blit(beefSprite, rectBeef)

位置(200, 300)你应该在开始时设置在rectBeef

rectBeef.lefttop = (200, 300)

或者你可以保留之前的位置

rectBeef.center = w // 2, h // 2

其他问题是 TimertimerLoop

Timer 等待 3 秒到 运行 image 但同时代码 运行s running = False 所以它从 while running 移动到 while running2 - 所以你仍然可以看到第一个屏幕,但代码可能已经 运行 第二个循环并检查 MOUSEBUTTONDOWN。您应该在 image() 中设置 running = False,它会在 3 秒后执行。

或者您应该使用 pygame.timer 检查当前时间并在 3 秒后退出第一个循环,然后显示图像和 运行 第二个循环


其他“问题”是windowwindow2window3.

PyGame 只能显示一个 window - 所以创建 3 个 windows 没有任何意义。你可以画在一个window.

如果你想在window中切换内容,那么你可以创建3个Surface(),并在这些表面上进行blit,以后你可以在不同的时刻blit不同的表面。


编辑:

我的版本有修复。我还使用 pygame.time 而不是 threading.Timer 但它可以为此使用特殊的 event

但我看到一个缺点:它不能从 window 3 返回到 window 2。它必须 运行 两个 windows 合而为一 while-循环 if nextWindow == 2:if nextWindow == 3:

import pygame

# --- constants --- 

w, h = 200, 300

pyX = 1280
pyY = 720

white = (255, 255, 255)
black = (0, 0, 0)

# --- functions ---

def draw_window1():
    window.blit(bg, (0, 0))
    window.blit(text1, textRect1)

def draw_window2():
    window.blit(bg, (0, 0))
    window.blit(beefSprite, rectBeef)
    window.blit(text2, textRect2)

def draw_window3():
    window.blit(bg, (0, 0))
    window.blit(text3, textRect3)

# --- main ---

# start the game
pygame.init()

# making the windows
window = pygame.display.set_mode((1280, 720))

# set up the games name
pygame.display.set_caption("Ordering Simulator")

# Variables
nextWindow = 0

# sprites
beefSprite = pygame.image.load("Hamburger.png").convert_alpha()
rectBeef = beefSprite.get_rect()
rectBeef.center = window.get_rect().center

# Set up the text
font1 = pygame.font.Font('freesansbold.ttf', 64)
font2 = pygame.font.Font('freesansbold.ttf', 30)

# Text
text1 = font1.render("Welcome to Cesar's ordering sim", True, black, white)
text2 = font2.render("What would you like? We have beef, chicken and tofu sandwich.", True, white, black)
text3 = font2.render("So you have chosen.", True, white, black)

# icon
icon = pygame.image.load("cheeseburger.png")
pygame.display.set_icon(icon)

# setup text pt2
textRect1 = text1.get_rect()
textRect2 = text2.get_rect()
textRect3 = text3.get_rect()
textRect1.center = (pyX // 2, pyY // 2)
textRect2.midtop = (pyX // 2, pyY - 600)
textRect3.midtop = (pyX // 2, pyY - 600)

# add a background
bg = pygame.image.load("restaurant.jpg")
bg = pygame.transform.scale(bg, (1280, 720))

# loop for game window
running1 = True
running2 = True
running3 = True

# timer setup
current_time = pygame.time.get_ticks()
loop_end = current_time + 3000  # 3000ms

print('[DEBUG] first')

draw_window1()

while running1:

    current_time = pygame.time.get_ticks()
    
    if current_time >= loop_end:
        nextWindow = nextWindow + 1
        running1 = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running1 = False
            running2 = False
            running3 = False
            
    pygame.display.update()

# Second screen which starts the game
print('[DEBUG] second')

draw_window2()

while running2:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            #running1 = False
            running2 = False
            running3 = False
            
        if event.type == pygame.MOUSEBUTTONDOWN:
            if rectBeef.collidepoint(event.pos):
                nextWindow = nextWindow + 1
                running2 = False
            
    pygame.display.update()

# third screen
print('[DEBUG] third')

draw_window3()

while running3:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            #running1 = False
            #running2 = False
            running3 = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            nextWindow = nextWindow + 1
            running3 = False
            
    pygame.display.update()

# --- end ---

pygame.quit()  # some systems need it to close window

编辑:

版本 window 2 和 window 3 在一个 while 循环中 - 所以你可以从 window 3 返回到 window 2,然后再次转到 window 3 并再次返回 window 2,等等

import pygame

# --- constants --- 

w, h = 200, 300

pyX = 1280
pyY = 720

white = (255, 255, 255)
black = (0, 0, 0)

# --- functions ---

def draw_window1():
    window.blit(bg, (0, 0))
    window.blit(text1, textRect1)

def draw_window2():
    window.blit(bg, (0, 0))
    window.blit(beefSprite, rectBeef)
    window.blit(text2, textRect2)

def draw_window3():
    window.blit(bg, (0, 0))
    window.blit(text3, textRect3)
    window.blit(text3a, text3a_rect)
    window.blit(text3b, text3b_rect)

# --- main ---

# start the game
pygame.init()

# making the windows
window = pygame.display.set_mode((1280, 720))

# set up the games name
pygame.display.set_caption("Ordering Simulator")

# Variables
nextWindow = 0

# sprites
beefSprite = pygame.image.load("Hamburger.png").convert_alpha()
rectBeef = beefSprite.get_rect()
rectBeef.center = window.get_rect().center

# Set up the text
font1 = pygame.font.Font('freesansbold.ttf', 64)
font2 = pygame.font.Font('freesansbold.ttf', 30)

# Text
text1 = font1.render("Welcome to Cesar's ordering sim", True, black, white)
text2 = font2.render("What would you like? We have beef, chicken and tofu sandwich.", True, white, black)
text3 = font2.render("So you have chosen.", True, white, black)

text3a = font2.render("BACK", True, white, black)
text3a_rect = text3a.get_rect(center=window.get_rect().center)
text3a_rect.x -= 200

text3b = font2.render("NEXT (EXIT)", True, white, black)
text3b_rect = text3b.get_rect(center=window.get_rect().center)
text3b_rect.x += 200

# icon
#icon = pygame.image.load("cheeseburger.png")
#pygame.display.set_icon(icon)

# setup text pt2
textRect1 = text1.get_rect()
textRect2 = text2.get_rect()
textRect3 = text3.get_rect()
textRect1.center = (pyX // 2, pyY // 2)
textRect2.midtop = (pyX // 2, pyY - 600)
textRect3.midtop = (pyX // 2, pyY - 600)

# add a background
bg = pygame.image.load("restaurant.jpg")
bg = pygame.transform.scale(bg, (1280, 720))

# loop for game window
running1 = True
running2 = True

# timer setup
current_time = pygame.time.get_ticks()
loop_end = current_time + 3000  # 3000ms

print('[DEBUG] first')

draw_window1()

while running1:

    current_time = pygame.time.get_ticks()
    
    if current_time >= loop_end:
        nextWindow = nextWindow + 1
        running1 = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running1 = False
            running2 = False
            
    pygame.display.update()

# Second screen which starts the game
print('[DEBUG] second & third')

nextWindow = 2

while running2:

    if nextWindow == 2:
    
        draw_window2()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                #running1 = False
                running2 = False
                
            if event.type == pygame.MOUSEBUTTONDOWN:
                if rectBeef.collidepoint(event.pos):
                    nextWindow = nextWindow + 1


    elif nextWindow == 3:
        draw_window3()
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                #running1 = False
                running2 = False

            if event.type == pygame.MOUSEBUTTONDOWN:
                if text3a_rect.collidepoint(event.pos):
                    nextWindow = nextWindow - 1
                if text3b_rect.collidepoint(event.pos):
                    nextWindow = nextWindow + 1
                    running2 = False
        
    pygame.display.update()

# --- end ---

pygame.quit()  # some systems need it to close window