2D网格游戏:表示可通行性



考虑一个基于平铺的游戏,其中每个代理可以直线/对角移动(8个方向)。基本上,像这样的地图可以表示为一个规则的2D网格,其中0表示可步行的位置,1表示不可步行的地点(我使用Lua):

-- Example : 3x3 sized map
local map = {
{0,0,0},
{0,1,1},
{0,0,0},
}

在这一点上,我们如何根据代理的来源来表示瓷砖的可行走性?也就是说,上面的单元格[2][2]是静态不可行走的,如果来自[1][2](上图)或[2][1](左),则现在可以行走,但不是,例如,来自[3][2](下)。

我对此有一些想法,但对我来说,我无法想出足够干净的东西。

提前谢谢。

我会用单个字节覆盖另一个2D网格。字节的每个比特对应于一个可能的进入方向,1表示可以从该方向继续前进,0表示不能。然后可以使用二进制掩码检查可进入性。

如果您的大多数单元格都可以从任何方向输入,那么您可以考虑使用一个具有磁贴绝对ID(例如,X*MaxY+Y)的映射作为键,并使用上面描述的指示可输入性的字节方案。访问速度较慢,但占用的空间较小。

例如,让方向按如下方式排列:

Bit #      X offset  Y offset
123        -1 0 1    -1 -1 -1
4 5        -1 0 1     0  0  0
678        -1 0 1     1  1  1

如果我在东北方向上,这对应于比特#3。我可以通过将上述值转换为位掩码来执行掩码:

1   2   4
8      16
32 64 128

如果以下返回真,我可以从一个方向进入

Enterability(CurrentX+Xoffset(Dir), CurrentY+Yoffset(Dir)) & BitMask(Dir)

(对不起,恐怕我对Lua不够了解,不能用那种语言写这篇文章)

编辑

所以,说出我的方向,如上所述,我想要一个只能从北方进入的广场。为此,我设置了位#2:

Enterability(X)=2

如果我想要一个可以从北部和西南部进入的广场,我会使用:

Enterability(X)=2 | 64

其中CCD_ 1是逐位OR运算。

如果我想让广场从除西面以外的任何方向进入,我会使用:

Enterability(X)=(~8)

其中CCD_ 2是非操作。

如果我需要关上门,比如说向东,我可以打开那一点:

Enterability(X)=Enterability(X) & (~16)

要再次打开门,我使用:

Enterability(X)=Enterability(X) | 16

或者,更简单地说,

Enterability(X)|=16

CCD_ 3产生一个比特字段,该比特字段是除了参考16的比特之外的所有比特。将其与AND运算符(&)一起使用会保留所有位,但引用16的位除外。

还要注意,十六进制寻址可能更方便:

Decimal          Hexadecimal
1   2   4       0x1  0x2  0x4
8      16   =   0x8       0x10
32 64 128       0x20 0x40 0x80

最新更新