为何游戏循环卡在点击检测函数,添加空print语句却能正常运行?
Pizza Clicker游戏卡顿问题解决
问题重现
开发的Pizza Clicker游戏加载图片后,游戏循环卡在点击检测逻辑,无法正常响应其他操作。诡异的是在游戏循环中添加print("")语句后,游戏就能正常运行。尝试过临时循环但无效,原代码如下:
import pygame import time import random pygame.display.set_caption('Pizza Clicker') RESOLUTION = (137, 78) PIZZARE = (6, 15) pygame.init() from pygame.locals import* window = pygame.display.set_mode (RESOLUTION, pygame.SCALED) #Functions def Quit(): global running for event in pygame.event.get(): if event.type == pygame.QUIT: running = False def Images(BackG, PizzaU): window.fill((255,255,255)) backgrounds = [] backgrounds.append(pygame.image.load('ClickerBackground.png')) pizzas = [] pizzas.append(pygame.image.load('0Pizza.png')) pizzas.append(pygame.image.load('1Pizza.png')) Images.P = pizzas[int(PizzaU)] window.blit(backgrounds[BackG], (0, 0)) window.blit(Images.P,(PIZZARE)) pygame.display.update() def ClickDetect(): pizzarect = Images.P.get_rect(center = (21, 30)) curpos = pygame.mouse.get_pos() for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONDOWN: if pizzarect.collidepoint(curpos): print("Click.") running = True background = 0 pizzarect = 0 curpos = 0 while running: Quit() Images(0, 0) ClickDetect() pygame.quit()
问题根源
- 事件队列被重复消费:
Quit()和ClickDetect()两个函数都调用了pygame.event.get(),事件被其中一个函数取走后,另一个函数无法获取到事件,进而造成循环阻塞。 - 循环内重复加载图片:
Images()函数每次循环都重新加载背景和披萨图片,IO操作的耗时直接拖慢了游戏运行,也是卡顿的重要诱因。 - 点击检测坐标不匹配:
get_rect(center=(21,30))设置的碰撞区域和图片实际绘制位置PIZZARE=(6,15)不对应,可能导致点击检测逻辑异常。 print("")能临时解决是因为该操作会触发控制台缓冲区刷新,间接调整了事件处理的时序,但这只是巧合,并非根本解决方案。
修复方案
修改后的完整代码
import pygame import random # 初始化配置 pygame.display.set_caption('Pizza Clicker') RESOLUTION = (137, 78) PIZZARE = (6, 15) pygame.init() from pygame.locals import * window = pygame.display.set_mode(RESOLUTION, pygame.SCALED) # 提前加载所有资源(仅执行一次) background_img = pygame.image.load('ClickerBackground.png') pizza_imgs = [ pygame.image.load('0Pizza.png'), pygame.image.load('1Pizza.png') ] current_pizza = pizza_imgs[0] def render_frame(): """绘制游戏帧""" window.fill((255, 255, 255)) window.blit(background_img, (0, 0)) window.blit(current_pizza, PIZZARE) pygame.display.update() running = True while running: # 统一处理所有事件,避免重复消费 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN: # 基于图片绘制位置生成碰撞矩形,确保检测准确 pizza_rect = current_pizza.get_rect(topleft=PIZZARE) if pizza_rect.collidepoint(event.pos): print("Click.") # 示例:点击后切换披萨图片 # current_pizza = pizza_imgs[1] render_frame() pygame.quit()
关键修改点
- 统一事件处理:将所有事件逻辑集中在主循环的
pygame.event.get()遍历中,确保每个事件只被处理一次,避免队列冲突。 - 预加载资源:把图片加载移到游戏初始化阶段,彻底消除循环内的IO耗时。
- 修正碰撞检测:使用
topleft=PIZZARE生成碰撞矩形,和图片实际绘制位置完全对应,保证点击检测的准确性。 - 简化函数结构:去掉分散的事件处理函数,让逻辑更清晰,减少出错概率。
内容的提问来源于stack exchange,提问作者VQ350GeTsome
相关产品推荐
相关产品推荐

