目录
1.加载场景
2.获取当前场景根节点
3.加载当前场景
4.获取所有子节点
5.获取某个子节点
6.拦截所有输入事件
6.1 监听键盘事件
6.2 监听鼠标事件
6.3 监听触摸事件
6.4 注意事项:
7.实例化物体
8.销毁物体
9.联合类型
10.显示隐藏物体
11. lable文本赋值
12.数据类型
13..将新建Node添加到场景中
14.标记为常驻节点,这样场景切换的时候就不会被销毁了
15.给node添加组件
16.音乐音效播放管理
17.对象池
18.随机整数
19.碰撞检测
20.本地存读档
20.1变量存读档
20.2 user类(玩家数据) 存读档
21.获取/设置node的坐标
22.运算符
22.1 算术运算符
应用于 number 类型:
应用于 string 类型:
应用于 boolean 类型:
22.2 比较运算符
应用于 number 类型:
应用于 string 类型:
应用于 boolean 类型:
22.3 总结
23.动画
23.1 Creator中常用的动画动作类:
23.2 node.runAction动画:
23.3 cc.tween动画:
23.4 自定义
24.变量注释
25.事件控制脚本
26.延迟指定时间(毫秒)
26.1 关于 setTimeout 的注意事项:
26.2 取消定时器
27.延迟指定时间(秒)
28.scheduleOnce 和 setTimeout 两个延迟执行的对比
28.1. 工作原理
28.2 延迟准确性
28.3 取消调度
28.4 target 参数
28.5总结
29. 预加载场景
30.碰撞检测
31.颜色设置
32.移除所有子物体
33.循环获取/查找
34.假值判定
35.lable动画
36.获取Node物体子组件
37.spine动画
37.1 物体换肤:
37.2 玩家骨骼控制器
1.加载场景
cc.director.loadScene("Game");
2.获取当前场景根节点
director.getScene().name
3.加载当前场景
director.loadScene(director.getScene().name);
4.获取所有子节点
const nodeArray = this.node.children;
5.获取某个子节点
let child1 = nodeList[0];
6.拦截所有输入事件
6.1 监听键盘事件
import { Node, director, input, EventKeyboard, KeyboardEvent } from 'cc';export default class InputManager extends Node { onLoad() {
// 添加键盘事件监听器
input.on(EventKeyboard.KEY_DOWN, this.onKeyDown, this);
input.on(EventKeyboard.KEY_UP, this.onKeyUp, this);
} onDestroy() {
// 移除键盘事件监听器
input.off(EventKeyboard.KEY_DOWN, this.onKeyDown, this);
input.off(EventKeyboard.KEY_UP, this.onKeyUp, this);
} onKeyDown(event: KeyboardEvent) {
console.log(`Key Down: ${event.keyCode}`);
} onKeyUp(event: KeyboardEvent) {
console.log(`Key Up: ${event.keyCode}`);
}
}
6.2 监听鼠标事件
import { Node, director, input, EventMouse, Mouse } from 'cc';export default class InputManager extends Node { onLoad() {
// 添加鼠标事件监听器
input.on(EventMouse.MOUSE_DOWN, this.onMouseDown, this);
input.on(EventMouse.MOUSE_UP, this.onMouseUp, this);
input.on(EventMouse.MOUSE_MOVE, this.onMouseMove, this);
} onDestroy() {
// 移除鼠标事件监听器
input.off(EventMouse.MOUSE_DOWN, this.onMouseDown, this);
input.off(EventMouse.MOUSE_UP, this.onMouseUp, this);
input.off(EventMouse.MOUSE_MOVE, this.onMouseMove, this);
} onMouseDown(event: Mouse) {
console.log(`Mouse Down: ${event.button}`);
} onMouseUp(event: Mouse) {
console.log(`Mouse Up: ${event.button}`);
} onMouseMove(event: Mouse) {
console.log(`Mouse Move: (${event.getLocationX()}, ${event.getLocationY()})`);
}
}
6.3 监听触摸事件
import { Node, director, input, EventTouch, Touch } from 'cc';export default class InputManager extends Node { onLoad() {
// 添加触摸事件监听器
input.on(EventTouch.TOUCH_START, this.onTouchStart, this);
input.on(EventTouch.TOUCH_END, this.onTouchEnd, this);
input.on(EventTouch.TOUCH_MOVE, this.onTouchMove, this);
} onDestroy() {
// 移除触摸事件监听器
input.off(EventTouch.TOUCH_START, this.onTouchStart, this);
input.off(EventTouch.TOUCH_END, this.onTouchEnd, this);
input.off(EventTouch.TOUCH_MOVE, this.onTouchMove, this);
} onTouchStart(event: Touch) {
console.log(`Touch Start: (${event.getLocationX()}, ${event.getLocationY()})`);
} onTouchEnd(event: Touch) {
console.log(`Touch End: (${event.getLocationX()}, ${event.getLocationY()})`);
} onTouchMove(event: Touch) {
console.log(`Touch Move: (${event.getLocationX()}, ${event.getLocationY()})`);
}
}
6.4 注意事项:
事件监听器的移除:
在 onDestroy 方法中移除所有注册的事件监听器是非常重要的,否则可能会导致内存泄漏。
事件优先级:
默认情况下,事件会传递到当前节点及其子节点。如果你想要拦截所有事件,可以考虑在 onTouchBegin 等方法中调用 event.stopPropagation() 来阻止事件传递。
全局事件监听器:
如果你希望在全局范围内捕获所有输入事件,可以考虑在主场景的根节点上添加一个专门用于处理输入事件的脚本。
7.实例化物体
const pipeInst = instantiate(this.pipePrefab);this.node.addChild(pipeInst);const p = this.node.getWorldPosition();pipeInst.setWorldPosition(p);const y = math.randomRangeInt(-100,200);const pLoca = pipeInst.getPosition();pipeInst.setPosition(pLoca.x,y);
8.销毁物体
this.node.destroy();
9.联合类型
@property({ type: Prefab })
pipePrefab: Prefab | null = null; // 预制体
如果不显式地设置默认值 = null,变量 pipePrefab 的初始值将是 undefined。但是,为了确保类型安全和编辑器支持,通常会显式地设置默认值为 null,即使 pipePrefab 在初始化时默认就是 null。
10.显示隐藏物体
this.node.active = true/false;
11. lable文本赋值
this.curScoreLabel.string = curScore.toString();
12.数据类型
number ==> 正负 整数、小数
字符串 ==> string
布尔 ==> boolean
音乐/音效 ==>AudioClip
刚体==> RigidBody2D
private rgd2D:RigidBody2D = null;
this.rgd2D = this.getComponent(RigidBody2D);
this.rgd2D.linearVelocity = new Vec2(0,10);
碰撞体==> Collider2D
物体==> Node
13..将新建Node添加到场景中
let node = new Node();node.name = '__newMgr__';director.getScene().addChild(node);
14.标记为常驻节点,这样场景切换的时候就不会被销毁了
director.addPersistRootNode(node);
15.给node添加组件
this._audioSource = node.addComponent(AudioSource);
16.音乐音效播放管理
import { events } from "./Events";
import { GameEvents } from "./EventConstants";
import { user } from "./User";/*** 音频组件*/
const { ccclass, property } = cc._decorator;// 音效
@ccclass('Sound')
export class Sound {@property({ type: cc.AudioClip })public audio: cc.AudioClip = null;@property({ type: cc.Float, tooltip: '音频音量' })public volume: number = 1;
}@ccclass
export default class SoundMgr extends cc.Component {@property(Sound)public soundMainBgm: Sound = null; // 背景音乐@property(Sound)public soundButton: Sound = null; // 按钮音效@property(Sound)public soundAward: Sound = null; // 奖励音效@property(Sound)public soundHandclap: Sound = null; // 鼓掌音效@property(Sound)public soundWhistle: Sound = null; // 吹哨音效@property(Sound)public soundRicochet: Sound = null; // 弹飞音效@property(Sound)public soundJump: Sound = null; // 起跳音效@property(Sound)public soundPerfect_01: Sound = null; // 完美1@property(Sound)public soundPerfect_02: Sound = null; // 完美2@property(Sound)public soundPerfect_03: Sound = null; // 完美3@property(Sound)public soundPerfect_04: Sound = null; // 完美4@property(Sound)public soundPerfect_05: Sound = null; // 完美5@property(Sound)public soundPerfect_06: Sound = null; // 完美6@property(Sound)public soundConformity: Sound = null; // 合格@property(Sound)public soundStagger: Sound = null; // 踉跄// 是否静音private isMute: boolean = false;// BGM idprivate bgmAudioId: number;private bgmPlaying: boolean = false;// 音效idprivate effectIds: any = [];private key: any = null;onLoad(): void {// 添加为全局节点cc.game.addPersistRootNode(this.node);this.initEvents();this.init();}onDestroy(): void {this.clearEvents();}private initEvents(): void {events.on(this.name, this.uuid, GameEvents.PLAY_BGM, this.playBGM, this);events.on(this.name, this.uuid, GameEvents.STOP_BGM, this.stopBGM, this);events.on(this.name, this.uuid, GameEvents.PLAY_SOUND_EFFECT, this.playSoundEffect, this);events.on(this.name, this.uuid, GameEvents.STOP_SOUND_EFFECT, this.stopEffect, this);events.on(this.name, this.uuid, GameEvents.SWITCH_MUTE, this.switchMute, this);events.on(this.name, this.uuid, GameEvents.STOP_ALL_SOUND_EFFECT, this.stopAllEffect, this);}private clearEvents(): void {events.removeListener(this.name, GameEvents.PLAY_BGM);events.removeListener(this.name, GameEvents.STOP_BGM);events.removeListener(this.name, GameEvents.SWITCH_BGM);events.removeListener(this.name, GameEvents.PLAY_SOUND_EFFECT);events.removeListener(this.name, GameEvents.STOP_SOUND_EFFECT);events.removeListener(this.name, GameEvents.SWITCH_MUTE);events.removeListener(this.name, GameEvents.STOP_ALL_SOUND_EFFECT);}private init(): void {this.isMute = user.getIsMute();}/*** 播放背景音乐* @private* @param {string} key* @returns*/private playBGM(key: string): void {// 如果KEY不相同则先暂停if (this.key && key != this.key) this.stopBGM();this.bgmPlaying = true;let bgm = this[key]if (this.isMute && typeof this.bgmAudioId !== 'number') {this.bgmAudioId = cc.audioEngine.play(bgm.audio as any, true, bgm.volume);this.key = key;}}/*** @private* 停止背景音乐*/private stopBGM(): void {this.bgmPlaying = false;if (this.isMute && typeof this.bgmAudioId === 'number') {cc.audioEngine.stop(this.bgmAudioId);cc.audioEngine.uncache(this.bgmAudioId as any);delete this.bgmAudioId;}}/*** @private* 播放音效剪辑,全局非静音且音效开关打开才会播*/private playSoundEffect(key: string, id?: any, loop?: boolean, cb?: Function): void {// step 1: 校验当前是否播放音效if (!this.isMute) return;// step 2: 校验音频剪辑是否存在let sound = this[key];if (!sound) return;if (typeof id === 'number')if (sound[id]) sound = sound[id];else return;if (!sound.audio) return;// step 3: 播放音效const effectId = cc.audioEngine.play(sound.audio, loop, sound.volume || 1);if (!this.effectIds) this.effectIds = [];this.effectIds.push({ key, effectId });// step 4: 检查回调if (loop) return;cc.audioEngine.setFinishCallback(effectId, () => {this.stopEffect(key);if (cb) cb();});}/*** 停止音效* @private* @param {string} key* @returns*/private stopEffect(key: string): void {const idx = this.effectIds.findIndex(data => key === data.key);if (idx != -1) {const effectId = this.effectIds[idx].effectIdcc.audioEngine.stop(effectId);cc.audioEngine.uncache(effectId as any);this.effectIds.splice(idx, 1);}}/*** 切换静音状态* @private* @returns*/private switchMute(): void {this.isMute = !this.isMute;if (!this.isMute) {cc.audioEngine.stopAll();cc.audioEngine.uncacheAll();delete this.bgmAudioId;this.effectIds = [];} else {// 播放背景音效if (this.bgmPlaying) this.playBGM(this.key || 'soundMainBgm');}}/*** 停止所有音效*/private stopAllEffect(): void {if (this.isMute) {cc.audioEngine.stopAll();cc.audioEngine.uncacheAll();delete this.bgmAudioId;this.effectIds = [];}}/*** 恢复所有音效*/private resumeAllEffect(): void {if (this.isMute) {if (this.bgmPlaying) this.playBGM(this.key);}}
}
17.对象池
import { _decorator, Component, instantiate, Node, Prefab } from 'cc';
import { Pipe } from './Pipe';
const { ccclass, property } = _decorator;@ccclass('PipePool')
export class PipePool extends Component
{@property(Prefab)private fab:Prefab;private static _inst:PipePool;private pool:Pipe[]=[];protected onLoad(): void {PipePool._inst = this;}public static inst = PipePool._inst;public GetPipe(parentNode:Node):Pipe{if(this.pool.length >0){const pipe = this.pool.pop()!;pipe.node.parent = parentNode; //重新关联父节点pipe.start(); //重新初始化pipe.node.active = true;return pipe;}else{const newNode = instantiate(this.fab)! as Node;const pipeComponent = newNode.getComponent(Pipe)!;pipeComponent.node = newNode;pipeComponent.node.parent = parentNode; // 设置父节点pipeComponent.start(); // 重新初始化return pipeComponent;}}public RecyclePipe(pipe:Pipe):void{pipe.node.setParent(this.node);pipe.node.setPosition(10000,10000);pipe.node.active = false; //隐藏this.pool.push(pipe);}
}
18.随机整数
const ranNum = math.randomRangeInt(-100,200);
19.碰撞检测
onLoad () {// 注册碰撞体的回调函数let collider = this.getComponent(Collider