002--自找麻烦之 cocos creator(简称 ccc )

这世上只有一种成功,就是能够用自己喜欢的方式度过自己的一生!

 

1. 项目基本结构

        +assets        (项目资源的根目录名)

            -Texture  (存放其他资源)

            -Script    (存放脚本文件)         ccc中脚本名就是组件名,大小写敏感!

            -Scene    (存放游戏场景)  

2. 脚本文件的结构               

cc.Class({
    extends: cc.Component,

    properties: {
        label: {
            default: null,
            type: cc.Label
        },
        // defaults, set visually when attaching this script to the Canvas
        text: 'Hello, World!'
    },

    // 用于初始化
    onLoad: function () {
        this.label.string = this.text;
    },

    // called every frame
    update: function (dt) {

    },
});

        properties :组件(挂载到场景中的节点上,提供控制节点的各种功能;这些properties可以直接在属性检查器中设置)

        onload :页面一加载完就执行里面的函数代码 

       update : 根据时间实时更新,更新回调

3. Prefab(预制资源)

        需要重复生成的节点,我们可以将他保存成Prefab(预制)资源,作为我们动态生成节点时使用的模板 

        比如将Texture文件夹下的一张图片,拖到层级管理器系统即是场景的canvas里面,再从层级管理器拖到Texture文件夹中就是预制资源(预制资源的图标是个灰色正方形)啦(我也觉得这操作有点奇怪)

4. 学习ccc需要对JavaScript非常熟悉

5. 常见基础 API

        cc.moveBy("几秒",cc.p("横坐标","纵坐标"))     移动指定的距离 

        cc.moveTo("几秒",cc.p("横坐标","纵坐标"))     移动到目标位置

        cc.easeCubicActionOut()       创建 easeCubicActionOut 缓动对象 ,就是缓慢减速的一种效果

        cc.repeatForever("一个序列")     永远地重复一个动作

        node.runAction("动作序列名")       执行并返回该执行的动作。该节点将会变成动作的目标。

                

        this.node.addChild("节点名","层级数字");     添加子节点

        "节点名".setPosition();           设置节点在父节点坐标系中的位置

        cc.callFunc       执行回调函数

        "节点名".removeFromParent        从父节点中删除该节点

        cc.sequence();         顺序执行动作,创建的动作将按顺序依次运行

6. Scene介绍和基本操作

        Scene  每个游戏都会用到场景切换!

 

        Director类  游戏导航仪,控制 初始化,场景切换,游戏暂停继续等等

 

        cc.director.loadScene("场景名");     加载一个场景 

        cc.director.preloadScene("场景名");        预加载场景(比如图片资源比较大就可以用它预先加载)

       this.node.on("事件名","函数");     事件(事件名,function)

       this.schedule(function(){},1);       类似js的setTimeout

        改变一个标签上面的文字居然是这样的 this.timeLabel.string=4;   (说好的和js差不多呢)

        模拟手机游戏的场景的canvas要改成   W:640     H: 960

7. 玩家输入事件语法

        

            

       EventTarget    事件目标是事件触发时,分派的事件对象,Node 是最常见的事件目标, 但是其他对象也可以是事件目标

8. 关闭左下角的fps面板,在场景脚本的文件中 onLoad 的函数中写以下:

cc.director.setDisplayStats(false);

=======================================================

腾讯课堂-cocos creator/cocos 2dx 入门 听课笔记

1. 使用ts来做ccc开发新建的脚本文件是这样的: (代码实现一只扇翅膀的小鸟)

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;

    @property(cc.Sprite)
    bird0: cc.Sprite = null;

    @property(cc.Sprite)
    bird1: cc.Sprite = null;

    @property(cc.Sprite)
    bird2: cc.Sprite = null;

    @property(cc.Sprite)
    bird3: cc.Sprite = null;

    @property(cc.Node)
    birdParent: cc.Node = null;

    @property
    text: string = 'hello';

    time: number = 0; // 距离上次切换显示的小鸟 流失的时间

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    start () {

    }

    update (dt: number) {
        // console.log(dt);
        let timeTmp = this.time + dt;
        this.time = timeTmp;

        if(this.time > 0.5){
            if(this.bird0.node.active){
                this.bird0.node.active = false;
                this.bird1.node.active = true;
            }else if (this.bird1.node.active){
                this.bird1.node.active = false;
                this.bird2.node.active = true;
            }else if (this.bird2.node.active){
                this.bird2.node.active = false;
                this.bird3.node.active = true;
            }else if (this.bird3.node.active){
                this.bird3.node.active = false;
                this.bird0.node.active = true;
            }
            this.time = 0;
        }

        let birdY = this.birdParent.y;
        this.birdParent.y = birdY - 1;
    }
}
// 重点来了,自定义枚举
    /**
     * 全局变量
     * const LEVEL = cc.Enum({EASY:1,HARD:2});
     */ 
     @property({
            type:LEVEL
     })
     enumVa = LEVEL.EASY;

2. 帧的概念是这样的: 比如一秒60帧,说明一秒钟画面刷新了60次,帧数为 1/60 

3. 节点 Node 是包含 组件的

4. 代码执行遇到return整个函数就都不执行了

5. BMfont 可以用图片数字来代替真实数字(不知道怎么做的)

=============================================================

1. ccc是一个组件化的开发工具

2. Prefab: 预制体,预制资源

// 预(提前)制体
        @property(cc.Prefab)//预制体类型
        myPrefab:cc.Prefab=null;//需要被克隆的对象

        //程序运行后加载对象
        start(){
            var loadobj =cc.instantiate(this.myPrefab);//将预制体克隆到场景
            this.node.addChild(loadobj);//将克隆出的物体作为子物体 
            //设置物体位置
            loadobj.setPosition(cc.p(300,-150));


            //5秒之后销毁对象
            setTimeout(
                function(){    //匿名方法            
                loadobj.destroy();
                }
            ,5000);
        }

3. ccc 的生命周期函数:

  • onLoad(会在这个组件所在的场景被载入的时候触发,执行最早的方法 只执行一次,在场景加载后立刻执行
  • start(会在组件第一次激活前,也就是第一次执行 update 之前触发,start 在onload 之后执行只执行一次
  • update(游戏开发一个关键是在每一帧渲染前更新物体的行为,状态和方位。这些更新操作通常都放在 update 回调中,会在所有动画更新前执行)(update 可以不带参数 参数的意思是游戏一帧执行的时间 大概为0.017秒 数值不固定
  • lateUpdate(动画更新后进行额外操作,在update执行之后马上执行 ,需要用到 lateUpdate 回调)
  • onDestroy(当组件调用了 destroy(),会在该帧结束被统一回收,此时会调用 onDestroy 回调。执行最晚的方法,物体被销毁之前执行
  • onEnable(当组件的 enabled 属性从 false 变为 true 时,会激活 onEnable 回调。倘若节点第一次被 创建且 enabled 
    为 true,则会在 onLoad 之后,start 之前被调用。脚本启用会执行
  • onDisable(当组件的 enabled 属性从 true 变为 false 时,会激活 onDisable 回调,脚本禁用会执行

4. Cocos Creator 中脚本名称就是组件的名称,这个命名是大小写敏感的!如果组件名称的大小写不正确,将无法正确通过名称使用组件!

5. 通过学习官网demo摘星星总结开发流程:

  • 找好游戏相关资源,包括图片,音频,位图字体文件等
  • 新建游戏场景(几个游戏画面就几个场景)(往场景添加背景,主角等)
  • 给你的主角写脚本(在 properties 中定义主角会用到的变量--想象主角会做什么动作,如主角会一直跳,我们还可以控制他左右走,跳有高度,也有跳一次所需 时间,左右走有速度,加速度等)
properties: {
    
}
  • 编写主角动作代码(主角自动执行的动作,如跳跃,为跳跃写一个方法),既然是自动执行就可以写在生命周期函数onload方法里面初始化调用;控制移动的再写一个方法,监听我们的按键,设置速度之类的属性
  • 重复生成的东西就要做成预制资源,为这个预制资源新建一个脚本文件
  • 添加游戏控制脚本,主逻辑包括计分,游戏开始,游戏失败等逻辑,一般绑在场景的canvas上面
  • 得分一般都是一个label标签,再价格位图字体,然后主逻辑脚本继续写得分逻辑
  • 最后加入音效

=================================================

1. 在场景的canvas的属性检查器中找到Group点击编辑可以分组配置碰撞检测

2. 添加物理边缘步骤(点击节点-添加组件-物理-collider-Box)如果边界是静止的吗,要在Rigidbody--type--static

3. 什么是ccc组件化开发: 节点 + 组件1 + 组件2 + 组件3 。。。 (也就是一个节点带着不同功能的组件)(开发一个功能,都是从组件开始的)

a: 创建一个组件类
           b: new 组件类出来
           c: 管理这些组件实例
              (1): 运行场景的时候初始化:
             遍历场景里面的每个节点,
                   遍历节点上面的每个组件实例;
                   调用 组件实例.onLoad, --> 组件实例在加载的时候调用;
                   调用 组件实例.start    -->组件实例在开始运行之前调用一次;
               (2): 每次游戏刷新的时候

4. 在一个节点操作 添加我们自己定义的脚本组件原来就是 实例化一个类 

5. 开启物理引擎:

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

开启调试状态/模式(给指定物理系统需要绘制哪些调试信息):

var draw = cc.PhysicsManager.DrawBits;
cc.director.getPhysicsManager().debugDrawFlags = draw.e_shapeBit|draw.e_jointBit;

物理引擎的脚本要挂载到根节点上,然后一定要在该脚本的onload()方法中所有的动作初始化前开启物理引擎。

6. 弧度转角度: 角度值 = 弧度值*180 / Math.PI

7. 碰撞检测: 

  • onBeginContact: 碰撞开始被调用
  • onEndContact: 碰撞结束被调用
  • onPreSolve: 碰撞接触更新前调用
  • onPostSolve: 碰撞接触更新后调用
  • 参数:contact 碰撞信息 ,selfCollider 自己的碰撞器 , otherCollider  撞到的谁

8. 微信打包发布:

  • 发布微信的话 canvas 节点上只能选择 Fit Width ,Fit Height 不能选
  • 项目--构建发布--发布平台(Wechat Game),MD5 Cache 选上,设备方向(竖屏选Portrait,横屏选landscape),appid(自己填自己的)--构建--运行(就会打开微信开发工具)--预览--扫描二维码玩游戏
  • cocos creator--偏好设置--原生开发环境--wechatGame程...(选择微信开发工具的地址exe的位置)

===============================================

1. moveBy:移动指定的距离

var jumpUp = cc.moveBy(this.jumpTimes,cc.p(0,this.jumpHeight));

2. cc.sequence: 顺序执行动作,创建的动作将按顺序依次运行

var seq = cc.sequence(this.jumpAction,this.maxMoveSpeed);

3. runAction: 执行并返回该执行的动作。该节点将会变成动作的目标。

this.node.runAction(seq);

4. getComponent: 获取节点上指定类型的组件,如果节点有附加指定类型的组件,则返回,如果没有则为空。
传入参数也可以是脚本的名称。

var HeroPlayer = require("HeroPlayer");
...
var hero = self.player.getComponent(HeroPlayer);

5. 除了微信小游戏以外,其他类型的小游戏 Canvas 中的Fit Height与Fit Width 一定要勾选上(为了适配)

6. cc.winSize: 为当前的游戏窗口的大小。

7. 获取一张图片的宽度: 

this._width = this.groundImg.spriteFrame.getRect().width;

8. 定时器:参数是回调函数和时间

this.schedule(function(),this.move_time)

9. 写动画(帧动画,例如 像素鸟的小鸟不断煽动翅膀)

      动画编辑器--添加animation组件--新建animationClip(存储在anim文件夹里面)--点击动画编辑器的左上角编辑按钮--属性列表点击 add property---选择 cc.Sprite.spriteFrame--点 “+” 号 -- 拉一帧点一次 “+” 号 -- 替换帧对应的图片--wrapMode选择Loop--点击左上角的播放按钮--保存--关闭--新建脚本--脚本拉到属性检查器--动画文件拉到对应位置--playOnload打钩--预览

10. 获取节点上指定类型的组件,如果节点有附加指定类型的组件,则返回,如果没有则为空。传入参数也可以是脚本的名称:

var pipeUp = cc.instantiate(this.pipePrefabs[0]);
pipe.getComponent('Pipe').init(0);

11. 返回父节坐标系下的轴向对齐的包围盒:(包围后是以盒的左下角为中心的)

var boundingBox = node.getBoundingBox();

12. 获取与设置本地 localstorage 的值:

cc.sys.localStorage.getItem('name');

cc.sys.localStorage.setItem('name',score);

13. 动画效果(例如为得分文字添加小动画):

  • scaleTo 将节点大小缩放到指定的倍数
  • sequence 顺序执行动作,创建的动作将按顺序依次运行。
var action1 = cc.scaleTo(this.scoreTime,1.1,0.6);
var action2 = cc.scaleTo(this.scoreTime,0.8,1.2);
var action3 = cc.scaleTo(this.scoreTime,1,1);
//播放形变动画
this.curScoreText.node.runAction(cc.sequence(action1,action2,action3));

========================================

1. 任何一个节点都会有一个 cc.Node(cc.Node是场景树中的节点对象);

2. cc.Node.rotation: 旋转,顺时针为正,数学逆时针为正;

3. cc.Node.anchor: 锚点,左下角(0,0),右上角(1,1),可以超过这个范围;

4. 在代码组件里面,使用 this.node 访问这个组件实例挂载的节点对象;

5. cc.Node.children/childrenCount: 获得孩子节点数组、孩子节点数量;

6. cc.Node场景树相关方法:

  • getChildByName: 通过名称获取节点的子节点
  • new cc.Node():代码中创建一个节点

  • setPosition/getPosition: 获取或设置节点的相对位置

  • cc.find(): 方便,不通用, 消耗

7. 触摸事件的类型:START, MOVED, ENDED(物体内弹起), CANCEL(物体外弹起);

  • cc.Node.EventType.TOUCH_START
  • cc.Node.EventType.TOUCH_MOVE
  • cc.Node.EventType.TOUCH_END
  • cc.Node.EventType.TOUCH_CANCEL

8. 监听触摸事件: node.on(类型, callback, target(回掉函数的this), [useCapture]);

9. 关闭触摸事件:  node.off(类型, callback, target(回掉函数的this), [useCapture]);

4. targetOff(target):移除所有的注册事件;

5. 触摸事件中回调函数的参数t:t.getLocation()  获取当前触点位置 ; t.getDelta()  获取触点距离上一次事件移动的距离对象,对象包含 x 和 y 属性(也就是距离上一次触摸变化了多少)

//在触摸移动的事件类型中的回调函数

var delta = t.getDelta();

this.node.x += delta.x;
this.node.y += delta.y;


//以上代码实现节点物体随着你点击移动的位置移动

6. stopPropagationImmediate: 立即停止当前事件的传递,事件甚至不会被分派到所连接的当前目标;

7. 监听键盘事件:cc.SystemEvent.on(type, function, target, useCapture);监听的时候,我们需要一个cc.SystemEvent的实例,我们有一个全局的实例cc.systemEvent,小写开头(实际使用时小写开头的)

  • cc.SystemEvent.EventType.KEY_DOWN  按键按下;
  • cc.SystemEvent.EventType.KEY_UP 按键弹起;

8. 自定义事件:

  • 监听:this.node.on(“自定义事件名称”, function, target, useCapture);
  • 自派送: emit(“事件名称”, [detail]); 只有自己能够收到;
  • 冒泡派送: dispatchEvent(new cc.Event.EventCustom(“name”, 是否冒泡传递));
start: function() {
        // 派发者,只能传递给自己,不会向上传递
        this.node.emit("pkg_event", {blake: "huang"});
        // end  

        // 派送者,不只是发给自己,发给我们这个体系;
        // true/false, true向上传递, false不向向上传递
        var e = new cc.Event.EventCustom("pkg_event", true);
        e.detail = {blake: "huang"};
        this.node.dispatchEvent(e);
},

9. ccc坐标系: 

  • 相对(节点)坐标系,两种相对节点原点的方式(1) 左下角为原点, (2) 锚点为原点(AR)

  • 节点坐标和屏幕坐标的相互转换; 我们到底使用哪个?通常情况下带AR

// 节点坐标转到屏幕(世界)坐标 cc.p(0, 0)
        var w_pos = this.node.convertToWorldSpace(cc.p(0, 0)); // 左下角为原点的   cc.p(430, 270)
        console.log(w_pos);
        w_pos = this.node.convertToWorldSpaceAR(cc.p(0, 0)); // 锚点为原点 cc.p(480, 320)
        console.log(w_pos);
        // end 

        var w_pos = cc.p(480, 320);

        var node_pos = this.node.convertToNodeSpace(w_pos);
        console.log(node_pos); // cc.p(50, 50)

        node_pos = this.node.convertToNodeSpaceAR(w_pos);
        console.log(node_pos); // cc.p(0, 0)
 // 获取节点的包围盒, 相对于父亲节点坐标系下的包围盒
        var box = this.node.getBoundingBox();
        console.log(box);

        // 世界坐标系下的包围盒
        var w_box = this.node.getBoundingBoxToWorld();
        console.log(w_box);

        this.node.on(cc.Node.EventType.TOUCH_START, function(t) {
            var w_pos = t.getLocation();
            var pos = this.node.convertToNodeSpaceAR(w_pos);
            console.log(pos);

            pos = this.node.convertTouchToNodeSpaceAR(t);
            console.log("====", pos);
        }, this);


        // 我要把当前这个sub移动到世界坐标为 900, 600;
        // 
        // 把世界坐标转到相对于它的父亲节点的坐标
        var node_pos = this.node.parent.convertToNodeSpaceAR(cc.p(900, 600));
        this.node.setPosition(node_pos); // 相对于this.node.parent这个为参照物,AR为原点的坐标系
        // end 
        // 获取当前节点的世界坐标;
        this.node.convertToWorldSpaceAR(cc.p(0, 0));

10. Action的使用: 

  • Action类是动作命令,我们创建Action,然后节点运行action就能够执行Action的动作;
  • Action分为两类: (1) 瞬时就完成的ActionInstant, (2) 要一段时间后才能完成ActionIntervial;
  • cc.Node runAction: 节点运行action;
  • cc.moveTo, cc.moveBy  To: 目标 By: 变化

    MoveTo:(x, y) → (x1, y1)

    MoveBy:(x, y) → (x + x1, y + y1)

  • cc.sequnce, cc.repeat, cc.repeatForever

  • Action easing(缓动的方式):  加上缓动特效, cc.easeXXXXX查看文档设置自己想要的缓动对象

  • stopAction: 停止运行action

  • stopAllActions: 停止所有的action;

onLoad: function () {
        // move
        // var mto = cc.moveTo(1, cc.p(100, 100)); // cc.moveTo(1, x, y);
        // this.node.runAction(mto);
        // var mby = cc.moveBy(1, cc.p(100, 100)); // cc.moveBy(1, x, y); 变化多少
        // this.node.runAction(mby);

        // rotate
        // var rto = cc.rotateTo(1, 180);  // 旋转到180度; rotation 180;
        // this.node.runAction(rto);
        // var rby = cc.rotateBy(1, 75); // 在原来的基础上,变化75,可正,可负
        // this.node.runAction(rby); 

        // scale
        // this.node.scale = 2;
        // var sto = cc.scaleTo(1, 1.1); // 到1.1倍
        // this.node.runAction(sto);

        // this.node.scale = 2;
        // var sby = cc.scaleBy(1, 1.1); // 原来的基础,变化1.1 * 2
        // this.node.runAction(sby);

        // opactify
        // var fin = cc.fadeIn(1);
        // this.node.opacity = 0;
        // this.node.runAction(fin);
        // var fout = cc.fadeOut(1);
        // this.node.runAction(fout); // 物体还是在的的
        // var fto = cc.fadeTo(1, 128);
        // this.node.runAction(fto);

        // function Action
        /*var func = cc.callFunc(function() {
            console.log("call Func actin!!!!!");
        }.bind(this));

        console.log("begin ####");
        this.node.runAction(func); 
        console.log("end ####");*/

        // 移动到 目的地,后,隐藏这个物体怎办? // 命令清单, [Action1, A2, A3], 
        // seq Action
        /*var m1 = cc.moveTo(1, 100, 100);
        var fout = cc.fadeOut(0.5);

        var seq = cc.sequence([m1, fout]);
        this.node.runAction(seq);*/

        // 一个节点可以同时运行多个Action, 一边,一边
        /*var m1 = cc.moveTo(1, 100, 100);
        var fout = cc.fadeOut(0.5);

        this.node.runAction(fout);
        this.node.runAction(m1);*/

        // 不断的放大缩小
        /*var s1 = cc.scaleTo(0.8, 1.1);
        var s2 = cc.scaleTo(0.8, 0.8);
        var seq = cc.sequence([s1, s2]);
        var rf = cc.repeatForever(seq);
        this.node.runAction(rf);*/

        // 匀速的飞过,傻了, 缓动
        // 回弹
        /*this.node.y = 0;
        var m = cc.moveTo(1, 100, 0).easing(cc.easeBackOut());
        this.node.runAction(m);*/
        
        /*var r = cc.rotateBy(3, 360).easing(cc.easeCubicActionOut());
        var rf = cc.repeatForever(r);
        this.node.runAction(rf);

        // this.node.stopAction(rf);
        this.node.stopAllActions();*/
        // end 

        // 移动了到100, 0,删除
        /*var m = cc.moveTo(1, 100, 0);
        var end_func = cc.callFunc(function() {
            this.node.removeFromParent();
        }.bind(this));
        var seq = cc.sequence([m, end_func]);
        this.node.runAction(seq);*/

        // cc.Delay,
        var d1 = cc.delayTime(3);
        var fout = cc.fadeOut(0.5);
        var end_func = cc.callFunc(function() {
            this.node.removeFromParent();
        }.bind(this))

        var seq = cc.sequence([d1, fout, end_func]);
        this.node.runAction(seq);
    },

11. cc.Component属性(组件类,所有组件的基类)

var my_item = require("my_item");

...

properties: {
    //基本数据类型,数,bool,字符串,color,pos,size
    speed: 100,
    is_debug: false,
    url_str: "",
    color: cc.color(0,0,0,255),
    pos: cc.p(0,0),
    size: cc.Size(100,100)

    // 系统的组件
    sprite_item: {
        type: cc.Sprite,
        default: null,  // null/[]
    }
    
    // 组件的代码组件
    custom_comp: {
        type: my_item,
        default: null, // null/[]
    },
}

12. cc.Sprite: 配置图片的SIZE_MODE

  • CUSTOM 大小和CCNode的大小一致;

  • RAW 原始的图片大小;

  • TRIMMED 大小为原始图片大小, 显示的内容是裁剪掉透明像素后的图片;

    trim: 是否裁剪掉 图片的透明区域, 如果勾选,就会把完全透明的行和列裁掉, 做帧动画的时候,我们一般是用原始大小不去透明 度,动画,不至于抖动;

13. Filled模式(游戏中道具的时间进度显示条、个性化时间进度条案例等应用,比较常用,最好掌握)

  • 配置Filled模式, 设置为Radius参数
  • 配置Radius的参数模式,
  1.  中心: 位置坐标(0, 1小数), (0, 0)左下脚, (1, 1) 右上角 (0.5, 0.5) 中心点           
  2. Fill Start 开始的位置: 0 ~1, 右边中心点开始,逆时针走

  3. Fill Range: 填充总量(0, 1];

  4. FillRange为正,那么就是逆时针,如果为负,那么就是顺时针;

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值