Cocos入门知识总结 (一)

Cocos Creator 的脚本主要是通过扩展组件来进行开发的。目前 Cocos Creator 支持 JavaScript 和 TypeScript 两种脚本语言。通过编写脚本组件,并将它赋予到场景节点中来驱动场景中的物体。

总结都是根据javaScript学习的。刚刚入门cocos。以前用pharser2.0做了一个小游戏。想发布到微信小游戏上面。但是因为没法做排行榜。用pharser做的排行榜没法翻页。自己也是刚刚入门pharser2.0.在网上找了很多资料。都没有解决pharser展示游戏排行榜的问题。后来经过查询发现。cocos已经非常成熟了。并且都微信小游戏的支持非常好。所以准备学习cocos。重新写一下那个小游戏。现在将cocos的一些基本api方法整理下。

一、节点和组件

1.1 创建和使用脚本组件

  • 创建脚本组件

    在 Cocos Creator 中,脚本也是资源的一部分。你可以在资源编辑器中通过点击"创建"按钮来添加并选择 JavaScript 或者 TypeScript 来创建一份组件脚本。此时你会在你的资源编辑器中出现一个新加的NewScript.js

  • 一份简单的组件脚本如下:

    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) {
    
        },
    
    });
  • 使用脚本组件

  • 将脚本添加到场景节点中,实际上就是为这个节点添加一份组件。我们先将刚刚创建出来的 NewScript.js重命名为 say-hello.js。然后选中我们希望添加的场景节点,此时该节点的属性会显示在 属性检查器 中。在 属性检查器 的最下方有一个 添加组件 的按钮,点击按钮并选择 添加用户脚本 -> say-hello 来添加我们刚刚编写的脚本组件。只有将js文件挂载在场景上才会走这个js里的方法。

1.2 使用 cc.Class 声明类型

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

  • 定义一个 CCClass

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

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

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

  • 实例化

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

  • 判断类型

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

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

  • 继承:使用 extends 实现继承

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

1.3 声明自定义属性

1.3.1 简单声明

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

    (1)基本类型

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

      properties: {
          height: 20,       // number
          type: "actor",    // string
          loaded: false,    // boolean                
          target: null,     // object
      }
  • 当声明的属性具备类型时(如:cc.Nodecc.Vec2 等),可以在声明处填写他们的构造函数来完成声明,如:

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

    (2)数组类型

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

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

    1.3.2 完整声明

    有些情况下,我们需要为属性声明添加参数,这些参数控制了属性在 属性检查器 中的显示方式,以及属性在场景序列化过程中的行为。

     (1)基本类型

properties: {
    score: {
        default: 0,
        displayName: "得分",
        tooltip: "设置玩家初始得分",
    }
}

以上代码为 score 属性设置了三个参数 default, displayNametooltip。这几个参数分别指定了 score 的默认值为 0,在 属性检查器 里,其属性名将显示为:“Score (player)”,并且当鼠标移到参数上时,显示对应的 Tooltip。

下面是常用参数:

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

(2)数组类型

数组的 default 必须设置为 [],如果要在 属性检查器 中编辑,还需要设置 type 为构造函数,枚举,或者 cc.Integercc.Floatcc.Booleancc.String
 

properties: {
    names: {
        default: [],
        type: [cc.String]   // 用 type 指定数组的每个元素都是字符串类型
    },
    enemies: {
        default: [],
        type: [cc.Node]     // type 同样写成数组,提高代码可读性
    },

}

1.4 脚本生命周期的回调函数

游戏运行的时期自动执行相关脚本,用户不需要手工调用它们。

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

  • onLoad
  • onEnable
  • start
  • update
  • lateUpdate
  • onDisable
  • onDestroy

1.4.1 onLoad

组件脚本的初始化阶段,我们提供了 onLoad 回调函数。onLoad 回调会在节点首次激活时触发,比如所在的场景被载入,或者所在节点被激活的情况下。在 onLoad 阶段,保证了你可以获取到场景中的其他节点,以及节点关联的资源数据。onLoad 总是会在任何 start 方法调用前执行,这能用于安排脚本的初始化顺序。通常我们会在 onLoad 阶段去做一些初始化相关的操作。例如:

cc.Class({

  extends: cc.Component,

  properties: {
    bulletSprite: cc.SpriteFrame,
    gun: cc.Node,
  },
  onLoad: function () {
    this._bulletRect = this.bulletSprite.getRect();
    this.gun = cc.find('hand/weapon', this.node);
  },
});

1.4.2 onEnable

当组件的 enabled 属性从 false 变为 true 时,或者所在节点的 active 属性从 false 变为 true时,会激活 onEnable 回调。倘若节点第一次被创建且 enabledtrue,则会在 onLoad 之后,start 之前被调用。

1.4.3 start

start 回调函数会在组件第一次激活前,也就是第一次执行 update 之前触发。start 通常用于初始化一些中间状态的数据,这些数据可能在 update 时会发生改变,并且被频繁的 enable 和 disable。

cc.Class({
  extends: cc.Component,

  start: function () {
    this._timer = 0.0;
  },

  update: function (dt) {
    this._timer += dt;
    if ( this._timer >= 10.0 ) {
      console.log('I am done!'); 
      this.enabled = false;
    }
  },
});

1.4.4 update

游戏开发的一个关键点是在每一帧渲染前更新物体的行为,状态和方位。这些更新操作通常都放在 update回调中。

cc.Class({
  extends: cc.Component,
  update: function (dt) {
    this.node.y+=1;
  }
});

1.4.5 lateUpdate

update 会在所有动画更新前执行,但如果我们要在动效(如动画、粒子、物理等)更新之后才进行一些额外操作,或者希望在所有组件的 update 都执行完之后才进行其它操作,那就需要用到 lateUpdate 回调。

cc.Class({

  extends: cc.Component,

  lateUpdate: function (dt) {
    this.node.rotation += 20;
  }

});

1.4.6 onDisable

当组件的 enabled 属性从 true 变为 false 时,或者所在节点的 active 属性从 true 变为 false时,会激活 onDisable 回调。

1.4.7 onDestroy

当组件或者所在节点调用了 destroy(),则会调用 onDestroy 回调,并在当帧结束时统一回收组件。

1.5 访问节点和其他组件

除了可以在 属性检查器 里修改节点和组件,也能在脚本中动态修改。动态修改的好处是能够在一段时间内连续地修改属性、过渡属性,实现渐变效果。脚本还能够响应玩家输入,能够修改、创建和销毁节点或组件,实现各种各样的游戏逻辑。要实现这些效果,需要先在脚本中获得你要修改的节点或组件。

1.5.1 获得组件所在的节点

获得组件所在的节点很简单,只要在组件方法里访问 this.node 变量:

start: function () {
    let node = this.node;
    node.x = 100;
}

1.5.2 获得当前节点下的其它组件

有时经常需要获得同一个节点上的其它组件,这就要用到 getComponent 这个 API,它会帮你查找你要的组件。

start: function () {
    let label = this.getComponent(cc.Label);
    let text = this.name + 'started';

    // Change the text in Label Component
    label.string = text;
}

1.5.3 获得其它节点及其下的组件

仅仅能访问节点自己的组件通常是不够的,脚本通常还需要进行多个节点之间的交互。例如,一门自动瞄准玩家的大炮,就需要不断获取玩家的最新位置。Cocos Creator 提供了一些不同的方法来获得其它节点或组件。

  • 使用属性检查器设置节点

    最直接的方式就是在 属性检查器 中设置需要的对象。以节点为例,这只需要在脚本中声明一个 type 为 cc.Node 的属性:

// Cannon.js

cc.Class({
    extends: cc.Component,
    properties: {
        // 声明 player 属性
        player: {
            default: null,
            type: cc.Node
        }
    }
});

 

 将player拖动cannon里即可产生关联。这样一来它的 player 属性就会被设置成功,可以直接在脚本里访问 player:

// Cannon.js

cc.Class({
    extends: cc.Component,
    properties: {
        // 声明 player 属性
        player: {
            default: null,
            type: cc.Node
        }
    },

    start: function () {
        cc.log("The player is " + this.player.name);
    },

});

使用属性检查器设置组件

在上面的例子中,如果将属性的 type 声明为 Player 组件,当拖动节点 Player Node属性检查器,player 属性就会被设置为这个节点里面的 Player 组件。这样就不需要再自己调用 getComponent 啦。

// Cannon.js

let Player = require("Player");

cc.Class({
    extends: cc.Component,
    properties: {
        // 声明 player 属性,这次直接是组件类型
        player: {
            default: null,
            type: Player
        }
    },

    start: function () {
        let playerComp = this.player;
        player.fire();
    },

});

还可以将属性的默认值由 null 改为数组 [],这样就能在 属性检查器 中同时设置多个对象。 不过如果需要在运行时动态获取其它对象,还需要用到下面介绍的查找方法。

1.5.4 查找子节点

有时候,游戏场景中会有很多个相同类型的对象,像是炮塔、敌人和特效,它们通常都有一个全局的脚本来统一管理。如果用 属性检查器 来一个一个将它们关联到这个脚本上,那工作就会很繁琐。为了更好地统一管理这些对象,我们可以把它们放到一个统一的父物体下,然后通过父物体来获得所有的子物体:

// sya-hello.js

cc.Class({
    extends: cc.Component,
    start: function () {
        let children = this.node.children;
        // ...
    }
});

 你还可以使用 getChildByName

this.node.getChildByName("Cannon");

如果子节点的层次较深,你还可以使用 cc.findcc.find 将根据传入的路径进行逐级查找:

cc.find("Cannon/Sub", this.node);

 1.5.5 全局名字查找

this.backNode = cc.find("Canvas/Hello/Cannon");

 

我要去学习二建了。等我考过二建。我就准备好好的学习cocos。现在我的重点还是在二建。已经努力了那么久。还有两个月就要考试了。加油加油。冲啊。

有时间在总结cocos相关的知识吧。

  • 21
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

留白的云

感谢鼓励。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值