This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
1. 产品名称:百梦。
|
||||
2. 产品愿景:百梦AI团队致力于打造AI互动内容UGC平台。
|
||||
3. 产品slogan:每个人都可以在10分钟内轻松创作出一款精品互动作品。
|
||||
3. 产品slogan:不用代码,不用美术,10分钟把脑洞变成有趣的体验。
|
||||
4. 产品特点:低门槛创作、高完成度作品、玩过后可改造并发布。
|
||||
5. 关键技术:Harness Engineering、多Agent调度、AI创作工具、AI原生游戏框架。
|
||||
6. 产品心智:想玩但找不到、玩到不满意、平台外体验不满意时,都可以来百梦做成自己满意的。
|
||||
@@ -28,16 +28,14 @@
|
||||
|
||||
```text
|
||||
百梦
|
||||
AI互动内容UGC平台
|
||||
把想玩的世界,亲手做出来
|
||||
10分钟做自己的互动内容
|
||||
```
|
||||
|
||||
第二层:远读slogan
|
||||
|
||||
```text
|
||||
每个人都可以在10分钟内
|
||||
轻松创作出一款
|
||||
精品互动作品
|
||||
不用代码,不用美术,
|
||||
10分钟把脑洞变成有趣的体验
|
||||
```
|
||||
|
||||
第三层:产品特点
|
||||
@@ -88,6 +86,8 @@ reference image: 百梦气泡共创logo方向图
|
||||
output: output/imagegen/baimeng-expo-rollup/baimeng-rollup-background-gpt-image-2.png
|
||||
```
|
||||
|
||||
2026-05-08 根据新文案重新调用 `gpt-image-2` 生成新版底图。新版底图在中上部保留更干净的两行 slogan 留白,并在下半部增加轻量内容卡、创作路径和 AI 辅助创作氛围,最终再叠加精确中文排版。
|
||||
|
||||
因为图片模型直接生成中文长文案存在错字风险,最终稿采用“gpt-image-2 底图 + 本地精确中文排版”的方式生成:
|
||||
|
||||
```text
|
||||
|
||||
@@ -250,3 +250,15 @@ cannon-es
|
||||
3. 只有水平外接半径发生重叠的已有物体会影响本次生成高度;远处物体不能把新物体整体抬高,避免破坏原有随机洒落和分层节奏。
|
||||
4. 该避让只解决“直接创建在已有模型内部”的初始穿插,后续沉降、翻滚、堆叠仍交给 cannon-es 物理模拟。
|
||||
5. 本节不允许额外引入中心引力、扩大锅容量或修改模型生成规则;若后续仍需优化,只继续围绕生成高度、入场节拍和沉降窗口做局部迭代。
|
||||
|
||||
## 20. 从小到大的生成动画
|
||||
|
||||
2026-05-08 追加生成动画优化,参考原型中物体逐个出现、从小到大补入容器的观感。
|
||||
|
||||
编码口径:
|
||||
|
||||
1. 该优化只作用于前端 3D 表现层的可见 mesh 缩放,不改变后端快照、碰撞体尺寸、物品数量、锅半径、点击判定、备选栏、三消和胜负规则。
|
||||
2. 物理 body 在创建时仍使用最终尺寸碰撞体,并立即加入 cannon-es 物理世界,确保生成动画过程中碰撞已经按完整体积稳定占位。
|
||||
3. 可见 mesh 初始以较小比例显示,再用缓动动画放大到完整尺寸;视觉缩放不得反向修改 body shape、质量、边界半径或生成高度避让计算。
|
||||
4. 入场动画继续服从第 18 节的创建限流和第 19 节的生成高度避让;不能为了动画效果把物体直接放进已有堆叠内部。
|
||||
5. 动画结束后 mesh 缩放必须回到 `1`,避免影响后续点击可读性和托盘对应关系。
|
||||
|
||||
@@ -140,6 +140,8 @@ const MATCH3D_ITEM_SPAWN_STAGGER_MS = 4;
|
||||
const MATCH3D_ITEM_SPAWN_STACK_CLEARANCE = 0.14;
|
||||
const MATCH3D_ITEM_SPAWN_STACK_RADIUS_PADDING = 0.08;
|
||||
const MATCH3D_ITEM_SPAWN_ANIMATION_MS = 260;
|
||||
const MATCH3D_ITEM_SPAWN_VISUAL_SCALE_START = 0.18;
|
||||
const MATCH3D_ITEM_SPAWN_VISUAL_DROP_OFFSET = 0.04;
|
||||
const MATCH3D_ITEM_EXTREME_VERTICAL_SPEED_LIMIT = 8.6;
|
||||
const MATCH3D_ITEM_EXTREME_HORIZONTAL_SPEED_LIMIT = 4.4;
|
||||
const MATCH3D_CENTER_GRAVITY_COEFFICIENT = 0;
|
||||
@@ -558,6 +560,18 @@ function resolveSpawnAnimationProgress(entry: PhysicsEntry, now: number) {
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveMatch3DSpawnVisualScale(progress: number) {
|
||||
const clampedProgress = Math.min(
|
||||
1,
|
||||
Math.max(0, Number.isFinite(progress) ? progress : 0),
|
||||
);
|
||||
const easedProgress = 1 - Math.pow(1 - clampedProgress, 3);
|
||||
return (
|
||||
MATCH3D_ITEM_SPAWN_VISUAL_SCALE_START +
|
||||
(1 - MATCH3D_ITEM_SPAWN_VISUAL_SCALE_START) * easedProgress
|
||||
);
|
||||
}
|
||||
|
||||
function applyCenterGravity(entry: PhysicsEntry) {
|
||||
if (MATCH3D_CENTER_GRAVITY_COEFFICIENT <= 0) {
|
||||
return;
|
||||
@@ -1028,7 +1042,7 @@ function createPhysicsEntryFromPendingSpawn(
|
||||
0.08,
|
||||
0.08 + (pendingSpawn.item.layer % 4) * 0.02,
|
||||
);
|
||||
visual.mesh.scale.setScalar(0.82);
|
||||
visual.mesh.scale.setScalar(MATCH3D_ITEM_SPAWN_VISUAL_SCALE_START);
|
||||
|
||||
runtime.world.addBody(body);
|
||||
runtime.scene.add(visual.mesh);
|
||||
@@ -1714,11 +1728,12 @@ export function Match3DPhysicsBoard({
|
||||
applyStabilityPlanToBody(entry, activeRuntime.stabilityPlan);
|
||||
constrainBodyInsidePot(entry);
|
||||
const spawnProgress = resolveSpawnAnimationProgress(entry, now);
|
||||
const spawnScale = 0.82 + spawnProgress * 0.18;
|
||||
const spawnScale = resolveMatch3DSpawnVisualScale(spawnProgress);
|
||||
entry.mesh.scale.setScalar(spawnScale);
|
||||
entry.mesh.position.set(
|
||||
entry.body.position.x,
|
||||
entry.body.position.y - (1 - spawnProgress) * 0.06,
|
||||
entry.body.position.y -
|
||||
(1 - spawnProgress) * MATCH3D_ITEM_SPAWN_VISUAL_DROP_OFFSET,
|
||||
entry.body.position.z,
|
||||
);
|
||||
entry.mesh.quaternion.set(
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
resolveMatch3DSpawnTimingPlan,
|
||||
resolveMatch3DStackTargetY,
|
||||
resolveMatch3DSpawnDelay,
|
||||
resolveMatch3DSpawnVisualScale,
|
||||
resolveMatch3DSpawnY,
|
||||
resolveMatch3DTrayPreviewRotation,
|
||||
resolveMatch3DTrayPreviewReferenceDimension,
|
||||
@@ -591,6 +592,18 @@ test('3D 新物体生成高度会避让同位置已有堆叠', () => {
|
||||
expect(unchangedSpawnY).toBe(plannedSpawnY);
|
||||
});
|
||||
|
||||
test('3D 新物体生成动画只缩放可见模型并最终回到完整尺寸', () => {
|
||||
const startScale = resolveMatch3DSpawnVisualScale(0);
|
||||
const middleScale = resolveMatch3DSpawnVisualScale(0.5);
|
||||
const endScale = resolveMatch3DSpawnVisualScale(1);
|
||||
|
||||
expect(startScale).toBeGreaterThan(0);
|
||||
expect(startScale).toBeLessThan(0.25);
|
||||
expect(middleScale).toBeGreaterThan(startScale);
|
||||
expect(middleScale).toBeLessThan(endScale);
|
||||
expect(endScale).toBe(1);
|
||||
});
|
||||
|
||||
test('积木视觉键不会被统一兜底成红色苹字', () => {
|
||||
const run = startLocalMatch3DRun(2);
|
||||
run.items = run.items.slice(0, 2).map((item, index) => ({
|
||||
|
||||
Reference in New Issue
Block a user