在二维阵列中制作/编辑图案。(Python)
我正在尝试制作一个基于瓷砖的游戏。在砖的顶部,有透明的遮阳砖。根据附近的光源,每个着色瓷砖将具有不同的透明度值。我遇到的问题是,设置2D阵列的模式(相当于游戏中的圆形瓷砖选择)需要付出艰苦的工作,每个阵列的值都会略有变化。 现在我有一个shade类,它是当前级别着色的全部信息。此类的二维数组等于平铺:在二维阵列中制作/编辑图案。(Python),python,arrays,Python,Arrays,我正在尝试制作一个基于瓷砖的游戏。在砖的顶部,有透明的遮阳砖。根据附近的光源,每个着色瓷砖将具有不同的透明度值。我遇到的问题是,设置2D阵列的模式(相当于游戏中的圆形瓷砖选择)需要付出艰苦的工作,每个阵列的值都会略有变化。 现在我有一个shade类,它是当前级别着色的全部信息。此类的二维数组等于平铺: [[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是地图上火炬的
[[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
正如一些人提到的,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
,你就会开始得到索引器。所以,现在我们想让它环绕一行的末尾,回到开头:
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]
我们所要做的就是确定以长度为模的更新索引(从技术上讲,这对于负面移动是不必要的,因为它可以像您所期望的那样从列表的末尾进行索引。为了代码一致性,我可能会做上述操作,为了代码效率,我会省略模,并且还将使用作为范围内的I(1,半径+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]
如果这两个函数总是要一起调用,那么您可以(也应该?)将它们合并为一个函数-定义两个不同的递增
列表,然后在该for
循环中引用相应的一个
最后,作为一个非sequeur:python有一个名为map
的函数,所以我会放弃使用属性或任何与之相关的东西(或任何其他关键字)。在这种情况下,这可能无关紧要,但是一个更好的实践(类似地:尽量不要命名变量dict
,列表
,文件
,等等).对于循环?这就是我要使用的。或者是返回索引列表的简单函数,但是你也可以只为整个事情编写一个函数。也许这是它艰苦乏味的证据-你是否还想包括shade.map[x][y-1]
和shape.map[x][y-2]
?哇,我真的忘了。我的观点完全正确。啊,好吧,我不想假设任何东西。那么,半径值将正确地覆盖这一点(在这一点上,它们根本不会被改变)。有没有办法让阴影不被包围,也能防止索引错误?我知道可以用很多if语句来实现,但有没有更简单的方法呢?我不知道。对于x和y,你至少需要4个if,正或负。我想你可以尝试使用min
和max
,但至少是fir看一眼,那更混乱。