Cocos Creator入门级文档

402 阅读6分钟

Cocos Creator 既是一款高效、轻量、免费开源的跨平台 2D&3D 图形引擎,也是一个实时 2D&3D 数字内容创作平台。拥有高性能低功耗流式加载跨平台等诸多优点,您可以用它来创作游戏车机XR元宇宙等领域的项目。本文将详细介绍cocos creator 入门常用知识。

1. 编辑环境配置

安装API 适配插件

  • 开发者 -> VS Code 工作流 -> 安装 VS Code 扩展插件
  • 该操作会将 Cocos Creator API 适配插件安装到 VS Code 全局的插件文件夹中
  • 这个操作只需要执行一次,如果 API 适配插件更新了,则需要再次运行来更新插件
  • 安装成功后在 控制台 会显示绿色的提示:VS Code extension installed to ...。
  • 这个插件的主要功能是为 VS Code 编辑状态下注入符合 Cocos Creator 组件脚本使用习惯的语法提示。 ** 生成智能提示数据 **
  • 开发者 -> VS Code 工作流 -> 更新 VS Code 智能提示数据
  • 该操作会将根据引擎 API 生成的 creator.d.ts 数据文件复制到项目根目录下
  • 操作成功时会在 控制台 显示绿色提示:API data generated and copied to ...
  • 对于每个不同的项目都需要运行一次这个命令

2. 场景

  • 预加载场景: cc.director.preloadScene('GameScene')
  • 切换场景: cc.director.loadScene('GameScene')

3. 节点

获取

  • 当前节点 this

  • 组件所依附的节点 this.node

  • 节点的父节点this.node.parent

  • 节点的子节点数组 this.node.children

  • 通过节点名获取子节点 this.node.getChildByName('Node3')

获取其他节点

  • 1 .声明
properties: {
  node5: cc.Node
}
    1. 拖拽节点到声明的节点中

删除

removeFromParent() 解除父子关系

destroy()删除该节点

添加

new --> addChild
onLoad () {
    let node8 = new cc.Node()
    node8.name = 'node-8'
    // 将当前node8添加到当前节点
    this.node.addChild(node8)
    console.log(node8.name) // node-8
}

4. 组件

添加 addComponent

移出 removeComponent

获取 getComponent

onLoad () {
    let sprite = this.node.addComponent(cc.Sprite)
    this.node.removeComponent(cc.Sprite)
    this.node.getComponent(cc.Sprite)
}

5. 动作Action

  • 1: Action类是动作命令,我们创建Action,然后节点运行action就能够执行Action的动作;

  • 2: Action分为两类: (1) 瞬时就完成的ActionInstant, (2) 要一段时间后才能完成ActionIntervial;

  • 3: cc.Node runAction: 节点运行action;

  • 4: cc.moveTo, cc.moveBy To: 目标 By: 变化

  • 5: cc.roateBy, cc.rotateTo,

  • 6: cc.scaleBy, cc.scaleTo,

  • 7: cc.fadeOut(淡出), cc.fadeIn(淡入): cc.fadeTo();

  • 8: cc.callFunc, cc.delayTime

  • 9: cc.sequnce, cc.repeat, cc.repeatForever

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

  • 11: stopAction: 停止运行action

  • 12: stopAllActions: 停止所有的action;

  • 时间间隔动作 移动 moveTo 旋转 rotateTo 缩放 scaleTo 渐隐 fadeOut

this.node.runAction(
    cc.moveTo(1, cc.v2(500, 500)) // 一秒钟移动到(500, 500)坐标处
    cc.rotateTo(1, 180) // 一秒钟旋转180度(+-180 顺+ 逆-)
    cc.scaleTo(1, 2, 2) // 一秒钟x轴y轴放大两倍
    cc.fadeOut(1) // 1s 渐隐
)
  • 容器动作 顺序执行动作 sequence 同步执行动作 spawn 重复执行动作 repeat 永远重复动作 repeatForever 修改动作速率 speed
  • 即时动作 执行回调函数 callFunc

缓动动作

action.easing(cc.easeBackIn())

  • easeBackIn 是在相反的方向缓慢移动,然后加速到正确的方向
  • easeBackOut 快速移动超出目标,然后慢慢回到目标点。
onLoad () {
    this.node.runAction(
        cc.sequence(
            cc.moveTo(1, cc.v2(500, 500)).easing(cc.easeBackIn()),
            cc.fadeOut(2),
            cc.callFunc(this.callback, this, {hello: 'world'})
        )
    )
},
callback: function(tagetNode, arg) {
    console.log(tagetNode) // 节点
    console.log(arg)  //{hello: "world"}
},

6. 事件

发射和监听

  • 监听 on

除了使用 on 监听,我们还可以使用 once 方法

once 监听在监听函数响应后就会关闭监听事件

  • 监听对应的触摸事件: 向引擎底层注册一个回调函数,当有触摸事件发生的时候调用

回调函数

/* 
	回掉函数的格式  function(t)  --> cc.Touch对象触摸事件对象 {触摸信息,事件信息}
    call --> this, this指向谁就是这个target;你要绑那个对象作为你回掉函数的this, 可以为空
    function () {}.bind(this); 
*/

关闭 off

off 方法的 参数必须和 on 方法的参数一一对应,才能完成关闭 移除target上所有的注册事件: this.node.targetOff(this); 发射 emit

在 emit 函数的第二个参数开始传递事件参数(最多只支持传递 5 个事件参数) 派送 dispatchEvent

cc.Class({
    extends: cc.Component,

    properties: {
        node4: cc.Node,
        node5: cc.Node
    },
    onLoad () {
        this.node.on('枪声', this.rush, this.node4)
        this.node.on('枪声', this.escape, this.node5)
        this.node.emit('枪声', {hello: 'world'})
    },
    rush: function (obj) {
        console.log(this.name, 'rush')  // node4 rush
        console.log(obj, 'rush')  // {hello: "world"} "rush"
        this.runAction(
            cc.moveTo(1, 500, 0)
        )
    },
    escape: function (obj) {
        console.log(this.name, 'escape') // node5 rush
        console.log(obj, 'escape')    // {hello: "world"} "escape"
        this.runAction(
            cc.moveTo(1, 0, 500)
        )
    },
    start () {}
});
  • 触摸事件 touchstart touchmove touchend touchcancel

  • 停止事件传递: t.stopPropagationImmediate()

cc.Class({
    extends: cc.Component,
    properties: {
    },
    // t: --> cc.Touch触摸的位置: 屏幕坐标,左下角(0, 0); getLocation();
    onTouchMove: function(t) {
        // 停止事件传递
        t.stopPropagationImmediate(); 
        // 位置
        var w_pos = t.getLocation(); // cc.Vec2 {x, y}
        // 距离上一次触摸变化了多少;
        var delta = t.getDelta(); // x, y各变化了多少cc.Vec2(x, y)
        this.node.x += delta.x;
        this.node.y += delta.y;
    },
    // use this for initialization
    onLoad: function () {
        this.node.on('touchmove', this.onTouchMove, this)
        // 移除
        // this.node.off('touchmove', this.onTouchMove, this);
    }
});
  • 鼠标事件 mousedown mouseenter mousemove mouseleave mouseup mousewheel
  • 键盘事件 keydown keyup
  • cc.KEY : 获取所有keyword以及对应的keycod 向引擎注册一个事件类型的回调函数
  • cc.systemEvent 小写开头,不是大写, 大写SystemEvent类, systemEvent 全局一个实例
onLoad () {
    cc.systemEvent.on('keydown', this.onKeyDown, this)  // 键盘
},
onKeyDown (e) {
    console.log(cc.KEY)
}

7. 坐标转换

  • 全局坐标系位置 location = e.getLocation()
  • 全局 --转换成–> 相对于this.node this.node.convertToNodeSpaceAR(location)
  • 全局 --转换成–> 相对于this.node的父节点
this.node.parent.convertToNodeSpaceAR(location)
onLoad () {
    // this.node.on('touchstart', this.onTouchStart, this)
    cc.find('node1').on('touchstart', this.onTouchStart, this)
},
onTouchStart: function (e) {
    // console.log(e.getLocation())  // Vec2 {x: , y:  }  全局坐标系位置
    let location = e.getLocation()
    // 全局 --转换成--> 相对于this.node
    let locationOfThisNode = this.node.convertToNodeSpaceAR(location)
    // 全局 --转换成--> 相对于this.node的父节点
    let locationOfThisNodeParent = this.node.parent.convertToNodeSpaceAR(location)
    // 赋值
    this.node.position = locationOfThisNodeParent
}

8. 预制体Prefab

步骤

  • 将要复制的节点拖到资源管理器
  • 声明预制体node5Prefab
  • 实例化该预制体instantiate
  • 将预制体添加到节点

// 浅拷贝

properties: {
    node5Prefab: cc.Prefab	// 声明
},
onLoad () {
    let node5Copy = cc.instantiate(this.node5Prefab) // 实例化(复制)
    this.node.addChild(node5Copy)	// 添加
}

9. 全局变量

  • window.xxx
onLoad () {
    window.globalVar = {
        hello: 'word'
    }
},
start () {
    console.log(globalVar)  //{hello: "word"}
}
  • require // global_module
let obj = {
    name: 'cc',
    age: 16
}
let str = 'string'
module.exports = {
    obj,
    str
}

// components
cc.Class({
    extends: cc.Component,

    properties: {
    },
    onLoad () {
        let global = require('global_module')
        console.log(global.str)	// string
    },
    start () {
    }
})
  • statics
let Component3 = cc.Class({
    extends: cc.Component,

    properties: {
    },
    statics: {
        statics3Num: 0
    },
    onLoad () {
        Component3.statics3Num ++
    },
    start () {
        console.log(Component3.statics3Num)
    }
});
  • addPersistRootNode
cc.Class({
    extends: cc.Component,

    properties: {
    },
    onLoad () {
        // 将this.node独立 (当前this.node的name为node3)
        cc.game.addPersistRootNode(this.node)
        // 获取该独立于场景的节点
        let node3 = cc.director.getScene().getChildByName('node3')
		// 移除
        // cc.game.removePersistRootNode(this.node)
        // 切换场景
        cc.director.loadScene('scene3')
    },
    start () {
    }
});
  • localStorage
cc.sys.localStorage.setItem('key', 'value')
cc.sys.localStorage.getItem('key')

10. 计时器

schedule

unschedule

scheduleOnce

onLoad () {
    this.schedule(this.timerCount, 1)   // 每一秒执行一次timerCount
    this.unschedule(this.timerCount)	// 停止
    this.scheduleOnce(this.timerCount)	// 回调延迟一帧

},
timerCount () {
    console.log(1)
},

11. 动画

步骤

  • 添加Animation组件
  • 添加Animation Clips 编辑动画
  • 选中Clip --> Add Property --> 拖拽图片 —> 选择WrapMode
  • 添加js组件
  • 创建 --> 声明动画 --> 拖拽节点( 赋值 )
  • 保存
  • 动画数据 获取
var anim = this.getComponent(cc.Animation);
// play 会返回关联的 AnimationState
var animState = anim.play('run');

// 或是直接获取
var animState = anim.getAnimationState('run');

动画信息

clip name speed duration time repeatCount wrapMode isPlaying isPaused frameRate

var anim = this.getComponent(cc.Animation);
var animState = anim.play('run')
// 获取动画的循环模式
var wrapMode = animState.wrapMode

循环

var animState = anim.play('run');
// 设置循环模式为 Normal
animState.wrapMode = cc.WrapMode.Normal;
// 设置循环模式为 Loop
animState.wrapMode = cc.WrapMode.Loop;
// 设置动画循环次数为2次
animState.repeatCount = 2;
// 设置动画循环次数为无限次
animState.repeatCount = Infinity;
动画事件
play stop pause resume(恢复播放) lastframe finished

实例

// 注册
animation.on('play', this.onPlay, this);
// 取消注册

animation.off('play', this.onPlay, this);
// 对单个 cc.AnimationState 注册回调

var anim1 = animation.getAnimationState('anim1');
anim1.on('lastframe', this.onLastFrame, this);

12. 碰撞

步骤

  • 添加碰撞组件

  • 编辑Group

  • 编辑js组件

  • 获取碰撞管理器 cc.director.getCollisionManager

  • 注册回调, 如果有碰撞则回调 manager.enabled = true

  • 碰撞函数 onCollisionEnter onCollisionStay onCollisionExit

cc.Class({
    extends: cc.Component,
    properties: {
    },
    onLoad () {
        // 获取碰撞管理器
        let manager = cc.director.getCollisionManager()
        // 注册回调, 如果有碰撞则回调
        manager.enabled = true
        // debug
        manager.enabledDebugDraw = true
        this.node.on('touchmove', this.onTouchMove, this)
    },
    onTouchMove (e) {
        console.log('move')
        this.node.position = 
            this.node.parent.convertToNodeSpaceAR(e.getLocation())
    },
    // 三个碰撞函数
    onCollisionEnter (other, self) {
        console.log('enter')
    },
    onCollisionStay (other, self) {
        console.log('stay')
    },
    onCollisionExit (other, self) {
        console.log('exit')
    }
})

13. 音乐音效

背景音乐

添加AudioSource组件 音效

声明

audio: {
    type: cc.AudioClip,
    default: null
}

播放

cc.audioEngine.play(audio)
// cc.audioEngine.play(audio, false, 0.2) // (audio, loop, volume)

14. 打包到微信小游戏

代码包问题

代码包超过4MB不能发布问题

  • 将打包生成的res文件放线上

  • 修改根目录下main.js里的资源导入路径

libraryPath: 'res/import' --> libraryPath: 'http://192.168.../res/import'
cc.AssetLibrary.init({
    libraryPath: 'http://192.168.../res/import',
    rawAssetsBase: 'http://192.168.../res/raw-',
    rawAssets: settings.rawAssets,
    packedAssets: settings.packedAssets,
    md5AssetsMap: settings.md5AssetsMap,
    subpackages: settings.subpackages
});