前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Cocos Creator] 制作简版消消乐(五):生成初始方块的补充

[Cocos Creator] 制作简版消消乐(五):生成初始方块的补充

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

前言

在上一篇文章我们实现了消消乐的消除算法,但是同时出现了一个问题,游戏开始时就存在一些可以消除的组合,这是我们不想要看到的情况。

正文

整体思路

1. 为了不生成可以直接消除的组合,那我们就要在生成类型表的时候动些手脚。我们是逐行生成类型表的,那我们就在生成类型的时候检测当前坐标左边两个相同类型是否相同下面两个类型是否相同,我们在获取随机类型的时候排除这两种类型就可以了。

左边有两颗草莓了!!!

2. 然后同时要有可一步消除的情况,那我们可以对已生成的类型表进行检测,不合格就再重新生成类型表再次检测。由于情况比较多,我这里只举一个例子,其他的大家看代码即可。比如下面图中这种情况,我们把左下角葡萄的位置设为 (1, 1) ,那我们可以检测 (1, 1) 的类型是否和 (2, 2) 、 (2, 3) 的类型相同,相同的话那就说明他们可以一步消除。

想吃葡萄

代码实现

1. 在 GameUtil 中添加 getInitTypeMap 函数:

代码语言:javascript
复制
/**
 * 获取初始类型表
 */
public static getInitTypeMap(): TileType[][] {
    let typeMap: TileType[][] = [];
    for (let c = 0; c < GameConfig.col; c++) {
        let colSet: TileType[] = [];
        for (let r = 0; r < GameConfig.row; r++) {
            let excludeTypes = [];
            // 水平检测左边 2 个相同类型
            let rowType: TileType = null;
            if (c > 1 && typeMap[c - 1][r] === typeMap[c - 2][r]) rowType = typeMap[c - 1][r];
            if (rowType) excludeTypes.push(rowType);
            // 垂直检测下面 2 个相同类型
            let colType: TileType = null;
            if (r > 1 && colSet[r - 1] === colSet[r - 2]) colType = colSet[r - 1];
            if (colType) excludeTypes.push(colType);
            // 获取可用的随机类型
            colSet.push(GameUtil.getRandomType(excludeTypes));
        }
        typeMap.push(colSet);
    }
    return typeMap;
}

2. 在 GameUtil 中添加 hasValidCombo 函数;你别看下面代码密密麻麻好像很复杂,其实原理很直接很简单(另外我们还可以返回结果来制作提示功能,可以自行尝试):

代码语言:javascript
复制
/**
 * 是否有可一步消除的组合
 */
public static hasValidCombo(map: TileType[][]) {
    for (let r = 0; r < GameConfig.row; r++) {
        for (let c = 0; c < GameConfig.col; c++) {
            if (c + 3 <= GameConfig.col - 1) {
                if (map[c][r] === map[c + 1][r] && map[c][r] === map[c + 3][r]) { // 1 1 X 1
                    return true;
                }
                if (map[c][r] === map[c + 2][r] && map[c][r] === map[c + 3][r]) { // 1 X 1 1
                    return true;
                }
            }
            if (map[c][r] === map[c + 1][r]) {
                if (r - 1 >= 0 && map[c][r] === map[c + 2][r - 1]) { // 1 1 X
                    return true; // X X 1
                }
                if (r + 1 <= GameConfig.row - 1 && map[c][r] === map[c + 2][r + 1]) { // X X 1
                    return true; // 1 1 X
                }
            }
            if (map[c][r] === map[c + 2][r]) {
                if (r - 1 >= 0 && map[c][r] === map[c + 1][r - 1]) { // 1 X 1
                    return true; // X 1 X
                }
                if (r + 1 <= GameConfig.row - 1 && map[c][r] === map[c + 1][r + 1]) { // X 1 X
                    return true; // 1 X 1
                }
            }
            if (r - 1 >= 0 &&
                map[c][r] === map[c + 1][r - 1] && map[c + 1][r - 1] === map[c + 2][r - 1]) { // 1 X X
                return true; // X 1 1
            }
            if (r + 1 <= GameConfig.row - 1 &&
                map[c][r] === map[c + 1][r + 1] && map[c + 1][r + 1] === map[c + 2][r + 1]) { // X 1 1
                return true; // 1 X X
            }

            if (r + 3 <= GameConfig.row - 1) {
                if (map[c][r] === map[c][r + 1] && map[c][r] === map[c][r + 3]) {
                    return true;
                }
                if (map[c][r] === map[c][r + 2] && map[c][r] === map[c][r + 3]) {
                    return true;
                }
            }
            if (map[c][r] === map[c][r + 1]) {
                if (c - 1 >= 0 && map[c][r] === map[c - 1][r + 2]) {
                    return true;
                }
                if (c + 1 <= GameConfig.col - 1 && map[c][r] === map[c + 1][r + 2]) {
                    return true;
                }
            }
            if (map[c][r] === map[c][r + 2]) {
                if (c - 1 >= 0 && map[c][r] === map[c - 1][r + 1]) {
                    return true;
                }
                if (c + 1 <= GameConfig.col - 1 && map[c][r] === map[c + 1][r + 1]) {
                    return true;
                }
            }
            if (c - 1 >= 0 &&
                map[c][r] === map[c - 1][r + 1] && map[c - 1][r + 1] === map[c - 1][r + 2]) {
                return true;
            }
            if (c + 1 <= GameConfig.col - 1 &&
                map[c][r] === map[c + 1][r + 1] && map[c + 1][r + 1] === map[c + 1][r + 2]) {
                return true;
            }
        }
    }
    return false;
}

3. 我们再对 TileManager 中的 generateInitType 函数进行改造,让他可以生成让我们满意的类型表:

代码语言:javascript
复制
/**
 * 生成初始的类型表
 */
private generateInitTypeMap() {
    this.typeMap = GameUtil.getInitTypeMap();
    if (!GameUtil.hasValidCombo(this.typeMap)) {
        this.typeMap = GameUtil.getInitTypeMap();
    }
}

4. 打开游戏预览,可以看到我们已经成功了,没有可以直接消除的类型,而且存在可以一步消除的情况!

消它!!!

★ 所以到这里这篇文章就结束啦,下篇文章我们就来实现消除之后方块的下落和新生成

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

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

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

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

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