本文首发于微信公众号: 小蚂蚁教你做游戏。欢迎关注领取更多学习做游戏的原创教程资料,每天学点儿游戏开发知识。
嗨!大家好,我是小蚂蚁。
终于要写第三篇教程了,中间拖的时间有点儿长,以至于我的好几位学员等不及已经自己做出来了。这是一件让我感到非常高兴的事情。一位学员从零基础开始学,到最后有一定的能力自己琢磨着把游戏做出来,这是一件不论是对学员来讲,还是对我来讲都是值得骄傲的事情。因为他们已经掌握了自己学习和前进的方法,我认为这种自发性的能动性是推动一个人自主学习或者前进的最强大的动力。
好了,接下来让我们来看一下这一节将要学习的内容。
如图,在之前的基础上我们要实现将拾取的牌放到下面的插槽中,插槽中如果有三张同样的牌,则将她们消除掉,在这个过程中我们还要根据当前要插入的牌,对其它牌进行位置调整,除此之外,在消除后,也要对插槽中的牌重新进行位置调整。
理论部分
老规矩,我们先来一起搞定理论部分。
如图,还是先进行一下数据抽象,每个不同类型的卡牌都可以使用一个数字代替,整个卡槽中的 7 张卡牌,其实就等同于下方的 7 个数字。
接着,我们来看一下将卡牌插入卡槽的几种情况。
第一种情况,如果当前卡槽中没有与它相同的卡牌,那么就可以将这张卡牌放到队伍的最后。
第二种情况,如果当前卡槽中有一张与它相同的牌,那么就将这张相同牌的后面的所有的牌(这里只有牌 3)向后移动一个位置,然后把它插入到让出的这个位置上。
第三种情况,如果当前卡槽中有两张与它相同的牌,那么就将最后一张相同的牌的后面的所有牌(这里有牌 3 和 牌 1)向后移动一个位置,然后把它插入到让出的这个位置上。
这就是这个游戏中可能出现的三种插牌情况了。如何实现一张牌的插入,以及其它的牌的位置调整呢?
假设当前卡槽中有四张牌[5,5,3,1],现在要往里再插入一张“牌5”,整个过程是这样的:依次检查每个位置的牌,如果发现这个位置的牌跟要插入的牌一样,就记录一下这个位置,否则的话则跳过继续检查下一个,直到检查完所有卡槽中的牌为止。
这个过程结束后,那个“标记位置”记录的就是最后一张跟插入卡牌相同的牌的位置,有了这个“标记位置”就相当于我们知道了这张牌要插在哪里了,其实就是“标记位置 + 1”的那个位置上。
那剩余其它牌的位置如何调整呢?只需要判断剩余的牌的位置是否大于“标记位置”,如果大于的话,就将自己的位置增加 1,看起来就像是这样。
这就是卡牌的插入和位置调整了,接着我们再来看一下如何判断是否需要消除,其实非常简单,看到这里你应该也能想到的,只需要判断这一串数字里是否有 3 个相邻又相同的数字,有的话,就满足消除条件。
如图,就是针对于 5 张卡牌的检查过程,从前往后,依次的取出一张牌,然后看看它后面有没有两张跟它一样的牌,有的话就满足消除条件,没有的话,就接着去检查下一张牌,继续这个过程,直到检查完卡槽中的所有牌。
其实在上图的例子中,我们只需要检查完前三张就可以了,因为到这里就能够判断出当前满足消除条件了,在这个游戏中不可能出现同时满足两个三消的情况,所以第三张牌之后就不需要检查了。
在完成了消除之后,还需要针对剩余的卡牌进行一次位置的调整,根据我们之前讲过的位置调整,想一下消除之后的调整应该怎么处理呢?
在进行消除的检查时,我们可以做一个记录,记录就是排在最后面的那一张要消除的牌的位置,有了这个“标记位置”,剩余的牌只需要判断自己的位置是否大于这个“标记位置”,如果大于的话,就将自己向前移动三个位置即可。
实践部分
好了,以上就是所有的理论基础了,接下来,我们就到微信小游戏制作工具中实现一下吧!
如图,这里我新增了两个资源,一个是“卡牌槽”用于在下面放置卡牌,另一个是“插槽卡牌”,这个精灵用作卡牌槽中的牌,它跟我们之前创建的“卡牌”精灵类似的地方是,都有 10 个小动物头像造型,而且造型的顺序也都是一样的(为什么要再去创建一个这样的“插槽卡牌”呢?我们稍后会解释)。
接着,来看一下新增的几个全局变量。
当前卡牌的插入位置:记录新来的牌要插入的位置。
当前卡牌的消除位置:记录最后的那一张要消除的牌的位置。
当前拾取的卡牌类型:记录当前从上方拾取的卡牌的类型。
是否可操作:用于判断是否可操作,在牌进行插入或者消除的过程中,玩家是不能够去操作其它牌的。
需要消除出的卡牌类型:满足消除条件的卡牌的类型。
除此之外,我们还创建了一个新的列表。
插槽牌的类型列表:卡牌槽中的卡牌的类型列表。
除了变量之外,我们还新建了几个通知。
几个通知的内容直接根据字面意思理解即可。
接下来,我们来看积木逻辑,首先从上方的要拾取的卡牌开始,先来看“卡牌”精灵上的拾取逻辑。
图中红线框出的就是我们在之前的基础上新增的积木块,图中已经有了详细的解释,这里就不再赘述了。
上方卡牌拾取完后,接着看这个被克隆出来的“插槽卡牌”。
先在“插槽卡牌”上创建几个新的局部变量。
位置:记录自己当前在卡牌槽中的位置。
类型:记录自己的卡牌类型。
迭代:在循环中用到。
标记位置:记录卡槽中跟自己一样的牌的位置。
是否是新牌:记录自己是否是新牌,刚拾取还没有进入到卡槽中的牌是新牌,进入卡槽之后就不再是新牌。
然后看一下“插槽卡牌”上的克隆积木逻辑。
其中的逻辑循环就是我们在理论中讲到的检查过程,可以对照着之前的图好好的理解一下。
在新卡牌插入卡槽之前,向卡槽中的其它的牌发送了一个调整位置的通知,接着,我们继续来看一下卡槽中的其它的牌是如何调整自己的位置的。
“当前卡牌的插入位置”这个变量中记录的是新牌插入的位置,卡牌的调整就是将大于等于这个位置的旧牌,全部向后移动一个位置,以此来为新牌腾出一个空位。
新牌被插入卡槽之后,再来看一下消除的计算和处理。我把消除计算的逻辑放在了“卡牌槽”上,来看一下“卡牌槽”这个精灵上。
首先,还是需要创建几个局部变量。
迭代1/2: 用于循环遍历。
比对类型:当前检查的卡牌类型。
匹配数量:当前检查的卡牌类型匹配的数量。
接着,来看一下消除计算的积木逻辑。
其中,较难以理解的一个是关于消除的遍历检查,这里用了双重的循环,另一个是关于“标记位置”的设置,为什么“当前卡牌的消除位置”设置的是“迭代2”呢?如果你觉得难以理解,我的建议是可以在纸上画出来一个卡牌队列,列举出一组数字,然后对照着你举出的例子来查看这段积木逻辑。其实,这整个过程你完全可以在一张纸上演绎出来。
最后,我们再来看一下“插槽卡牌”上的消除处理,以及消除后的剩余牌的位置调整。
这样这个从插入到消除的功能就完成啦!至于游戏的结束和过关条件如何判断,我们把它放在了上方的“消除处理”积木逻辑的最后。判读条件很简单,如果插槽中的 7 个位置都放满了卡牌,那么游戏就结束了;如果当前的游戏中不再有剩余的牌了,即“卡牌总数”变量等于 0 ,那么就证明玩家消除掉了所有的牌,游戏过关。
最后说一下为什么要再新增加一个“插槽卡牌”,而不是把“插槽卡牌”中的逻辑都放到原来的“卡牌”中,这是一种职责的分离,游戏中的每一个精灵只需要处理自己的职责即可,“卡牌”负责的是主要是堆叠的布局和拾取,拾取之后它的职责就结束了,剩余的如何插入卡槽,如果在卡槽中进行位置调整,如何进行删除等职责将都由“插槽卡牌”来处理。
把不同的职责和功能划分开来,会方便我们做计划或者开发,因为每一部分都只负责处理自己份内的事情,所以你在实现这部分功能的时候,就可以更专注啦!
最后,我们再预览一下整个游戏吧!
到这里肯定会有人问了,如何获取示例呀?答案是没有示例的获取方法,如果你想找的是一份类似“羊了个羊”游戏的源码,那么网上已经有开源的源码了,可以自己去搜索。如果你想要的是学习自己动手做一个这样的游戏,那么相信我,最好的方式就是你自己动手做一个。
只有你自己动手做出来的游戏才是真正属于你的,否则的话,即使游戏在你手里,它也不属于你。