在2D阵列中制作/编辑图案。 (蟒蛇)

时间:2014-05-28 21:04:48

标签: python arrays

我正在尝试制作基于磁贴的游戏。在块砖的顶部,有透明的阴影砖。每个阴影瓦片将根据附近的光源具有不同的透明度值。我遇到的麻烦是设置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

1 个答案:

答案 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的函数,所以我会偏离使用属性或任何东西(或任何其他关键字)。在这种情况下,这可能并不重要,但这是一种更好的做法(类似地:尽量不要命名变量mapdictlist等。)