尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Cocos Creator入门指南:从场景构建到脚本编程与物理碰撞

Cocos Creator入门指南:从场景构建到脚本编程与物理碰撞 1. 从零到一理解Cocos Creator的核心工作流很多刚接触Cocos Creator的朋友打开编辑器后可能会有点懵这么多面板我该从哪里开始这一章我们就来彻底搞懂这个“数字工坊”的运作逻辑。Cocos Creator的核心是一个高度集成的可视化编辑与代码驱动相结合的工作流。你可以把它想象成一个乐高工厂场景编辑器是你的组装台资源管理器是你的零件库属性检查器是你的零件规格说明书而控制台和动画编辑器则是你的调试和美化工具。这个工作流的核心是“场景-节点-组件”的树状结构。一个游戏世界就是一个场景场景里的一切物体无论是主角、敌人、一颗树还是一段背景音乐都是一个节点。节点本身只是一个空壳它的所有能力都来自于挂载在它身上的组件。比如一个精灵组件让节点能显示图片一个刚体组件让它具备物理特性一个你自己写的脚本组件则赋予它独特的游戏逻辑。这种设计哲学让游戏对象的构建变得像搭积木一样灵活。理解这一点至关重要因为它决定了你思考问题的方式。当你想实现“角色碰到金币会消失并加分”这个功能时你不会去凭空写一段代码而是会分解为在角色节点上挂一个碰撞检测组件如Box Collider在金币节点上也挂一个然后分别编写或使用脚本来处理碰撞事件。这种组件化的思维是现代游戏引擎尤其是Cocos Creator和Unity这类引擎的基石。注意新手最容易犯的错误就是试图把所有逻辑都写在一个巨大的脚本里。请务必养成“一个节点一类职责”的习惯。移动的逻辑放在PlayerController.js里攻击的逻辑放在Weapon.js里UI更新的逻辑放在UIManager.js里。这样代码才清晰、易维护也便于在编辑器里灵活配置。2. 场景构建打造你的第一个游戏世界理论说再多不如动手做。让我们创建一个最简单的场景一个可控制的角色在平面上移动并收集物品。2.1 资源导入与节点创建首先你需要准备资源。将你的角色图片如player.png、背景图、金币图片拖拽到编辑器下方的资源管理器面板中。Cocos Creator支持常见的图片、声音、字体等格式它会自动导入并生成对应的资源引用。接着在场景编辑器中右键点击“场景”层级管理器中的Canvas节点选择“创建节点” - “创建渲染节点” - “Sprite”。将这个节点重命名为Player。然后在右侧的属性检查器中找到Sprite组件的Sprite Frame属性点击旁边的小圆点选择你刚刚导入的player.png。看你的角色就出现在场景里了。用同样的方法创建几个Coin节点作为可收集物。你还可以创建一个Background节点将背景图拖给它并调整它的层级在属性检查器中修改Layer或直接拖拽层级管理器中的顺序确保背景在最下面。2.2 组件挂载与基础属性设置节点创建好了但现在的Player只是一个静态图片。我们需要让它动起来。选中Player节点点击属性检查器下方的“添加组件”按钮选择“用户脚本组件” - “新建组件”命名为PlayerController。这时编辑器会自动在你的项目脚本目录下生成一个PlayerController.ts或.js文件。双击这个文件会打开代码编辑器。我们先实现一个最简单的键盘移动逻辑import { _decorator, Component, input, Input, KeyCode, Vec3 } from cc; const { ccclass, property } _decorator; ccclass(PlayerController) export class PlayerController extends Component { // 移动速度可以在编辑器里调整 property public moveSpeed: number 200; start() { // 注册键盘按下事件 input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this); } onKeyDown(event: any) { const pos this.node.position; switch(event.keyCode) { case KeyCode.KEY_A: case KeyCode.ARROW_LEFT: this.node.setPosition(pos.x - this.moveSpeed, pos.y, pos.z); break; case KeyCode.KEY_D: case KeyCode.ARROW_RIGHT: this.node.setPosition(pos.x this.moveSpeed, pos.y, pos.z); break; case KeyCode.KEY_W: case KeyCode.ARROW_UP: this.node.setPosition(pos.x, pos.y this.moveSpeed, pos.z); break; case KeyCode.KEY_S: case KeyCode.ARROW_DOWN: this.node.setPosition(pos.x, pos.y - this.moveSpeed, pos.z); break; } } onDestroy() { // 记得在组件销毁时取消事件监听防止内存泄漏 input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this); } }保存代码回到Cocos Creator编辑器你会发现PlayerController组件上多了一个Move Speed的可调节属性。这就是property装饰器的作用它将脚本中的变量暴露给编辑器让你可以不用改代码就能调整游戏参数这是非常强大的工作流。2.3 坐标系与节点变换在移动角色时你操作的是节点的position属性。Cocos Creator使用一个笛卡尔右手坐标系X轴向右Y轴向上Z轴从屏幕里指向外用于层级。所有变换位置、旋转、缩放都是相对于父节点的。如果Player节点是Canvas的子节点那么它的位置就是相对于Canvas原点的。理解局部坐标和世界坐标的区别很重要。node.position获取的是局部坐标。如果你需要知道它在整个场景中的位置世界坐标需要使用node.worldPosition。在进行UI布局或复杂对象层次结构计算时这个概念会经常用到。3. 脚本编程为游戏注入灵魂脚本是游戏逻辑的载体。Cocos Creator支持TypeScript和JavaScript我强烈推荐使用TypeScript它的类型系统能在开发阶段就帮你发现很多潜在错误大大提升开发效率和代码质量。3.1 生命周期函数脚本的脉搏每个组件脚本都有一系列由引擎自动调用的生命周期函数理解它们的执行顺序是编写稳定脚本的关键onLoad: 组件首次激活时调用早于start。通常用于初始化一些需要早于start执行的变量或查找节点。start: 在组件第一次激活前也就是第一次执行update之前调用。通常用于初始化需要依赖其他组件或数据的逻辑。我们上面的键盘事件注册就放在这里。update: 每一帧渲染前调用帧率取决于游戏运行速度。所有与时间相关的连续变化如移动、动画都应该放在这里。我们之前的键盘移动例子其实有缺陷因为它只在按键瞬间移动而不是持续移动。更好的做法是update(deltaTime: number) { // deltaTime是上一帧到当前帧的时间间隔用于保证在不同帧率下移动速度一致 let moveDir Vec3.ZERO; if (input.getKey(KeyCode.KEY_A)) moveDir.x - 1; if (input.getKey(KeyCode.KEY_D)) moveDir.x 1; if (input.getKey(KeyCode.KEY_W)) moveDir.y 1; if (input.getKey(KeyCode.KEY_S)) moveDir.y - 1; moveDir.normalize(); // 归一化避免斜向移动更快 const moveStep moveDir.multiplyScalar(this.moveSpeed * deltaTime); this.node.position this.node.position.add(moveStep); }lateUpdate: 在所有update函数执行完毕后调用。常用于跟随相机、或需要在所有对象移动后再执行的逻辑。onDestroy: 组件或节点被销毁时调用。用于清理工作如取消事件监听、释放资源。3.2 常用模块与API实战Cocos Creator的API非常丰富这里介绍几个最核心的模块cc命名空间v3.x之前或模块化导入v3.xv3.0之后Cocos Creator全面转向ES Module模块化导入就像我们上面代码中的import { Component, input, Input, KeyCode, Vec3 } from cc。你需要什么就导入什么这有利于代码摇树优化。节点与组件操作this.node: 当前脚本所属的节点。this.getComponent(PlayerController): 获取当前节点上挂载的某个组件。this.node.getComponentInChildren/this.node.getComponentInParent: 在子节点或父节点中查找组件。this.node.addComponent(PlayerController): 动态添加组件。this.node.destroy(): 销毁节点。资源动态加载不要把所有资源都预先放在场景里。对于大量或不确定的资源需要动态加载。import { resources, SpriteFrame } from cc; // 加载resources目录下的图片 resources.load(textures/player, SpriteFrame, (err, spriteFrame) { if (err) { console.error(err); return; } this.getComponent(Sprite).spriteFrame spriteFrame; });3.3 通信与事件系统让节点“对话”游戏中的对象需要交互。比如角色碰到金币金币要通知游戏管理器“我被打分了”。有几种常见的通信方式直接引用最简单但不灵活。在PlayerController里获取GameManager组件的引用。// PlayerController.ts property(GameManager) // 通过编辑器拖拽赋值 public gameManager: GameManager null; // 碰撞后 this.gameManager.addScore(10);查找节点通过节点路径查找。const gameManagerNode find(Canvas/GameManager); const comp gameManagerNode.getComponent(GameManager);全局事件系统最推荐的方式解耦彻底。Cocos Creator内置了EventTarget系统。// GameManager.ts (事件监听方) import { EventTarget } from cc; const eventTarget new EventTarget(); // 监听自定义事件 eventTarget.on(add-score, (score: number) { this.totalScore score; }, this); // Coin.ts (事件发射方) // 碰撞后发射事件 eventTarget.emit(add-score, 10);通常我们会创建一个单例的全局事件管理器来统一管理所有自定义事件。4. 物理与碰撞让世界互动起来没有物理和碰撞游戏世界就是一堆互不干扰的图片。Cocos Creator内置了基于Box2D的2D物理系统3.0版本也集成了Bullet物理引擎用于3D。4.1 物理组件与刚体要让节点参与物理模拟必须为它添加刚体组件。2D刚体主要是RigidBody2D。刚体类型有三种Static静态刚体质量无限大不受力影响通常用于地面、墙壁。Dynamic动态刚体完全受物理引擎控制会受力、碰撞、反弹。Kinematic运动学刚体不受力影响但可以通过速度或位置移动常用于平台、电梯或由玩家直接控制需谨慎处理碰撞。为你的Player和Coin节点都添加RigidBody2D组件。Player可以设为Kinematic因为我们用脚本控制移动Coin设为Static。然后为它们添加碰撞体组件如BoxCollider2D矩形碰撞体或CircleCollider2D圆形碰撞体并调整大小使其贴合图片。4.2 碰撞与触发检测物理交互分为两种碰撞和触发。碰撞两个碰撞体会发生物理相互作用如反弹、阻挡。需要双方都有刚体。触发一个碰撞体穿过另一个只检测到接触事件不发生物理阻挡。只需将碰撞体组件的Is Trigger属性勾选上。我们需要检测玩家碰到金币。由于我们不希望玩家和金币发生物理阻挡而是直接穿过并收集所以将Coin的BoxCollider2D设为Trigger。然后在PlayerController脚本中监听触发事件import { Collider2D, Contact2DType, IPhysics2DContact } from cc; onLoad() { // 获取碰撞体组件 const collider this.getComponent(Collider2D); if (collider) { // 注册触发回调 collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); } } onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) { // 判断碰到的是不是金币 if (otherCollider.node.name.includes(Coin)) { console.log(收集到金币); // 发射得分事件 eventTarget.emit(add-score, 10); // 销毁金币节点 otherCollider.node.destroy(); } }4.3 物理材质与调试你可能会发现角色移动有点“滑”或者碰撞反弹很奇怪。这时就需要调整物理材质。在碰撞体组件的Material属性中可以设置摩擦力和弹性系数恢复系数。摩擦力为0时表面绝对光滑为1时摩擦很大。弹性为0时碰撞无反弹为1时完全弹性碰撞。调试物理时可以点击编辑器场景上方的“物理调试”按钮这样就能在运行时看到所有碰撞体的轮廓线非常直观。实操心得物理引擎的参数调节是个细活尤其是摩擦力和弹性。建议先从一个简单的场景开始测试记录下一组感觉不错的参数作为基准。另外对于移动平台手机物理模拟的步长和迭代次数会影响性能和稳定性如果发现物理表现怪异或性能低下可以尝试在项目设置-物理中调整这些参数。5. 动画系统让角色活灵活现动画分为两种序列帧动画和骨骼动画。Cocos Creator对两者都有很好的支持。5.1 创建与播放序列帧动画序列帧动画就是将一系列图片快速连续播放形成动画。首先你需要准备一套动作的序列图片如run_01.png,run_02.png, ...。在资源管理器中选中所有这些图片。右键选择“创建” - “动画剪辑”。这会生成一个.anim文件。选中你的Player节点在属性检查器中点击“添加组件” - “Animation”。将刚才创建的.anim文件拖拽到Animation组件的Clips属性栏里。在脚本中控制播放const animation this.getComponent(Animation); animation.play(run); // 播放名为‘run’的动画剪辑你还可以在动画编辑器中精细调整这个动画剪辑点击.anim文件下方会打开动画编辑器。你可以在这里添加属性轨道如改变节点位置、旋转、缩放、颜色等创建更复杂的关键帧动画而不仅仅是切换图片。5.2 动画状态机管理复杂动作当角色有 idle待机、run跑、jump跳等多个动画时手动在代码里切换play会很混乱。这时就需要动画状态机。确保节点上有Animation组件。在动画编辑器中切换到“动画图”模式。你可以创建多个状态State每个状态关联一个动画剪辑如idle.anim, run.anim。然后创建条件Conditions和转换Transitions来定义状态之间何时切换。例如可以创建一个布尔型参数IsRunning当它为true时从idle状态转换到run状态。在脚本中你只需要控制这些参数状态机会自动处理动画的切换和融合。const animationController this.getComponent(AnimationController); // 这是一个用于控制状态机的组件 animationController.setValue(IsRunning, true); // 触发跑步动画动画状态机能极大简化复杂角色动画的逻辑让美术和策划也能参与调整是制作角色动画的必备工具。6. UI系统构建游戏界面游戏离不开UI。Cocos Creator的UI系统基于节点和组件与游戏场景一脉相承学习成本低。6.1 基础UI组件与应用创建一个UI通常从Canvas节点开始编辑器默认创建。在Canvas下创建UI节点常用的有Widget对齐挂件这不是一个可见组件而是一个用于自动布局的工具。挂上它你可以设置节点相对于父节点的边距、水平/垂直对齐方式。当屏幕尺寸变化时Widget能帮你自动调整位置是实现多分辨率适配的利器。Sprite显示图片用于图标、背景图等。Label显示文本。可以设置字体、大小、颜色、描边、阴影等。Button按钮。它本身是一个节点通常包含一个背景Sprite和一个子文本节点Label。你可以为它的“点击”、“按下”、“抬起”等状态设置不同的图片或颜色。EditBox输入框。Layout布局组件可以自动排列其子节点支持水平、垂直、网格布局。6.2 多分辨率适配策略这是移动游戏开发永远的课题。Cocos Creator提供了强大的适配工具。Canvas组件选中Canvas节点看它的Canvas组件。Design Resolution是你设计UI时使用的分辨率如1920x1080。Fit Height和Fit Width决定了在不同屏幕比例下如何缩放和裁剪。Fit Height保持设计高度不变宽度可能超出或不足。适合高度方向内容重要的游戏如竖屏跑酷。Fit Width保持设计宽度不变高度可能超出或不足。适合宽度方向内容重要的游戏如横屏射击。SHOW_ALL等比例缩放全部显示屏幕边缘可能有黑边。FIXED_WIDTH / FIXED_HEIGHT固定宽或高另一边适配。Widget对齐挂件这是实现元素精确定位的关键。比如一个“返回按钮”需要始终在左上角你可以给它添加Widget设置Top和Left为20像素并勾选对应的对齐选项。这样无论屏幕多大它距离左上角都是20像素。使用锚点每个节点都有锚点它决定了节点自身的定位参考点。比如锚点在(0.5, 0.5)即中心那么节点的位置就是其中心点所在的位置。将按钮的锚点设为(0.5, 1)位置设为(0, -50)它就会在父节点的顶部居中并向下偏移50像素。我的常用策略是选择Fit Height或Fit Width作为基础策略然后对每一个UI元素仔细思考它在不同屏幕下应该如何表现是固定边距、居中、还是按比例缩放并灵活运用Widget和锚点来实现。对于背景图可能需要准备不同长宽比的版本或者使用“九宫格”拉伸来避免变形。7. 数据存储与音频管理7.1 使用LocalStorage持久化数据玩家得分、设置、解锁关卡等数据需要保存到本地。浏览器环境或小游戏平台可以使用localStorageCocos Creator对其进行了封装使用sys.localStorage。// 保存数据 sys.localStorage.setItem(highScore, this.highScore.toString()); // 读取数据 const score sys.localStorage.getItem(highScore); this.highScore score ? parseInt(score) : 0;注意localStorage存储的是字符串。存储对象或数组需要先用JSON.stringify()序列化读取时用JSON.parse()解析。同时它不是加密的不适合存储敏感信息。7.2 音频的加载、播放与控制声音是游戏体验的重要组成部分。Cocos Creator的音频系统使用AudioSource组件。背景音乐通常需要一个常驻节点如AudioManager来管理。为其添加AudioSource组件将背景音乐文件拖入Clip属性。在脚本中调用this.audioSource.play()即可循环播放。音效对于大量、频繁播放的音效如射击声、跳跃声使用音频池是更高效的方式可以避免频繁创建销毁组件带来的性能开销。Cocos Creator的AudioEngine模块提供了更底层的控制。import { AudioEngine } from cc; // 预加载音效 const audioID AudioEngine.load(sounds/jump); // 播放音效可以同时播放多个 AudioEngine.play(audioID); // 停止播放 AudioEngine.stop(audioID);音量控制可以通过AudioEngine.setVolume()设置全局或指定音频的音量。通常会在设置界面提供滑块来控制bgmVolume和sfxVolume并将这些值保存到localStorage。8. 项目构建与发布游戏做完了最后一步就是打包发布。Cocos Creator支持一键构建到多个平台。8.1 构建流程详解点击编辑器顶部菜单的“项目” - “构建发布”会打开构建面板。选择发布平台Web Mobile、Android、iOS、Windows等。配置构建参数主包压缩类型选择default或mini-game小游戏平台。合并所有JSON。MD5 Cache给生成的文件名加上MD5戳用于打破浏览器缓存建议开发时关闭发布时开启。Source Maps用于调试压缩后的JavaScript代码发布版本应关闭。调试模式发布版本关闭。配置原生平台如Android需要安装对应的SDK/NDK构建面板有指引。填写应用标识包名如com.mycompany.mygame。选择目标API级别和应用版本名称。点击“构建”。构建完成后点击“运行”可以在模拟器或真机上预览。8.2 不同平台的注意事项与优化Web平台注意首次加载速度。合理使用“资源分包”功能将首屏不需要的资源放到后续加载。启用“资源服务器地址”配置CDN。微信小游戏平台有严格的包体大小限制通常4M/8M首包。必须使用资源分包将大部分资源放到远程服务器或子包中。同时小游戏的API登录、支付、分享等需要调用微信提供的wx.xxx接口Cocos Creator提供了适配层但代码需要做条件编译。Android/iOS图标与启动图在构建面板的“原生平台”选项里仔细配置各个分辨率的图标和启动图。权限在project.json或构建面板中配置应用所需的权限如网络、振动、存储。性能发布前务必在真机上进行性能测试。注意Draw Call渲染批次数量、内存使用、CPU占用。可以使用Cocos Creator自带的性能分析器。构建发布不是最后一步而是一个持续的过程。建立自动化的构建流水线每次提交代码后自动打包并分发到测试环境能极大提升团队效率。9. 常见问题与调试技巧实录开发过程中你一定会遇到各种“坑”。这里记录一些高频问题和我的排查思路。9.1 资源加载失败现象图片显示为粉色方块或控制台报错“Failed to load resource”。检查路径代码中resources.load的路径是相对于assets/resources目录的。确认文件是否在正确目录下。检查格式和名称文件名不要有中文或特殊字符。图片格式是否被支持PNG, JPG, WebP等。检查资源依赖如果使用图集Auto Atlas确保精灵帧是从图集中引用的而不是直接引用原始图片。9.2 脚本不执行或报错现象代码改了但没效果或者运行时控制台报红。检查组件是否挂载确保脚本已经成功挂载到目标节点上并且节点处于激活状态。检查控制台错误Cocos Creator的控制台底部面板会显示详细的JavaScript/TypeScript错误堆栈。根据错误信息定位代码行。使用Debugger在浏览器中运行游戏Web平台按F12打开开发者工具在“Sources”面板找到你的TypeScript源码可以设置断点进行单步调试这是最强大的调试手段。9.3 物理表现异常现象物体穿模、下坠过快、碰撞没反应。开启物理调试点击场景编辑器上方的“物理调试”按钮可视化查看碰撞体形状和刚体状态。检查碰撞体大小和位置碰撞体是否完全覆盖了可见的精灵它们的Offset偏移和Size是否正确检查刚体类型动态刚体是否设置了质量静态刚体是否意外被设置了速度检查碰撞分组在“项目设置” - “物理” - “碰撞矩阵”中确认你希望碰撞的图层是否已经勾选上。9.4 UI显示错乱或点击无效现象UI在不同屏幕上位置不对或者按钮点不到。检查Canvas适配策略确认Fit Height/Width是否符合你的设计预期。善用Widget对于需要精确定位的UI元素务必添加Widget组件并设置对齐和边距。检查层级按钮是否被其他更大的UI元素如图片覆盖了检查节点在层级管理器中的顺序以及Layer设置。检查节点尺寸按钮的碰撞区域通常就是节点本身的大小是否足够大有时图片透明部分很大但实际可点区域需要调整节点尺寸。9.5 性能问题排查现象游戏卡顿帧率低。打开Stats面板在浏览器中运行按CtrlShiftP打开Cocos Creator调试菜单搜索“Stats”可以显示实时帧率、Draw Call数量、三角形数量等。分析Draw CallDraw Call过高是Web和移动端性能的主要杀手。使用合图Auto Atlas将大量小图打包成一张大图可以显著降低Draw Call。确保静态UI元素和背景等可以合并。检查内存泄漏频繁创建和销毁节点而不释放资源会导致内存增长。使用浏览器的“Memory”快照功能对比游戏运行前后的内存占用查找未被释放的对象。特别注意事件监听、定时器、动态加载的资源是否在适当的时候被清理了。开发就是一个不断遇到问题、解决问题的过程。建立一个自己的“问题-解决方案”知识库下次再遇到类似问题解决起来就得心应手了。记住控制台是你的好朋友遇到任何异常第一反应就是打开它看看。
返回列表