20 KiB
抓大鹅运行态 3D 几何体实验 2026-05-02
1. 实验目标
本轮只验证抓大鹅运行态把可消除物从 2D 纯色几何图案切换为 3D 几何体后的可读性、点击手感和堆叠碰撞观感。
3D 表现层必须满足:
- 圆形图案映射为球体。
- 方形图案映射为方块。
- 三角形、菱形、五角星、六边形、胶囊、心形、梯形、平行四边形等现有视觉键映射为近似 3D 几何体。
- 物体在圆形空间内保持边界约束,并使用物理模拟产生轻微碰撞、堆叠、晃动效果。
- 点击、备选栏、消除、胜负判定仍使用当前后端权威快照与前端即时反馈协议,不把规则真相迁到前端。
2. 回退要求
这是一次可取消实验,不替换现有 2D 方案。
- 现有
Match3DVisualIcon、Match3DToken和托盘 2D 图案渲染代码必须保留。 - 新增 3D 表现层只作为运行态棋盘的可选渲染分支。
- 当浏览器不支持 WebGL、3D 依赖加载失败或实验开关关闭时,运行态必须自动回到现有 2D 图案表现。
- 3D 模式下,托盘直接复用场内同一套程序化 3D 模型,以固定斜
45度识别视角展示已选物品;托盘内物品不进入物理世界,不参与碰撞。WebGL 不可用或实验回退时,托盘继续使用当前 2D 图标。
3. 工程落点
本轮只改前端表现层:
src/components/match3d-runtime/Match3DPhysicsBoard.tsx
src/components/match3d-runtime/Match3DRuntimeShell.tsx
src/components/match3d-runtime/Match3DRuntimeShell.test.tsx
src/components/match3d-runtime/match3dRuntimePresentation.ts
src/components/match3d-runtime/match3dVisualAssets.tsx
新增依赖:
three
cannon-es
@types/three
3D 棋盘默认启用;需要快速回到当前 2D demo 表现时,在运行态 URL 上追加任一参数:
?match3dRender=2d
?match3d3d=off
3D 分支只读取后端快照中的物品坐标、层级、可点击状态和视觉键。物理碰撞、轻微堆叠和几何体姿态只作为前端表现层,不改变消除规则、备选栏规则、胜负判定或最终权威快照。
match3dVisualAssets.tsx 保留 2D 纯色几何图案映射,运行态托盘在 3D 模式下通过 Match3DTrayPreviewBoard 使用单个共享 WebGL 预览层复用 createMatch3DItemMesh 生成同款 3D 模型,不能为每个托盘格单独创建 WebGLRenderer。托盘预览层必须按实际容器宽高更新正交相机,并把每个模型放入独立 pivot 后再沿相机屏幕横轴定位到对应格子中心;托盘预览不能把所有模型统一缩放到同一外观尺寸,必须保留场内相对尺寸差异,否则会让点击后入槽的模型和场内物件对应关系失真。WebGL 不可用或 2D 回退时继续使用该 2D 图标;match3dRuntimePresentation.ts 收口显示层坐标和状态兼容,避免异常旧坐标把 2D 或 3D 物体推到圆形边界外。
4. 验收口径
/match3d能打开并默认看到 3D 几何体棋盘。- 3D 几何体保持在圆形区域内,不被圆形边界裁切到不可点。
- 物体进入场景后有轻微物理碰撞和堆叠稳定过程。
- 点击 3D 物体后仍执行原有乐观入槽、后端确认、三消反馈和结算。
- 被取出的 3D 物体必须立即从棋盘物理世界移除;备选栏展示的是无碰撞、固定角度的独立预览模型,不允许继续受场内碰撞、重力或堆叠影响。
- 托盘 3D 预览必须共享一个 renderer,避免多个 WebGL 上下文导致中心棋盘上下文被浏览器回收;中心棋盘监听
webglcontextlost,丢失时自动回退 2D 表现,禁止出现模型不可见但仍可点击的状态。 - 单元测试仍覆盖 2D 回退图案,确保回退路径没有被删除。
- 390px 移动端与桌面端均不能出现横向溢出,顶部状态、圆形棋盘和 7 格备选栏都要完整可见。
5. 锅型容器优化
2026-05-02 追加一轮 3D 表现优化,把运行态圆形空间明确解释为一口有固定深度和确定边界的锅。
编码口径:
- 相机改为俯视角,玩家优先看到锅内物体的平面分布、遮挡关系和向上堆叠。
- 3D 场景里的圆形区域拆成锅底、锅壁和锅沿三层视觉结构,锅壁有固定高度,锅沿明确标出边界。
- 物理世界使用同一个锅内半径作为水平活动边界,所有可消除物体的初始位置和运行中位置都必须被约束在圆形锅内。
- 物体受到重力后只允许在锅内碰撞、滑动、翻滚和向上堆叠,不能因为碰撞或初始坐标散落到圆形区域外。
- 该优化仍只属于前端 3D 表现层,不改变后端运行态坐标、点击权威判定、备选栏、消除和胜负规则。
6. 中心引力优化
2026-05-02 追加中心引力,用来解决高消除次数下 3D 物体过于松散、贴边后被圆形场地裁切的问题。体验后发现默认向心力会让模型过度挤压成团,因此当前先关闭默认引力,只保留代码开关,后续如需再尝试可重新调参。
编码口径:
- 中心引力默认系数为
0,默认不对物理 body 施加水平向心力。 - 引力只作用在 X/Z 平面,不改变垂直重力,物体仍会自然落到锅底或堆叠在其他物体上。
- 引力在越靠近锅边时越明显,避免大量物体碰撞后形成稀疏外环;靠近中心时力度收敛,避免所有物体被吸成单点。
- 锅内活动边界继续作为硬约束;高数量物体应被锅边挡住并向上堆叠,不允许散落到圆形场地外。
/match3d?clearCount=100可作为本地直达压力测试入口,用于验证 300 个物体时仍在锅内聚拢。
7. 正交俯视与真实场地边界
2026-05-02 针对高堆叠时 3D 物体被 DOM 圆形裁切的问题,明确中心圆形区域不是裁切蒙版,而是游戏实际游玩场地。
编码口径:
- 3D 棋盘使用正交俯视相机,避免高处物体因为透视放大而投影到圆形场地外。
- 圆形场地的内圈圆环对应 3D 世界里的锅内空气墙,物体范围由物理约束控制,不再依赖 DOM
overflow-hidden裁切。 - 外层圆形 UI 只负责显示锅沿和场地外观,不能把物体裁成半截;如果物体看起来越界,优先修正相机、物理半径和空气墙。
- 高数量压力测试以
/match3d?clearCount=100为基准,物体可以在场地内向上堆叠,但不能被圆形边缘压住或切掉。
8. 类型数量与样式池历史口径
2026-05-03 曾调整消除物类型生成规则,解决 3D 关卡中可消除物类型和样式过少的问题。该节为历史口径,后续实际实现以第 11 节 25 个积木件资源池为准。
编码口径:
- 历史版本曾使用 20 类形状颜色组合。
- 当前版本已替换为 25 个积木件,旧 20 类上限不再作为编码依据。
- 3D 与 2D 回退仍共用视觉键映射,新增样式不能破坏
?match3dRender=2d回退路径。
9. 特殊形状 3D 可读性修正
2026-05-03 针对 20 组关卡中看不到十字、圆环、盾形、闪电、月牙、箭头等新形状的问题,补充 3D 几何体渲染口径。
编码口径:
- 数据层仍使用
visualKey决定类型,不新增贴图素材或文本标识。 - 十字、心形、星形、圆环、盾形、闪电、月牙、箭头、V 形等特殊形状不能继续使用普通盒子、球体或锥体代理,必须生成俯视角可辨认的 3D 轮廓。
- 特殊形状使用 Three.js 程序化轮廓挤出生成,保持当前 3D 实验可快速回退,不影响现有 2D 图案分支。
- 特殊形状的物理碰撞可以继续使用近似碰撞体,但显示网格需要固定为俯视可读姿态,避免落地翻滚后又变成长方块或普通三角体。
- 当前特殊形状已被 25 个积木件资源池替换;不能为了让玩家开局肉眼看到全部类型而改动初始层级、物理堆叠、遮挡、边界或可点击规则。
10. 15 组中档局面的类型唯一性修正
2026-05-03 针对 clearCount=15 时可消除物类型不足 15 种的问题,补充中档局面的规则验收口径。
编码口径:
clearCount=15时,运行态数据中必须生成15种不同itemTypeId,且首个15个visualKey必须分别对应不同几何形状。- 每种
itemTypeId在clearCount=15时只对应 1 次消除目标,即恰好生成3件物体;同一种视觉模型在同局中不应出现超过 3 件。 - 不为了展示 15 种而修改初始层级、物理堆叠、遮挡、边界或可点击规则;被盖住、堆叠和局部不可见是正常玩法效果。
- 当前版本已改为第 11 节的
itemTypeCount = clearCount <= 25 ? clearCount : 25规则。
11. 25 个积木件资源池替换
2026-05-03 根据新的参考图,把可消除物体替换为 25 个积木件类型,并调整本局类型抽取规则。
编码口径:
- 默认
visualKey资源池改为 25 个积木件,覆盖长条、短条、2x2、2x3、2x4、1x1、光板、斜坡、圆柱、透明圆环、拱门和锥形件等差异化模型。 - 前端 3D 表现继续使用 Three.js 程序化几何体生成,不引入外部贴图或 GLB;托盘和 2D 回退继续使用同一批
visualKey的简化图标。 clearCount <= 25时,本局从 25 个类型中按确定性随机顺序抽取clearCount种类型,不允许同局刷新重复类型。clearCount > 25时,本局最多使用 25 种类型,额外消除组在这 25 种中轮转复用;每种类型最终数量仍必须是 3 的倍数。- 该随机抽取只决定本局使用哪些类型和使用顺序,不改变物理堆叠、遮挡、边界、可点击判定、备选栏和胜负规则。
- 前端本地试玩、创作后试玩和后端权威运行态必须使用同一套
itemTypeCount = clearCount <= 25 ? clearCount : 25口径。
12. 五档体积规则
2026-05-03 追加可消除物模型大小规则,把每局可消除物按五档相对体积分配。
编码口径:
- M 型作为标准体积
1.00。 - XL 型相对体积范围为
1.60~2.30,占本局可消除类型数的20%。 - L 型相对体积范围为
1.25~1.60,占本局可消除类型数的30%。 - M 型相对体积固定为
1.00,占本局可消除类型数的30%。 - XS 型相对体积范围为
0.65~0.85,占本局可消除类型数的15%。 - S 型相对体积范围为
0.35~0.50,占本局可消除类型数的5%。 - 本局使用类型数仍按第 11 节计算,即
clearCount <= 25 ? clearCount : 25。比例遇到非整数时按最大余数补齐,确保五档数量之和等于本局使用类型数。 - 体积档位分配绑定到本局选中的
visualKey,同一局内同一个颜色和造型只能有一个尺寸档位和一个半径;当clearCount > 25轮转复用类型时,复用的同一visualKey继续沿用同一尺寸。 - 前端本地试玩、创作后试玩和后端权威运行态必须使用同一套五档体积分配口径。
13. 可点击物整体显示倍率
2026-05-04 追加一轮点击手感优化,解决当前玩家点击可消除物偏困难的问题。
编码口径:
- 运行态表现层使用
MATCH3D_RENDER_ITEM_SCALE = 2,把后端快照中的item.radius统一乘2后再进入显示层坐标收束。 - 该倍率只影响前端 2D 回退图标、3D 场内模型、碰撞体、射线点击命中区域和托盘 3D 预览测量。
- 五档体积规则、每局类型数量、每种物品的唯一尺寸关系、后端权威快照和消除判定不做变化;所有物体之间的相对大小比例保持不变。
- 放大后的物体仍必须通过圆形场地显示层收束和 3D 锅内空气墙约束,不允许重新依赖 DOM 圆形裁切。
- 2026-05-04 追加修正:碰撞体必须和当前视觉模型使用同一套尺寸公式。长条、光板、斜坡、圆柱、圆环、拱门和锥形件不能再只按
shape + radius粗略生成统一碰撞体;不得借此调整整体显示倍率、点击倍率、锅体尺寸或物理步进。
14. 两位数消除局的点击命中与旧模型复用修正
2026-05-05 针对 clearCount >= 10 时出现“点击到的 3D 模型和下方备选栏模型不一致”的问题,补充运行态复用口径。
编码口径:
- 运行态 3D 棋盘的物理条目不能只按
itemInstanceId复用,还必须结合runId、itemTypeId、visualKey、radius和layer生成当前渲染签名。 - 当同一个
itemInstanceId出现在新的 run 快照里,但渲染签名已经变化时,旧 mesh 和 body 必须先销毁,再按当前快照重建。 - 这条修正只针对前端 3D 表现层,不改变后端权威快照、点击判定、备选栏规则和三消规则。
- 底部备选栏预览继续沿用按当前 run 快照重建的视觉键,不允许把上一局的旧 3D 资源误复用到新一局。
15. 备选栏 3D 模型可读性优化
2026-05-05 针对备选栏中的 3D 模型偏小、部分积木件难以辨认的问题,补充 UI 预览层展示口径。
编码口径:
- 备选栏 3D 预览可以使用比场内更紧凑的显示尺度,让模型在单格 UI 中占用更大可读面积。
- 托盘相机和模型姿态只服务 UI 识别;当前采用偏强的俯视
3/4立体角,并通过更明显的光照对比突出顶面与侧面差异,避免退化成纯平面旋转。 - 该调整不能改变中心场地 3D 模型的物理姿态、碰撞体、点击判定和后端权威快照。
- 托盘仍使用共享
WebGLRenderer,继续按当前visualKey和尺寸关系生成同款模型;不得新增每格独立 renderer。 - 托盘缩放不能继续只按本局最大模型统一压缩所有物体;小尺寸模型需要保留最低可读显示尺寸,但仍不能改动场内真实尺寸、碰撞尺寸和后端权威尺寸。
- 备选栏单格高度可大于宽度,优先保证局内 3D 预览的识别面积;不得为了适配旧正方形格子把模型再次压小。
16. 中心场地隐藏纵深与动态上顶
2026-05-05 针对中心场地高数量局面穿模严重、消除后中下层物体长期陷在深处的问题,追加隐藏纵深与动态上顶表现修正。
编码口径:
- 该纵深只存在于 3D 物理表现层,不修改锅体图案、锅壁模型、托盘表现、后端快照、点击权威判定、消除和胜负规则。
- 物体生成高度不再使用固定极小层级步长,而是按本局总物体数计算一个隐藏初始纵深;物体总量越大,初始逻辑纵深越深,用来减少大量放大后模型被挤进同一高度区间导致的穿模。
- 当前剩余场内物体数会动态缩短可用纵深;随着玩家持续消除,下层物体的目标高度逐步上移,表现为中下层物体陆续向上顶到表面层。
- 动态上顶只通过向上托举力和目标高度调整完成,不增加中心引力,不修改水平约束半径,不改变碰撞体尺寸倍率。
- 表面层高度保持稳定,避免越消除越显得物体掉进深处或视觉尺寸异常变小。
17. 高数量局面物理稳定与动态锅容量
2026-05-06 继续按方案 C 和方案 D 优化 clearCount=100 等高数量局面的稳定性。
方案 C 编码口径:
- 只调整 3D 表现层的物理稳定参数,包括求解迭代次数、接触摩擦、接触弹性、线性阻尼、角阻尼、睡眠阈值和速度上限。
- 物体数量越大,物理世界越偏向高摩擦、低弹性和更强阻尼,减少大量物体同时生成后的持续弹跳、穿插和边界挤压。
- 速度保护只限制极端水平速度和垂直速度,不改物体位置生成规则、点击判定、备选栏、消除和胜负规则。
方案 D 编码口径:
- 隐藏锅容量的纵深按本局总物体数,也就是用户配置的消除次数乘
3后动态计算;消除次数越大,锅内容量纵深越深。 - 动态纵深只影响 3D 物理层的生成高度、目标层高度和消除后的上顶回补;锅底、锅壁、锅沿和 DOM 场地外观不随纵深变化。
- 高数量局面需要降低单层容量,让更多物体分散到纵向层级中,避免
300个物体被压进少量高度层。 - 随着消除进度推进,当前可用纵深继续按剩余物体数收缩,确保下层物体逐步向表面回补,保持中心场地表层稳定可见。
- 本节不改变中心引力默认值,不改水平活动半径,不改碰撞体与视觉模型的尺寸一致性规则。
18. 原型入场节奏与创建限流
2026-05-07 根据原型视频补充创建过程优化。原型不是在同一帧把全部物体摆进容器,而是先短暂空场,再用连续小批量把物体投放到容器中,批与批之间留出自然沉降时间,最后再进入可操作局面。
编码口径:
- 该优化只作用于前端 3D 表现层的物理 body 创建节奏,不改变后端快照、消除目标数量、点击权威判定、备选栏、三消和胜负规则。
totalItemCount < 30时保留较快创建节奏;30 <= totalItemCount <= 50进入中速波次投放,降低每波数量并增加波次沉降窗口,避免最后一层物体压进尚未稳定的表层堆叠。totalItemCount > 50后进入更强限流投放,单帧创建数量下降,避免同一帧把过多碰撞体塞入物理世界。- 随着总物体数增加,投放初始等待、层级间隔和同层错峰间隔都要逐步变长,模拟原型中“持续落入、短暂沉降、继续补入”的节奏。
clearCount=100对应300个物体时,投放节奏应接近连续数秒完成,而不是在一秒左右完成全量创建。- 该节不允许通过缩小碰撞体、扩大锅半径、开启中心引力或修改模型尺寸来掩盖穿模;如果后续仍需调整,只继续围绕创建节拍和物理沉降窗口处理。
19. 生成高度避让已有堆叠
2026-05-07 继续按方案 2 优化 30 件左右局面最后一层或最后一波物体仍会穿进已有堆叠的问题。
编码口径:
- 该优化只作用于前端 3D 表现层的新物体创建高度,不改变后端快照、物品数量、模型尺寸、碰撞体尺寸、锅半径、点击判定、备选栏、三消和胜负规则。
- 新物体进入物理世界前,先根据当前同一水平区域附近已有物体的碰撞体顶部高度,计算一个不低于原计划高度的生成高度。
- 只有水平外接半径发生重叠的已有物体会影响本次生成高度;远处物体不能把新物体整体抬高,避免破坏原有随机洒落和分层节奏。
- 该避让只解决“直接创建在已有模型内部”的初始穿插,后续沉降、翻滚、堆叠仍交给 cannon-es 物理模拟。
- 本节不允许额外引入中心引力、扩大锅容量或修改模型生成规则;若后续仍需优化,只继续围绕生成高度、入场节拍和沉降窗口做局部迭代。
20. 从小到大的生成动画
2026-05-08 追加生成动画优化,参考原型中物体逐个出现、从小到大补入容器的观感。
编码口径:
- 该优化只作用于前端 3D 表现层的可见 mesh 缩放,不改变后端快照、碰撞体尺寸、物品数量、锅半径、点击判定、备选栏、三消和胜负规则。
- 物理 body 在创建时仍使用最终尺寸碰撞体,并立即加入 cannon-es 物理世界,确保生成动画过程中碰撞已经按完整体积稳定占位。
- 可见 mesh 初始以较小比例显示,再用缓动动画放大到完整尺寸;视觉缩放不得反向修改 body shape、质量、边界半径或生成高度避让计算。
- 入场动画继续服从第 18 节的创建限流和第 19 节的生成高度避让;不能为了动画效果把物体直接放进已有堆叠内部。
- 动画结束后 mesh 缩放必须回到
1,避免影响后续点击可读性和托盘对应关系。