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

Python Pygame开发NES风格游戏时数组意外同步赋值问题排查

问题描述

用Python结合Pygame开发NES风格游戏,将关卡数据存储在二维数组中。每个关卡包含三个独立数组:

  • collisionData:记录所用方块
  • tileset:记录方块调色板
  • flipmap:记录方块镜像

已实现通过修改数组数值实现方块动画的功能,但执行代码时,本应仅修改目标数组,却意外同时改动了三个数组。怀疑是数组内存引用关联导致,但未找到原因,请求协助排查。

相关代码:

if Datafile["TileAnimations"][self.animList[item][2]][self.animFrames[item]][0] == "Layout":
    self.collisionData[self.animList[item][1]][self.animList[item][0]] = Datafile["TileAnimations"][self.animList[item][2]][self.animFrames[item]][1]
elif Datafile["TileAnimations"][self.animList[item][2]][self.animFrames[item]][0] == "FlipMap":
    self.flipmap[self.animList[item][1]][self.animList[item][0]] = Datafile["TileAnimations"][self.animList[item][2]][self.animFrames[item]][1]
elif Datafile["TileAnimations"][self.animList[item][2]][self.animFrames[item]][0] == "Tileset":
    self.tileset[self.animList[item][1]][self.animList[item][0]] = Datafile["TileAnimations"][self.animList[item][2]][self.animFrames[item]][1]
排查思路与解决方案

你遇到的问题确实是Python二维数组的内存引用共享导致的,问题根源大概率不在你提供的这段修改代码里,而是出在三个数组的初始化阶段。

常见错误初始化场景

  1. 用乘法批量创建二维数组
    比如这样的写法:
rows, cols = 10, 10
self.collisionData = [[0]*cols]*rows
self.tileset = [[0]*cols]*rows
self.flipmap = [[0]*cols]*rows

这种方式会让数组的每一行都指向同一个列表对象,修改任意一行的元素会同步影响所有行;如果三个数组用了完全相同的生成逻辑,甚至会让三个数组本身指向同一内存块。

  1. 直接赋值共享引用
    如果初始化时写了类似代码:
self.collisionData = level_source_data
self.tileset = self.collisionData
self.flipmap = self.collisionData

这会让三个变量指向同一个二维数组对象,修改其中任何一个都会同步改变另外两个。

解决方法

  1. 正确初始化独立二维数组
    用列表推导式创建数组,确保每一行都是全新的列表:
rows, cols = 10, 10
self.collisionData = [[0 for _ in range(cols)] for _ in range(rows)]
self.tileset = [[0 for _ in range(cols)] for _ in range(rows)]
self.flipmap = [[0 for _ in range(cols)] for _ in range(rows)]
  1. 深拷贝已有关卡数据
    如果是从外部加载关卡数据,必须用深拷贝来避免引用共享:
import copy
# 假设level_collision、level_tileset、level_flipmap是原始关卡数据
self.collisionData = copy.deepcopy(level_collision)
self.tileset = copy.deepcopy(level_tileset)
self.flipmap = copy.deepcopy(level_flipmap)

验证方法

可以在初始化后打印三个数组的内存地址,确认它们不是同一对象:

print(id(self.collisionData))
print(id(self.tileset))
print(id(self.flipmap))

如果三个地址相同,说明确实是数组级别的引用共享;如果地址不同,再检查每一行的地址:

print(id(self.collisionData[0]))
print(id(self.tileset[0]))

如果行的地址相同,说明是行级别的引用共享。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:07:31