Python “如何修复”;索引器:列表索引超出范围“;在我的代码里?
我对Python非常陌生,我想测试一下tilemap系统。当我尝试加载磁贴时,会收到错误消息Python “如何修复”;索引器:列表索引超出范围“;在我的代码里?,python,list,indexing,Python,List,Indexing,我对Python非常陌生,我想测试一下tilemap系统。当我尝试加载磁贴时,会收到错误消息indexer错误:列表索引超出范围。我需要做什么来解决这个问题,以及其他人将来喜欢的问题? 确切错误: 回溯(最近一次呼叫最后一次): 文件“N:/Python/Projects/Projects/First-top-down/First-top-down.py”,第114行,在 pygame.draw.rect(屏幕,颜色[tilemap[row][column],(column*tilesize,r
indexer错误:列表索引超出范围
。我需要做什么来解决这个问题,以及其他人将来喜欢的问题?
确切错误:
回溯(最近一次呼叫最后一次):
文件“N:/Python/Projects/Projects/First-top-down/First-top-down.py”,第114行,在
pygame.draw.rect(屏幕,颜色[tilemap[row][column],(column*tilesize,row*tilesize,tilesize,tilesize))
索引器:列表索引超出范围
我听说这意味着我试图访问none
或空的值。
下面是关于tilemap
的代码部分。没有最后一个绘图位,其余的工作正常。(这不是很多其他代码,只是运动。)
您得到的是
索引器
,因为您在tilemap
中只定义了一行,但是外部for
循环提供了行
索引,从0
到mapheight-1
,因为以下语句:
for row in range(mapheight):
要避免该错误,请尝试将其更改为:
for row in range(len(tilemap)):
更新
我想我已经知道你想做什么了。如前所述,索引器
是因为tilemap
中的行数与您试图用嵌套的for
循环显示的行数不匹配
下面我修正了tilemap
的定义方式,使其具有适当的行数和列数(还简化了一些其他定义,并在显示循环中添加了一些事件处理,以允许脚本正常关闭,而不是在无限循环中运行)
好了,我终于明白你在做什么了 您尝试对tilemap进行第二次切片,即使tilemap是一维的。对于多维数组,最好在imo中使用numpy数组。当您在我的代码中打印tmap时,您将看到我的意思,它更具可读性。此外,由于python使用缩进,因此最好通过将不同的参数分隔成不同的行来组织长函数调用。否则,您的代码中会出现一条无法阅读的长线
导入pygame
将numpy作为np导入
pygame.init()
#定义平铺的基值
t尺寸、宽度、高度=64,16,13
#使用充满零的空2D数组设置阶段
#从宽度和高度动态创建平铺贴图。
tmap=np.zero((高度、宽度),dtype=int)
#我想是定义了屏幕?
screen=pygame.display.set_模式((宽度*tsize,高度*tsize))
pygame.display.set_标题(“Asspain”)
#现在可以手动更改tilemap。
#您有三个唯一的行,因此可以
#只需列出这些内容,然后插入
#将它们放入您的np数组中
r1=[1]*宽度
r2=[1]
r2.扩展([2]*14)
r2.扩展([1])
r3=[1]
r3.扩展([0]*14)
r3.扩展([1])
#将列表转换为np.array,以便它们工作
#用你的tmap。
r1,r2,r3=np.数组(r1),np.数组(r2),np.数组(r3)
#在适当的位置插入行
#请注意,索引在中的工作方式有点不同
#np.array,而不是python内置列表中的数组。
tmap[0]=r1.copy()
tmap[1]=r2.copy()
tmap[2:12]=r3.copy()
tmap[12]=r1.copy()
#现在,您有了一个漂亮且可读的tmap。
#您可以进行地图创建过程
#就像你想要的那样,我只是使用了快捷方式
#基于对称性。
打印(tmap)
#现在您可以迭代每个元素
#通过双重迭代,或使用索引。
#我听说过使用范围迭代索引
#速度总是更快。
#定义颜色映射
cmap={0:(50205,50),
1:(128, 128, 128),
2:(210, 105, 30,)}
#这是不必要的,但很高兴知道
#numpy数组也有一个类似len()的
#属性名为shape。
宽度,高度=tmap.shape[0],tmap.shape[1]
#游戏圈
尽管如此:
#这是瓷砖的默认颜色吗?
#你需要吗?
屏幕填充((64,64,64))
对于范围内的行(宽度):
对于范围内的列(高度):
pygame.draw.rect(屏幕,
cmap[tmap[行][列]],
(col*tsize,
行*t大小,
tsize,
tsize)
pygame.display.update()
编辑:我注意到你做了很多字典切片,速度非常慢。如果您不需要在游戏循环中重复分割字典(即地图不变),请不要这样做。我已经编写了一些额外的代码,它生成了与上面相同的tmap
数组,作为平铺的模板,但这次,我还铸造了一个数组,它将颜色三元组映射到这些位置
通过这种方式,您可以使用fast numpy数组一次性创建整个地图,该数组利用数组的数据类型类型转换,同时仍然受益于之前指定的tmap的可读性
将numpy导入为np
将matplotlib.pyplot作为plt导入
t尺寸、宽度、高度=64,16,13
tmap=np.zero((高度、宽度),dtype=int)
cmap=np.zero((高度、宽度,4),dtype=int)
r1=[1]*宽度
r2=[1]
r2.扩展([2]*14)
r2.扩展([1])
r3=[1]
r3.扩展([0]*14)
r3.扩展([1])
r1,r2,r3=np.数组(r1),np.数组(r2),np.数组(r3)
tmap[0]=r1.copy()
tmap[1]=r2.copy()
tmap[2:12]=r3.copy()
tmap[12]=r1.copy()
cdct={0:np.array((50205,50200),dtype=int),
1:np.array((128128128200),dtype=int),
2:np.array((210,105,30,200),dtype=int)}
对于posy,枚举中的行(tmap):
对于posx,枚举中的列(行):
cmap[posy,posx]=cdct[col].copy()
图,ax=plt.子批次()
打印轴(“关闭”)
ax.imshow(cmap)
正如您所看到的,matplotlib
可以轻松地可视化X、Y、Z数组,imshow()
函数可以将其读取为位图。X是行,Y是列,Z是颜色三元组。实际上,我将Z四个元素设置为长,以便用第四个元素切换透明度。这样您就可以创建y
for row in range(mapheight):
for row in range(len(tilemap)):
import pygame
pygame.init()
tilesize = 64
mapwidth, mapheight = 16, 13
screen = pygame.display.set_mode((mapwidth*tilesize, mapheight*tilesize))
pygame.display.set_caption("Aspen")
WALLTOP, WALLBOT, GRASS = range(3)
wallTop = (128, 128, 128)
wallBot = (210, 105, 30,)
grass = (50, 205, 50)
colors = {
WALLTOP : wallTop,
WALLBOT : wallBot,
GRASS : grass
}
tilemap = [
[WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP],
[WALLTOP, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLBOT, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, WALLTOP],
[WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP, WALLTOP],
]
running = True
while running:
screen.fill((64, 64, 64))
for row in range(mapheight):
for column in range(mapwidth):
pygame.draw.rect(screen, colors[tilemap[row][column]], (column*tilesize, row*tilesize, tilesize, tilesize))
# Process user-events.
for event in pygame.event.get():
if event.type == pygame.QUIT: # User clicked to close window.
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE: # Press escape key to quit.
running = False
pygame.display.update()