前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Cocos Creator] 制作简版消消乐(六):方块下落与空位填充(完结)

[Cocos Creator] 制作简版消消乐(六):方块下落与空位填充(完结)

作者头像
陈皮皮
发布2020-07-10 16:57:02
2.7K0
发布2020-07-10 16:57:02
举报
文章被收录于专栏:菜鸟小栈菜鸟小栈

前言

上回我们正式完成了初始方块的正确生成以及组合的消除,同时我们这个系列也接近尾声。

这篇文章和大家一起实现组合消除之后,方块的下落以及新方块的生成

项目预览

消消消

正文

整体思路

1. 方块的下落:我们从左下角第一个方块开始,向上遍历检查,发现有空位后,向上查找直到有可用的方块,将可用方块交换(做下落动画)到刚刚的空位,每一列都重复以上步骤,即可让下面的空位被填满。

2. 生成新方块:下落之后,再遍历每一个位置,发现有空的就随机生成一个新的方块就好啦。

3. 消除并检测可玩性:生成新的方块之后又可以继续查找可消除的组合了,如果没有可以消除的组合,还要检查有没有可以一步消除的组合,如果没有,那就要重新生成全部方块了。

代码实现

1. 在 TileManager 组件中实现方块下落函数 fallDown :

代码语言:javascript
复制
/**
 * 方块下落
 */
private async falldown() {
    let promises: Promise<void>[] = [];
    for (let c = 0; c < GameConfig.col; c++) {
        for (let r = 0; r < GameConfig.row; r++) {
            // 找到空位
            if (!this.getType(c, r)) {
                // 往上找方块
                for (let nr = r + 1; nr < GameConfig.row; nr++) {
                    // 找到可以用的方块
                    if (this.getType(c, nr)) {
                        // 转移数据
                        this.setType(c, r, this.getType(c, nr));
                        this.setTile(c, r, this.getTile(c, nr));
                        this.getTile(c, r).setCoord(c, r);
                        // 置空
                        this.setTile(c, nr, null);
                        this.setType(c, nr, null);
                        // 下落
                        let fallPos = MapManager.getPos(c, r);
                        let fallTime = (nr - r) * 0.1;
                        promises.push(new Promise(res => {
                            cc.tween(this.getTile(c, r).node)
                                .to(fallTime, { position: cc.v2(fallPos.x, fallPos.y - 10) })
                                .to(0.05, { position: fallPos })
                                .call(() => res())
                                .start();
                        }));
                        break;
                    }
                }
            }
        }
    }
    // 等待所有方块完成下落动画
    await Promise.all(promises);
}

2. 在 TileManager 组件中实现生成新方块的函数 fillEmpty :

代码语言:javascript
复制
/**
 * 填充空位
 */
private async fillEmpty() {
    for (let c = 0; c < GameConfig.col; c++) {
        for (let r = 0; r < GameConfig.row; r++) {
            // 找到空位
            if (!this.getType(c, r)) {
                let type = GameUtil.getRandomType();
                let tile = this.getNewTile(c, r, type);
                this.setTile(c, r, tile)
                this.setType(c, r, type);
            }
        }
    }
    await new Promise(res => setTimeout(res, 100));
}

3. 在 TileManager 组件实现函数 keepCheckingUntilNoMoreCombiantion ,用于持续检查组合然后消除下落并填充,没有可一步操作的组合时重新生成全部方块:

代码语言:javascript
复制
/**
 * 检查可消除组合直到没有可以消除的组合
 */
private async keepCheckingUntilNoMoreCombiantion() {
    this.combinations = GameUtil.getCombinations(this.typeMap); // 获取可消除的组合
    // 有可消除的组合吗
    while (this.combinations.length > 0) {
        this.eliminateCombinations(); // 消除
        await new Promise(res => setTimeout(res, 250));
        await this.falldown(); // 下落
        await new Promise(res => setTimeout(res, 250));
        await this.fillEmpty(); // 填充
        await new Promise(res => setTimeout(res, 250));
        this.combinations = GameUtil.getCombinations(this.typeMap); // 获取可消除的组合
        await new Promise(res => setTimeout(res, 250));
    }
    // 存在一步可消除情况吗
    if (!GameUtil.hasValidCombo(this.typeMap)) {
        this.removeAllTiles(); // 移除所有方块
        this.generateInitTypeMap(); // 生成可用 typeMap
        this.generateTiles(); // 生成方块
    }
}

4. 改造 tryExchange 函数,实现交换消除后下落并填充,然后持续检测:

代码语言:javascript
复制
/**
 * 尝试交换方块
 * @param coord1 1
 * @param coord2 2
 */
private async tryExchange(coord1: Coordinate, coord2: Coordinate) {
    // 交换方块
    await this.exchangeTiles(coord1, coord2);
    // 获取可消除组合
    this.combinations = GameUtil.getCombinations(this.typeMap);
    if (this.combinations.length > 0) {
        await new Promise(res => setTimeout(res, 250));
        this.eliminateCombinations(); // 消除
        await new Promise(res => setTimeout(res, 250));
        await this.falldown(); // 下落
        await new Promise(res => setTimeout(res, 250));
        await this.fillEmpty(); // 填充
        await new Promise(res => setTimeout(res, 250));
        this.keepCheckingUntilNoMoreCombiantion(); // 持续检测
    } else {
        // 不能消除,换回来吧
        await this.exchangeTiles(coord1, coord2);
    }
}

★ 到这里,我们完成了简版消消乐的制作啦,但是我们只有核心基础玩法,如果想要让游戏更好玩,可以在这基础上实现特殊方块道具系统之类的功能,这些就需要你自己去探索啦~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 菜鸟小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档