0
点赞
收藏
分享

微信扫一扫

羊了个羊系统开发实现原理

游戏的整体很简单,但其中有几个实现的重点需要注意:

牌堆数据结构的实现

如何检测和更新可拾取的牌

先做个小定义,一个牌堆中可被拾取的牌以下将简称其为:“窗口牌”。

牌堆的结构及其数据结构(更多软件开发,可与小编punk2558探讨)

最初,我还真被这复杂的牌堆结构蒙住了,但仔细研究一番发现,无论多么复杂的牌堆,其实都是由如下三种牌堆模式组合拼凑而成的。

蓝圈圈出的牌堆模式A:上面1张牌只挡住下面1张牌;同时下面的牌仅被上面1张牌挡住。只要上面的1张牌被取走,下面的牌就成为窗口牌;

红圈圈出的牌堆模式C:上面1张牌可以挡住下面4张牌;同时下面的牌可能被上面4张牌挡住,一张牌只有它上面的4张牌都被取走,它自己才成为窗口牌。

虽然上图中体现不是很明显,但不难猜想出,第三种牌堆模式B的存在,那就是:

上面1张牌可以挡住下面2张牌;同时下面的牌可能被上面2张牌挡住,一张牌只有它上面的2张牌都被取走,它自己才成为窗口牌。

对于牌堆模式A,有些朋友会迫不及待地用“队列”或“栈”实现它,这样做有两个缺点:

逻辑上牌堆模式A的窗口牌也可能是2维的,如果用队列实现就限制了它的灵活性;

牌堆模式B和C都不好用队列实现,所以想追求数据结构的统一,还要另求他法。

实际上无论牌堆模式A、B还是C,都不过是3维数组结构,上图中模式A看起来特殊,无非是它的x,y维度都为1罢了。而三种牌堆的区别也无非就是当一张窗口牌被取走,检查牌堆是否出现新的窗口牌的方法罢了。

牌堆模式A

羊了个羊系统开发实现原理_三维数组

牌堆模式B

羊了个羊系统开发实现原理_数据结构_02

牌堆模式C

羊了个羊系统开发实现原理_三维数组_03

牌堆的数据结构

我将其定义为MContainerBase基类

#MContainerBase extends Node2D class_name MContainerBase

func _ready:add_to_group(name)add_to_group("game")varMask=FileReader.read(mask_file,null)box.resize(size_x)fori inrange(size_x):box<i>=[]box<i>.resize(size_y)forj inrange(size_y):box<i>[j]=[]box<i>[j].resize(size_z)fork inrange(size_z):ifMask==nullor Mask<i>[j]==1:box<i>[j][k]=add_tile(i,j,k,get_parent.distribute_face)else:box<i>[j][k]=nullforx inrange(size_x):fory inrange(size_y):forz inrange(size_z):check_is_on_top(x,y,z)

最基础的牌堆就是一个xyz的三维数组,我们可以使用一切方法构造想要的排队形状:柱形、条形、甚至金字塔形。这都不会影响后面程序的实现。

项目中为了增加这个“大方块”的多样性,我还给它设置了如下的“遮罩”,这就是游戏中文字的由来。当然我们还可以通过“遮罩”来自由定义窗口牌,这部分就请大家自由发挥了。

#S形遮罩[[0,0,0,0,0],[0,0,0,0,0],[1,1,1,0,1],[1,0,1,0,1],[1,0,1,1,1],]

如何检测和更新可拾取的牌

三种牌堆模式分别派生自MContainerBase,并对应着如下三种检测方式:

牌堆模式A

仅检测自己正上方是否有牌

#1Cover1extends MContainerBase

funccheck_is_on_top(x,y,z):ifhas_tile(x,y,z):ifnot has_tile(x,y,z+1):(box[x][y][z]asMTile).set_is_on_top(true)

牌堆模式B

检测自己上方两方位是否有牌

#1 Cover 2extends MContainerBase

func check_is_on_top(x,y,z):ifhas_tile(x,y,z):ifz%2==0:ifnothas_tile(x,y,z+1)andnothas_tile(x-1,y,z+1):(box[x][y][z]asMTile).set_is_on_top(true)else:ifnothas_tile(x,y,z+1)andnothas_tile(x+1,y,z+1):(box[x][y][z]asMTile).set_is_on_top(true)

牌堆模式C

检测自己上方四方位是否有牌

#1 Cover 4extends MContainerBase

func check_is_on_top(x,y,z):ifhas_tile(x,y,z):ifz%2==0:ifnothas_tile(x,y,z+1)andnothas_tile(x-1,y,z+1)andnothas_tile(x,y-1,z+1)andnothas_tile(x-1,y-1,z+1):(box[x][y][z]asMTile).set_is_on_top(true)else:ifnothas_tile(x,y,z+1)andnothas_tile(x+1,y,z+1)andnothas_tile(x,y+1,z+1)andnothas_tile(x+1,y+1,z+1):(box[x][y][z]asMTile).set_is_on_top(true)

在Godot中,这三种牌堆模式还可以通过场景节点制作成预制体,这样关卡设计师就可以轻松地制作出美观的关卡了。

举报

相关推荐

0 条评论