Pygame游戏画面闪烁求助(仅调用一次display.update)
《圣诞老人大战邪恶精灵》Pygame问题修复方案
一、画面闪烁问题修复
核心问题分析
- 循环内重复创建窗口(
pygame.display.set_mode),每次循环重置显示表面 - 背景图片每次循环重新加载、缩放,IO与计算开销过大
- Timer类在循环内重复实例化,导致计时逻辑混乱
- Snow类初始化时直接绘制图形,帧绘制顺序错误
修复措施
- 全局窗口仅初始化一次,统一使用
win变量,删除循环内重复创建窗口的代码 - 背景图片提前加载并缩放,放在循环开始前
- Timer类仅实例化一次,循环内仅调用
countDown更新时间 - 修改Snow类,初始化时仅记录位置与尺寸,绘制逻辑移至
show方法
二、胜负逻辑完善
当前问题
计时结束直接显示失败界面,未判断玩家是否已消灭所有精灵
修复逻辑
计时结束时:
- 若已消灭全部20个精灵(
Dis == 20),显示胜利界面 - 否则显示失败界面
- 无论胜负,停止游戏循环与后续交互
修改后的完整代码
import pygame, random pygame.init() # 窗口初始化(仅执行一次) w = 600 h = 600 win = pygame.display.set_mode((w,h)) pygame.display.set_caption("圣诞老人大战邪恶精灵") # 资源预加载与配置 img_size = (50,100) img_size2 = (30,30) # 提前加载并缩放背景图 background = pygame.image.load('SnowBackground.webp').convert() background = pygame.transform.smoothscale(background, (w, h)) # 预加载胜负界面图 victory_bg = pygame.image.load('Victory.png').convert() victory_bg = pygame.transform.smoothscale(victory_bg, (w, h)) defeat_bg = pygame.image.load('Defeat.png').convert() defeat_bg = pygame.transform.smoothscale(defeat_bg, (w, h)) # 圣诞老人类 class Santa: def __init__(self,color,x,y): self.color = color self.x = x self.y = y self.img = pygame.image.load("santaimg.png").convert_alpha() self.img = pygame.transform.scale(self.img, img_size) self.center=(x,y) def Right(self): if self.x <551: self.x +=20 self.center=(self.x,self.y) def Left(self): if self.x >0: self.x -=20 self.center=(self.x,self.y) def show(self): win.blit(self.img, self.center) # 精灵类 class Elves(): def __init__(self, color, pos_x, pos_y): self.color = color self.pos_x= pos_x self.pos_y = pos_y self.square = 20 self.velocity = 0 self.box = pygame.Rect(self.pos_x,self.pos_y,self.square,self.square) self.img2 = pygame.image.load("elfimg.png").convert_alpha() self.img2 = pygame.transform.scale(self.img2,img_size2) self.draw = True def Show(self): if self.draw: win.blit(self.img2, (self.pos_x, self.pos_y)) def dissapear(self, box): global Dis if self.draw and self.box.colliderect(box): Dis += 1 self.draw = False # 全部消灭时触发胜利 if Dis == 20: print("Victory! You Saved Christmas!") win.blit(victory_bg, (0, 0)) pygame.display.update() global running running = False def Moving(self): self.pos_y += self.velocity if 0 <= self.pos_y < h/2.4: self.velocity +=.3 if self.pos_y > h/2.4: self.velocity -= .3 self.box = pygame.Rect(self.pos_x,self.pos_y,self.square,self.square) # 雪球类 class Snow: def __init__(self,color,x,y): self.x = x self.y = y self.color = color self.height = 15 self.length = 15 self.draw = True # 初始化时仅创建Rect,不绘制 self.snowy = pygame.Rect(self.x,self.y,self.height,self.length) def show(self): if self.draw: self.snowy = pygame.draw.ellipse(win,self.color,self.snowy) def upward(self): global SUp if SUp: self.snowy.y -= 5 # 雪球移出屏幕后不再绘制 if self.snowy.y < -self.height: self.draw = False # 计时器类 class Timer: def __init__(self,limit): self.limit = limit self.start=pygame.time.get_ticks() def countDown(self): currTime=(pygame.time.get_ticks() - self.start)/1000 return max(0, int(self.limit - currTime)) # 游戏管理器 class Manager: def __init__(self): self.colors = ((255,255,255),(0,0,0),(173,216,230),(252,36,2),(0,0,255)) self.ElvesList = [] self.snowballs=[] global SUp SUp = True global Dis Dis = 0 def main(self): global running running = True clock = pygame.time.Clock() # 创建精灵 for i in range(20): x = random.randint(0,w-20) y= random.randint(0,h/3) self.ElvesList.append(Elves(self.colors[2],x,y)) SantaC= Santa(self.colors[3],w/2,h-50) # 计时器仅实例化一次 timer = Timer(25) font = pygame.font.Font("freesansbold.ttf",32) def showtimer(x,y): timeLeft = timer.countDown() timing = font.render(f"Timer : {timeLeft}",True,self.colors[4]) win.blit(timing,(x,y)) return timeLeft while running: # 绘制背景(仅用预加载的图) win.blit(background, (0, 0)) # 更新精灵 for evil in self.ElvesList: evil.Show() evil.Moving() # 绘制圣诞老人 SantaC.show() # 显示计时器并获取剩余时间 timeLeft = showtimer(10,10) # 计时结束判断胜负 if timeLeft <=0: if Dis ==20: win.blit(victory_bg, (0,0)) else: win.blit(defeat_bg, (0,0)) pygame.display.update() running = False continue # 更新雪球 for s in self.snowballs: if s.draw: s.show() s.upward() # 碰撞检测 for evil in self.ElvesList: for s in self.snowballs: if s.draw: evil.dissapear(s.snowy) # 事件处理 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.snowballs.append(Snow(self.colors[0],17.5+ SantaC.x,SantaC.y)) if event.key == pygame.K_RIGHT or event.key == pygame.K_d: SantaC.Right() if event.key == pygame.K_LEFT or event.key == pygame.K_a: SantaC.Left() # 更新显示 pygame.display.update() clock.tick(30) Manager().main()
内容的提问来源于stack exchange,提问作者Luka LUSV6912
相关产品推荐
相关产品推荐

