当前位置: 首页 > news >正文

Oops Framework-4-Oops Framework入口类Root.ts

OOPS项目的入口场景结构是固定的。Root节点下有一个空节点game和一个UI节点gui。而root节点必须要挂载入口类,这里命名是Main,Main要继承Root类控制整个游戏的流程。

核心基类Root.ts游戏的 Main 必须继承它

一、Root类是干嘛的?

Root 实际上是 oops 框架的总控制器它负责:

  1. 加载框架配置
  2. 初始化所有核心模块(音频、UI、计时器、ECS、存储、网络)
  3. 管理游戏的显示 / 隐藏(切后台、切前台)
  4. 提供给子类Main继承并实现游戏逻辑
  5. 每帧驱动 ECS 系统

二、导入部分

import { Component, Game, JsonAsset, Node, _decorator, director, game, log, sys, view } from "cc";

Cocos 引擎核心 API

import { LanguageManager } from "../libs/gui/language/Language"; import { BuildTimeConstants } from "../module/config/BuildTimeConstants"; import { GameConfig } from "../module/config/GameConfig"; import { GameQueryConfig } from "../module/config/GameQueryConfig"; import { oops, version } from "./Oops";

oops 框架自己的工具、配置、语言、全局对象oops.xxx

import { AudioManager } from "./common/audio/AudioManager"; import { EventMessage } from "./common/event/EventMessage"; import { GameManager } from "./game/GameManager"; import { GUI } from "./gui/GUI"; import { LayerManager } from "./gui/layer/LayerManager"; import { TimerManager } from "./common/timer/TimerManager";

音频、事件、游戏管理、UI、层级、计时器


三、类定义

@ccclass('Root') export class Root extends Component {

标准 Cocos 组件,所有游戏场景的根节点脚本都挂它。


四、编辑器可见属性(面板上能看到)

/** 游戏层节点 */ @property({ type: Node, tooltip: "游戏层" }) game: Node = null!; /** 界面层节点 */ @property({ type: Node, tooltip: "界面层" }) gui: Node = null!;

作用:

  • game:放角色、怪物、场景、特效
  • gui:放 UI、弹窗、按钮、导航

这就是 oops 的两层结构游戏内容层+UI层分离


五、onLoad —— 框架启动的真正入口

onLoad() { console.log(`Oops Framework v${version}`); this.enabled = false; // 先关闭 update,等配置加载完再开启

重点:加载 config.json

let config_name = "config"; oops.res.load(config_name, JsonAsset, () => { var config = oops.res.get(config_name);

加载框架配置文件:resources/config.json这个文件里写了:

  • 游戏版本
  • 服务器地址
  • 帧率
  • 加密密钥
  • 热更地址
  • 等等...

配置初始化

ts

oops.config.btc = new BuildTimeConstants(); oops.config.query = new GameQueryConfig(); oops.config.game = new GameConfig(config);

网络、存储、帧率设置

ts

oops.http.server = 地址 // 网络请求地址 oops.http.timeout = 超时 // 超时时间 oops.storage.init(加密key) // 本地存储加密 game.frameRate = 60 // 游戏帧率

配置加载完成 → 正式启动框架

ts

this.enabled = true; this.init(); // 初始化所有模块 this.run(); // 子类(Main)重写,启动游戏逻辑

六、update —— 每帧执行

ts

update(dt: number) { oops.ecs.execute(dt); }

驱动整个 ECS 系统运行所有 System 的 update 都从这里来。


七、init () —— 框架核心初始化(最重要)

ts

protected init() {

1. 创建持久根节点(切场景不销毁)

ts

this.persistRootNode = new Node("PersistRootNode"); director.addPersistRootNode(this.persistRootNode);

放:音频、计时器、全局管理

2. 初始化音频

ts

oops.audio = this.persistRootNode.addComponent(AudioManager); oops.audio.load();

3. 初始化计时器

ts

oops.timer = this.persistRootNode.addComponent(TimerManager)!;

4. 初始化多语言

ts

oops.language = new LanguageManager();

5. 初始化游戏层、UI 层

ts

oops.game = new GameManager(this.game); oops.gui = new LayerManager(this.gui);

6. 让子类初始化自己的 UI 和 ECS

this.initGui(); // 子类 Main 重写 this.initEcsSystem(); // 子类 Main 重写 oops.ecs.init(); // 启动 ECS 框架

7. 游戏切前台(EVENT_SHOW)

game.on(Game.EVENT_SHOW, () => { oops.timer.load(); // 恢复计时 oops.audio.resumeAll(); // 恢复声音 director.resume(); // 恢复游戏 game.resume(); oops.message.dispatchEvent(EventMessage.GAME_ENTER); });

8. 游戏切后台(EVENT_HIDE)

game.on(Game.EVENT_HIDE, () => { oops.timer.save(); // 保存计时 oops.audio.pauseAll(); // 暂停声音 director.pause(); // 暂停游戏 game.pause(); oops.message.dispatchEvent(EventMessage.GAME_EXIT); });

9. PC 窗口大小改变时自动适配 UI

view.setResizeCallback(() => { c_gui.resize(); oops.message.dispatchEvent(EventMessage.GAME_RESIZE); });

八、三个留给子类重写的方法

protected initGui() { } protected initEcsSystem() { } protected run() { }

initGui管理UI,initEcsSystem管理Game,run方法是框架的配置加载完成后所做的执行

整个流程是固定的,在Main.ts基本上只需要重写这三个方法


总结

Root 类做了 6 件事:

  1. 加载 config.json 配置
  2. 初始化音频、计时器、语言、网络、存储、UI、ECS
  3. 管理游戏前后台切换
  4. 每帧驱动 ECS
  5. 提供两层结构:game (游戏) + gui (界面)
  6. 把管理权扔给子类 Main 实现游戏逻辑
export class Main extends Root

就是继承这个类,启动整个游戏

http://www.jsqmd.com/news/953075/

相关文章:

  • 【git】-- 远程操作
  • 2026年6月喷码机企业推荐,大字符喷码机/喷码机/激光喷码机,喷码机实力厂家有哪些 - 品牌推荐师
  • Code to Story:用AST解析构建工程师叙事力
  • BFS-Best-Face-Swap高级技巧:利用LoRA技术提升换脸效果与效率
  • 从游戏地形到有限元分析:Delaunay三角剖分在Unity和COMSOL中的隐藏用法
  • 提升团队效能,基于快马AI构建chromedriver智能版本管理与自动下载工具
  • KV-Embedding技术:无训练文本嵌入新方法解析
  • 2026年知名的不锈钢双层风口/304不锈钢单层风口/不锈钢格栅风口厂家哪家好 - 品牌宣传支持者
  • javascript实战:基于快马平台构建电商商品多条件筛选系统
  • Qt数据库开发避坑指南:QSqlTableModel的三种编辑策略到底怎么选?(OnManualSubmit实例详解)
  • Mutual Information实战指南:非线性特征依赖量化与工程落地
  • 2026年知名的平模门芯板发泡剂/硫氧镁保温发泡剂/水泥发泡剂优质厂家推荐榜 - 行业平台推荐
  • 微博话题洞察工作流:Plotly交互式可视化实战
  • arabic_PP-OCRv5_mobile_rec_onnx性能测试报告:准确率、速度和内存占用全面分析
  • STM32F105双CAN实测工程:CAN1专注接收、CAN2独立发送,开箱即用
  • 压缩感知三大测量矩阵Matlab实现:伯努利、循环、部分傅里叶矩阵一键生成
  • AutoGen本地部署避坑指南:Poetry+Ollama+Chroma全链路实操
  • 2026年评价高的冷饮巧克力酱/耐烘烤巧克力酱/咖啡巧克力酱多家厂家对比分析 - 品牌宣传支持者
  • TongWeb 7.0.C 容器版 vs 企业版:JNDI数据源配置到底差在哪?一个坑位引发的思考
  • 别再踩坑了!手把手教你用Overleaf和本地LaTeX向arXiv提交论文(附.bbl文件处理指南)
  • GPT-4参数量与激活率真相:1.8万亿不是显存需求,2%不是固定计算比例
  • 告别重复劳动:用快马AI辅助一键生成mootdx多股数据清洗与合并代码
  • Linkbricks-Llama3.2-Korean-cpt-3b实战教程:韩语文本生成与对话系统构建
  • 利用快马AI快速原型化:十分钟构建ccswitch下载管理工具界面
  • 2026年评价高的无机硫氧镁改性剂/硫氧镁门芯改性剂主流厂家对比评测 - 品牌宣传支持者
  • STM32F103驱动1.14寸ST7789彩屏的Keil工程源码(含SPI底层+LVGL显示支持)
  • LangGraph实现可审计的人机协同工作流
  • 模板即规则:文档自动化中的低代码视觉协议设计
  • 避坑指南:MicroBlaze软核开发中DDR3和Local Memory配置的那些“坑”与优化策略
  • OpenCV凸包缺陷检测报错‘索引非单调’?自相交轮廓预处理修复方案