Files
erqiwang_youle/docs/client/development-guide/01-前端架构与运行环境.md
T
2026-07-06 17:16:05 +08:00

112 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 01 · 前端架构与运行环境
本篇建立**全局认知**:前端跑在什么环境、由哪几层构成、新旧两套架构如何并存、文件按什么顺序加载。
> 举例以麻将为主,但 `gameabc-framework` 是游戏中立的通用框架,本篇机制对任意子游戏一致。
---
## 1. 运行环境
- **部署形态**:前端是**浏览器静态资源**,由 gameabc 引擎(`js/vendor/gameabc.min.js`)驱动,绘制基于精灵(Sprite)/图层(Layer)/群组(Group)的 2D 画面。不走 npm 构建。
- **与服务端**:通过平台网络层收发 JSON 包(`{app, route, rpc, data}`),全程异步。**服务端权威**——所有核心运算与胜负裁定以服务端为准、数据以服务端为权威;**前端只做界面展示与玩家交互**,本地保存的数据只是「用于渲染的副本」,不做权威计算(前端渲染与交互范式见 02,红线见 05)。
- **ES5 强制**:线上浏览器/平台不保证 ES6+。全部 JS 必须严格 ES5——用 `var`/`function`,对象继承用 `Object.create`,禁 `let`/`const`/箭头函数/模板字符串/`class`/解构/默认参数。
- **少量 Node 仅用于测试/工具**:`shared/` 算法可在 Node 跑单测,`scripts/` 是 Spine 数据构建脚本;线上运行时无 `require`,跨文件一律按**全局名**引用(各文件用 `var X = ...` 暴露全局,`index.html` 顺序加载)。
---
## 2. 三层结构:平台 / 框架 / 子游戏
```
js/vendor/ 第三方与引擎(禁改)
gameabc.min.js gameabc 引擎原生 API
jquery / spine-canvas.js
js/00_Surface/ 前端平台代码(禁改)
Const/Data/Desk/Func/Game/GameUI/Logic/Net/Player/Utl_* ...
js/gameabc-framework/ ★ 通用模板框架(游戏中立,可复用)
core/ GameABCUtils(唯一直连引擎)、SpriteManager(业务级精灵 API)
system/ EventBus、AnimationManager、AudioManager
ui/ BaseComponent、UIManager、SpriteCopyUtils、DynamicSpriteList
spine/ SpineMgr
templates/ *.template.js(派生子游戏时复制填充的模板)
js/01_SubGame/ 子游戏前端
00_/01_/02_SubGame_*.js ★ 受限对接层(平台入口,尽量不改)
codes/ ★ 子游戏实例(单向依赖框架;内部结构由子游戏自行组织)
shared/ 前后端共享算法(服务端为权威源,同步而来,只读)
```
> `codes/` 内部如何分目录、如何命名文件,均由子游戏自行决定,本套文档不作规定;唯一例外是 `shared/`——它是服务端共享算法的同步副本,前端只读(见 05)。
依赖方向是**单向**的:`01_SubGame/codes` → `gameabc-framework` → `gameabc.min.js`。框架**不反向依赖**任何子游戏(见 03/05 的「框架中立」)。
---
## 3. 新旧两套架构并存(重要)
前端当前**两套架构并存**,理解边界才不会改错地方:
| | 旧架构(受限对接层) | 新架构(gameabc-framework + codes) |
|--|----------------------|--------------------------------------|
| 位置 | `js/00_Surface/`、`01_SubGame/00_/01_/02_SubGame_*.js` | `js/gameabc-framework/`、`01_SubGame/codes/` |
| 角色 | 平台框架的**固定入口**,承接平台事件 | 子游戏真正的渲染/逻辑/网络实现 |
| 可改性 | 平台代码禁改;受限文件不新增接口、尽量不改 | 在此自由开发 |
**对接方式**:平台事件先进旧的 `Game_Modify.*` 入口,旧入口**只做转交**,把数据委托给新架构处理(详见 04):
```
平台 → Game_Modify.appStart() → 启动初始化 启动
平台 → Game_Modify.StartWar(_msg) → 开局处理 开局
平台 → Game_Modify._ReceiveData() → 收包分发(按 rpc 分发) 对局推送
平台 → Game_Modify.Reconnect(info) → 重连处理(据数据重画) 重连
```
红线:**受限文件里只做“接住并转交”,业务逻辑写在新架构的 controllers/handlers 里**,不要在 `Game_Modify.*` 里堆逻辑。
---
## 4. 加载顺序(index.html)
`index.html` 按严格顺序加载脚本,**顺序即依赖**。典型分段:
```
阶段0 引擎与 Spine vendor/gameabc.min.js → generated/spine_* → spine/SpineMgr.js
阶段1 框架核心 + 常量 gameabc-framework/core·system → 子游戏共享常量
阶段1.5 子游戏事件常量 追加到 EventBus.Events
阶段2 工具/数据结构/算法 子游戏共享算法
阶段3 精灵/资源/布局常量 整合入口最后加载
阶段4 框架 UI + 业务视图 gameabc-framework/ui/* → 子游戏视图组件
阶段5 控制器/管理器/网络 子游戏消息处理/资源管理/收发包
阶段6 旧受限对接层 01_SubGame/00_/01_/02_SubGame_*.js
```
> 上表按“职责”分段,非规定 `codes/` 的目录布局;具体目录/文件由子游戏自定,只要**被依赖者先加载**即可。
加载顺序的两条铁律:
1. **被依赖者先加载**。例如框架 `EventBus.js` 必须在子游戏事件常量之前、事件常量又必须在任何注册这些事件的视图之前;整合所有精灵常量的入口文件必须**最后**加载。
2. **新增文件要插对位置**。新增一个常量/组件文件,必须在 `index.html` 里插到其依赖之后、使用者之前,否则运行时拿到 `undefined`。
---
## 5. codes/ 内部组织
`codes/` 是子游戏的自由开发区,**目录如何划分、文件如何命名,由子游戏自行决定**,本套文档不作强制规定。
只需把握两条通用原则(不依赖具体目录布局):
- **职责分离、调用不重造**:一个职能只在一处实现,其他地方调用它,不复制近似逻辑(渲染/动画/音频/收发包/共享算法等,见 05「模块职责边界」)。
- **`shared/` 是唯一受约束的子目录**:它是服务端共享算法的同步副本,前端**只读**,改服务端权威源再同步(见 05「shared 同步」)。
---
## 6. 小结
- 前端是浏览器静态资源 + gameabc 引擎,**严格 ES5**,跨文件按全局名引用、`index.html` 顺序加载。
- 三层:平台(禁改) / 框架(游戏中立、可复用) / 子游戏(单向依赖框架)。
- 新旧架构并存:平台事件经旧 `Game_Modify.*` 入口**转交**到新架构 handler;受限文件只接不写。
- 加载顺序即依赖,新增文件务必插对位置。
下一篇 [02-渲染与UI组件体系](./02-渲染与UI组件体系.md) 讲:精灵怎么画、资源常量怎么组织、UI 组件怎么写。