模型类
初始化
有了方块类,我们现在终于可以添加方块了。
添加方块
现在我们来编写添加方块的代码:
class Model:
...
def add_block(self, position, block, immediate=True):
# 如果该位置已经存在了方块那么先删除原方块,用新的方块替代它
if position in self.world:
self.remove_block(position, immediate, real)
# 填充 world 字典,这里会调用 Block.__call__
self.world[position] = blocks[block](self, *position)
# == A ==
self.sectors.setdefault(sectorize(position), []).append(position)
# immediate 为 True 即为立即显示这个方块
if immediate:
# == B ==
if self.exposed(position):
self.show_block(position)
self.check_neighbours(position)
A:世界的最小单位是一个方块(Block),组织方块的单位是一个区块(Sector)。区块的大小定义在Settings
类中(为16),sectorize
函数就是把一个坐标区块化,例如(0, 0, 0)
位于区块(0, 0, 0)
,(0, 0, 15)
也位于区块(0, 0, 0)
,但是(0, 0, 16)
就位于区块(0, 0, 1)
。注意,一个区块的y
坐标永远为0
,因为区块是平铺在世界里的。
B:世界中会存在许多的方块,但是不是每个方块都是看得见的。换句话说,并不是每一个方块都是要显示的。GPU:我压力山大…… 有的方块的上下前后左右都被别的(不透明的)方块所包围着,这样的方块就是不用显示的。exposed
函数会检查一个方块是否有露出的一面。check_neighbours
函数我们后面再说。
接下来编写exposed
函数:
class Model:
...
# 这个是 exposed 函数的容易理解的版本
def exposed(self, position):
x, y, z = position
# 检查上下前后左右6个方向的方块
for dx, dy, dz in Settings.faces:
# 只要有一个方向没有方块,就要显示了
if (x + dx, y + dy, z + dz) not in self.world:
return True
# 所有面都被覆盖着
return False
但是当我把这段代码写到 Microsoft Visual Studio 里的时候,它擅自帮我给改成了这个样子:
class Model:
...
# 这个是 exposed 函数的难懂的版本
def exposed(self, position):
x, y, z = position
return any(
(x + dx, y + dy, z + dz) not in self.world
for dx, dy, dz in Settings.faces
)
如果真的照着第2种办法写的话,我都没有办法讲了(笑),我还是推荐大家写第1种。引用import this
中的话:
Readability counts.
可读性很重要。
那么我们这篇文章就讲完啦,如果有不懂欢迎评论区讨论哦~