Cocos 常用功能介绍

1,688 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

学习来源链接:《Cocos Creator零基础小白超神教程》

cocos思想

cocos2d的编程最重要的是在于继承, 一个对象继承自一个类。

cocos creator的编程是每一个对象都是一个节点,在节点中可以挂载组件,一个节点中可以挂载无数的组件component,偏向于面向组件的设计

单例模式

单例模式:在它的核心结构中值包含一个被称为单例的特殊类。一个类只有一个实例,即一个类只有一个对象实例。 比如说在一些单机游戏中的玩家,就是一个单例。

可以将 constructor构造方法通过修饰符来私有化,让外部无法定义类的实例

class Manager {
    static Instance = new Manager();
    // 通过private修饰符,让类无法在外部创建新的实例
    private constructor() {

    }
}
// Manager.Instance就是唯一的实例
Manager.Instance;

当然,此种形式的类的单例无论是否使用都会存在所以可以对此进行修改

class Manager {
    private static instance: Manager;

    static Instance() {
        if (!this.instance) {
            this.instance = new Manager();
        }
        return this.instance;
    };
    // 通过private修饰符,让类无法在外部创建新的实例
    private constructor() { }
}

// Manager.Instance()创建单例
let n = Manager.Instance();
console.log(n);

代理模式

有一个正常的类,可以将内部属性给别的类进行代理处理。相同的数据经过不同的代理者处理后,会得到不同的结果。

// 代理者需要遵守的规则
interface Icalc {
    calc(num1, num2)
}
// 委托者
class Person {
    delegate: Icalc;
    getNums(num1: number, num2: number) {
        // 让代理者进行运算
        let res1 = this.delegate.calc(num1, num2);
        console.log(res1);
    }
}
// 代理人
class proxy1 implements Icalc {
    calc(num1: any, num2: any) {
        return num1 + num2;
    }
}
class proxy2 implements Icalc {
    calc(num1: any, num2: any) {
        return num1 - num2;
    }
}
let n = new Person();
n.delegate = new proxy1(); // 选择代理
n.getNums(5, 6);  // 11

工厂模式

工厂模式:在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

一个工厂可以生产出多个形象不同的种类相同的对象,比如说游戏中怪物,可以是地精、狐妖、幽灵,但都可以从怪物工厂中生产出来。

enum cars { Audi, BWM, Benz}
class CarMakin {
    name: string
    // 工厂方法
    static creating(carType: cars): CarMakin {
        let car: CarMakin;
        switch(carType) {
            case cars.Audi: car = new Audi(); break;
            case cars.BWM: car = new BWM(); break;
            case cars.Benz: car = new Benz(); break;
        }
        return car;
    }
}

class BWM extends CarMakin {}
class Benz extends CarMakin {}
class Audi extends CarMakin {}
// 生产一辆新车,输入类型 
let newcar = CarMakin.creating(cars.Audi);
console.log(newcar);

精灵和精灵图集

在节点上面可以使用Sprite组件来进行图片的显示

但是对于比较复杂的场景,场景中需要显示的图片节点较多时,一张张加载精灵效率就比较低下了。 所以这时可以使用雪碧图来进行加载,只加载一张大的雪碧图,各个节点需要渲染的精灵从雪碧图中获取。

通过 TexturePacker 工具,将图片合成。 参考: 《纹理打包器 TexturePacker》

然后在cocos中对此进行使用,生成雪碧图时还产生了一个plist文件,这是以 xml 方式来进行保存雪碧图各部分信息的文件

plist文件下面的图片拉入精灵组件中即可,这样场景渲染时也只会加载雪碧图

生命周期

生命周期回调Cocos Creator 为组件脚本提供了生命周期的回调函数。用户只要定义特定的回调函数,Creator 就会在特定的时期自动执行相关脚本,用户不需要手工调用它们。

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

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

节点常用属性

  1. 获取子节点:
  2. this.node.children[n] 或者
  3. this.node.getChildByName('xxx')
  4. cc.find('Canvas/xxx/xx') 这是从canvas开始的路径
  5. 获取父节点:
  6. getParent()
  7. setParent() 设置父节点,将当前节点放到该节点下
  8. 移除remove
  9. removeAllChildren() 移除所有子节点
  10. removeChild(xxx) 移除某个子节点
  11. removeFromParent() 从父节点移除
  12. removeComponent(xxx) 从该节点中移除某个组件
  13. 节点开启关闭
  14. this.active = true/false
  15. 获取组件
  16. getComponent 获取组件
  17. getComponentInChildren 递归查找所有子节点中第一个匹配指定类型的组件

脚本创建预设体

预设体指预先设置的模板物体,后续可以直接调用生成,后面的精灵都是预设体样式。

@property(cc.Prefab)
pre: cc.Prefab = null;

// 实例化预设体
// instantiate 克隆指定的任意类型的对象,或者从 Prefab 实例化出新节点
let newnode = cc.instantiate(this.pre)
// 设置父节点
newnode.setParent(this.node)

动态加载资源

  1. 需要一个 resources 的文件夹,在此文件夹下的资源都能够在脚本中动态加载
  2. 官方api
// 动态加载图片
cc.resources.load("sprite/npc", cc.SpriteFrame,  (err, spriteFrame)=> {
    this.node.addComponent(cc.Sprite);
    this.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});
// 动态加载预设体
cc.resources.load("prefab/tt", cc.Prefab, (err, prefab) => {
    var newNode = cc.instantiate(prefab);
    newNode.parent = this.node;
});

场景切换

  1. 使用loadScene可以做到切换场景
cc.director.loadScene(场景名称, ()=>{
    // 当前已经加载到新场景了
})
  1. 使用 preloadScene 可以预加载场景,此方法只是将场景提前先加载到内存,但是并没有进行切换
  2. 如果某个节点不会因为场景的切换而改变,可以将此节点添加为常驻节点cc.game.addPersistRootNode参考链接

自定义事件

this.node.on(cc.Node.EventType.TOUCH_START, ()=>{
    this.node.emit('event1');
}, this);

this.node.on('event1', ()=>{
    console.log('发生触摸了');
})

音频播放

组件形式播放

可以通过创建一个空节点,在节点当中添加音频组件的方式来进行播放

将资源文件夹中的音频文件拖拽到clip中。

使用 AudioEngine 播放

这与上面使用组件稍有不同,AudioEngine是一个单纯的api,只能编写脚本进行调用。

参考链接

射线

// 使用射线一定要注意,在onload中射出,不会返回结果
// 射出一条射线  参数1是起点,参数二是方向位置,参数3是类型
let res = this.gp.rayCast(this.node.getPosition(), cc.v2(this.node.getPosition().x, this.node.getPosition().y - 300), cc.RayCastType.AllClosest )

for(let i = 0; i < res.length; i++) {
    let r = res[i];
    // 射线碰到的碰撞器
    // res.collider
    // 碰到的点
    // res.point
    // 碰到的法线
    // res.normal
}

动作系统

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

动作系统并不能取代动画系统,动作系统提供的是面向程序员的 API 接口,而动画系统则是提供在编辑器中来设计的。同时,它们服务于不同的使用场景,动作系统比较适合来制作简单的形变和位移动画,而动画系统则强大许多,美术可以用编辑器制作支持各种属性,包含运动轨迹和缓动的复杂动画

// 动作
// 移动  参数1:时间  参数2/3:位置 
let action = cc.moveTo(2, 200, 200);
action = cc.moveBy(2, 200, 200)
// 旋转
action = cc.rotateTo(2, 90);
// 缩放
action = cc.scaleTo(2, 1.5, 0.5);
// 跳跃
action = cc.jumpBy(2, 200, 0, 100, 2)
// 闪烁
action = cc.blink(3, 5);
// 淡出
action = cc.fadeOut(3);
// 淡入
action = cc.fadeIn(3);
// 渐变
action = cc.fadeTo(3, 100);
// 颜色
action = cc.tintTo(3, 100, 20, 100);

// 显示 隐藏 
let action2 = cc.show();
let action3 = cc.hide();
// 切换显示隐藏
action2 = cc.toggleVisibility();
// 翻转
action2 = cc.flipX(true);
// 容器动作
let seq = cc.sequence(action, action3, cc.show(), cc.fadeOut(3), cc.callFunc(()=>{
           console.log('动作都执行完了');
       }));

// 执行动作
this.node.runAction(seq);
// 停止动作
// this.node.stopAction(action)

分辨率

Cocos Creator 在设计之初就致力于解决一套资源适配多种分辨率屏幕的问题。简单概括来说,我们通过以下几个部分完成多分辨率适配解决方案:

  • Canvas(画布) 组件随时获得设备屏幕的实际分辨率并对场景中所有渲染元素进行适当的缩放。
  • Widget(对齐挂件) 放置在渲染元素上,能够根据需要将元素对齐父节点的不同参考位置。
  • Label(文字) 组件内置了提供各种动态文字排版模式的功能,当文字的约束框由于 Widget 对齐要求发生变化时,文字会根据需要呈现完美的排版效果。
  • Sliced Sprite(九宫格精灵图) 则提供了可任意指定尺寸的图像,同样可以满足各式各样的对齐要求,在任何屏幕分辨率上都显示高精度的图像。

首先了解设计分辨率、屏幕分辨率的概念,才能理解 Canvas(画布) 组件的缩放作用。

在canvas节点当中,可以调节 Fit HeightFit Width来让画布对屏幕进行自适应