我正在尝试制作基于磁贴的游戏。在块砖的顶部,有透明的阴影砖。每个阴影瓦片将根据附近的光源具有不同的透明度值。我遇到的麻烦是设置2D阵列模式(相当于游戏中的圆形选择)所需的艰苦工作,每个都稍微改变它们的值。 现在我有一个阴影类,它是当前级别阴影的全部信息。这个类的二维数组等于tile:
[[1,1,1,1,1],
[1,1,1,1,1,],
[1,1,1,1,1,],
[1,1,1,1,1,],
[1,1,1,1,1,]]
这里的代码是一个编辑火炬周围区域的块,x和y是地图上火炬的x和y值。我想知道是否可以缩短此代码,以便可以使圆形区域更轻?此外,如果呈现了可变半径,是否可以通过该模式/算法轻松地编辑该半径中的切片?
shade.map[x][y] = 0
shade.map[x-1][y] = 64
shade.map[x-2][y] = 128
shade.map[x+1][y] = 64
shade.map[x+2][y] = 128
shade.map[x][y+1] = 64
shade.map[x][y+2] = 128
shade.map[x][y-1] = 64
shade.map[x][y-2] = 128
shade.map[x-1][y-1] = 96
shade.map[x+1][y-1] = 96
shade.map[x+1][y+1] = 96
shade.map[x-1][y+1] = 96
答案 0 :(得分:0)
正如一些人所提到的,for循环可能对你有好处。我不确定你的半径函数应该是什么样的,就像你似乎有:
? ? 128 ? ?
? 48 64 48 ?
128 64 0 64 128
? 48 64 48 ?
? ? 128 ? ?
你有两个不同的想法,你想如何向外辐射,一个用于直线,一个用于对角线(对不起,如果我错过了一些清晰/明显的数学进展)。
让我们至少从直接的左右上下开始,也许我可以稍后用更多的信息来解决对角线。
def update(shade, x, y, radius=2):
increases = [i*64 for i in range(radius+1)] # [0, 64, 128] for example
for i in range(radius+1):
shade.map[x+i][y] = increases[i]
shade.map[x-i][y] = increases[i]
shade.map[x][y+i] = increases[i]
shade.map[x][y-i] = increases[i]
这应该向外辐射,几乎可以做你想要的(只有直线),除非你从数组的末尾掉下来:如果你试过这个,并给了x, y = 4, 2
,例如,你&# 39; d开始得到IndexError
s。所以,现在我们想把它包裹在一行的末尾并回到开头:
128 ? ? ? ?
64 48 ? ? 48
0 64 128 128 64
64 48 ? ? 48
128 ? ? ? ?
在代码中实现它可能会更难实现,但幸运的是,它并非如此:
def update(shade, x, y, radius=2):
mlen = len(shade.map) ## assuming it's a square array; use xlen and ylen separately if needed
increases = [i*64 for i in range(radius+1)] # [0, 64, 128] for example
for i in range(radius+1):
shade.map[(x+i)%mlen][y] = increases[i]
shade.map[(x-i)%mlen][y] = increases[i]
shade.map[x][(y+i)%mlen] = increases[i]
shade.map[x][(y-i)%mlen] = increases[i]
我们所要做的就是确定我们的更新索引的模数长度(从技术上讲,这对负面运动来说并不是必需的,因为它可以像你期望的那样从列表的末尾开始索引。一致性,我可能会做以上,为了提高代码效率,我会将模数保留,并且还会使用for i in range(1, radius+1)
,因为i = 0
不会改变任何内容。
修改强> 想象我应该添加一些关于对角线的东西,虽然上面的内容可能足以引导这个想法。
def update_diagonal(shade, x, y, radius=1):
mlen = len(shade.map) ## assuming it's a square array; use xlen and ylen separately if needed
increases = [i*48 for i in range(radius+1)] # [0, 48] for example
for i in range(radius+1):
shade.map[(x+i)%mlen][(y+i)%mlen] = increases[i]
shade.map[(x+i)%mlen][(y-i)%mlen] = increases[i]
shade.map[(x-i)%mlen][(y+i)%mlen] = increases[i]
shade.map[(x-i)%mlen][(y-i)%mlen] = increases[i]
你可以(并且应该)将这两个函数合并为一个,如果它们总是被一起调用 - 定义两个不同的increases
列表,然后只引用那个单独的{{1} }循环。
最后,作为非sequitur:python有一个名为for
的函数,所以我会偏离使用属性或任何东西(或任何其他关键字)。在这种情况下,这可能并不重要,但这是一种更好的做法(类似地:尽量不要命名变量map
,dict
,list
等。)