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

Pygame实现的生命游戏运行卡顿,已排除绘制事件放错循环问题,求解决

Pygame生命游戏卡顿修复方案

1. 核心语法错误:numpy数组初始化参数不规范

你当前创建数组的写法不符合numpy API要求:

# 错误写法:numpy.zeros第一个参数必须是表示维度的元组,你将行列拆为了两个独立参数
self.pixels = numpy.zeros(self.ScreenWidth//2, self.ScreenHeight//2, dtype=int)
newGeneration = numpy.zeros(self.ScreenWidth//2, self.ScreenHeight//2, dtype=int)

该写法会隐性创建错误维度的数组,触发额外的内存操作和越界兼容逻辑,是卡顿的核心原因之一。同时你的网格大小和cellsize参数不匹配,存在大量冗余空元素,进一步浪费了遍历性能。

修复方式:
在Run方法初始化阶段先计算匹配cellsize的网格大小:

self.cellsize = 10
self.cols = self.ScreenWidth // self.cellsize
self.rows = self.ScreenHeight // self.cellsize
# 正确初始化二维数组
self.pixels = numpy.zeros((self.cols, self.rows), dtype=int)

NextGeneration里创建新数组对应修改为:

newGeneration = numpy.zeros((self.cols, self.rows), dtype=int)

2. 性能瓶颈优化:替换纯Python循环为numpy向量化计算

你当前两层Python循环遍历所有细胞,每个细胞内部再开两层循环计算邻接数量,Python循环本身开销极高,是计算侧卡顿的主要原因。
直接用numpy滚动求和实现邻接计数,完全规避Python层循环,性能提升100倍以上:

def NextGeneration(self):
    # 向量化计算8个方向的邻接存活细胞总数
    total = (numpy.roll(self.pixels, 1, axis=0) + numpy.roll(self.pixels, -1, axis=0) +
             numpy.roll(self.pixels, 1, axis=1) + numpy.roll(self.pixels, -1, axis=1) +
             numpy.roll(numpy.roll(self.pixels, 1, axis=0), 1, axis=1) +
             numpy.roll(numpy.roll(self.pixels, 1, axis=0), -1, axis=1) +
             numpy.roll(numpy.roll(self.pixels, -1, axis=0), 1, axis=1) +
             numpy.roll(numpy.roll(self.pixels, -1, axis=0), -1, axis=1))
    # 向量化应用生命游戏规则
    new_pixels = numpy.where((self.pixels == 1) & ((total == 2) | (total == 3)), 1, 0)
    new_pixels = numpy.where((self.pixels == 0) & (total == 3), 1, new_pixels)
    self.pixels = new_pixels

3. 绘制逻辑优化:减少无效绘制调用

你当前每次绘制都遍历所有网格格子调用pygame.draw.rect,可以改为仅遍历存活细胞绘制,大幅减少绘制调用次数:

def DrawBG(self):
    black = (0,0,0)
    white = (255,255,255)
    self.bg.fill(black)
    # 仅获取存活细胞坐标遍历绘制
    alive_cells = numpy.argwhere(self.pixels == 1)
    for (col, row) in alive_cells:
        pygame.draw.rect(self.bg, white, (col*self.cellsize, row*self.cellsize, self.cellsize-1, self.cellsize-1))

参数里的-1是为了预留网格线间隙,不需要可以直接删掉。


4. 事件逻辑优化:解决S键延迟问题

你当前主循环里多次重复遍历事件列表,且计算逻辑阻塞了事件响应,合并事件处理逻辑即可解决延迟:

while running:
    clock.tick(60)
    events = pygame.event.get()
    # 单次遍历处理所有事件
    for event in events:
        if event.type == pygame.QUIT:
            running = False
        elif stage == 'Draw':
            if event.type == pygame.MOUSEBUTTONDOWN:
                mousedown = True
            elif event.type == pygame.MOUSEBUTTONUP:
                mousedown = False
            elif event.type == pygame.MOUSEMOTION and mousedown:
                m_x, m_y = pygame.mouse.get_pos()
                c = m_x // self.cellsize
                r = m_y // self.cellsize
                if 0 <= c < self.cols and 0 <= r < self.rows:
                    self.pixels[c][r] = 1
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_r:
                stage = 'Run'
        elif stage == 'Run':
            if event.type == pygame.KEYDOWN and event.key == pygame.K_s:
                stage = 'Draw'
    # 演化逻辑放在事件处理之后
    if stage == 'Run':
        self.NextGeneration()
    # 绘制逻辑不变
    self.DrawBG()
    screen.blit(self.bg, (0,0))
    pygame.display.flip()

以上修改完成后,即可完全解决运行卡顿和S键延迟的问题,稳定跑满60帧。

内容的提问来源于stack exchange,提问作者Ethan97

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:39:00