MatchMaster/assets/GameplayIntro/README.md

177 lines
14 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.

# 玩法介绍正式功能包
Asset Bundle 名称:`gameplay_intro`。
- `prefab/GameplayIntro.prefab`:本关介绍面板固定布局,可在 Creator 中编辑背景、标题、滑动区域和分页器位置。
- `assets/Script/module/Tool/LevelGameplay.ts`:主脚本目录中的筛选工具,从实际关卡的方块、门、地块及生成队列识别玩法,并按类型去重。主场景仅以类型引用 GameplayIntro,在分包加载完成后用组件名获取实例,避免启动时依赖尚未加载的分包脚本。
- `script/GameplayIntro.ts`:绑定预制体节点,关闭按钮或外部点击关闭,相邻三页图片加载与释放。
- `script/GuideCarousel.ts`:鼠标/触摸翻页、缓动回弹、最多三点分页及白点替换动画;单页隐藏分页且不绑定拖动,双页显示两点。
- `Texture/`:面板背景、玩法指南标题、问号、关闭按钮及分页圆点等 UI 素材;原有中文玩法图片已清理,玩法图片统一加载公共目录。
- `assets/resources/Window_Prop/`:34 组公共玩法图片,按 `titleN`、`iconN`、`IntroductionN` 加载。daoju26 使用素材 27,daoju27 使用素材 26。
游戏入口由 `assets/Script/SceneManager.ts` 控制:进入场景时按实际加载的关卡生成介绍列表,没有特殊道具就隐藏问号。首次点击 `openGameplayIntro` 加载本包的 `prefab/GameplayIntro`,实例挂到 Inspector 绑定的 `tipPanel` 节点;关闭后保留固定布局,释放所有玩法页图片,再次打开复用实例,按解锁关卡倒序排列后定位最左端的最新玩法;三个分页点时高亮左边第 1 点。
`GameplayIntro.open(entries)` 接收已经筛选的介绍列表。`NEW_LEVEL.json` 仅提供介绍编号和排列顺序,不再用解锁关卡或玩家进度筛选。开局方块和 `spawnGates[].spawnQueue[].members` 都纳入本关范围,消除后仍可查看;同类型只展示一页。木箱/快递盒/彩色木箱、普通/定次连接等按实际变体匹配,花盆借用的不可见盖板不增加快递盒介绍。
场景接线:在 GameScene 的 Top/tip 下放置问号 Sprite + Button,图片使用本包 `wenhao`;Button 点击事件绑定 Canvas 上的 SceneManager.openGameplayIntro。SceneManager 的 Tip Panel 属性绑定场景现有的 tipPanel。tipPanel 应作为位于游戏内容之上的居中容器,不需要添加覆盖整个屏幕的输入拦截组件。
预制体直接引用背景、标题、关闭按钮和两种分页圆点;34 种公共玩法图片由脚本按当前页及相邻页动态加载,不能把所有玩法图片拖到预制体中,以免一次加载全部图片。
测试工具位于 `assets/test`。当前 `settings/project.json` 的启动场景是 `TestLayout`;不需要测试时,先在 Creator 中切回正式启动场景并保存设置,再删除 `assets/test` 和同级 `assets/test.meta`。当前 HomeScene 没有 HomePropTestPanel 节点。
## 与已拉取 main 的改动对比
核对日期:2026-09-15。最新 `origin/main`(`e992a8f`)已快进合入当前 `layout-optimization` 分支。以下以 `e992a8f` 为基准,包含当前工作区的暂存、未暂存和未跟踪文件;本地 `main`(`122b504`)未移动,不作为本清单的对比基准。此清单是本次核对快照,后续代码变更需同步更新。
新增业务代码并非全部放在新包:面板与滑动脚本位于 `gameplay_intro`,测试代码位于 `test`,`LevelGameplay.ts` 位于原公共脚本目录。
```
GameplayIntro/
├─ assets/
│ ├─ GameplayIntro/ 【新增资源包:gameplay_intro】
│ │ ├─ script/
│ │ │ ├─ GameplayIntro.ts 面板展示、图片加载与释放
│ │ │ └─ GuideCarousel.ts 滑动翻页、分页指示
│ │ ├─ prefab/
│ │ │ └─ GameplayIntro.prefab 玩法介绍面板
│ │ ├─ Texture/ 玩法介绍美术资源
│ │ └─ README.md
│ │
│ ├─ test/ 【新增资源包:test】
│ │ ├─ script/
│ │ │ └─ TestLayoutPanel.ts 独立测试面板
│ │ ├─ scene/
│ │ │ └─ TestLayout.fire 测试场景
│ │ ├─ tests/
│ │ │ ├─ guide-carousel.cjs
│ │ │ ├─ home-prop-panel.cjs 残留测试,依赖的脚本已不存在
│ │ │ └─ preview.cjs
│ │ └─ README.md
│ │
│ ├─ Script/ 【原有脚本目录】
│ │ ├─ module/Tool/
│ │ │ └─ LevelGameplay.ts 【新增】当前关卡玩法筛选
│ │ ├─ SceneManager.ts 【修改】入口、加载、暂停与恢复
│ │ └─ ItemGuide.ts 无实际内容差异
│ │
│ ├─ NewMode/script/
│ │ └─ NewMode.ts 无实际内容差异
│ │
│ ├─ Scene/
│ │ ├─ GameScene.fire 【修改】问号按钮及面板接线
│ │ └─ HomeScene.fire 无实际内容差异
│ │
│ ├─ gacha_bundle/img/cat.meta 【删除】
│ ├─ libs/dn-sdk-minigame.meta 【删除】
│ ├─ passCheck/script.meta 【删除】
│ └─ pause/texture.meta 【删除】
│
├─ build-templates/wechatgame/
│ └─ project.config.json 【修改】上传时忽略 cocos 目录
│
└─ settings/
└─ project.json 【修改】启动场景、记录时间
```
新增资源对应的 `.meta` 文件未逐一展开。**原有脚本实际只改了 `SceneManager.ts`;新增的 `LevelGameplay.ts` 位于公共脚本目录。两个新资源包尚未配置为微信独立分包。**
`assets/custom/Json/level1961.json.meta` 至 `level1980.json.meta` 共 20 个关卡元数据文件现已包含在 main 基准中,合并时采用 main 的 UUID;未发现资源对旧本地 UUID 的引用。`.codex_tmp/prop-compare.jpg` 和 `.codex_tmp/texture-compare.jpg` 是本地对比图片,不是业务代码。`project.json`、`settings/services.json`、`settings/wechatgame.json` 相对上述基准没有实际文本内容差异。
本次合入 main 的 3 个提交包含:GameScene 点击拦截组件、门生方块介绍关卡改为 1943、AB 测试 B 方案第 15 关不返回首页及版本配置更新、战令图片更新。场景合并保留了 main 的拦截组件及本地问号按钮、坐标和面板接线;这些 main 自带改动不计入本地新增功能差异。
### 新增正式脚本及方法职责
整体调用关系:`SceneManager` 控制入口和暂停恢复 → `LevelGameplay` 筛选本关玩法 → `GameplayIntro` 管理内容与图片 → `GuideCarousel` 处理滑动分页。
#### LevelGameplay.ts(公共目录)
| 方法 | 作用 |
| --- | --- |
| `getLevelGameplay(config, data)` | 输入全部介绍配置和当前关卡数据,扫描方块、门、特殊地块及生成队列,返回本关介绍列表;按名称去重,保留配置顺序 |
| 内部 `add(id)` | 将编号转换为 `daojuN` 存入 Set,重复玩法只记录一次 |
该工具只读取数据。方块列表使用浅复制后再补充待生成方块,不向原数组追加内容。根据方块类型及附加属性区分普通/定次、木板/快递盒/彩色箱子等变体;花盆接收块借用的不可见盖板不额外计入箱子介绍。它不使用玩家进度或配置中的 `level` 筛选,也不负责显示、加载图片或暂停游戏;最终只返回在介绍配置中存在的条目。
#### GameplayIntro.ts(gameplay_intro 包)
挂在正式预制体根节点,负责内容、开关动画和图片资源。
| 方法 | 作用 |
| --- | --- |
| `open(entries)` | 复制列表并按 `level` 倒序排列,绑定固定节点、初始化分页,播放打开动画;空列表直接关闭 |
| `syncPages()` | 只保留当前页和前后相邻页的图片,优先加载当前页 |
| `picture(...)` | 排队加载公共标题、道具或说明图;标题和道具图等比适配,说明图保持预制体设置;丢弃失效页面的加载结果 |
| `nextImage()` | 依次启动图片加载任务,避免集中加载 |
| `releasePage(index)` / `releasePages()` | 清空图片显示引用、归还资源引用、隐藏页面;批量清理时同时清空待加载队列,固定节点保留复用 |
| `close()` / `finishClose()` | 播放关闭动画后释放图片、隐藏面板并发出 `intro-closed`,由场景判断是否恢复游戏 |
| `stopPanelAnimation()` | 停止开关动画并重置状态 |
| `onDisable()` / `onDestroy()` | 隐藏或销毁时清理图片和动画 |
| `previewNavigate(action)` / `getPreviewState()` | 提供测试跳页入口,以及当前页、总页数和当前配置 |
| `showMessage(value)` | 使用预制体的 Status 节点显示提示 |
#### GuideCarousel.ts(gameplay_intro 包)
挂在 `IntroViewport`,只负责手势、页面位置和圆点动画。逻辑页循环使用预制体中的三个固定页面节点。
| 方法 | 作用 |
| --- | --- |
| `initialize(...)` / `clear()` | 初始化页数、默认页、圆点及输入监听;重复打开前清理旧状态 |
| `goTo(index, animated)` | 限制目标页范围,更新分页高亮,发出 `page-changed` 通知内容加载 |
| `begin(...)` / `move(...)` / `end(...)` | 开始拖动、跟手移动、根据距离和速度决定翻页或回弹;首尾越界有阻力 |
| `x(event)` | 将屏幕坐标转为视口局部坐标,适配面板缩放 |
| `touchStart/Move/End/Cancel` | 将带手指 ID 的触摸事件转给拖动逻辑 |
| `mouseDown/Move/Up/Leave` | 处理鼠标左键拖动与离开视口结束拖动 |
| `createDot()` / `styleDot()` | 创建圆点并设置选中样式 |
| `animateDots()` / `resetDotAnimation()` | 推进或重置圆点替换动画 |
| `render()` / `update(dt)` | 应用页面位移、缩放和透明度,每帧推进吸附、回弹及圆点动画 |
| `onDisable()` | 结束手势和动画,避免重开后残留中间状态 |
### 原有 SceneManager.ts 的具体改动
| 改动位置 | 改动及作用 |
| --- | --- |
| 文件顶部 | 引入 `getLevelGameplay`;以 `import type` 引用 GameplayIntro,不产生启动时的运行时导入 |
| 新增字段 | `tipPanel` 绑定场景容器;`gameplayIntro` 缓存面板控制器;`levelGameplay` 保存本关介绍列表 |
| `isPauseOpen()` | 将介绍面板加载中、显示中计入暂停判断,防止重复打开及原有流程提前恢复游戏 |
| `onLoad()` | 增加 `refreshGameplayInfo()` 调用,进场景时初始化列表和问号显隐 |
| 新增 `refreshGameplayInfo()` | 使用已有 NEW_LEVEL 配置,未就绪则异步加载;按实际关卡筛选并缓存列表,没有介绍时隐藏问号 |
| 新增 `openGameplayIntro()` | 检查场景、暂停、结束、商城和容器状态;暂停游戏并停止炸弹计时;通过原有动态弹窗加载器加载或复用正式面板,再传入列表 |
| 内部 `resume()` 回调 | 关闭或加载失败时,仅在无冰冻、无其他暂停、无商城暂停且游戏未结束时恢复游戏;游戏已开始才恢复炸弹计时 |
| 加载完成回调 | 结束加载标记;失败时尝试恢复;成功时按组件名取得面板,同一实例只绑定一次关闭回调 |
| 原空 `start()` | 删除无内容的方法,没有移除实际业务逻辑 |
`loadDynamicPopup()` 等通用加载方法沿用原有实现。`MapConroler`、`ItemGuide.ts`、`NewMode.ts` 等其他原有业务脚本没有内容修改。
配套非脚本改动:`GameScene.fire` 新增问号按钮、tipPanel 容器及点击/属性绑定;微信构建模板增加上传忽略 `cocos` 目录;`settings/project.json` 将启动场景改为 `TestLayout`(UUID `8e21ec7e-3913-44ec-8f99-53ff52fe81ed`)并更新记录时间。
### 新增测试脚本
| 脚本 | 作用 |
| --- | --- |
| `assets/test/script/TestLayoutPanel.ts` | 独立测试界面,支持指定本地关卡、全部玩法、重新打开和跳页;直接复用正式面板,不写玩家进度 |
| `assets/test/tests/guide-carousel.cjs` | 使用模拟 Cocos 环境检查筛选、分页、资源回收及场景入口的暂停恢复逻辑 |
| `assets/test/tests/preview.cjs` | 本地预览服务,使用 Creator 编译器及运行中的编辑器引擎/资源展示测试场景 |
| `assets/test/tests/home-prop-panel.cjs` | 残留道具测试;依赖的 HomePropTestPanel.ts 和 HomeScene 节点已不存在,当前不可正常运行 |
运行方式与移除步骤见 `assets/test/README.md`。本次合并后执行 `node assets/test/tests/guide-carousel.cjs`,全部回归项通过;同时验证了场景引用索引和双方场景改动的保留情况。未进行 Creator 真机视觉及性能验证。
## 可编辑的固定玩法页结构
直接打开 `prefab/GameplayIntro.prefab`:
```
IntroViewport
└─ Pages
├─ Page1
│ ├─ TitleImage
│ ├─ IconImage
│ └─ DescriptionImage
├─ Page2(相同结构)
└─ Page3(相同结构)
```
所有图片节点已经放在面板预制体内,SpriteFrame 留空。最下方 DescriptionImage 的大小由 Sprite 的 Size Mode、Trim 及节点尺寸/缩放控制,代码不覆盖;TitleImage 和 IconImage 仍以预制体 Width/Height 为展示区域等比适配;三页需要保持相同布局。代码仅复用三个页面、改变分页位置并动态加载图片。说明图不做代码缩放,标题和道具图保留等比适配;没有单图比例修正。翻远或关闭面板时清空图片并归还资源引用,不销毁这三个页面;面板整体销毁时由引擎销毁子节点。