cocos creator_cocos creator删除 - CSDN
  • 如今,H5游戏、微信小游戏、抖音小游戏、头条小游戏、快手小游戏、百度小游戏、QQ轻游戏等小程序游戏都特别火,而这些小游戏中80%都是用Cocos Creator开发的,Cocos Creator可以做到一次开发,多平台部署。...
  • cocoscreator 微信跳一跳

    2018-11-08 09:37:00
    使用cocoscreator 游戏引擎开发微信跳一跳游戏
  • Cocos Creator游戏视频培训课程设计上,由一个简单的游戏,引入课程主体。先熟练开发流程,在熟练API,后熟练使用UI,理解碰撞和物理系统。循序渐进,课程中穿插很多小案例实践功能,压缩枯燥内容。
  • 把计步器写好了,到了写游戏场景、控件什么的时候,傻眼了。想做一个简单的地图,可以在地图上...今晚被长辈连番教育中,说到了撞墙走弯路才想起来,当初光顾着学引擎看代码了,竟然忘了还有CocosCreator,这么简单实

    把计步器写好了,到了写游戏场景、控件什么的时候,傻眼了。想做一个简单的地图,可以在地图上点击选择城市,发现用Cocos2D-X代码码出来好麻烦,尤其是城市位置问题,需要调试去找对像素区域做一个按钮控制,整个人都不好了。本来还想尝试用Tiled map来做,想法很逗比,应该不能用。今晚被长辈连番教育中,说到了撞墙走弯路才想起来,当初光顾着学引擎看代码了,竟然忘了还有CocosCreator,这么简单实用的工具我竟然没有去用,太傻了。而且现在距离比较提交程序结果时间也比较紧了,直接用CocosCreator做游戏时最明智的。下面将转向CocosCreator的学习。

    CocosCreator有很详细的入门教程,下面我就跟随这个教程来进行学习。
    http://www.cocos.com/docs/creator/getting-started/quick-start.html#–2

    打开项目

    教程中提供了一个简单游戏的初始版本,我就从这个游戏入手进行学习。从CocosCreator选择打开其他项目,打开start_project文件夹,选中即可打开。注意下载的start_project不能放在CocosCreator路径下。

    打开后如图:
    这里写图片描述

    在资源管理器面板中,可以看到项目中的文件。项目资源的根目录叫asserts,对应于解压初始版本得到的文件夹名。其中标注bf图标的文件是位图字体,是一种字体资源,由fnt文件和同名的png图片文件共同组成。

    创建场景

    下面来创建游戏场景。游戏场景一般包括:场景图像(Sprite)、文字(Label)、角色、以组件形式附加在场景节点上的游戏逻辑脚本。在资源管理器中点击asserts目录前面的加号,选择Scene,会创建一个New Scene的场景文件。
    这里写图片描述
    双击New Scene,就会在场景编辑器和层级管理器中打开这个场景。在层级管理器中可以看到当前场景的所有节点和他们的层级关系。

    Canvas画布节点/渲染根节点

    现在New Scene中只有一个Canvas节点,称为画布节点或渲染根节点,点击选中Canvas可以在属性检查器中看到他的属性。
    这里写图片描述
    这里写图片描述
    其中的Design Resolution属性用来指定游戏分辨率,Fit Hight和Fit Width是分辨率自适应匹配方法。只需要把图像放到Canvas下,就可以完成对不同分辨率的自适应,非常简单。

    设置场景图像

    增加背景图像

    在资源管理器中将textures中background图像拖到
    层级管理器的Canvas下即可增加背景图像,会看到Canvas下增加了一个background子节点。
    这里写图片描述
    点击文件->保存场景或使用快捷键ctrl+s保存场景后,在场景编辑器中便会显示增加的背景图像。
    这里写图片描述
    点击窗口左上角工具栏的第四格矩形变换工具,然后选中场景编辑器中的背景图像,可以实现对图像尺寸、位置、锚点的修改。
    这里写图片描述
    当然也可以直接使用属性检查器来直接设置这些参数。
    在实际的应用开发中背景图像一般都是要大于显示范围的,这样可以让背景图覆盖整个屏幕,不出现穿帮的情况。

    增加地面
    使用和增加背景图像相同的方法,将地面图像拖到层级管理器的Canvas上,将ground节点移到background节点下方。
    这里写图片描述
    在层级管理器中,下方的节点的渲染顺序在上方节点之后,也就是说下方节点会遮挡上方节点。
    这里写图片描述
    使用相同的方法可以对地面图像的尺寸、位置、锚点进行修改。

    增加主角
    同样的方法,将主角图像player拖到ground下方。在之后的动画中,需要主角接触地面并跳跃,因此将锚点改为最下方,即y值为0,然后将它拖到地面上。
    这里写图片描述

    编写脚本

    创建并添加脚本
    脚本也就是游戏的逻辑规则,需要代码实现。
    首先在资源管理器中右键点击assets文件夹,新建->文件夹,创建一个名为New Folder的文件夹,然后对其右击选择新建->JavaScript,创建一个JavaScript脚本NewScript,重命名为Player,双击即可打开编写界面。Cocos Creator 中脚本名称就是组件的名称。
    在Player中的properties部分增加以下代码:

    // Player.js
        //...
        properties: {
            // 主角跳跃高度
            jumpHeight: 0,
            // 主角跳跃持续时间
            jumpDuration: 0,
            // 最大移动速度
            maxMoveSpeed: 0,
            // 加速度
            accel: 0,
        },
        //...

    这些属性用于规定主角的移动方式,可以在属性检查器中直接设置属性的数值。

    然后在层级编辑器中选择player,在属性检查器中选择添加组件,选择增加用户脚本组件->Player,即可为主角添加组件。

    现在可以在属性检查器看到Player组件并修改属性数值了。
    这里写图片描述

    跳跃和移动代码
    在properties代码块下面定义setJumpAction方法:

    // Player.js
        properties: {
            //...
        },
    
        setJumpAction: function () {
            // 跳跃上升
            var jumpUp = cc.moveBy(this.jumpDuration, cc.p(0, this.jumpHeight)).easing(cc.easeCubicActionOut());
            // 下落
            var jumpDown = cc.moveBy(this.jumpDuration, cc.p(0, -this.jumpHeight)).easing(cc.easeCubicActionIn());
            // 不断重复
            return cc.repeatForever(cc.sequence(jumpUp, jumpDown));
        },

    修改onLoad: function:

    // Player.js
        onLoad: function () {
            // 初始化跳跃动作
            this.jumpAction = this.setJumpAction();
            this.node.runAction(this.jumpAction);
        },

    onLoad方法会在场景加载完成后立即执行,所以在这里进行初始化操作。
    保存脚本运行一下试试,可以看到player不断的在进行跳跃动作。

    在setJumpAction下面定义setInputControl方法来实现用A和D控制主角的移动操作:

    // Player.js
        setJumpAction: function () {
            //...
        },
    
        setInputControl: function () {
            var self = this;
            // 添加键盘事件监听
            cc.eventManager.addListener({
                event: cc.EventListener.KEYBOARD,
                // 有按键按下时,判断是否是我们指定的方向控制键,并设置向对应方向加速
                onKeyPressed: function(keyCode, event) {
                    switch(keyCode) {
                        case cc.KEY.a:
                            self.accLeft = true;
                            self.accRight = false;
                            break;
                        case cc.KEY.d:
                            self.accLeft = false;
                            self.accRight = true;
                            break;
                    }
                },
                // 松开按键时,停止向该方向的加速
                onKeyReleased: function(keyCode, event) {
                    switch(keyCode) {
                        case cc.KEY.a:
                            self.accLeft = false;
                            break;
                        case cc.KEY.d:
                            self.accRight = false;
                            break;
                    }
                }
            }, self.node);
        },

    修改onLoad方法,在其中加入向左和向右加速的开关,以及主角当前在水平方向的速度,最后再调用我们刚添加的setInputControl方法,在场景加载后就开始监听键盘输入:

    // Player.js
        onLoad: function () {
            // 初始化跳跃动作
            this.jumpAction = this.setJumpAction();
            this.node.runAction(this.jumpAction);
    
            // 加速度方向开关
            this.accLeft = false;
            this.accRight = false;
            // 主角当前水平方向速度
            this.xSpeed = 0;
    
            // 初始化键盘输入监听
            this.setInputControl();
        },

    最后修改update方法,添加加速度、速度和主角当前位置的设置:

    // Player.js
        update: function (dt) {
            // 根据当前加速度方向每帧更新速度
            if (this.accLeft) {
                this.xSpeed -= this.accel * dt;
            } else if (this.accRight) {
                this.xSpeed += this.accel * dt;
            }
            // 限制主角的速度不能超过最大值
            if ( Math.abs(this.xSpeed) > this.maxMoveSpeed ) {
                // if speed reach limit, use max speed with current direction
                this.xSpeed = this.maxMoveSpeed * this.xSpeed / Math.abs(this.xSpeed);
            }
    
            // 根据当前速度更新主角的位置
            this.node.x += this.xSpeed * dt;
        },

    这样就可以实现对主角移动的控制了。

    制作Prefab脚本-星星
    这里增加游戏规则,从随机位置生成星星,用主角接住星星即可得分。
    对于重复生成的节点,可以保存成Prefab(预置)资源,作为动态生成节点时的模板。
    这里直接将assets/textures/star资源到场景中,位置随意,给星星增加一个脚本,当主角碰到星星时,让星星消失。

    // Star.js
        properties: {
            // 星星和主角之间的距离小于这个数值时,就会完成收集
            pickRadius: 0
        },

    给star节点增加脚本,将pickRadius值设置为60。将层级管理器中的star节点拖到资源管理器的assets文件夹下,将场景中的star节点删除。star现在即为Prefab资源。

    添加游戏控制脚本
    在assets/scripts文件夹下添加游戏的主逻辑脚本Game,添加生成星星需要的属性:

    // Game.js
        properties: {
            // 这个属性引用了星星预制资源
            starPrefab: {
                default: null,
                type: cc.Prefab
            },
            // 星星产生后消失时间的随机范围
            maxStarDuration: 0,
            minStarDuration: 0,
            // 地面节点,用于确定星星生成的高度
            ground: {
                default: null,
                type: cc.Node
            },
            // player 节点,用于获取主角弹跳的高度,和控制主角行动开关
            player: {
                default: null,
                type: cc.Node
            }
        },

    然后将Game添加到Canvas节点上,然后将star这个Prefab资源拖到Canvas属性检查器Game组件中的Star Prefab属性上。把层级管理器中的ground和Player节点也拖到组件中相应属性处即可。设置Min Star Duration和Max Star Duration值为3和5,之后生成星星时,会在这两个值之间随机取值作为星星消失前经过的时间。

    在随机位置生成星星
    修改Game脚本,在onLoad方法后面添加星星的逻辑:

    // Game.js
        onLoad: function () {
            // 获取地平面的 y 轴坐标
            this.groundY = this.ground.y + this.ground.height/2;
            // 生成一个新的星星
            this.spawnNewStar();
        },
    
        spawnNewStar: function() {
            // 使用给定的模板在场景中生成一个新节点
            var newStar = cc.instantiate(this.starPrefab);
            // 将新增的节点添加到 Canvas 节点下面
            this.node.addChild(newStar);
            // 为星星设置一个随机位置
            newStar.setPosition(this.getNewStarPosition());
        },
    
        getNewStarPosition: function () {
            var randX = 0;
            // 根据地平面位置和主角跳跃高度,随机得到一个星星的 y 坐标
            var randY = this.groundY + cc.random0To1() * this.player.getComponent('Player').jumpHeight + 50;
            // 根据屏幕宽度,随机得到一个星星 x 坐标
            var maxX = this.node.width/2;
            randX = cc.randomMinus1To1() * maxX;
            // 返回星星坐标
            return cc.p(randX, randY);
        }

    添加主角碰触收集星星的行为
    重点在于星星要随时获取主角节点的位置,才能判断与主角的距离是否小于可收集距离。因此将Game组件的实例传给星星并保存,然后可以随时通过game.player来访问主角节点。
    在Game脚本的spawnNewStar方法最后添加如下代码:

    // Game.js
        spawnNewStar: function() {
            // ...
            // 将 Game 组件的实例传入星星组件
            newStar.getComponent('Star').game = this;
        },

    然后在star脚本里onLoad方法后面添加getPlayerDistance和onPicked方法:

    // Star.js
        getPlayerDistance: function () {
            // 根据 player 节点位置判断距离
            var playerPos = this.game.player.getPosition();
            // 根据两点位置计算两点之间距离
            var dist = cc.pDistance(this.node.position, playerPos);
            return dist;
        },
    
        onPicked: function() {
            // 当星星被收集时,调用 Game 脚本中的接口,生成一个新的星星
            this.game.spawnNewStar();
            // 然后销毁当前星星节点
            this.node.destroy();
        },

    在update方法中添加每帧判断距离,如果距离小于pickRadius属性规定值,就执行收集行为:

    // Star.js
        update: function (dt) {
            // 每帧判断和主角之间的距离是否小于收集距离
            if (this.getPlayerDistance() < this.pickRadius) {
                // 调用收集行为
                this.onPicked();
                return;
            }
        },

    现在可以看效果了。
    这里写图片描述

    添加计分牌
    在层级管理器的Canvas中右键创建新节点->创建渲染节点->Label(文字),命名为score。将position设为(0,180),string设为score:0,Font Size设为50。从资源管理器中将assets/mikado_outline_shadow位图字体资源拖到Font属性中。
    这里写图片描述

    添加得分逻辑
    在Game的properties里添加score需要的属性:

    // Game.js
        properties: {
            // ...
            // score label 的引用
            scoreDisplay: {
                default: null,
                type: cc.Label
            }
        },

    在onLoad方法里添加计分用的变量初始化:

    // Game.js
        onLoad: function () {
            // ...
            // 初始化计分
            this.score = 0;
        },

    在update方法后面添加gainScore的新方法:

    // Game.js
        gainScore: function () {
            this.score += 1;
            // 更新 scoreDisplay Label 的文字
            this.scoreDisplay.string = 'Score: ' + this.score.toString();
        },

    将score节点拖到Canvas属性的Game组件中的Score Display属性中。
    在Star脚本的onPicked方法中添加gainScore的调用:

    // Star.js
        onPicked: function() {
            // 当星星被收集时,调用 Game 脚本中的接口,生成一个新的星星
            this.game.spawnNewStar();
            // 调用 Game 脚本的得分方法
            this.game.gainScore();
            // 然后销毁当前星星节点
            this.node.destroy();
        },

    这样收集到星星,分数就会变化了。
    这里写图片描述

    失败判断和重新开始
    加入给星星加入计时消失的逻辑,在Game脚本的onLoad方法的spawNewStar调用之前加入需要的变量声明:
    // Game.js
    onLoad: function () {
    // …
    // 初始化计时器
    this.timer = 0;
    this.starDuration = 0;
    // 生成一个新的星星
    this.spawnNewStar();
    // 初始化计分
    this.score = 0;
    },
    然后在spawnNewStar方法最后加入重置计时器的逻辑,其中this.minStarDuration和this.maxStarDuration是我们一开始声明的Game组件属性,用来规定星星消失时间的随机范围:

    // Game.js
        spawnNewStar: function() {
            // ...
            // 重置计时器,根据消失时间范围随机取一个值
            this.starDuration = this.minStarDuration + cc.random0To1() * (this.maxStarDuration - this.minStarDuration);
            this.timer = 0;
        },

    在update方法中加入计时器更新和判断超过时限的逻辑:

    // Game.js
        update: function (dt) {
            // 每帧更新计时器,超过限度还没有生成新的星星
            // 就会调用游戏失败逻辑
            if (this.timer > this.starDuration) {
                this.gameOver();
                return;
            }
            this.timer += dt;
        },

    最后加入gameOver方法,游戏失败重新加载场景。

    // Game.js
        gameOver: function () {
            this.player.stopAllActions(); //停止 player 节点的跳跃动作
            cc.director.loadScene('game');
        }

    然后修改Star脚本,加入即将消失星星的提示效果,在update方法中加入以下代码:

    // Star.js
        update: function() {
            // ...
            // 根据 Game 脚本中的计时器更新星星的透明度
            var opacityRatio = 1 - this.game.timer/this.game.starDuration;
            var minOpacity = 50;
            this.node.opacity = minOpacity + Math.floor(opacityRatio * (255 - minOpacity));
        }

    这样游戏画面和逻辑就全部完成了,可以说游戏已经基本完成了。

    加入音效
    首先加入跳跃音效,在Player脚本中引用声音文件资源jumpAudio属性:

    // Player.js
        properties: {
            // ...
            // 跳跃音效资源
            jumpAudio: {
                default: null,
                url: cc.AudioClip
            },
        },

    修改setJumpAction方法,插入播放音效的回调,并通过添加playJumpSound方法来播放声音:

    // Player.js
        setJumpAction: function () {
            // 跳跃上升
            var jumpUp = cc.moveBy(this.jumpDuration, cc.p(0, this.jumpHeight)).easing(cc.easeCubicActionOut());
            // 下落
            var jumpDown = cc.moveBy(this.jumpDuration, cc.p(0, -this.jumpHeight)).easing(cc.easeCubicActionIn());
            // 添加一个回调函数,用于在动作结束时调用我们定义的其他方法
            var callback = cc.callFunc(this.playJumpSound, this);
            // 不断重复,而且每次完成落地动作后调用回调来播放声音
            return cc.repeatForever(cc.sequence(jumpUp, jumpDown, callback));
        },
    
        playJumpSound: function () {
            // 调用声音引擎播放声音
            cc.audioEngine.playEffect(this.jumpAudio, false);
        },

    然后加入得分音效,在Game脚本的properties添加引用声音文件:

    // Game.js
        properties: {
            // ...
            // 得分音效资源
            scoreAudio: {
                default: null,
                url: cc.AudioClip
            }
        },

    在gainScore方法添加播放声音的代码:

    // Game.js
        gainScore: function () {
            this.score += 1;
            // 更新 scoreDisplay Label 的文字
            this.scoreDisplay.string = 'Score: ' + this.score.toString();
            // 播放得分音效
            cc.audioEngine.playEffect(this.scoreAudio, false);
        },

    在层级管理器中,将assets/audio/jump声音资源拖到Player节点的组件Jump Audio属性上。将assets/audio/score资源拖拽到Canvas节点Game组件的Score Audio属性上。
    大功告成,一个完整的游戏就做好了。

    展开全文
  • CocosCreator入门

    2019-04-18 22:31:47
    1.关于Cocos Creator Cocos Creator 是什么? 它是一个完整的游戏开发解决方案,包括了 cocos2d-x 引擎的 JavaScript 实现,以及能让你更快速开发游戏所需要的各种图形界面工具,在 Cocos2d-x 基础上实现了彻底脚本...

    1.关于Cocos Creator

    Cocos Creator 是什么?
    它是一个完整的游戏开发解决方案,包括了 cocos2d-x 引擎的 JavaScript 实现,以及能让你更快速开发游戏所需要的各种图形界面工具,在 Cocos2d-x 基础上实现了彻底脚本化、组件化和数据驱动等特点。
    cocos creator

    2.项目文件夹结构

    初次创建并打开一个 Cocos Creator 项目后,您的项目文件夹将会包括以下结构:

    ProjectName(项目文件夹)
    ├──assets (资源文件夹:游戏中所有本地资源、脚本和第三方库文件)
    ├──library(资料库:将 assets 中的资源导入后自动生成的,不需要版本控制)
    ├──local(包含该项目的本地设置,包括编辑器面板布局,窗口大小,位置等信息)
    ├──settings(settings 里保存项目相关的设置,如 构建发布 菜单里的包名、场景和平台选择等)
    ├──temp(临时文件)
    ├──project.json(project.json 文件和 assets 文件夹一起,作为验证 Cocos Creator 项目合法性的标志,必须有)
    └──build(构建目标:构建的微信小程序等项目)

    3.代码编辑环境

    • 1.安装Visual Studio Code
    • 2.安装 Cocos Creator API 适配插件
    • 3.在项目中生成智能提示数据

    4.制作第一个游戏

    • 1.准备资源
    • 2.打开创建项目
    • 3.创建游戏场景
    • 4.新建Canvas
    • 5.添加背景,修改背景尺寸
    • 6.添加主角
    • 7.编写主角脚本(js组件)
    • 8.绑定组件到主角对象上

    5.脚本开发

    1. 一般的组件类如下:

    cc.Class({
        extends: cc.Component,
    
        properties: {
        },
    
        // use this for initialization
        onLoad: function () {
        },
    
        // called every frame, uncomment this function to activate update callback
        update: function (dt) {
        },
    });
    

    2.脚本解释

    使用 cc.Class 声明类型

    cc.Class 是一个很常用的 API,用于声明 Cocos Creator 中的类,为了方便区分,我们把使用 cc.Class 声明的类叫做 CCClass。

    定义CCClass

    调用 cc.Class,传入一个原型对象,在原型对象中以键值对的形式设定所需的类型参数,就能创建出所需要的类。

    var Sprite = cc.Class({
        name: "sprite"
    });
    

    以上代码用 cc.Class 创建了一个类型,并且赋给了 Sprite 变量。同时还将类名设为 “sprite”,类名用于序列化,一般可以省略。

    实例化

    Sprite 变量保存的是一个 JavaScript 构造函数,可以直接 new 出一个对象:

    var obj = new Sprite();

    判断类型

    需要做类型判断时,可以用 JavaScript 原生的 instanceof:
    cc.log(obj instanceof Sprite); // true

    构造函数

    使用 ctor 声明构造函数:

    var Sprite = cc.Class({
        ctor: function () {
            cc.log(this instanceof Sprite);    // true
        }
    });
    

    实例方法

    var Sprite = cc.Class({
        // 声明一个名叫 "print" 的实例方法
        print: function () { }
    });
    

    继承

    使用 extends 实现继承:

    // 父类
    var Shape = cc.Class();
    
    // 子类
    var Rect = cc.Class({
        extends: Shape
    });
    

    属性声明

    通过在组件脚本中声明属性,我们可以将脚本组件中的字段可视化地展示在 属性检查器 中,从而方便地在场景中调整属性值。

    要声明属性,仅需要在 cc.Class 定义的 properties 字段中,填写属性名字和属性参数即可,如:

    cc.Class({
        extends: cc.Component,
        properties: {
            userID: 20,
            userName: "Foobar"
        }
    });
    

    这时候,你可以在 属性检查器 中看到你刚刚定义的两个属性:
    属性面板

    简单声明

    在多数情况下,我们都可以使用简单声明。

    当声明的属性为基本 JavaScript 类型时,可以直接赋予默认值:

      properties: {
          height: 20,       // number
          type: "actor",    // string
          loaded: false,    // boolean                
          target: null,     // object
      }
    

    当声明的属性具备类型时(如:cc.Node,cc.Vec2 等),可以在声明处填写他们的构造函数来完成声明,如:

      properties: {
          target: cc.Node,
          pos: cc.Vec2,
      }
    

    当声明属性的类型继承自 cc.ValueType 时(如:cc.Vec2,cc.Color 或 cc.Rect),除了上面的构造函数,还可以直接使用实例作为默认值:

      properties: {
          pos: new cc.Vec2(10, 20),
          color: new cc.Color(255, 255, 255, 128),
      }
    

    当声明属性是一个数组时,可以在声明处填写他们的类型或构造函数来完成声明,如:

      properties: {
          any: [],      // 不定义具体类型的数组
          bools: [cc.Boolean],
          strings: [cc.String],
          floats: [cc.Float],
          ints: [cc.Integer],
          values: [cc.Vec2],
          nodes: [cc.Node],
          frames: [cc.SpriteFrame],
      }
    

    完整声明

    properties: {
      score: {
          default: 设置属性的默认值,这个默认值仅在组件第一次添加到节点上时才会用到
      	type: 限定属性的数据类型,详见 CCClass 进阶参考:type 参数
      	visible: 设为 false 则不在 属性检查器 面板中显示该属性
      	serializable: 设为false 则不序列化(保存)该属性
      	displayName: 在属性检查器 面板中显示成指定名字
      	tooltip: 在属性检查器 面板中添加属性的 Tooltip
      }
    }
    

    3.访问节点和组件

    获得组件所在的节点

    var node = this.node;

    获得其它组件

    //获取单个组件
    var label = this.getComponent(cc.Label);
    //获取多个组件
    var labels = this.getComponents(cc.Label);
    

    获得其它节点及其组件

    可以在属性检查器 中拖拽设置你需要的对象或组件

    查找子节点

    //获取孩子节点数组
    var childs= this.node.children;
    
    //根据名字获取孩子节点
    this.node.getChildByName("Cannon");
    

    全局名字查找节点

    this.backNode = cc.find("Canvas/Menu/Back");
    

    全局变量访问

    window代表了当前浏览器的单例对象
    window.Global = {
        backNode: null,
        backLabel: null,
    };
    

    定义全局变量时的 window. 不可省略。
    接着你可以在合适的地方直接访问并初始化 Global:
    初始化后,你就能在任何地方访问到 Global 里的值:

    // Back.js
    cc.Class({
        extends: cc.Component,
    
        onLoad: function () {
            Global.backNode = this.node;
            Global.backLabel = this.getComponent(cc.Label);
        }
        
        start: function () {
            var text = 'Back';
            Global.backLabel.string = text;
        }
    });
    

    访问全局变量时,如果变量未定义将会抛出异常。
    添加全局变量时,请小心不要和系统已有的全局变量重名。
    你需要小心确保全局变量使用之前都已初始化和赋值。

    通过模块访问

    // Global.js, now the filename matters
    module.exports = {
        backNode: null,
        backLabel: null,
    };
    

    每个脚本都能用 require + 文件名(不含路径) 来获取到对方 exports 的对象。

    // Back.js
    
    // this feels more safe since you know where the object comes from
    var Global = require("Global");
    
    cc.Class({
        extends: cc.Component,
    
        onLoad: function () {
            Global.backNode = this.node;
            Global.backLabel = this.getComponent(cc.Label);
        }
        
        start: function () {
            var text = "Back";
            Global.backLabel.string = text;
        }
    });
    

    4.生命周期

    目前提供给用户的生命周期回调函数主要有:

    onLoad
    onEnable
    start
    update
    lateUpdate
    onDestroy
    onDisable
    

    5.创建和销毁节点

    创建新节点

    除了通过场景编辑器创建节点外,我们也可以在脚本中动态创建节点。通过 new cc.Node() 并将它加入到场景中,可以实现整个创建过程

    start: function () {
        var node = new cc.Node('Sprite');
        var sp = node.addComponent(cc.Sprite);
    
        sp.spriteFrame = this.sprite;
        node.parent = this.node;
      },
    
    克隆已有节点

    有时我们希望动态的克隆场景中的已有节点,我们可以通过 cc.instantiate 方法完成。使用方法如下:

    cc.Class({
      extends: cc.Component,
    
      properties: {
        target: cc.Node,
      },
    
      start: function () {
        var scene = cc.director.getScene();
        var node = cc.instantiate(this.target);
        node.parent = scene;
        node.setPosition(0, 0);
      },
    });
    
    创建预制节点

    和克隆已有节点相似,你可以设置一个预制(Prefab)并通过 cc.instantiate 生成节点。使用方法如下:

    cc.Class({
    extends: cc.Component,
    
    properties: {
      target: cc.Prefab,
    },
    
    start: function () {
      var scene = cc.director.getScene();
      var node = cc.instantiate(this.target);
      node.parent = scene;
      node.setPosition(0, 0);
    },
    });
    
    销毁节点

    通过 node.destroy() 函数,可以销毁节点。值得一提的是,销毁节点并不会立刻被移除,而是在当前帧逻辑更新结束后,统一执行。当一个节点销毁后,该节点就处于无效状态,可以通过 cc.isValid 判断当前节点是否已经被销毁。

    使用方法如下:

    cc.Class({
      extends: cc.Component,
    
      properties: {
        target: cc.Node,
      },
    
      start: function () {
        // 5 秒后销毁目标节点
        setTimeout(function () {
          this.target.destroy();
        }.bind(this), 5000);
      },
    
      update: function (dt) {
        if (cc.isValid(this.target)) {
          this.target.rotation += dt * 10.0;
        }
      },
    });
    

    5.加载和切换场景

    在 Cocos Creator 中,我们使用场景文件名(不包含扩展名)来索引指代场景。并通过以下接口进行加载和切换操作:

    cc.director.loadScene("MyScene");
    cc.director.loadScene("MyScene", onSceneLaunched);
    
    常驻节点

    当切换场景时,该组件所在节点标记为「常驻节点」,使它在场景切换时不被自动销毁,常驻内存。

    //设置为常驻节点
    cc.game.addPersistRootNode(myNode);
    //取消常驻节点
    cc.game.removePersistRootNode(myNode);
    

    6.获取和加载资源

    Creator 中,所有继承自 cc.Asset 的类型都统称资源,如 cc.Texture2D, cc.SpriteFrame, cc.AnimationClip, cc.Prefab 等。它们的加载是统一并且自动化的,相互依赖的资源能够被自动预加载。

    1.属性面板设置资源,拖拽加载资源
    2.resources.load 动态加载

    动态加载资源要注意两点,
    一是所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下。resources 需要在 assets 文件夹中手工创建,并且必须位于 assets 的根目录。、
    二是 Creator 相比之前的 Cocos2d-JS,资源动态加载的时候都是 异步 的,需要在回调函数中获得载入的资源。这么做是因为 Creator 除了场景关联的资源,没有另外的资源预加载列表,动态加载的资源是真正的动态加载。

    动态加载 Asset

    Creator 提供了 cc.loader.loadRes 这个 API 来专门加载那些位于 resources 目录下的 Asset,和 cc.loader.load 不同的是,loadRes 一次只能加载单个 Asset。调用时,你只要传入相对 resources 的路径即可,并且路径的结尾处 不能 包含文件扩展名

    // 加载 Prefab
    cc.loader.loadRes("test assets/prefab", function (err, prefab) {
        var newNode = cc.instantiate(prefab);
        cc.director.getScene().addChild(newNode);
    });
    
    // 加载 AnimationClip
    var self = this;
    cc.loader.loadRes("test assets/anim", function (err, clip) {
        self.node.getComponent(cc.Animation).addClip(clip, "anim");
    });
    
    加载 SpriteFrame

    图片设置为 Sprite 后,将会在 资源管理器 中生成一个对应的 SpriteFrame。但如果直接加载 test assets/image,得到的类型将会是 cc.Texture2D。你必须指定第二个参数为资源的类型,才能加载到图片生成的 cc.SpriteFrame:

    // 加载 SpriteFrame
    var self = this;
    cc.loader.loadRes("test assets/image", cc.SpriteFrame, function (err, spriteFrame) {
        self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
    });
    
    加载图集中的 SpriteFrame

    对从 TexturePacker 等第三方工具导入的图集而言,如果要加载其中的 SpriteFrame,则只能先加载图集,再获取其中的 SpriteFrame。这是一种特殊情况。

    // 加载 SpriteAtlas(图集),并且获取其中的一个 SpriteFrame
    // 注意 atlas 资源文件(plist)通常会和一个同名的图片文件(png)放在一个目录下, 所以需要在第二个参数指定资源类型

    cc.loader.loadRes("test assets/sheep", cc.SpriteAtlas, function (err, atlas) {
        var frame = atlas.getSpriteFrame('sheep_down_0');
        sprite.spriteFrame = frame;
    });
    
    资源释放
    cc.loader.releaseRes("test assets/image", cc.SpriteFrame);
    cc.loader.releaseRes("test assets/anim");
    
    加载远程资源和设备资源

    Cocos Creator 支持加载远程贴图资源,开发者直接调用 cc.loader.load。同时,如果用户用其他方式下载了资源到本地设备存储中,也需要用同样的 API 来加载,上文中的 loadRes 等 API 只适用于应用包内的资源和热更新的本地资源。

    // 远程 url 带图片后缀名
    var remoteUrl = "http://unknown.org/someres.png";
    cc.loader.load(remoteUrl, function (err, texture) {
        // Use texture to create sprite frame
    });
    
    // 远程 url 不带图片后缀名,此时必须指定远程图片文件的类型
    remoteUrl = "http://unknown.org/emoji?id=124982374";
    cc.loader.load({url: remoteUrl, type: 'png'}, function () {
        // Use texture to create sprite frame
    });
    
    // 用绝对路径加载设备存储内的资源,比如相册
    var absolutePath = "/dara/data/some/path/to/image.png"
    cc.loader.load(absolutePath, function () {
        // Use texture to create sprite frame
    });
    

    7.发射和监听事件

    事件处理是在节点(cc.Node)中完成的。对于组件,可以通过访问节点 this.node 来注册和监听事件。监听事件可以 通过 this.node.on() 函数来注册,方法如下:

    cc.Class({
      extends: cc.Component,
    
      _sayHello: function () {
        console.log('Hello World');
      },
    
      onEnable: function () {
      //监听事件
        this.node.on('foobar', this._sayHello, this);
      },
    
      onDisable: function () {
      //关闭监听
        this.node.off('foobar', this._sayHello, this);
      },
        start () {
        // 发送监听,最多传递5个参数
        this.node.emit('foobar', arg1, arg2, arg3);
      },
    });
    

    8.系统内置事件

    Cocos Creator 支持的系统事件包含鼠标、触摸、键盘、重力传感四种

    // 使用枚举类型来注册
    node.on(cc.Node.EventType.MOUSE_DOWN, function (event) {
      console.log('Mouse down');
    }, this);
    
    // 使用事件名来注册
    node.on('mousedown', function (event) {
      console.log('Mouse down');
    }, this);
    
    鼠标事件类型
    枚举对象定义 对应的事件名 事件触发的时机
    cc.Node.EventType.MOUSE_DOWN mousedown 当鼠标在目标节点区域按下时触发一次
    cc.Node.EventType.MOUSE_ENTER mouseenter 当鼠标移入目标节点区域时,不论是否按下
    cc.Node.EventType.MOUSE_MOVE mousemove 当鼠标在目标节点在目标节点区域中移动时,不论是否按下
    cc.Node.EventType.MOUSE_LEAVE mouseleave 当鼠标移出目标节点区域时,不论是否按下
    cc.Node.EventType.MOUSE_UP mouseup 当鼠标从按下状态松开时触发一次
    cc.Node.EventType.MOUSE_WHEEL mousewheel 当鼠标滚轮滚动时
    触摸事件类型和事件对象
    枚举对象定义 对应的事件名 事件触发的时机
    cc.Node.EventType.TOUCH_START touchstart 当手指触点落在目标节点区域内时
    cc.Node.EventType.TOUCH_MOVE touchmove 当手指在屏幕上目标节点区域内移动时
    cc.Node.EventType.TOUCH_END touchend 当手指在目标节点区域内离开屏幕时
    cc.Node.EventType.TOUCH_CANCEL touchcancel 当手指在目标节点区域外离开屏幕时

    9.玩家输入事件

    键盘、设备重力传感器此类全局事件是通过函数 cc.systemEvent.on(type, callback, target) 注册的。

    键盘事件
    cc.Class({
        extends: cc.Component,
        onLoad: function () {
            // add key down and key up event
            cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
            cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
        },
    
        onDestroy () {
            cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
            cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
        },
    
        onKeyDown: function (event) {
            switch(event.keyCode) {
                case cc.macro.KEY.a:
                    console.log('Press a key');
                    break;
            }
        },
    
        onKeyUp: function (event) {
            switch(event.keyCode) {
                case cc.macro.KEY.a:
                    console.log('release a key');
                    break;
            }
        }
    });
    

    10.动画系统

    Cocos Creator 提供的动作系统源自 Cocos2d-x,API 和使用方法均一脉相承。动作系统可以在一定时间内对节点完成位移,缩放,旋转等各种动作。

    动作系统 API
    // 创建一个移动动作
    var action = cc.moveTo(2, 100, 100);
    // 执行动作
    node.runAction(action);
    // 停止一个动作
    node.stopAction(action);
    // 停止所有动作
    node.stopAllActions();
    
    容器动作
    1. 顺序动作 cc.sequence 顺序动作可以让一系列子动作按顺序一个个执行。示例:
     // 让节点左右来回移动
     var seq = cc.sequence(cc.moveBy(0.5, 200, 0), cc.moveBy(0.5, -200, 0));
     node.runAction(seq);
    
    1. 同步动作 cc.spawn 同步动作可以同步执行对一系列子动作,子动作的执行结果会叠加起来修改节点的属性。示例:
     // 让节点在向上移动的同时缩放
     var spawn = cc.spawn(cc.moveBy(0.5, 0, 50), cc.scaleTo(0.5, 0.8, 1.4));
     node.runAction(spawn);
    
    1. 重复动作 cc.repeat 重复动作用来多次重复一个动作。示例:
     // 让节点左右来回移动,并重复5次
     var seq = cc.repeat(
    	cc.sequence(
    	cc.moveBy(2, 200, 0),
    	cc.moveBy(2, -200, 0)
    ), 5);
     node.runAction(seq);
    
    1. 永远重复动作 cc.repeatForever 顾名思义,这个动作容器可以让目标动作一直重复,直到手动停止。
     // 让节点左右来回移动并一直重复
    var seq = cc.repeatForever(
    	cc.sequence(
    	cc.moveBy(2, 200, 0),
    	cc.moveBy(2, -200, 0)
    ));
    
    1. 速度动作 cc.speed 速度动作可以改变目标动作的执行速率,让动作更快或者更慢完成。
     // 让目标动作速度加快一倍,相当于原本2秒的动作在1秒内完成
     var action = cc.speed(
    	cc.spawn(
    	cc.moveBy(2, 0, 50),
    	cc.scaleTo(2, 0.8, 1.4)
    ), 0.5);
     node.runAction(action);
    
    补间动画 cc.tween

    cc.tween 会比 cc.Action 更加简洁易用,因为 cc.tween 提供了链式创建的方法,可以对任何对象进行操作,并且可以对对象的任意属性进行缓动。

    cc.tween(this.node)
    	//同时对 position, rotation 属性缓动
       .to(1, { position: cc.v2(100, 100), rotation: 360 })
       //1秒后,开始缩放
       .to(1, { scale: 2 })
       .start()
    

    11.计时器

    Cocos Creator 中,我们为组件提供了方便的计时器,这个计时器源自于 Cocos2d-x 中的 cc.Scheduler,我们将它保留在了 Cocos Creator 中并适配了基于组件的使用方式。

    下面来看看它的具体使用方式:

    开始一个计时器

    component.schedule(function() {
        // 这里的 this 指向 component
        this.doSomething();
    }, 5);
    

    上面这个计时器将每隔 5s 执行一次。

    更灵活的计时器

    // 以秒为单位的时间间隔
    var interval = 5;
    // 重复次数
    var repeat = 3;
    // 开始延时
    var delay = 10;
    component.schedule(function() {
        // 这里的 this 指向 component
        this.doSomething();
    }, interval, repeat, delay);
    

    上面的计时器将在10秒后开始计时,每5秒执行一次回调,重复3次。

    只执行一次的计时器(快捷方式)

    component.scheduleOnce(function() {
        // 这里的 this 指向 component
        this.doSomething();
    }, 2);
    

    上面的计时器将在两秒后执行一次回调函数,之后就停止计时。

    取消计时器

    开发者可以使用回调函数本身来取消计时器:

    this.count = 0;
    this.callback = function () {
        if (this.count === 5) {
            // 在第六次执行回调时取消这个计时器
            this.unschedule(this.callback);
        }
        this.doSomething();
        this.count++;
    }
    component.schedule(this.callback, 1);
    

    11.物理系统

    Creator 里的物理系统包括两个部分:碰撞系统和刚体系统,(刚体系统使用box2d,里面也有碰撞,我们简称刚体碰撞和碰撞系统中的碰撞不同,且两者不兼容使用);

    1.碰撞系统

    获取碰撞检测系统

    var manager = cc.director.getCollisionManager();
    

    默认碰撞检测系统是禁用的,如果需要使用则需要以下方法开启碰撞检测系统

    manager.enabled = true;
    

    默认碰撞检测系统的 debug 绘制是禁用的,如果需要使用则需要以下方法开启 debug 绘制:

    manager.enabledDebugDraw = true;
    

    碰撞系统回调

    /**
     * 当碰撞产生的时候调用
     * @param  {Collider} other 产生碰撞的另一个碰撞组件
     * @param  {Collider} self  产生碰撞的自身的碰撞组件
     */
    onCollisionEnter: function (other, self) {
        console.log('on collision enter');
        // 碰撞系统会计算出碰撞组件在世界坐标系下的相关的值,并放到 world 这个属性里面
        var world = self.world;
    },
    
    点击测试
        properties: {
            collider: cc.BoxCollider
        },
        start () {
            // 开启碰撞检测系统,未开启时无法检测
            cc.director.getCollisionManager().enabled = true;
            this.collider.node.on(cc.Node.EventType.TOUCH_START, function (touch, event) {
                // 返回世界坐标
                let touchLoc = touch.getLocation();
                if (cc.Intersection.pointInPolygon(touchLoc, this.collider.world.points)) {
                    console.log("Hit!");
                } else {
                    console.log("No hit");
                } }, this);
        }
    

    2.刚体物理引擎

    开启物理系统
    物理系统默认是关闭的,如果需要使用物理系统,那么首先需要做的事情就是开启物理系统,否则你在编辑器里做的所有物理编辑都不会产生任何效果。

    cc.director.getPhysicsManager().enabled = true;
    

    绘制物理调试信息
    物理系统默认是不绘制任何调试信息的,如果需要绘制调试信息,请使用 debugDrawFlags 。 物理系统提供了各种各样的调试信息,你可以通过组合这些信息来绘制相关的内容。

    cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit |
        cc.PhysicsManager.DrawBits.e_pairBit |
        cc.PhysicsManager.DrawBits.e_centerOfMassBit |
        cc.PhysicsManager.DrawBits.e_jointBit |
        cc.PhysicsManager.DrawBits.e_shapeBit;
    

    点测试
    点测试将测试是否有碰撞体会包含一个世界坐标系下的点,如果测试成功,则会返回一个包含这个点的碰撞体。注意,如果有多个碰撞体同时满足条件,下面的接口只会返回一个随机的结果。

    var collider = cc.director.getPhysicsManager().testPoint(point);
    

    矩形测试
    矩形测试将测试指定的一个世界坐标系下的矩形,如果一个碰撞体的包围盒与这个矩形有重叠部分,则这个碰撞体会给添加到返回列表中。

    var colliderList = cc.director.getPhysicsManager().testAABB(rect);
    

    射线测试
    射线检测用来检测给定的线段穿过哪些碰撞体,我们还可以获取到碰撞体在线段穿过碰撞体的那个点的法线向量和其他一些有用的信息。

    var results = cc.director.getPhysicsManager().rayCast(p1, p2, type);
    
    for (var i = 0; i < results.length; i++) {
        var result = results[i];
        var collider = result.collider;
        var point = result.point;
        var normal = result.normal;
        var fraction = result.fraction;
    }
    
    刚体

    刚体属性

    //质量
    var mass = rigidbody.getMass();
    
    // 设置移动速度
    rigidbody.linearVelocity = velocity;
    // 设置旋转速度
    rigidbody.angularVelocity = velocity;
    
    //获取刚体世界坐标值
    var out = rigidbody.getWorldPosition();
    
    // 施加一个力到刚体上指定的点上,这个点是世界坐标系下的一个点
    rigidbody.applyForce(force, point);
    // 或者直接施加力到刚体的质心上
    rigidbody.applyForceToCenter(force);
    // 施加一个冲量到刚体上指定的点上,这个点是世界坐标系下的一个点
    rigidbody.applyLinearImpulse(impulse, point);
    

    开启碰撞监听

    只有开启了刚体的碰撞监听,刚体发生碰撞时才会回调到对应的组件上。

    rigidbody.enabledContactListener = true;
    

    定义一个碰撞回调函数很简单,只需要在刚体所在的节点上挂一个脚本,脚本中添加上你需要的回调函数即可。

    cc.Class({
        extends: cc.Component,
    
        // 只在两个碰撞体开始接触时被调用一次
        onBeginContact: function (contact, selfCollider, otherCollider) {
        		console.log(otherCollider.tag);
        },
    
        // 只在两个碰撞体结束接触时被调用一次
        onEndContact: function (contact, selfCollider, otherCollider) {
        },
    
        // 每次将要处理碰撞体接触逻辑时被调用
        onPreSolve: function (contact, selfCollider, otherCollider) {
        },
    
        // 每次处理完碰撞体接触逻辑时被调用
        onPostSolve: function (contact, selfCollider, otherCollider) {
        }
    });
    

    12.音乐和音效

    通过脚本控制 AudioSource 组件,如下所示:

    // AudioSourceControl.js
    cc.Class({
        extends: cc.Component,
    
        properties: {
            audioSource: {
                type: cc.AudioSource,
                default: null
            },
        },
    
        play: function () {
            this.audioSource.play();
        },
    
        pause: function () {
            this.audioSource.pause();
        },
    });
    

    AudioEngine 与 AudioSource 都能播放音频,它们的区别在于 AudioSource 是组件,可以添加到场景中,由编辑器设置。而 AudioEngine 是引擎提供的纯 API,只能在脚本中进行调用。如下所示:

    在脚本的 properties 中定义一个 AudioClip 资源对象
    直接使用 cc.audioEngine.play(audio, loop, volume); 播放,如下所示:

    // AudioEngine.js
    cc.Class({
        extends: cc.Component,
        properties: {
            audio: {
                default: null,
                type: cc.AudioClip
            }
        },
        onLoad: function () {
            this.current = cc.audioEngine.play(this.audio, false, 1);
        },
        onDestroy: function () {
            cc.audioEngine.stop(this.current);
        }
    });
    
    展开全文
  • 从微信小游戏出生(2018年初)到现在,已经使用CocosCreator一年多了(之前做手游主要是cocos2d-x+lua),趁着这段时间有空,想着整理出一个基于CocosCreator游戏开发框架。 这个框架主要是将我在开发过程中觉得好用...

    写在前面


    从微信小游戏出生(2018年初)到现在,已经使用CocosCreator一年多了(之前做手游主要是cocos2d-x+lua),趁着这段时间有空,想着整理出一个基于CocosCreator游戏开发框架

    这个框架主要是将我在开发过程中觉得好用的结构和模式、插件,以及在论坛上和博客上参考大神们的教程和想法(有些是直接拿来用),整合在一起的。一方面想提高开发效率,另一方面大家发现问题及时提出及时讨论,慢慢优化和改进。

    框架工程是否跟游戏工程分开

    在开始之前,因为这个问题纠结了好久。框架工程跟游戏工程分离,框架工程作为一个独立代码库,仅仅作为游戏工程的子模块,这样代码库可以统一管理。

    我上个项目就是这样做的,但是你会发现,把框架模块单独拿出来给下一个项目复用,里面有一些耦合了游戏工程的代码。如果要每个成员在紧张的游戏开发过程中保持清醒,去保持框架模块的独立性,肯定是一个蛋疼的过程。

    后来阅读了两篇文章(关于游戏设计模式的)之后,确定了该框架仅仅作为一个“纯净”的基础框架,每开一个新项目就拷贝过去,然后根据游戏的需求自己去调整。

    两篇文章的链接在下面,有兴趣的可以了解下,不扯远了,准备进入正题!

    【游戏设计模式】之一 序言:架构,性能与游戏

    为什么在游戏开发中我不喜欢用MVC系列模式了




    正文


    目录细分和规划

    如下图:

    • animClip:存放动画文件(.anim)
    • font:存放字体文件
    • prefab:存放不需要动态加载的预制体
    • texture:存放用于贴图资源
    • texture/ui_common:存放公用的ui资源图集文件。
    • texture/ui_module:每个功能/模块单独用到的资源打包后的图集文件,比如main场景单独用到的打包一起,然后mian场景勾选自动释放资源,切换场景时就会自动释放没用的资源(前提是没有被其他的地方引用到)。
    • resources:存放一切需要用于动态加载(cc.load.loadRes)的资源

    为什么有些资源放在resources里面,有些放到外面?

    先看官网的解释:

    总结一下:

    1、resources文件夹中的资源可以跟它外部的其他资源,相互引用,所以放哪,问题不大。
    2、只有放在resources文件夹的资源才能用cc.loader.loadRes动态加载。
    3、构建时,resources文件夹中的所有资源连同它们关联依赖的resources文件夹外部的资源,都会被导出,并且项目中无用的资源将会在构建的过程中自动剔除。
    4、resources文件夹的资源,会增大包体和settings.js的大小,JSON的自动合并策略也将受到影响,无法尽可能将零碎的JSON合并起来。




    框架模块介绍


    # 配置表模块

    直接在现有的插件excel-killer的基础上做了小调整。

    • 相关目录(可以根据需求自己改动,相关文件:packages/excel-killer/panel/index.js)

    plugins-excel/excel:存放excel表

    plugins-excel/excel-ouput: 存放执行插件后的js输出文件

    assets/script/data/config: 执行插件后,会自动把js文件从plugins-excel/excel-ouput拷贝到此目录


    • 如何使用
    let cfgman = require('CfgMan');
    console.log(cfgman[1].name);  // 小明
    



    # 数据模块

    • 目录结构

    IDataModel.ts:数据模块基类,主要功能:读取数据表、读写本地缓存数据、网络数据交互


    • 本地缓存数据接口

    LoadStorage():将该模块的本地缓存数据读取到内存

    Query(sKey: string, defaultValue: any = null):访问指定键名的值

    Set(sKey: string, value: string | number):设置指定键名的值

    Save():保存内存数据到缓存文件


    • 网络数据交互接口

    sendProtocolMsg(msg):发送协议到服务端

    registerListeners():注册网络监听事件,需要在getMessageListeners()定义需要监听的协议和方法

    // AccountModel.ts
    getMessageListeners() {
        return {
            // key:消息名,value:执行函数
            ['G2C_Login']: (msg) => { this.G2C_LoginSuccess(msg) },
        }
    }
    



    # UI模块

    • 目录结构

    UIMng:UI管理器,用于打开、关闭UI

    UIBase:UI界面基类,在这里可以定义一些通用方法,供子类调用或者继承

    UIHelp:UI工具类,封装一系列UI相关的功能方法


    • 如何使用(配合自动化插件)

    1、新建一个场景或者prefab

    2、选中,然后到工具栏:扩展 -> ui-creator

    create-node-tree操作:将prefab节点树的结构自动导出到ts文件(目标文件夹:assets/script/data/autoui)

    export default class auto_notice extends cc.Component {
    const { ccclass } = cc._decorator;
    
    @ccclass
    export default class auto_notice extends cc.Component {
    	notice: cc.Node;
    	background: cc.Node;
    	title: cc.Node;
    	content: cc.Node;
    	btnClose: cc.Node;
    
    	public static URL:string = "db://assets/resources/prefab/notice/notice.prefab"
    
        onLoad () {
    		this.notice = this.node
    		this.background = this.notice.getChildByName("background");
    		this.title = this.notice.getChildByName("title");
    		this.content = this.notice.getChildByName("content");
    		this.btnClose = this.notice.getChildByName("btnClose");
    
        }
    }
    
    

    以后,你想要使用ui节点,就不需要各种getChildByName,或者搞个property在编辑器拖,所有的节点都导出在一个ts文件,然后作为一个组件添加到UI文件中,你只需要this.ui[节点名称]即可访问。

    create-ui-template操作:自动生成UI模板TS文件

    UI模板在packages\ui-creator\core\ui-template.txt中定义。

    3、将第2步create-ui-template操作生成的UI脚本文件,在编辑器拖到prefab的根节点作为组件

    4、UI的基本操作都封装在UIHelp中

    UIHelp.ShowUI(UINotice);    // 打开ui
    UIHelp.CloseUI(UINotice);   // 关闭ui
    UIHelp.SetLabel(this.ui.title, '测试公告标题'); // 修改label节点文本
    

    • TODO

    后续补充关闭UI清除相关无用资源


    • 这里说一下对于UI的一些想法和见解

    1、MVC模式。在框架中,每一个功能创建一个model类继承IDataModel,用于处理数据(配置表、本地数据、网络数据)。新建的prefab就是view,挂载在prefab的脚本组件就是controller,在controller实现功能逻辑。

    2、很多人在用CocosCreator开发时,经常会往节点上挂脚本,往按钮上绑定事件(看过好多github上的项目都是这样)。但我个人是很不建议这样做的,正常的团队开发合作中都是分工明确的,比如你在编辑器中用按钮绑定事件,难道美术修改的时候还要关心代码么。而且任意节点都可以挂脚本,这个真的有点“灾难性”,我要找在这个脚本在哪里用到的时候还要去编辑器一个个找么(可能有其他快速查找的方法,我不知道的,请指点一下)。

    3、所以我是比较支持,能用代码实现的尽量用代码实现,脚本文件能挂在根节点(方便找)的尽量挂在根节点。




    # 网络模块

    数据协议用Protobufjs,网络协议用WebSocket

    • Protobufjs(用的是5.x)

    1、安装nodejs、npm

    2、到新建的cocoscreator工程目录,初始化项目:执行npm init -y

    3、安装protobufjs5.x版本:执行npm install --save-dev protobufjs@5

    4、覆盖原protobuf的loadProtoFile方法

    protobuf原来的loadProtoFile方法:

    ProtoBuf.loadProtoFile = function(filename, callback, builder) {
        if (callback && typeof callback === 'object')
            builder = callback,
            callback = null;
        else if (!callback || typeof callback !== 'function')
            callback = null;
        if (callback)
            return ProtoBuf.Util.fetch(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(contents) {
                if (contents === null) {
                    callback(Error("Failed to fetch file"));
                    return;
                }
                try {
                    callback(null, ProtoBuf.loadProto(contents, builder, filename));
                } catch (e) {
                    callback(e);
                }
            });
        var contents = ProtoBuf.Util.fetch(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename);
        return contents === null ? null : ProtoBuf.loadProto(contents, builder, filename);
    };
    

    这里用了ProtoBuf.Util.fetch来读文件,所以需要重写loadProtoFile方法,用cc.loader.loadRes代替Util.fetch方法来读取文件:

    let ProtoBuf = require('protobufjs');
    ProtoBuf.Util.IS_NODE = cc.sys.isNative;
    // 此方法是将ProtoBuf.Util.fetch函数替换成cc.loader.loadRes函数,以解决在微信小游戏中不能使用XHR的问题
    ProtoBuf.loadProtoFile = function(filename, callback, builder) {
        if (callback && typeof callback === 'object')
            builder = callback,
            callback = null;
        else if (!callback || typeof callback !== 'function')
            callback = null;
        if (callback)
            return cc.loader.loadRes(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(error, contents) {
                if (contents === null) {
                    callback(Error("Failed to fetch file"));
                    return;
                }
                try {
                    callback(error, ProtoBuf.loadProto(contents, builder, filename));
                } catch (e) {
                    callback(e);
                }
            });
        var contents = cc.loader.loadRes(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename); 
        return contents === null ? null : ProtoBuf.loadProto(contents, builder, filename);
    };
    

    • WebSocket

    CocosCreator已经支持WebSocket,而如果是微信小游戏则用微信提供的WebSocket,具体查看:https://developers.weixin.qq.com/minigame/dev/api/network/websocket/wx.connectSocket.html

    工程中两种都实现了,其中浏览器平台已经测试过可行,并且提供了Nodejs服务端工程。


    • 目录结构

    ProtoBuf.ts:对protobufjs的修改和封装

    ProtoLoader.ts:用于加载proto文件

    Message.ts:proto msg的基类,并将msg缓存起来

    ProtoMessage.ts:插件根据proto文件生成的代码

    Socket.ts:WebSocket/WxSocket的具体实现

    SocketDelegate.ts:Socket代理类,根据具体平台创建socket,提供统一回调接口供具体Socket调用

    Network.ts:网络的逻辑实现,跟用户打交道,连接网络、关闭网络、登录流程、断网、重连都可以在这里处理


    • proto-killer插件

    将proto转成TS代码,在开发中会有编辑器智能提示。




    # 日志模块

    • 增加开关配置,每个大功能可以有一个开关,每个开发人员可以有一个开关,按需定义
    export const LOG_TAG = {
        SOCKET: { desc: 'LOG_SOCKET', isOpen: true },
        TEST: { desc: 'LOG_TEST', isOpen: false },
    }
    

    • 使用
    Log.log(LOG_TAG.SOCKET, 'socketprint');
    Log.warn('warn');
    Log.error('error');
    

    log方法第一个参数为开关分类,warn和error没有,因为我认为一般调试打印用log方法就够了,如果你用warn或error,肯定是需要所有人都知道的。




    # 事件模块

    EventMng.ts:事件分发我偷懒了,直接new一个cc.EventTarget来用,目前没有发现其他问题。




    # 其他

    GameController.ts:游戏全局控制类,比较杂的不知道放哪的可以看看能不能放这里

    GameDataCenter.ts:管理游戏各个模块数据

    global.d.ts:用于扩展基础模块

    utils文件夹:用于存放一些工具类





    最后


    这篇文章讲的主要是框架有什么东西,有些地方为何要这么设计,githu工程点这里

    看完有点懵逼?没关系,下篇文章是:CocosCreator游戏开发框架(二):怎么用

    我会在框架的基础上快速开发一个简单的客户端登陆系统,帮助大家快速上手。

    展开全文
  • 最近使用cocos creator制作了一个攀登楼梯的游戏,使用到了cocos creator 的碰撞系统,动画系统,还使用了骨骼动画。 这个游戏本身是一个3d游戏,使用2d引擎表现出来的效果自然比不上3d,一开始是要考虑上线微信小...

    最近使用cocos creator制作了一个攀登楼梯的游戏,使用到了cocos creator 的碰撞系统,动画系统,还使用了骨骼动画。

    这个游戏本身是一个3d游戏,使用2d引擎表现出来的效果自然比不上3d,一开始是要考虑上线微信小程序,所以选了creator引擎。

    游戏的核心玩法就是人物向上攀登,点击抓到木头就可以继续向上抓,否则就会掉下,落入水中游戏结束。就是很简单的碰撞检测,不过动画的表现,我需要把手单独的抠出来,一开始使用帧动画的时候,没办法碰撞检测,我使用了一个比较笨的方法,就是在帧动画的每一帧结束后发射一个事件,带给程序一个参数,我把每一帧对应的手的位置全部记录在一个数组中,然后根据帧动画传过来的参数设定左右手的位置,达到了预期的效果。

    首先在creator的动画系统中给每一帧添加帧事件,选中帧,点击播放帧动画右边的那个箭头可以添加帧事件,添加成功后帧上会出现一个白点。

    双击白块可以给帧事件添加函数并附带参数,参数可以是number,string,boolean三种类型。如下图,每一帧可以添加很多个函数回调。写完之后点击保存。

    然后在绑定改动画节点上添加一个脚本组件,在脚本中添加这个函数名,就能监听到回调。注意:只能在当前动画节点绑定的脚本组件上监听到。如果有参数可以带过来。

    //帧动画的回调

    onTextureChange(event){

         let self = this;

    },

    帧事件是在添加帧事件的那一帧播放完成后才调用,所以对位置的话,要注意不要错帧。

    这样就把手单独的拿了出来,我可以以一个节点的形式去操作手掌,对手添加碰撞区域,改变手的spriteFrame属性。然后就是对手和木头的碰撞开启监听。

    因为是要用户点击才能够抓住木块,所以在碰撞检测里边的操作就是,监听每个木块的onCollisionStay,保存一个全局布尔变量,在点击的start和end中做操作,start时设为true,end时设为false。这样就做到了在点击的时候才会真正处理碰撞。点击到了,也要将该布尔变量设为false,不然会连续进入处理很多次。

    以上关于爬行碰撞的就处理完了。然后就是场景的移动,我一开始使用的是人物不动,背景移动,不过这样子看起来十分突兀。后边选择了摄像机。一开始是摄像机放在人物身上,可是移动还是很突兀,后边把摄像机拿了出来,人物移动后,摄像机跟随移动,就解决了这个问题。

    后边因为帧动画资源占用太多选择了骨骼动画,在骨骼动画中,依然是把手单独的抠出来,监听骨骼动画每帧的回调。将骨骼动画拖入游戏场景中设定好位置,然后在代码里取到该节点,hero_spine:sp.Skeleton,

    注意:骨骼动画的是不能设置锚点和size的,不过可以设置位置。

    骨骼动画每帧的监听方法是

    self.hero_spine.setEventListener(function(event){   });

    self.hero_spine.setEndListener()  骨骼动画这个方法,在浏览器中会在动画播放完成调用,但是在模拟器和真机中,会直接调用。

    展开全文
  • CocosCreator

    2018-11-01 21:59:42
    由于cocos舍弃了cocostudio,需要关注官方推荐的creator了...2 CocosCreator + 从零开始(15楼) - CocoaChi… http://www.cocoachina.com/bbs/3g/read.php?tid=460272 新编辑器Cocos Creator发布:对不起我来晚了!

    由于cocos舍弃了cocostudio,需要关注官方推荐的creator了。
    1 creator实现了:脚本化(jS开发), 组件化, 数据驱动器。
    2 CocosCreator + 从零开始(15楼) - CocoaChi…
    http://www.cocoachina.com/bbs/3g/read.php?tid=460272
    新编辑器Cocos Creator发布:对不起我来晚了!–
    学无止境的专栏 博客-- http://blog.csdn.net/dingxiaowei2013/article/details/50551900
    cocos creator第一个星星游戏 – http://docs.cocos.com/creator/manual/zh/getting-started/quick-start.html
    Cocos Creator跨平台的调用方法 –http://blog.csdn.net/potato47/article/details/68954272 js与Java和OC互调用
    -----------------------注:转载
    1 但是脚本化并不是意味着整个引擎都用脚本来写。Cocos Creator的框架核心仍然是大家熟悉的整个Cocos 2d-x C++引擎,引擎的主循环和绝大多数计算工作都在C++层面完成。只是利用JavaScript bindings绑定出Cocos Creator的JavaScript API。所以大家无需担心性能问题。

    2 为什么在脚本里面选择JavaScript而不是Lua

    1. 无数的大公司,包括Microsoft, Google, Apple, Facebook, Intel等都在大力投入JavaScript的研发上面,但Lua则没有这个生态。JavaScript领域,有node.js,有npm,这些Lua都没有;有Intel的nw.js(node-webkit),有Facebook的React,有Apple和Google鼎力支持的HTML5和WebGL,有Mozilla的asm.js,在桌面跨平台领域有Github的Electron和Atom,有Adobe的Brackets,而我们没有见到上述哪家大公司投入资源大把资源在Lua上,这-是-事-实。请各位老板深思为什么巨头们都做出这样的选择,或者你们觉得自己比这些大公司的决策者更聪明也无妨。

    2. JavaScript可以让游戏跨Native, Runtime, 纯HTML5三种模式,也就是我上文所说的「广义跨平台」,而Lua只能发布前两种。今天腾讯QQ浏览器、QQ空间、QQ游戏大厅已经都开放手机页游接入了,腾讯工作室的《欢乐斗地主》已经发布了基于Cocos Play加速器的手机页游版本。如果哪一天微信或手机QQ开放了 HTML5游戏领域,那时候再来Lua转JavaScript就已经来不及了,各位老板只能面壁哭去了。

    3. Cocos Creator底层选择了Github公司开发的开源项目Electron。而Eletron是Github官方的代码编辑器Atom,以及微软开源项目VS Code所用的底层基础。其实我们很有幸和国际巨头公司做出了同样的架构选择。如我前文所说,当然也不排除未来和VS Code合作、快速提高Creator开发体验的各种可能。

    引用我一个好友对Cocos Creator的评论:「有了这玩意儿我还管什么Lua啊,游戏公司要的就是降低开发成本,管它是什么编程语言」

    3 C++和Lua的死忠粉,希望学一门语言吃一辈子的程序员 —— 不适合。为了Cocos Creator的纯粹,我选择了JavaScript作为引擎、编辑器、游戏逻辑的核心语言。
    4 Cocos Creator开源吗?
    在Cocos Creator里面,得益于高度可扩展的架构设计,对于不涉及核心技术门槛的编辑器组件,我们全部开源奉献给行业。完全开源的部分包括:
    这里写图片描述
    3Label:新增overFlow
    换图片:拖入Sprite sFame
    widget实现屏幕适配
    LayOut实现子节点自动对齐
    4
    组件执行顺序
    遇到问题: 12.1日
    1 mask:是限制Node显示区域的。是组件不是Size属性. ==Studio中Layout裁剪属性
    2 scroView 不显示内容。因为content中没有添加Layout组件/代码中没有设置位置
    4 如何修改Canvas组件设计屏幕尺寸?
    12.2日
    Cocos Creator中获取和加载资源(官方文档摘录)
    Cocos Creator 模块化脚本(摘自官方文档)
    Cocos creator】文件数据读写,用户数据存储
    Cocos creator中出现Uncaught TypeError: Cannot read property ‘node’ of undefined
    1 vsCode修改代码后,依旧执行旧代码。 办法:ctrl+s 刷新编辑器
    2 如何动态从图集中修改图片
    3 函数嵌套报错误: XXX not undefined; 办法:定义一个var self =this; 因为在嵌套this会产生歧义
    https://blog.csdn.net/lipei1220/article/details/39339557
    4 GameLogic类编译报错:声明类用cc.Class使用时要先new。 而var XXX = {}这种不用new直接用
    5 数组[] 从0开始 http://www.jb51.net/article/94050.htm

    1: 2种格式区别
    A var cfg = {
    moveSpeed: 10,
    version: “0.15”,
    showTutorial: true,

    load: function () {
        // …
    }
    

    };
    B var Rotate = cc.Class({。。。}。。
    C function PokerSprite(nValeu, nFlower)
    {
    this.value = nValeu;
    this.flower = nFlower,
    this.add = function(a, b){ return nValeu + nFlower ; //a+b;}
    }
    PokerSprite.prototype.onSum =function(a, b){
    return a+b;
    }
    PokerSprite.onSub = function(a, b){
    return a-b;
    }
    module.exports = PokerSprite;
    (前者A是obj 后者B C是类) 类在使用前要先new
    这里写图片描述这里写图片描述
    这里写图片描述scroview遇到的大坑这里写图片描述这里写图片描述
    这里写图片描述这里写图片描述
    每一个单独的脚本文件就构成一个模块。所有用户代码最终会由 Cocos Creator 编译为原生的 JavaScript,
    var Rotate = require(“Rotate”); require 返回的就是被模块导出的对象,通常我们都会将结果立即存到一个变量(var Rotate),传入 require 的字符串就是文件名,不包含路径也不包含后缀,而且大小写敏感
    ---------------------------不会— 百度 goole 翻API
    12.13. 菊花弹框 手动绑定事件/post发射事件/开始按钮
    1 _pBtn.active = false;为啥不会隐藏?用btn组件调用node”组件”的函数。。。 children[I]方法 /AlterLayer回调实现null
    2 闭包一般是传到其他的类中执行,或者其他线程. / 非阻塞=-1,设为阻塞模式 就啥都没卡主

    12.9
    1 一般将需要渲染Node都挂在Canvars下-适配 /WebGL(web图形库):是一种JavaScript API;与openGl一样
    2 只有在属性声明时规定type为引用类型时,才能将资源或节点拖拽到该属性检查器上。
    3 update:我们一般把需要经常计算或及时更新的逻辑内容放在这里
    4 事件处理是在节点(cc.Node)中完成的。对于组件,可以通过访问节点 this.node /
    一个节点上只能添加一个渲染组件sp,label 粒子 /Canvas下面Z值大 组件脚本执行顺:上面先执行
    5 创建(cc.instantiate)和销毁(X.destroy)非常耗费性;如大量敌人或子弹.cc.NodePool put/get/szie
    6 bug:node.node./this.getComponent(“”) 脚本组件是绑定在节点上的,先获取到节点-再用该节点获取脚本.
    8 unity用directX(左手Z指向屏幕里) cocos用OpenGL(右手so Z值越大越在前)
    7 if你尝试访问null值,将会在陨石跑出TypeError错误 / js [push/pop/length/下标0] 与 {s.a==s[“a”]}的区别 /(function(){})();如何理解? / 二维数组
    8 使用:预加载All/ this.emptyAtlas.getSpriteFrame(“Res-Face-5“)-是/ /statics 静态方法变量-单列 /(“btn”+j+1)得出“btn01/btn02…” 运算符从左至右的,成了字符串相加 /[]常用函数sort 清空length=0 删除.splice
    .emit/on无需同一node-冒泡派送(子到父不能反) bug:node在隐藏时收不到infor / target节点类型 detail自定义数据 / ProgressBar slider的坑 / command+p @类文件+方法
    9 cc.class()调用cc对象中的class方法 / cc引擎中所有的类,函数,属性和常量都在这个命名空间中定义 / 你匿名函数or{}常常做函数参数 ()=>{}与前者等价. / debug:F9/5/11/10 Log

    切换纹理setTexture和setSpriteFrame;不会goole和查源码
    pushScene(栈/保留状态/占内存/init不走Enter走)
    

    https://zhidao.baidu.com/question/288052936.html
    https://zhidao.baidu.com/question/156291805.html

    12.6
    1 框架支持系统事件包含鼠标、触摸、键盘、重力传感四种;
    鼠标和触摸事件是被直接触发在相关节点上的,被称为节点系统事件。键盘和重力传感事件被称为全局系统事件(与节点树不相关)
    既可以使用枚举类型也可以直接使用事件名来注册. on/off
    2 RPG:
    vt=v0+a 加速度a=*v/*t
    匀变速直线运动:匀加速 匀减速
    竖直上抛运动: 上升过程是匀减速直线运动,下落过程是匀加速直线运动.全过程:是初速度为VO,加速度为g的
    物体做加速(减速)运动的条件是加速度方向与初速度方向相同(相反)
    牛顿第二定律:a=F/m
    位移是表示质点位置的变化的物理量 /路程是指质点所通过的实际轨迹的长度 是标量 /速度:表示质点的运动快慢和方向,是矢量
    3 快速上手:制作第一个游戏 http://docs.cocos.com/creator/manual/zh/getting-started/quick-start.html

    12.1日
    canvas Widget. Layout mask组件。属性size。。
    12.2日
    【Cocos creator】文件数据读写,用户数据存储
    Cocos creator中出现Uncaught TypeError: Cannot read property ‘node’ of undefined
    1 vsCode修改代码后,依旧执行旧代码。 办法:ctrl+s 刷新编辑器
    2 如何动态从图集中修改图片
    3 函数嵌套报错误: XXX not undefined; 办法:定义一个var self =this; 因为在嵌套this会产生歧义


    *文档的缺失,是现在 CCC 最大的问题,但是这也是没有办法的,毕竟这是个时间精力的问题,把有限的精力,放在最重要的工作上,才是正确的选择
    *其实对于一个好的程序员来说,学会看源码是极其基础的能力,你想要的大部分功能,在 CCC自带的源码中,其实已
    经都有,只是你需要自己去寻找
    *现在的 CCC 社区还是十分活跃的,大部分的问题,在这里基本上都能找到答案,毕竟有 cocos 引擎这么多年的用户积累

    展开全文
  • cocos creator-Action类

    2018-07-05 17:44:54
    Action类Action类是所有动作类型的基类 并且Action有两个类别 1、瞬时完成(ActionInstant) 2、非瞬时完成,即到完成时需要一定的时间ActionIntervial相关API功能cc.moveTo()移动到目标位置cc.moveBy()移动指定的...
  • 先贴上几个链接 : https://developers.weixin.qq.com/minigame/dev/tutorial/open-ability/open-data.html?q=  这个是介绍了子域和主域之间的通信 https://www.w3cschool.cn/weixinapp/weixinapp-vibrate.html ...
  • 这不是 Cocos Creator 的入门教程,也不是TypeScript 的入门教程,这是 Cocos Creator+TypeScript 的入门教程。 前提 无论学什么技术知识,官方文档都应该是你第一个教程,所以请先至少阅读新手上路这...这里假设
  • Cocos Creator游戏引擎是一个完整的游戏开发解决方案,包含从设计、开发、预览、调试到发布的整个工作流所需的全部功能。目前支持发布游戏到 Web、iOS、Android、各类"小游戏"、PC 客户端等平台,真正实现一次开发,...
  • 关于cocoscreator 转微信小游戏的遇到的一些问题 做为一个程序菜鸟 总是会遇到这样那样的问题 最后决定把自己遇到为一些智障问题还有 我的智障解决方法总结分享一下 微信 在初期的时候关于cocoscreator转微信啥都...
  • 在用CocosCreator做项目的时候,如果项目过大,资源很多,然后,现在我们假设我们这样设计架构: 1、打开一个界面(预制体)的时候,有关这个预制体的图片资源也用cc.loader加载进来; 2、关闭这个界面的时候,把...
  • 在用cocosCreator开发微信小游戏的时候,由于微信只允许上传4M的发布包,所以包体成为开发者斤斤计较的对象.但有时候我们游戏明明没有什么资源,但是编译后却发现空间不足,这是因为cocosCreator引擎本身携带的组件就...
  • KUOKUO 今天为大家带来 CocosCreator 的像素化 Effect。 正文 版本说明 使用 CocosCreator 的 2.2.0 版本演示。 像素化原理 对于一张图片,它是有着大量的像素点的。数量多到一定程度你就感觉不到像素的存在,我们...
  • 刚接触CocosCreator,写个小游戏练练手,熟悉一下cocos creator。 水果忍者的游戏,逻辑部分应该还是比较简单的,主要应该就涉及到水果的运动、分开,刀光效果等等。 CocosCreator版本是2.1.2,相关图片资源来源于...
  • CocosCreator properties:公布属性,可以把从外部取得其他节点或者其他图片精灵或者其他属性,属性的赋值和修改都可以在外部。公布属性,有简单的属性说明,也有完整的属性说明,完整的属性说明是加大括号的。注意...
  • 记得CocosCreator刚出来的时候就好奇安装了一个。。。因为听说坑很多就一直没有怎么认真去学习,版本变动特别快。我当前版本是1.9的。。。当时是下载的官方稳定版。。。这学期开学回来后,稳定版变1.1了。。。。好了...
  • 本次引擎2.0.5 编辑工具VSCode 简单说说Spine骨骼动画 (官方说2.0.7版本会修复...新建场景然后导入到CocosCreator中: 然后在面板里选择一下皮肤跟默认动画。 运行看看(编辑器里可能会出现显示不全等问...
1 2 3 4 5 ... 20
收藏数 7,288
精华内容 2,915
关键字:

cocos creator