精华内容
下载资源
问答
  • cocos creator 消消乐游戏
  • 这是用cocos creator做的消消乐,可以帮助初学者快速掌握这软件。
  • cocoscreator javascript 开心消消乐 源码,仅供学习。
  • cocoscreator引擎开发的开心消消乐源码,亲测1.x版本以及2.x版本都可运行。用于学习交流,不可商用。
  • cocosCreator开心消消乐源码以及素材,使用js语言开发,开源供开发者学习。
  • 开心消消乐demo
  • cocos creator开发的开心消消乐,需要的小伙伴可以下载研究一下。
  • creator实现的三消游戏,creator1.8 版本。算是比较完整的版本。实现了很多特效,效果。
  • 适合cocos creator游戏初学者
  • cocos消消乐源码

    2018-10-30 16:46:28
    coocs creator消消乐源码,发不出来供大家学习使用,还有很多未完善的地方,留给大家努力吧。。
  • cocos creator小游戏合集

    2020-05-29 10:44:18
    2048,小鸟,黄金矿工,开心消消乐,跑酷,扫雷,飞机大战等 cocos creator小游戏合集 cocos2dx
  • Cocos Creator7个小游戏合集2048、小鸟、 黄金矿工 、开心消消乐、 跑酷、 扫雷、 飞机大战
  • cocosCreator 学习用的多个小游戏源码,有需要的可以下载来参考学习
  • 本文由“壹伴编辑器”提供技术支前言来了来了,终于来了!上篇文章我们实现了方块的生成和交换,那本篇文章就到了该系列的重头戏,我们一起来实现消消乐的消除算法!别说了,冲!!!本文由“壹伴编辑...


    本文由“壹伴编辑器”提供技术支

    前言

    来了来了,终于来了!上篇文章我们实现了方块的生成和交换,那本篇文章就到了该系列的重头戏,我们一起来实现消消乐消除算法

    别说了,冲!!!

    本文由“壹伴编辑器”提供技术支

    正文

    思路讲解

    1. 首先我们确定消除规则,这里我们采用和开心消消乐类似的消除规则(核心为超过 3 个连续的同类型即可消除),具体分为以下几点:

    1-1. 横型和竖型;这两种种情况很简单,我们只需要遍历每一行每一列,找出那些连续超过 3 个的组合就可以了

    普通横竖型

    1-2. 十字型 T 型 L 型;这三种情况相对比较复杂了,但是实质上他们都是由一个横型加上一个竖型组合而成的,这三种组合的不同点在于他们的共同方块的上下左右有多少方块(比如十字型的共同方块上下左右都有 1 个以上的方块),我们需要进行额外的判断:

        

    左:十字型和 T 型 | 右:L 型

    代码实现

    提示:项目已更新至码云,点击文章底部阅读原文获取该项目

    1. 在 Enum 文件中定义一个组合类型的枚举:

    // 以下为 Enum.ts 中添加的内容
    
    /**
     * 组合类型
     */
    export enum CombinationType {
        Horizontal = 1, // 横型
        Vertical, // 竖型
        Cross, // 十字型
        TShape, // T 型
        LShape, // L 型
    }
    

    2. 在 DataStructure 文件中定义一个组合的类:

    // 以下为 DataStructure.ts 文件添加的内容
    
    /**
     * 组合
     */
    export class Combination {
    
        public coords: Coordinate[]; // 坐标集
    
        public commonCoord: Coordinate; // 共同坐标
    
        public type: CombinationType; // 组合类型
    
        constructor(coords: Coordinate[]) {
            this.coords = coords;
            this.updateType();
        }
    
        /**
         * 更新类型
         */
        private updateType() {
            let up = 0;
            let down = 0;
            let left = 0;
            let right = 0;
            let keyCoord = this.commonCoord ? this.commonCoord : this.coords[0]; // 关键坐标
            // 收集数量
            for (let i = 0; i < this.coords.length; i++) {
                if (this.coords[i].compare(keyCoord)) continue; // 同一个坐标时跳过
                // 判断位置
                if (this.coords[i].x === keyCoord.x) {
                    if (this.coords[i].y > keyCoord.y) up++;
                    else down++;
                } else {
                    if (this.coords[i].x < keyCoord.x) left++;
                    else right++;
                }
            }
            // 判断类型
            if (up === 0 && down === 0) this.type = CombinationType.Horizontal;
            else if (left === 0 && right === 0) this.type = CombinationType.Vertical;
            else if (up > 0 && down > 0 && left > 0 && right > 0) this.type = CombinationType.Cross;
            else if ((up > 0 && down === 0 && left === 0 && right > 0) ||
                (up > 0 && down === 0 && left > 0 && right === 0) ||
                (up === 0 && down > 0 && left === 0 && right > 0) ||
                (up === 0 && down > 0 && left > 0 && right === 0)) {
                this.type = CombinationType.LShape;
            } else if ((up === 0 && down > 0 && left > 0 && right > 0) ||
                (up > 0 && down === 0 && left > 0 && right > 0) ||
                (up > 0 && down > 0 && left === 0 && right > 0) ||
                (up > 0 && down > 0 && left > 0 && right === 0)) {
                this.type = CombinationType.TShape;
            }
        }
    
        /**
         * 组合是否包含坐标集中的任意一个,有得返回对应坐标
         * @param coords 查询坐标集
         */
        public include(coords: Coordinate[]): Coordinate {
            for (let i = 0; i < this.coords.length; i++) {
                for (let j = 0; j < coords.length; j++) {
                    if (this.coords[i].compare(coords[j])) return coords[j];
                }
            }
            return null;
        }
    
        /**
         * 合并组合
         * @param coords 坐标集
         * @param commonCoord 共同坐标
         */
        public merge(coords: Coordinate[], commonCoord: Coordinate) {
            for (let i = 0; i < coords.length; i++) {
                if (!coords[i].compare(commonCoord))
                    this.coords.push(coords[i]);
            }
            this.commonCoord = commonCoord;
            this.updateType();
        }
    }
    

    3. 接下来在 GameUtil 中实现获取当前所有可消除组合的函数:

    /**
     * 获取可消除的组合
     */
    public static getCombinations(typeMap: TileType[][]) {
        let combinations: Combination[] = [];
        // 逐行检测
        for (let r = 0; r < GameConfig.row; r++) {
            let count: number = 0;
            let type: TileType = null;
            for (let c = 0; c < GameConfig.col; c++) {
                if (c === 0) {
                    count = 1; // 连续计数
                    type = typeMap[c][r]; // 保存类型
                } else {
                    if (typeMap[c][r] && typeMap[c][r] === type) {
                        // 类型相同
                        count++;
                        // 到最后一个了,是不是有 3 个以上连续
                        if (c === GameConfig.col - 1 && count >= 3) {
                            let coords = [];
                            for (let i = 0; i < count; i++) {
                                coords.push(Coord(c - i, r));
                            }
                            combinations.push(new Combination(coords));
                        }
                    } else {
                        // 类型不同
                        if (count >= 3) {
                            // 已累积 3 个
                            let coords = [];
                            for (let i = 0; i < count; i++) {
                                coords.push(Coord(c - 1 - i, r));
                            }
                            combinations.push(new Combination(coords));
                        }
                        // 重置
                        count = 1;
                        type = typeMap[c][r];
                    }
                }
            }
        }
        // 逐列检测
        for (let c = 0; c < GameConfig.col; c++) {
            let count: number = 0;
            let type: TileType = null;
            for (let r = 0; r < GameConfig.row; r++) {
                if (r === 0) {
                    count = 1;
                    type = typeMap[c][r];
                } else {
                    if (typeMap[c][r] && typeMap[c][r] === type) {
                        count++;
                        if (r === GameConfig.row - 1 && count >= 3) {
                            let coords = [];
                            for (let i = 0; i < count; i++) {
                                coords.push(Coord(c, r - i));
                            }
                            // 是否可以和已有组合合并
                            let hasMerge = false;
                            for (let i = 0; i < combinations.length; i++) {
                                let common = combinations[i].include(coords);
                                if (common) {
                                    combinations[i].merge(coords, common);
                                    hasMerge = true;
                                    break;
                                }
                            }
                            if (!hasMerge) combinations.push(new Combination(coords));
                        }
                    } else {
                        if (count >= 3) {
                            let coords = [];
                            for (let i = 0; i < count; i++) {
                                coords.push(Coord(c, r - 1 - i));
                            }
                            // 是否可以和已有组合合并
                            let hasMerge = false;
                            for (let i = 0; i < combinations.length; i++) {
                                let common = combinations[i].include(coords);
                                if (common) {
                                    combinations[i].merge(coords, common);
                                    hasMerge = true;
                                    break;
                                }
                            }
                            if (!hasMerge) combinations.push(new Combination(coords));
                        }
                        count = 1;
                        type = typeMap[c][r];
                    }
                }
            }
        }
        return combinations;
    }
    

    4. 然后我们对 TileManager 进行改造;添加了 combinations 变量、更新 tryExchange 函数并加入 eliminateCombinations 和 eliminateTile 函数:

    private combinations: Combination[] = null; // 可消除组合
    
    /**
     * 尝试交换方块
     * @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) {
            // 消除!!!
            this.eliminateCombinations();
        } else {
            // 不能消除,换回来吧
            await this.exchangeTiles(coord1, coord2);
        }
    }
    
    /**
     * 消除组合
     */
    private eliminateCombinations() {
        for (let i = 0; i < this.combinations.length; i++) {
            for (let j = 0; j < this.combinations[i].coords.length; j++) {
                this.eliminateTile(this.combinations[i].coords[j]);
            }
        }
        this.combinations = [];
    }
    
    /**
     * 消除方块
     * @param coord 坐标
     */
    private eliminateTile(coord: Coordinate) {
        this.getTileMap(coord).disappear(); // 方块消失
        this.setTileMap(coord, null); // 数据置空
        this.setTypeMap(coord, null); // 数据置空
    }
    

    5. 此时,我们的消除功能也实现了:

    ★ 但是现在还有一个问题,游戏开始时就随机出现了一些可消除的组合,理论上来说开局时是不能有任何消除但是同时又要存在可一步消除的情况,所以这就是我们下篇文章会讲到的东西了。

    本文由“壹伴编辑器”提供技术支

    结束语

    以上皆为本菜鸡的个人观点,文采实在不太好,如果写得不好还请各位见谅。如果有哪些地方说的不对,还请各位指出,大家共同进步。

    接下来我会持续分享自己所学的知识与见解,欢迎各位关注本公众号。

    我们,下次见!

    本文由“壹伴编辑器”提供技术支

    扫描二维码

    获取更多精彩

    文弱书生陈皮皮

    点击 阅读原文 获取完整项目

    展开全文
  • 整合了多个小游戏 供大家分享 2048 傻鸟. 消消乐等6个小程序. cocoscreator 实现. 可直接运行 大家互相学习
  • 本文由“壹伴编辑器”提供技术支前言由于内容较多,不能够在一篇文章内完成,所以接下来会有一个系列文章来和大家一起从 0 开始制作一个 8 x 8 包含 5 种方块的简版消消乐。本篇文章作为...

    本文由“壹伴编辑器”提供技术支

    前言

    由于内容较多,不能够在一篇文章内完成,所以接下来会有一个系列文章来和大家一起从 0 开始制作一个 8 x 8 包含 5 种方块的简版消消乐

    本篇文章作为该系列的第一篇,不含代码,讲解资源准备与场景搭建

    话不多说,让我们开始吧!

    本文由“壹伴编辑器”提供技术支

    正文

    资源准备

    1. 首先我们创建一个空项目,我用的 Cocos Creator 版本为 2.3.3 ,如果跟我一起做的话建议使用和我同样的版本,避免出现版本兼容性问题。

    2. 创建好项目之后,先点击左上角 项目 -> 项目设置 -> 项目预览 ,将设计分辨率改为 宽度:720 | 高度:1280 。

    3. 然后创建好资源目录结构并导入之后要用到的素材(点击文章底部阅读原文获取素材)。

        

    左:资源目录结构  |  右:导入素材

    场景搭建

    1. 首先我们在 scenes 目录下新建一个名为 game 的空场景,并且切换到 game 场景。

    2. 在 Canvas 节点下创建一个带 Sprite 组件的 background 节点并应用我们准备好的背景图,并调整为合适的大小。

    3. 在 Canvas 节点下创建一个空节点 main 作为我们主要游戏内容的父节点,并且使用 FlatPanel 图片来创建一个游戏内容大背景(使用图片前,我们需要编辑它的 Border 属性来支持九宫格模式,避免拉伸时变形)。

        

    左:编辑素材  |  右:游戏内容背景

    4. 制作 8 x 8 的地图(简版为固定地图,所以这里不采用动态生成的方式)。首先用 FlatPanel 来制作 64 个大小为 70 x 70 的方格 vacancy 节点作为单个方块的背景,创建节点 mapContainer 作为方格的容器,并加入 Layout 组件快速排列,边距(padding)和方格间距(spacing)均为 5,最后顺便调整一下背景:

    mapContainer

    5. 制作方块预制体。创建节点 tileContainer 作为方块的容器,在容器中创建一个 70 x 70 的空节点 tile ,给 tile 节点添加一个带有 Sprite 组件的子节点 sprite 并调整到合适的大小,该节点用来显示方块的图像。然后将节点拖到 prefabs 目录下保存为预制体,并将 tile 节点删除。

    制作方块 tile 的预制体

    ★ 到这里我们资源准备和场景搭建的部分就已经完成啦,下篇文章正式开始 撸 代 码 !

    本文由“壹伴编辑器”提供技术支

    本文由壹伴编辑器”提供技术支

    结束语

    以上皆为本菜鸡的个人观点,文采实在不太好,如果写得不好还请各位见谅。如果有哪些地方说的不对,还请各位指出,大家共同进步。

    接下来我会持续分享自己所学的知识与见解,欢迎各位关注本公众号。

    我们,下次见!

    本文由“壹伴编辑器”提供技术支

    扫描二维码

    获取更多精彩

    文弱书生陈皮皮

    点击 阅读原文 获取文中用到的素材

    展开全文
  • Cocos Creator源码和教程分享

    千次阅读 2019-08-02 13:54:37
    https://forum.cocos.com/t/cocoscreator/80131 https://forum.cocos.com/t/cocoscreator/83015 关注微信公众号公众号,根据提示获取完整游戏源码和游戏开发教程。 以上是已有游戏源码,由于游戏项目较多,...

    由于受论坛修改时间限制,后续不能修改的情况下,开新帖分享新源码和教程。

    https://forum.cocos.com/t/cocoscreator/80131

    https://forum.cocos.com/t/cocoscreator/83015

     

    关注微信公众号公众号,根据提示获取完整游戏源码和游戏开发教程。

     

    以上是已有游戏源码,由于游戏项目较多,后期还会不定期更新,需要先关注公众号,再获取对应游戏的源码工程,使用CocosCreator2.0.8,项目可以直接打开使用。已有的游戏源码有:动物同化、左右跳、重力球、推箱子、扫雷、消消乐、六边形消除、数钱、打飞机、跑酷、杆子游戏、打地鼠、口红机。大部分都是自己开发的,少部分拿的网上改编的。

    项目中的游戏资源时网络上搜集的,游戏效果如下:

    猴子吃香蕉
    动物同化
    左右跳
    重力球
    虚拟摇杆
    扫雷
    六边形
    数钱
    打飞机
    跑酷
    打地鼠
    口红机
    撑杆跳
    展开全文
  • 本文由“壹伴编辑器”提供技术支前言在上一篇文章中我们实现部分基础组件和管理脚本,那么本篇文章将和大家一起实现方块的生成与交换的逻辑。温馨提醒:本文含有大量代码和注释,请提前做好心理准备并...

    本文由“壹伴编辑器”提供技术支

    前言

    在上一篇文章中我们实现部分基础组件和管理脚本,那么本篇文章将和大家一起实现方块的生成与交换的逻辑

    温馨提醒:本文含有大量代码和注释,请提前做好心理准备并认真阅读

    话不多说,冲鸭!!!

    本文由“壹伴编辑器”提供技术支

    正文

    生成方块

    1. 新建脚本 GameUtil ,用来实现游戏中的各种算法,是游戏中最重要的模块之一。我这里暂时只实现了一个获取随机类型的函数:

    import { TileType } from "../type/Enum";
    import GameConfig from "../../data/GameConfig";
    
    export default class GameUtil {
    
        /**
         * 获取随机类型
         * @param exclude 需排除的类型
         */
        public static getRandomType(exclude: TileType[] = []):TileType {
            let types = GameConfig.types.concat();
            for (let i = 0; i < exclude.length; i++) {
                types.splice(types.indexOf(exclude[i]), 1);
            }
              return types[Math.floor(types.length * Math.random())];
        }
    
    }
    

    2. 新建脚本 TileManager ,用来管理所有方块逻辑和操作实现,也是游戏最重要的模块之一。 

    2-1. 用二维数组变量 typeMap 和 tileMap 分别来装所有方块类型和组件,我们就可以根据二维坐标来获取特定的类型和组件;

    2-2. 根据 GameConfig 中的配置遍历生成类型表,然后再根据类型表生成方块:

    import Tile from "../component/Tile";
    import { TileType } from "../type/Enum";
    import GameConfig from "../../data/GameConfig";
    import GameUtil from "../util/GameUtil";
    import PoolManager from "./PoolManager";
    import MapManager from "./MapManager";
    
    const { ccclass, property } = cc._decorator;
    
    @ccclass
    export default class TileManager extends cc.Component {
    
        @property(cc.Node)
        private container: cc.Node = null; // 所有方块的容器
    
        private typeMap: TileType[][] = null; // 类型表:二维数组,保存所有方块的类型,方便计算
    
        private tileMap: Tile[][] = null; // 组件表:二维数组,保存所有方块 Tile 组件,方便读取
    
        private static instance: TileManager = null
    
        protected onLoad() {
            TileManager.instance = this;
        }
    
        public static init() {
            this.instance.generateInitTypeMap();
            this.instance.generateTiles();
        }
    
        /**
         * 生成初始的类型表
         */
        private generateInitTypeMap() {
            this.typeMap = [];
            for (let c = 0; c < GameConfig.col; c++) {
                let colSet: TileType[] = [];
                for (let r = 0; r < GameConfig.row; r++) {
                    colSet.push(GameUtil.getRandomType());
                }
                this.typeMap.push(colSet);
            }
        }
    
        /**
         * 根据类型表生成方块
         */
        private generateTiles() {
            this.tileMap = [];
            for (let c = 0; c < GameConfig.col; c++) {
                let colTileSet: Tile[] = [];
                for (let r = 0; r < GameConfig.row; r++) {
                    colTileSet.push(this.getTile(c, r, this.typeMap[c][r]));
                }
                this.tileMap.push(colTileSet);
            }
        }
    
        /**
         * 生成并初始化方块
         * @param x 横坐标
         * @param y 纵坐标
         * @param type 类型
         */
        private getTile(x: number, y: number, type: TileType): Tile {
            let node = PoolManager.get();
            node.setParent(this.container);
            node.setPosition(MapManager.getPos(x, y));
            let tile = node.getComponent(Tile);
            tile.init();
            tile.setCoord(x, y);
            tile.setType(type);
            tile.appear();
            return tile;
        }
    }
    

    3. 将我们写好的 Tile 组件挂在 tile 预制体上,并将子节点 sprite 拖到 Tile 组件上,然后保存:

    预制体 tile

    4. 在场景中新建一个节点 managers ,然后把 ResManager 、 PoolManager 和 TileManager 脚本拖到 managers 节点下,并设置好他们各自的属性:

    managers 节点 

      

    左:ResManager | 中:PoolManager | 右:TileManager

    5. 新建脚本 Game ,这个脚本为游戏的入口,启动游戏就靠它:

    import MapManager from "./manager/MapManager";
    import TileManager from "./manager/TileManager";
    
    const { ccclass, property } = cc._decorator;
    
    @ccclass
    export default class Game extends cc.Component {
    
        protected start() {
            MapManager.init();
            TileManager.init();
        }
    
    }
    

    6. 在场景下新建 main 节点,并将 Game 组件拖到该节点上。保存场景,点击预览,就可以看到已经成功生成方块了:

        

    左:main 节点 | 右:预览画面

    交换方块

    1. 我们交换方块有两种方式:点击和滑动。我们先在 Enum 文件中添加一个枚举 SlidDirection 来表示滑动方向:

    /**
     * 滑动方向
     */
    export enum SlidDirection {
        Up = 1, // 上
        Down, // 下
        Left, // 左
        Right, // 右
    }
    

    2. 向 GameUtil 中添加一个计算滑动方向的函数和一个根据坐标和方向计算目标坐标的函数:

    /**
     * 获取滑动的方向
     * @param startPos 开始位置
     * @param endPos 结束位置
     */
    public static getSlidDirection(startPos: cc.Vec2, endPos: cc.Vec2): SlidDirection {
        let offsetX = endPos.x - startPos.x; // x 偏移
        let offsetY = endPos.y - startPos.y; // y 偏移
    
        if (Math.abs(offsetX) < Math.abs(offsetY)) {
            return offsetY > 0 ? SlidDirection.Up : SlidDirection.Down
        } else {
            return offsetX > 0 ? SlidDirection.Right : SlidDirection.Left;
        }
    }
    
    /**
     * 获取指定方向的坐标
     * @param coord 坐标
     * @param direction 方向
     */
    public static getCoordByDirection(coord: Coordinate, direction: SlidDirection) {
        switch (direction) {
            case SlidDirection.Up:
                return coord.y === GameConfig.row - 1 ? null : Coord(coord.x, coord.y + 1);
            case SlidDirection.Down:
                return coord.y === 0 ? null : Coord(coord.x, coord.y - 1);
            case SlidDirection.Left:
                return coord.x === 0 ? null : Coord(coord.x - 1, coord.y);
            case SlidDirection.Right:
                return coord.x === GameConfig.col - 1 ? null : Coord(coord.x + 1, coord.y);
        }
    }
    

    3. 接下来在 TileManager 中更新并添加了很多变量和函数来实现方块交换的逻辑。高能预警!!!接下来有大量代码和注释,虽然我每个函数都加了注释,但是我还是建议你直接拉到底部阅读完整文件,那样会比较好理解

    private selectedCoord: Coordinate = null; // 当前已经选中的方块坐标
    
    private tileTouchStartPos: cc.Vec2 = null; // 滑动开始位置
    
    protected onLoad() {
        TileManager.instance = this;
    
        GameEvent.on(TileEvent.TouchStart, this.onTileTouchStart, this);
        GameEvent.on(TileEvent.TouchEnd, this.onTileTouchEnd, this);
        GameEvent.on(TileEvent.TouchCancel, this.onTileTouchCancel, this);
    }
    
    protected onDestroy() {
        GameEvent.off(TileEvent.TouchStart, this.onTileTouchStart, this);
        GameEvent.off(TileEvent.TouchEnd, this.onTileTouchEnd, this);
        GameEvent.off(TileEvent.TouchCancel, this.onTileTouchCancel, this);
    }
    
    /**
     * 方块的 touchstart 回调
     * @param coord 坐标
     * @param pos 点击位置
     */
    private onTileTouchStart(coord: Coordinate, pos: cc.Vec2) {
        cc.log('点击 | coord: ' + coord.toString() + ' | type: ' + this.getTypeMap(coord));
        // 是否已经选中了方块
        if (this.selectedCoord) {
            // 是否同一个方块
            if (!this.selectedCoord.compare(coord)) {
                // 判断两个方块是否相邻
                if (this.selectedCoord.isAdjacent(coord)) {
                    this.tryExchangeByTouch(this.selectedCoord, coord);
                    this.setSelectedTile(null); // 交换后重置
                } else {
                    this.tileTouchStartPos = pos;
                    this.setSelectedTile(coord); // 更新选中的方块坐标
                }
            } else {
                this.tileTouchStartPos = pos;
            }
        } else {
            this.tileTouchStartPos = pos;
            this.setSelectedTile(coord);
        }
    }
    
    /**
     * 方块的 touchend 回调
     */
    private onTileTouchEnd() {
        this.tileTouchStartPos = null;
    }
    
    /**
     * 方块的 touchcancel 回调
     * @param coord 坐标
     * @param cancelPos 位置
     */
    private onTileTouchCancel(coord: Coordinate, cancelPos: cc.Vec2) {
        if (!this.tileTouchStartPos) return;
        this.tryExchangeBySlid(coord, GameUtil.getSlidDirection(this.tileTouchStartPos, cancelPos));
        this.tileTouchStartPos = null;
    }
    
    /**
     * 设置选中的方块
     * @param coord 坐标
     */
    private setSelectedTile(coord: Coordinate) {
        this.selectedCoord = coord;
    }
    
    /**
     * 尝试点击交换方块
     * @param coord1 1
     * @param coord2 2
     */
    private tryExchangeByTouch(coord1: Coordinate, coord2: Coordinate) {
        cc.log('尝试点击交换方块 | coord1: ' + coord1.toString() + ' | coord2: ' + coord2.toString());
        this.tryExchange(coord1, coord2);
    }
    
    /**
     * 尝试滑动交换方块
     * @param coord 坐标
     * @param direction 方向
     */
    private tryExchangeBySlid(coord: Coordinate, direction: SlidDirection) {
        cc.log('点击交换方块 | coord1: ' + coord.toString() + ' | direction: ' + direction);
        let targetCoord = GameUtil.getCoordByDirection(coord, direction);
        if (targetCoord) {
            this.tryExchange(coord, targetCoord);
            this.setSelectedTile(null);
        }
    }
    
    /**
     * 尝试交换方块
     * @param coord1 1
     * @param coord2 2
     */
    private async tryExchange(coord1: Coordinate, coord2: Coordinate) {
        await this.exchangeTiles(coord1, coord2);
    }
    
    /**
     * 交换方块
     * @param coord1 1
     * @param coord2 2
     */
    private async exchangeTiles(coord1: Coordinate, coord2: Coordinate) {
        // 保存变量
        let tile1 = this.getTileMap(coord1);
        let tile2 = this.getTileMap(coord2);
        let tile1Type = this.getTypeMap(coord1);
        let tile2Type = this.getTypeMap(coord2);
        // 交换数据
        tile1.setCoord(coord2);
        tile2.setCoord(coord1);
        this.setTypeMap(coord1, tile2Type);
        this.setTypeMap(coord2, tile1Type);
        this.setTileMap(coord1, tile2);
        this.setTileMap(coord2, tile1);
        // 交换方块
        cc.tween(tile1.node).to(0.1, { position: MapManager.getPos(coord2) }).start();
        cc.tween(tile2.node).to(0.1, { position: MapManager.getPos(coord1) }).start();
        await new Promise(res => setTimeout(res, 100));
    }
    
    /**
     * 设置类型表
     * @param x 横坐标
     * @param y 纵坐标
     */
    private getTypeMap(x: number | Coordinate, y?: number): TileType {
        return typeof x === 'number' ? this.typeMap[x][y] : this.typeMap[x.x][x.y];
    }
    
    /**
     * 获取类型
     * @param x 横坐标
     * @param y 纵坐标
     * @param type 类型
     */
    private setTypeMap(x: number | Coordinate, y: number | TileType, type?: TileType) {
        if (typeof x === 'number') this.typeMap[x][y] = type;
        else this.typeMap[x.x][x.y] = <TileType>y;
    }
    
    /**
     * 获取组件
     * @param x 横坐标
     * @param y 纵坐标
     */
    private getTileMap(x: number | Coordinate, y?: number): Tile {
        return typeof x === 'number' ? this.tileMap[x][y] : this.tileMap[x.x][x.y]; }
    
    /**
     * 设置组件表
     * @param x 横坐标
     * @param y 纵坐标
     * @param type 组件
     */
    private setTileMap(x: number | Coordinate, y: number | Tile, tile?: Tile) {
        if (typeof x === 'number') this.tileMap[x][<number>y] = tile;
        else this.tileMap[x.x][x.y] = <Tile>y;
    }

    4. 以上逻辑写好之后,我们就已经实现了交换方块的逻辑了:

    点点点,滑滑滑

    5. 为了更直观的让我们知道当前选中了哪个方块,我们接着作。

    5-1.  在 tileContainer 节点上方添加一个空节点 underLayer ,将资源中的 selectFrame 图片拖到 underLayer 节点下,调整为合适的大小,然后将 selectFrame 节点关闭:

    selectFrame

    5-2. 给 TileContainer 添加一个属性,并对 setSelectedTile 函数进行升级:

    @property(cc.Node)
    private selectFrame: cc.Node = null; // 选中框
    
    /**
     * 设置选中的方块
     * @param coord 坐标
     */
    private setSelectedTile(coord: Coordinate) {
        this.selectedCoord = coord;
        if (coord) {
            this.selectFrame.active = true;
            this.selectFrame.setPosition(MapManager.getPos(coord));
        } else {
            this.selectFrame.active = false;
        }
    }
    

    5-3. 将 selectFrame 节点拖到 TileContainer 组件上之后,再预览游戏:

    wow awsome

    ★ 到这里本篇文章内容就结束了,不知道你看懵了没,反正我是写懵了。下篇文章是将会是这个系列最重要的一篇,消消乐消除算法的实现!!!

    本文由“壹伴编辑器”提供技术支

    结束语

    以上皆为本菜鸡的个人观点,文采实在不太好,如果写得不好还请各位见谅。如果有哪些地方说的不对,还请各位指出,大家共同进步。

    接下来我会持续分享自己所学的知识与见解,欢迎各位关注本公众号。

    我们,下次见!

    本文由“壹伴编辑器”提供技术支

    扫描二维码

    获取更多精彩

    文弱书生陈皮皮

    点击 阅读原文 获取该项目

    展开全文
  • 本文由“壹伴编辑器”提供技术支前言在上一篇文章中我们初步建立了项目并搭建好了场景,那么本篇文章将和大家一起实现部分基础组件和管理脚本。温馨提醒:本文含有大量代码和注释,请提前做好心理准备...
  • cocoscreator 砖块消消消

    2019-01-10 15:16:40
    前两天帮朋友模仿砖块消消消做了个游戏,里面素材和关卡都是爬...creator版本 1.9.3 代码放在github上了,记录一下。觉得ok的麻烦star一下,积分什么的不重要 github下载地址:https://github.com/bark-ice/bounceGame/
  • 快乐消消乐游戏简介 快乐消消乐主要模仿《天天爱消除》,主角小图块如图9-2所示,主要选择卡通的图案和比较好辨识的图形作为游戏主要物块。 图9-2 小图块 快乐消消乐的游戏规则非常简单:可以用手指拖动交换相邻的...
  • 章 消除类游戏:快乐消消乐 从本章起,将以案例的形式介绍如何使用Cocos Creator进行游戏开发。本章使用Cocos Creator进行三消游戏的开发,将模仿《天天爱消除》这款三消游戏。
  • 3457 教程司令部 【20160418】 | Cocos Creator - CocoaChina CocoaChina_让... 2033 Cocos Creator - Next的博客 - 博客频道 - CSDN.NETcsdn.net ...CocosCreator零基础制作游戏《极限跳跃》一、游戏分析 - 闭...
  • 以上是已有游戏源码,由于游戏项目较多,后期还会不定期更新,使用CocosCreator,项目可以直接打开使用。已有的游戏源码有:动物同化、左右跳、重力球、推箱子、扫雷、消消乐、六边形消除、数钱、打飞机、跑酷、杆子...
  • cc_board_system Cocos Creator棋类游戏开发组件,以组件化的方式开发各种棋类游戏,例如消消乐,2048,俄罗斯方块
  • cocoscreator 写的砖块消消消项目demo

    千次阅读 2019-01-10 15:11:59
    creator版本 1.9.3 代码放在github上了,记录一下。觉得ok的麻烦star一下,积分什么的不重要 CSDN下载地址:https://download.csdn.net/download/bark_ice/10908781 github下载地址:...
  • 三部分 实例篇 ·第9章 消除类游戏:快乐消消乐·第10章 射击类游戏:飞机大战·第11章 棋牌类游戏:欢乐斗地主
  • cocos_creator_demos.zip

    2019-10-08 20:18:29
    cocos creator小游戏合集(6款经典:消消乐、2048、飞机等等),承诺源码有效。
  • 获取代码 关注微信公众号,发送【射箭】获取代码   ...点击屏幕,屏幕出现起始位置标志的圆点,不松开手指,...当官消消乐   ☞  虚拟摇杆 ​ 扫一扫,关注微信公众号【一枚小工】,获取更多游戏代码

空空如也

空空如也

1 2 3 4
收藏数 65
精华内容 26
关键字:

cocoscreator消消乐