Files
HexTrails/docs/cocos-port.md
T

95 lines
8.3 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.
# Cocos Creator 3.8 接入
## 可复用部分
`core.js`、`path-math.js`、`geometry.js` 不依赖 DOM、Canvas 或浏览器物理引擎。转盘和连续碰撞都是普通数学运算,Cocos 与 HTML 直接复用同一套规则。场景绘制只要求多边形、线段、圆和图集 Sprite。
[Cocos 官方模块说明](https://docs.cocos.com/creator/3.8/manual/en/scripting/modules/index.html)与 [Graphics 说明](https://docs.cocos.com/creator/3.8/manual/en/ui-system/components/editor/graphics.html)对应本项目的 ESM/绘制适配方式。
## 接入步骤
复制这些目录到 Creator 的 `assets/hex-trails/`,保留相对路径:
```text
hex-trails/
cocos/HexTrailsBoard.ts
cocos/CandyUiSkin.ts
src/core.js
src/path-math.js
src/geometry.js
src/renderer.js
src/collision-animation.js
src/tile-shape.js
src/sprites.js
src/levels.js
src/design-tokens.js
src/ui-skin.js
design/tokens.json
assets/tiles-matte-clean-v8.png
assets/ui-surfaces.png
assets/ui-icons-generated.png
```
1. 在 Canvas 下建立 `Board` 节点,UITransform 设为 390×390,挂载 `HexTrailsBoard`,使用正常 UI 正交相机。
2. 将 `tiles-matte-clean-v8.png` 的 Texture2D 资源赋给 `tileAtlas`。组件根据 `TILE_FRAMES` 建立四个 SpriteFrame,复用原图,不需要重新生成贴图。未指定时使用基础几何绘制。
3. 棋盘 Graphics 负责轨道;Sprite 池与圆角六边形 Mask 负责哑光棋子;前景 Graphics 负责箭头。源矩形及顶面锚点在 `src/sprites.js` 中,箭头方向与贴图朝向分离。
4. `levelIndex` 选择内置关卡,或把单关 JSON 赋给 `levelAsset`。
5. 按钮绑定 `rotateLeft()`、`rotateRight()`、`undo()`、`restart()`、`hint()`。
6. 监听 `trail-state`,更新步数、剩余棋子、朝向、胜负和忙碌状态。监听 `trail-hint-rotation` 高亮对应旋转按钮;`trail-blocked` 可接声音/震动。
7. 按 `THEME.background` 设置纯色背景;当前主界面只保留居中的 Level、其下方的剩余步数,以及左侧选关、右侧设置。按钮与面板使用下述图片皮肤,动态文字与布局使用 Label、Button、Layout、Widget、EditBox、ScrollView 等节点搭建。原生端不需要 WebView。
## 坐标与动画
逻辑坐标从左上角出发、y 向下,Cocos 默认居中、y 向上。适配器已处理绘制和触摸两侧的转换,并使用相同的正六边形命中计算。
`update(dt)` 驱动转盘和路径动画。转盘动画只转轨道底板,棋子保持不动。失败动画沿计算得到的接触路径前进再回退,使用与浏览器相同的 `drawScene()` 和扫掠碰撞结果。
## 需要替换的宿主接口
| HTML | 原生接口 |
| --- | --- |
| Canvas 图集采样 | SpriteFrame.rect + Sprite,已提供 |
| requestAnimationFrame | Component.update(dt),已提供 |
| pointerup | TOUCH_END,已提供 |
| HTML 按钮、CSS 布局 | Button、Label、Widget、Layout |
| 浏览器 localStorage | 存储适配,可使用 sys.localStorage |
| 文件上传/下载 | Creator 资源系统或目标平台文件接口 |
| CSS 纯色页面背景 | 使用共享 background token 的 Graphics 或纯色 Sprite |
| CSS 面板与图标 | CandyUiSkin 的纯色 PNG、圆角 Mask 与图标 Sprite |
Cocos 示例提供按钮旋转;若需要同样的边缘拖动手势,可复用 `app.js` 中的角度差判定,接到 TOUCH_START/TOUCH_END。文件接口不属于游戏规则,不应直接复制浏览器 `app.js` 到原生环境。
## 验证限制
已核对本机 Creator 3.8.8 的相关接口,适配脚本通过 TypeScript 语法检查。当前交付不是完整 Creator 工程,尚未运行 Creator 场景或完成 Android/iOS 构建。接入后需验证相机缩放、SpriteFrame 裁切、触摸、Mask、目标平台存储与性能。静态轨道可单独缓存,降低动画时的绘制开销。
## 图片 UI 移植
配色与组件规范以 [Design.md](../Design.md) 为准。`src/design-tokens.js` 是颜色数值的唯一来源;改色后在网页工程运行 `npm run design`,再同步生成的 `design/tokens.json` 与 `assets/ui-surfaces.png`。`src/ui-skin.js` 依赖该 token 模块,并提供网页和 Cocos 共用的图集路径、尺寸和裁切矩形。
| 导入资源 | 规格与用途 |
| --- | --- |
| `assets/ui-surfaces.png` | 416×32,单行 13 个 32×32 纯色色块;颜色由 token 烘入 PNG |
| `assets/ui-icons-generated.png` | 1254×1254,用户选定的生成白色图标原图;按 `ICONS` 的正方形矩形采样 |
| `src/ui-skin.js` | `PANELS`、`ICONS` 与 `UI_REFERENCE` 的共用定义;不可手抄旧版裁切坐标 |
`CandyUiSkin` 挂在 UITransform 节点上,将两张图集的 Texture2D 分别赋给 `panels` 和 `icons`。`panel` 默认是 `surface`,`corner` 默认 14;弹窗设为 24,小角标设为 8。面板使用 `Sprite.Type.SIMPLE` 拉伸纯色色块,通过 `Mask.Type.GRAPHICS_STENCIL` 和 `Graphics.roundRect` 保持圆角;`PANELS` 的 `cap` 为 0,不采用九宫格。Sprite 保持原色,不再加 Color tint 或亮度滤镜。
面板角色包括 `surface`、`primary`、`secondary`、`utility`、`warning`、`reward`、`input`、`selection`、`disabled` 和四个 `tileBlue/tilePink/tileYellow/tilePurple` 色块。常规面板用 `surface`,下一关和当前关卡用 `primary`,次级动作与普通关卡用 `secondary`,选关、设置和道具图标底板统一用 `utility`。Label 颜色读取 token 中的配对角色,例如 `primary/onPrimary`、`surface/textPrimary`。
图标由 `icon` 名称选择,组件按原裁切比例适配节点并居中,不能拉伸为长方形。需要不同面板和图标尺寸时,分别使用背景节点与居中的图标子节点;图标子节点将 `panel` 留空。左右转只放大生成箭头并在下方放置 Label,同样将 `panel` 留空,不创建按钮底板。原图细节和颜色保持不变;轮廓阴影属于额外原生渲染效果,当前组件未实现,需单独对齐网页并验收。
尺寸及锚点变化会自动更新裁切形状与图标位置;运行时修改 `panel`、`icon`、`corner` 或纹理后调用 `refresh()`。组件复用至多两个 SpriteFrame,并在销毁时释放,不要在每次缩放时另外创建图集帧。按钮交互由宿主实现:禁用需同时关闭 Button 交互,若对齐网页透明度则用 UIOpacity 140(约 55%);按压在 150ms 内缩放至 94%,松开恢复。弹窗遮罩、禁止后方交互、入场动画和音效也由原生宿主实现,皮肤组件不负责这些行为。
Canvas 使用参考设计分辨率 390×844、适配宽度。`docs/ui-layout.json` 是旧版界面的历史坐标快照,其中包含已经移除的控件和旧面板名称,不能直接作为当前场景模板。若从当前网页重新量取左上角矩形,转换到 Cocos 居中锚点:x = rect.x + rect.width/2 - 195;y = 422 - rect.y - rect.height/2。所有动态文案仍用 Label;统一字体资源后再检查字宽。轨道与路径为运行时玩法几何,继续使用共享 renderer。
旧的 `ui-panels.png`、`ui-icons.png`、`ui-icons-flat.png`、`board-tray.png`、背景图和 Logo 均不属于当前 UI 导入清单。生成图标只做登记矩形采样,未对原 PNG 承诺像素级去噪,需检查实机透明边缘。当前已验证网页,Cocos 原生场景尚未完成视觉验收。
## 哑光版本与碰撞反馈
背景使用 `THEME.background`(当前 #A8BECF),移除旧背景图片节点。棋子采用 tiles-matte-clean-v8.png,共享 src/sprites.js 裁切。src/collision-animation.js 是 renderer.js 的依赖,也必须复制进 Cocos。碰撞总长 1.25 秒,前 42% 接近,42%–64% 接触停顿及双棋子反馈,最后 36% 原路退回。不会修改阻挡棋子的模型坐标;视觉接触位置依据 Sprite 外形提前截断,避免相互穿插。网页减少动态效果模式下取消阻挡棋子震动。
## 干净边缘与背景
背景采用冷蓝灰 `background`,棋盘采用暖白 `board`(当前 #F2EEE5),轨道与分格也读取同一 token 模块。棋子 PNG 只取每个色块中央 20% 的干净区域,运行时通过 `src/tile-shape.js` 的圆角正六边形遮罩显示;网页 Canvas.clip 和 Cocos Mask.GRAPHICS_STENCIL 共用轮廓。必须复制 tile-shape.js。原图边缘仍有生成杂点,不要直接显示整张原图或旧裁切矩形。