从零开始教你制作一个羊了个羊游戏2:随机生成卡牌

1,723 阅读8分钟

我正在参加「掘金·启航计划」

嗨!大家好,我是会做游戏也会教你做游戏的小蚂蚁。欢迎关注微信公众号【小蚂蚁教你做游戏】,每天学点儿做游戏的知识。

上一节教程里我们实现了游戏中最难的地方——堆叠牌的拾取,这节教程我们来继续学习一下如何随机的生成一个关卡中的牌。

上一节教程中我们使用的红色和白色的方块代表卡牌,为了区分不同的牌,我找了一些可爱的小动物头像(共 10 个),我们仍然是创建两层堆叠牌,不过这次这些牌会显示出不同的类型(不同的动物头像),每次生成的牌都是随机的,也就说即使是同一个关卡,每次打开也都会不一样。

这些小动物头像的素材我给大家打包好了,可以在公众号【小蚂蚁教你做游戏】中回复“动物头像”获取,或者你也可以使用自己的图片素材,只要能够区分不同的卡牌即可。

接下来我们就直接开始吧!

还是先从理论开始,一共有 10 种不同类型的小动物卡牌,我们先给它们依次编上序号。

如图,每一个数字代表一种类型的卡牌。一个数字就等同于一个动物头像,这个其实就是所谓的数据抽象了。

如图,右侧上方的这个 3 x 5 的头像排列,与下方的这个 3 x 5 的表格是等价的,后续我们将会暂时忽略掉这些可爱的动物头像,而直接跟数字打交道。

先回忆一下上一节课我们是如何创建初始牌的两层布局的,是不是先创建第一层,然后再创建第二层。就像是这样:

我们再继续往下拆解,第一层牌都是如何创建的呢?是不是从左上角的第一个位置开始,一行一行的,依次的创建每一张牌,直到创建完 15(3x5)张牌为止。接着,第二层牌与第一层牌一样,从左上角第一个位置开始,一行一行的,直到创建完 12(3x4)张牌为止。

在这个关卡布局中,一共需要创建 27 (15+12) 张牌,上方我们已经把牌的类型抽象成了数字,那是不是只要随机的生成 27 个数字,然后再根据每一个数字依次的去设置每一张牌的类型就可以了。这样在创建牌的时候,只要随机的从 1~10 这 10 个数字中取出一个,然后根据取出的数字设置一下牌的类型就 ok 了,貌似是很简单。

不过且慢,这个游戏是有一定的规则的,满足三个一样的牌可消除,也就是说如果这个关卡要能闯过去,必须要满足这样的两个条件:

  • 所有牌的总数必须是 3 的倍数
  • 每种类型的牌的数量必须是 3 的倍数

这个其实比较好理解,第一个条件,比如说一共有 20 张牌,那就肯定会出现凑不够三个消除的情况。第二个条件,比如当前有 5 个熊猫头像,那就肯定会出现有 2 个熊猫头像消不了的情况。

所以,我们在随机生成牌的时候是需要有一定的限制的,这个限制就是要满足上方的这两个条件,否则的话,这个关卡就是无法通过的。

如何生成有限制的随机牌呢?我们可以一组一组的去生成,每一组都是三张相同的牌,比如说现在总共要生成 9 张牌,卡牌的类型为 1~5 的五种类型,那么这个随机生成的过程就是这样的:

随机一个卡牌类型,例如 3,然后创建一组卡牌[3,3,3];

再随机一个卡牌类型,例如 5,创建一组卡牌 [3,3,3,5,5,5];

再随机一个卡牌类型,例如 2,创建一组卡牌[3,3,3,5,5,5,2,2,2];

这样就随机的生成了 9 张卡牌类型,并且它们满足能过关的条件。

这一点明白了,再回来看我们的游戏,假设我们设置这个关卡一共会出现 5 种不同类型的卡牌,那么整个生成过程就可以像下面这样。

先从 10 种类型中随机取出 5 种类型,然后再根据这 5 种类型依次的生成一组一组的卡牌,直到创建完成 27 张牌,最终看起来应该是这样。

你可能会说了,这个顺序也太整齐了吧,这样的牌在游戏里不是依次点击就好了吗?这样怎么能算是随机呢?

别急,在有了这样一组数据之后,我们还要做最后一步工作,即将这组数据随机的打乱顺序。

最终我们要在游戏中使用的是最下方的这组被随机打乱了顺序的数据。

接下来,让我们到微信小游戏制作工具中实现一下这个功能吧!

我们项目里还是只有这样的几个素材(我新添加了一个“基础文字”,显示了“羊了个羊”文字,其实没啥用,可以忽略)。

首先,选中“卡牌”,然后点击属性区中的“编辑造型”按钮,打开造型编辑窗口,我们把可爱的动物头像素材都导入到项目中,并且把它们添加到“卡牌”的造型上。

如图,造型的编号 1~10 对应的就是 10 个不同的动物头像,造型的编号其实也对应的卡牌的类型。

接着,新创建几个全局变量

卡牌总数:记录的是当前关卡中所有牌的总数;

卡牌类型数:用于设置当前的关卡中一共有几种类型的卡牌,例如设置为 5 ,即当前关卡中只会出现五种动物头像;

卡牌编号:用于记录当前创建的卡牌是第几张。例如我们共计要创建 27 张卡牌,则卡牌的编号就是 1~27;

除了全局变量之外,我们还创建了两个新的数据类型——列表。

随机牌列表: 存放着最后生成的那组被打乱的数据;

随机牌索引: 存放着从 1~10 个类型中随机抽取出的 5 个类型数字;

在“创建卡牌”精灵上,我们再创建三个局部变量

随机数:用于记录生成的随机数;

索引:记录当前用到的是随机牌索引列表中的第几个数据;

迭代:在循环中使用;

接着来看一下随机生成卡牌数据的积木逻辑。

逻辑刚开始,我们通过依次遍历两个表格中的每一项,来统计卡牌的总数。这里为什么不直接设置成 27 ,而要这么麻烦呢?是因为我们的关卡不一定总算是满满当当的 27 张牌,每一个关卡的游戏布局可能都不一样,卡牌的总数可能也会不一样。通过这样的操作,我们就无需每次去数一个关卡中的牌数了,只需要在表格中编辑当前关卡的布局,游戏启动后,程序就会自动帮我们统计的(它总是比我们数的更精确)。

接着,我们使用“取余”操作来检查牌的总数是否为 3 的倍数,如果不满足条件的话,会显示一个提醒,以后只要在游戏中看到这个提醒,就意味着你的关卡编辑的有问题了。满足条件的话,首先随机的取出指定数量的卡牌类型数字,然后按照顺序一组一组(3个)的生成放到列表中,直到生成卡牌总数个为止,最后使用一个“将列表随机打乱”的积木,打乱整个列表的顺序。

有了一个包含着 27 个卡牌类型数字的列表,接着要做的就是一个一个的创建真实的卡牌了。

图中红线圈出的就是在之前的逻辑上新增的积木,创建卡牌之前,先将“卡牌编号”设置为 1,然后每创建一张牌,这个数字就加 1。

再来看一下“卡牌”上的修改,我们为其增加了一个新的局部变量。

类型: 记录的是当前的卡牌的类型(这个会在后续消除判断的时候用到)。

看一下“卡牌”上的克隆逻辑的修改。

红色框圈出的为新增的积木,记录自己的类型,然后根据类型数字设置自己的造型。

最后,我们来预览一下。

每次重新启动,都会生成不同的图标排列,即使是同一个布局的关卡,每次游戏也都会有不一样感觉。而且这个关卡是绝对能够闯过去的。

你可以通过调试场景来看一下两个随机列表中的数据的变化。

好了,这节教程的内容就到这里了。看完后,就动手试试吧!

最后,给大家留一个小的思考题,下方的这三行数据,代表的就是我们这个示例中制作的关卡。有了这 3 行数据,我们就能在游戏中创建出一个关卡。

这三行数据分别代表的是什么呢?想明白这个问题,关卡编辑器你就会做了。