You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame游戏画面闪烁求助(仅调用一次display.update)

《圣诞老人大战邪恶精灵》Pygame问题修复方案

一、画面闪烁问题修复

核心问题分析

  1. 循环内重复创建窗口(pygame.display.set_mode),每次循环重置显示表面
  2. 背景图片每次循环重新加载、缩放,IO与计算开销过大
  3. Timer类在循环内重复实例化,导致计时逻辑混乱
  4. Snow类初始化时直接绘制图形,帧绘制顺序错误

修复措施

  1. 全局窗口仅初始化一次,统一使用win变量,删除循环内重复创建窗口的代码
  2. 背景图片提前加载并缩放,放在循环开始前
  3. Timer类仅实例化一次,循环内仅调用countDown更新时间
  4. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:40:37