pygame开发2D游戏地图时如何修复'unhashable type list'报错
错误原因
unhashable type 'list'报错由地图变量map1的定义错误直接触发,代码还存在一个不会抛错但会导致渲染失效的隐性bug:
- 包裹地图数据的外层符号误用了大括号
{}:Python中直接用大括号包裹逗号分隔的非键值对元素,会被解析为集合(set),集合强制要求所有元素必须是可哈希的不可变类型;你写的后三行地图行是方括号[]创建的列表,列表属于可变类型、不可哈希,放入集合时就会触发本次报错。你需要的是二维列表结构来按行列存地图瓦片数据,外层应该改用方括号[]。 - 代码末尾的
pygame.display.update漏写了调用括号,仅拿到了函数对象、没有实际执行画面刷新逻辑,就算修好前序错误,窗口也会是一片空白或者无响应。
修复后可直接运行的代码
import pygame, sys W = 0 S = 1 G = 2 F = 3 BLUE = (0,0,255) SAND = (194,176,128) GRASS = (124,252,0) FOREST = (0,100,0) TileColor = {W : BLUE, S : SAND, G : GRASS, F : FOREST } # 修正1:外层大括号改方括号,第一行元组也统一改成列表,保持二维列表格式一致 map1 = [[W, S, G, F, F, F, G, S, W, W, W, W], [W, S, S, G, G, G, G, F, F, W, W, W], [W, S, G, G, G, F, F, F, F, F, W, W], [W, S, S, G, G, G, G, G, F, F, F, W] ] TILESIZE = 40 MAPWIDTH = 12 MAPHEIGHT = 4 pygame.init() DISPLAY = pygame.display.set_mode((MAPWIDTH * TILESIZE,MAPHEIGHT * TILESIZE)) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() for row in range(MAPHEIGHT): for col in range(MAPWIDTH): pygame.draw.rect(DISPLAY,TileColor[map1[row][col]],(col * TILESIZE,row * TILESIZE,TILESIZE,TILESIZE)) # 修正2:补充括号,实际调用画面刷新方法 pygame.display.update()
Replit平台开发pygame的实用建议
- Replit的pygame环境不需要复杂本地配置,直接在侧边栏依赖库搜索安装pygame即可运行,渲染窗口会默认嵌在页面右侧。注意所有图片、音频等资源文件都要用相对路径引用,不要写本地绝对路径,否则重启项目或者复制项目后会出现资源找不到的问题。
- 新手写Python复合结构时注意区分三类括号的用途,避免类似本次的符号误用问题:
[]定义列表:可变、支持索引修改、允许重复元素,适合存地图网格、精灵组这类需要顺序读取/修改的数据()定义元组:不可变、可哈希,适合存颜色值、窗口尺寸这类固定常量{}要么定义存键值对的字典,要么定义存不重复元素的集合,不要和列表的外层符号搞混
- 遇到类型相关报错时,可以在报错行之前加
print(type(待检查的变量))打印变量类型,比如本次问题如果打印type(map1),会发现它不是预期的list而是set,能快速定位问题。 - 调用pygame的内置方法时注意检查末尾有没有加括号,比如
update()、flip()、tick()这类需要执行的方法,漏写括号不会抛错,只会出现画面卡住、交互失效的问题,是新手非常容易踩的隐性坑。
内容的提问来源于stack exchange,提问作者roarg
相关产品推荐
相关产品推荐

