目录
[1 UI系统](#1 UI系统)
[1.1 Canvas](#1.1 Canvas)
[1.2 Sprite组件](#1.2 Sprite组件)
[1.3 Label组件](#1.3 Label组件)
[1.4 Button组件](#1.4 Button组件)
[1.5 ProgressBar组件](#1.5 ProgressBar组件)
[1.6 ScrollView组件](#1.6 ScrollView组件)
[2 动画系统](#2 动画系统)
[2.1 Animation组件](#2.1 Animation组件)
[2.2 创建动画剪辑](#2.2 创建动画剪辑)
[2.3 动画事件](#2.3 动画事件)
[3 音频系统](#3 音频系统)
[3.1 AudioSource组件](#3.1 AudioSource组件)
[4 物理系统](#4 物理系统)
[4.1 物理组件](#4.1 物理组件)
[4.2 射线检测](#4.2 射线检测)
[5 网络系统](#5 网络系统)
[5.1 HTTP请求](#5.1 HTTP请求)
[5.2 WebSocket](#5.2 WebSocket)
[6 总结](#6 总结)
本文介绍了Cocos Creator 3.x的核心游戏开发系统,主要包括:UI系统(Canvas、Sprite、Label、Button、ProgressBar和ScrollView组件)、动画系统(Animation组件、动画剪辑创建和事件处理)、音频系统(AudioSource组件控制)、物理系统(2D物理组件、碰撞检测和射线检测)以及网络系统(HTTP请求和WebSocket通信)。
通过代码示例详细展示了各系统的使用方法,为开发者提供了完整的游戏开发基础框架参考。
1 UI系统
1.1 Canvas
Canvas是UI系统的根节点,所有UI元素都应该放在Canvas下。
import { _decorator, Component, Node, Canvas } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('CanvasExample')
export class CanvasExample extends Component {
start() {
// 获取Canvas组件
const canvas = this.node.getComponent(Canvas);
if (canvas) {
// 设置分辨率适配
canvas.alignCanvasWithScreen = true;
// 获取画布大小
const size = canvas.getCanvasSize();
console.log(`画布大小: ${size.width} x ${size.height}`);
}
}
}
1.2 Sprite组件
Sprite组件用于显示2D图片。
import { _decorator, Component, Node, Sprite, SpriteFrame } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('SpriteExample')
export class SpriteExample extends Component {
@property({ type: SpriteFrame })
public spriteFrame: SpriteFrame = null!;
start() {
// 获取Sprite组件
const sprite = this.node.getComponent(Sprite);
// 设置SpriteFrame
sprite.spriteFrame = this.spriteFrame;
// 设置渲染模式
sprite.type = Sprite.Type.SIMPLE;
// 设置颜色
sprite.color.set(255, 255, 255, 255);
}
}
Sprite渲染模式
// 普通模式
sprite.type = Sprite.Type.SIMPLE;
// 九宫格模式(适合UI按钮等可拉伸元素)
sprite.type = Sprite.Type.SLICED;
// 平铺模式
sprite.type = Sprite.Type.TILED;
// 填充模式(适合进度条等)
sprite.type = Sprite.Type.FILLED;
1.3 Label组件
Label组件用于显示文字。
import { _decorator, Component, Node, Label } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('LabelExample')
export class LabelExample extends Component {
start() {
const label = this.node.getComponent(Label);
// 设置文字内容
label.string = 'Hello, Cocos Creator!';
// 设置字体大小
label.fontSize = 24;
// 设置颜色
label.color.set(255, 0, 0, 255);
// 设置对齐方式
label.horizontalAlign = Label.HorizontalAlign.CENTER;
label.verticalAlign = Label.VerticalAlign.CENTER;
// 设置溢出处理
label.overflow = Label.Overflow.CLAMP;
// 设置是否换行
label.enableWrapText = true;
}
}
1.4 Button组件
Button组件用于响应用户点击。
import { _decorator, Component, Node, Button } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('ButtonExample')
export class ButtonExample extends Component {
@property({ type: Node })
public buttonNode: Node = null!;
start() {
const button = this.buttonNode.getComponent(Button);
// 设置按钮交互状态
button.interactable = true;
// 添加点击事件
button.clickEvents.push({
target: this.node,
component: 'ButtonExample',
handler: 'onButtonClick',
customEventData: 'custom data'
});
// 通过代码添加点击事件
this.buttonNode.on('click', this.onButtonClick, this);
}
onButtonClick(event: any, customData?: string) {
console.log('按钮被点击!');
console.log('自定义数据:', customData);
}
}
Button过渡效果
import { _decorator, Component, Node, Button } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('ButtonTransition')
export class ButtonTransition extends Component {
start() {
const button = this.node.getComponent(Button);
// 设置过渡类型
button.transition = Button.Transition.COLOR;
// 设置不同状态的颜色
const colorBlock = button.color;
colorBlock.normal = new Color(255, 255, 255, 255);
colorBlock.pressed = new Color(200, 200, 200, 255);
colorBlock.hover = new Color(230, 230, 230, 255);
colorBlock.disabled = new Color(100, 100, 100, 255);
button.color = colorBlock;
}
}
1.5 ProgressBar组件
ProgressBar组件用于显示进度。
import { _decorator, Component, Node, ProgressBar } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('ProgressBarExample')
export class ProgressBarExample extends Component {
@property({ type: Node })
public progressBarNode: Node = null!;
private progressBar: ProgressBar | null = null;
private currentProgress: number = 0;
start() {
this.progressBar = this.progressBarNode.getComponent(ProgressBar);
// 设置进度范围
this.progressBar.totalLength = 100;
this.progressBar.progress = 0;
// 设置方向
this.progressBar.direction = ProgressBar.Direction.LEFT_TO_RIGHT;
// 开始加载动画
this.startLoading();
}
startLoading() {
const interval = setInterval(() => {
this.currentProgress += 5;
if (this.progressBar) {
this.progressBar.progress = this.currentProgress / 100;
}
if (this.currentProgress >= 100) {
clearInterval(interval);
console.log('加载完成!');
}
}, 100);
}
}
1.6 ScrollView组件
ScrollView组件用于滚动显示内容。
import { _decorator, Component, Node, ScrollView, Label } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('ScrollViewExample')
export class ScrollViewExample extends Component {
@property({ type: Node })
public scrollViewNode: Node = null!;
@property({ type: Node })
public contentNode: Node = null!;
start() {
const scrollView = this.scrollViewNode.getComponent(ScrollView);
// 设置滚动方向
scrollView.horizontal = false;
scrollView.vertical = true;
// 设置回弹效果
scrollView.bounceEnabled = true;
// 设置惯性滚动
scrollView.inertia = true;
// 添加列表项
this.createListItems();
}
createListItems() {
for (let i = 0; i < 20; i++) {
const itemNode = new Node(`Item_${i}`);
const label = itemNode.addComponent(Label);
label.string = `列表项 ${i + 1}`;
label.fontSize = 24;
// 设置位置
itemNode.setPosition(0, -i * 50, 0);
// 添加到content节点
itemNode.parent = this.contentNode;
}
// 更新content大小
this.contentNode.setContentSize(400, 20 * 50);
}
}
2 动画系统
2.1 Animation组件
Animation组件用于播放动画剪辑。
import { _decorator, Component, Node, Animation } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('AnimationExample')
export class AnimationExample extends Component {
@property({ type: Node })
public animatedNode: Node = null!;
private animation: Animation | null = null;
start() {
this.animation = this.animatedNode.getComponent(Animation);
if (this.animation) {
// 播放动画
this.animation.play('walk');
// 设置循环模式
const state = this.animation.getState('walk');
if (state) {
state.wrapMode = Animation.WrapMode.Loop;
}
}
}
playAnimation() {
if (this.animation) {
// 播放指定动画
this.animation.play('jump');
// 播放下一个动画
this.animation.playNext();
}
}
pauseAnimation() {
if (this.animation) {
this.animation.pause();
}
}
resumeAnimation() {
if (this.animation) {
this.animation.resume();
}
}
stopAnimation() {
if (this.animation) {
this.animation.stop();
}
}
}
2.2 创建动画剪辑
import { _decorator, Component, Node, AnimationClip, animation } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('CreateAnimation')
export class CreateAnimation extends Component {
start() {
// 创建动画剪辑
const clip = new AnimationClip();
clip.name = 'custom_animation';
clip.duration = 1; // 1秒
clip.sample = 30; // 30帧/秒
// 创建曲线
const curve = new animation.BasicCurve();
// 添加关键帧(位置动画)
const positions: number[] = [];
const times: number[] = [];
times.push(0);
positions.push(0, 0, 0); // 起始位置
times.push(0.5);
positions.push(100, 100, 0); // 中间位置
times.push(1);
positions.push(0, 0, 0); // 结束位置
curve.keys = times;
curve.values = positions;
// 设置曲线目标
clip.addCurve('position', curve);
// 添加到Animation组件
const animation = this.node.getComponent(Animation);
if (animation) {
animation.addClip(clip);
animation.play('custom_animation');
}
}
}
2.3 动画事件
import { _decorator, Component, Node, Animation } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('AnimationEvent')
export class AnimationEvent extends Component {
start() {
const animation = this.node.getComponent(Animation);
if (animation) {
// 监听动画事件
animation.on(Animation.EventType.FINISHED, this.onAnimationFinished, this);
animation.on(Animation.EventType.LOOP, this.onAnimationLoop, this);
// 监听特定动画状态
const state = animation.getState('attack');
if (state) {
state.on('frame', this.onFrame, this);
}
}
}
onAnimationFinished(type: Animation.EventType, state: any) {
console.log('动画播放完成:', state.name);
}
onAnimationLoop(type: Animation.EventType, state: any) {
console.log('动画循环:', state.name);
}
onFrame(frame: number, state: any) {
console.log(`当前帧: ${frame}`);
}
}
3 音频系统
3.1 AudioSource组件
AudioSource组件用于播放音频。
import { _decorator, Component, Node, AudioSource, AudioClip } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('AudioExample')
export class AudioExample extends Component {
@property({ type: AudioClip })
public bgmClip: AudioClip = null!;
@property({ type: AudioClip })
public sfxClip: AudioClip = null!;
private audioSource: AudioSource | null = null;
start() {
// 获取AudioSource组件
this.audioSource = this.node.getComponent(AudioSource);
if (!this.audioSource) {
// 如果没有,添加一个
this.audioSource = this.node.addComponent(AudioSource);
}
// 播放背景音乐
this.playBGM();
}
playBGM() {
if (this.audioSource) {
this.audioSource.clip = this.bgmClip;
this.audioSource.loop = true;
this.audioSource.volume = 0.5;
this.audioSource.play();
}
}
playSFX() {
// 创建临时AudioSource播放音效
const tempNode = new Node('TempAudio');
const tempSource = tempNode.addComponent(AudioSource);
tempSource.clip = this.sfxClip;
tempSource.loop = false;
tempSource.volume = 0.8;
tempSource.play();
// 播放完成后销毁临时节点
setTimeout(() => {
tempNode.destroy();
}, this.sfxClip.duration * 1000);
}
stopAudio() {
if (this.audioSource) {
this.audioSource.stop();
}
}
pauseAudio() {
if (this.audioSource) {
this.audioSource.pause();
}
}
resumeAudio() {
if (this.audioSource) {
this.audioSource.resume();
}
}
}
4 物理系统
4.1 物理组件
Cocos Creator 3.x提供了完整的2D和3D物理系统。
2D物理组件
import { _decorator, Component, Node, RigidBody2D, Collider2D, PhysicsSystem2D } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('Physics2DExample')
export class Physics2DExample extends Component {
@property({ type: Node })
public playerNode: Node = null!;
start() {
// 获取刚体组件
const rigidBody = this.playerNode.getComponent(RigidBody2D);
if (rigidBody) {
// 设置质量
rigidBody.mass = 1;
// 设置重力缩放
rigidBody.gravityScale = 1;
// 设置是否受重力影响
rigidBody.gravityScale = 1;
// 设置速度
rigidBody.linearVelocity = new Vec2(100, 200);
// 设置角速度
rigidBody.angularVelocity = 0;
// 设置是否允许旋转
rigidBody.fixedRotation = true;
}
// 开启物理系统
PhysicsSystem2D.instance.enable = true;
// 设置重力
PhysicsSystem2D.instance.gravity = new Vec2(0, -100);
}
}
碰撞检测
import { _decorator, Component, Node, Collider2D, Contact2DType } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('CollisionDetection')
export class CollisionDetection extends Component {
onLoad() {
const collider = this.node.getComponent(Collider2D);
if (collider) {
// 监听碰撞事件
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
collider.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
collider.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
}
}
onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D) {
console.log(`开始碰撞: ${otherCollider.node.name}`);
// 检查碰撞对象标签
if (otherCollider.node.tag === 1) {
console.log('碰到了敌人!');
}
}
onEndContact(selfCollider: Collider2D, otherCollider: Collider2D) {
console.log(`结束碰撞: ${otherCollider.node.name}`);
}
onPreSolve(selfCollider: Collider2D, otherCollider: Collider2D) {
console.log('碰撞前处理');
}
onPostSolve(selfCollider: Collider2D, otherCollider: Collider2D) {
console.log('碰撞后处理');
}
}
4.2 射线检测
import { _decorator, Component, Node, PhysicsSystem2D, Vec2 } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('RaycastExample')
export class RaycastExample extends Component {
start() {
// 射线检测
const start = new Vec2(0, 0);
const end = new Vec2(100, 100);
const results = PhysicsSystem2D.instance.raycast(start, end);
if (results.length > 0) {
console.log(`检测到 ${results.length} 个碰撞`);
for (const result of results) {
console.log(`碰撞对象: ${result.collider.node.name}`);
console.log(`碰撞点: ${result.point}`);
}
}
}
}
5 网络系统
5.1 HTTP请求
import { _decorator, Component, Node } from 'cc';
import { HttpRequest } from 'cc/net';
const { ccclass, property } = _decorator;
@ccclass('HttpExample')
export class HttpExample extends Component {
async fetchData() {
try {
// GET请求
const response = await HttpRequest.get('https://api.example.com/data');
console.log('GET响应:', response);
// POST请求
const postData = {
username: 'player1',
score: 100
};
const postResponse = await HttpRequest.post('https://api.example.com/save', postData);
console.log('POST响应:', postResponse);
} catch (error) {
console.error('请求失败:', error);
}
}
}
5.2 WebSocket
import { _decorator, Component, Node } from 'cc';
import { WebSocket } from 'cc/net';
const { ccclass, property } = _decorator;
@ccclass('WebSocketExample')
export class WebSocketExample extends Component {
private ws: WebSocket | null = null;
connect() {
// 创建WebSocket连接
this.ws = new WebSocket('wss://game.example.com/ws');
// 监听连接事件
this.ws.onOpen(() => {
console.log('WebSocket连接成功');
// 发送消息
this.ws?.send(JSON.stringify({
type: 'join',
room: 'game1'
}));
});
// 监听消息
this.ws.onMessage((event: any) => {
const data = JSON.parse(event.data);
console.log('收到消息:', data);
// 处理消息
this.handleMessage(data);
});
// 监听错误
this.ws.onError((error: any) => {
console.error('WebSocket错误:', error);
});
// 监听关闭
this.ws.onClose((code: number, reason: string) => {
console.log(`WebSocket关闭: ${code} - ${reason}`);
});
// 连接
this.ws.connect();
}
handleMessage(data: any) {
switch (data.type) {
case 'joinSuccess':
console.log('加入房间成功');
break;
case 'gameStart':
console.log('游戏开始');
break;
case 'update':
console.log('游戏状态更新:', data.state);
break;
}
}
sendMessage(message: any) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
}
}
disconnect() {
this.ws?.close();
}
}
6 总结
通过本章的学习,你应该掌握了:
-
UI系统的核心组件(Sprite、Label、Button、ProgressBar、ScrollView)
-
动画系统的使用(Animation组件、动画剪辑、动画事件)
-
音频系统的使用(AudioSource组件)
-
物理系统的基本操作(刚体、碰撞检测、射线检测)
-
网络系统的使用(HTTP请求、WebSocket)
这些子系统构成了Cocos Creator 3.x游戏开发的基础,掌握它们可以帮助你开发出功能丰富的游戏。