-
Notifications
You must be signed in to change notification settings - Fork 0
Greddysnake #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Greddysnake #3
Changes from 2 commits
77d6548
3df1c20
fad5fee
5967495
de97e60
1c23e3a
c76eaa7
4ce959b
26a26dc
19764e3
2f48266
9154730
56a3499
b2f00fb
8f6a44d
578942b
c25634f
939a5cb
270d78e
f36901d
05aaea5
2ecdaec
be42bdb
9016ebb
4012425
9e5ee89
f55e695
ab3c661
94312cb
1f045f0
d33308f
3ae7ad1
ec30e8b
d0c0e16
e565989
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,4 +4,6 @@ ignore/ | |
| .trae/ | ||
|
|
||
| Packages/RealityKitContent/.build/ | ||
| .build/ | ||
| .build/ | ||
|
|
||
| buildServer.json | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,217 @@ | ||||||||||||||
| # 3D 贪食蛇 (Snake3D) - 开发计划 | ||||||||||||||
|
|
||||||||||||||
| ## 项目概述 | ||||||||||||||
|
|
||||||||||||||
| 在 VisionOS 沉浸式空间中实现的 3D 贪食蛇游戏。核心视觉机制:**蛇头始终朝向玩家正前方**,玩家按转向键时,游戏世界做反向旋转,造成"蛇一直向前冲、空间在翻滚"的沉浸感。 | ||||||||||||||
|
|
||||||||||||||
| --- | ||||||||||||||
|
|
||||||||||||||
| ## 核心机制:世界旋转视角 | ||||||||||||||
|
|
||||||||||||||
| ### 原理 | ||||||||||||||
|
|
||||||||||||||
| - 蛇在逻辑 3D 网格中记录真实方向,但渲染时蛇头坐标系始终对齐摄像机前方(-Z 轴) | ||||||||||||||
| - 每次转向,维护一个**累积世界旋转四元数** `worldOrientation: simd_quatf` | ||||||||||||||
| - 渲染所有几何体(蛇身、食物、边界框)时,先用 `worldOrientation` 旋转世界坐标,再做 ViewProjection 变换 | ||||||||||||||
| - 转向时,用 `simd_slerp` 做平滑插值,动画时长约 0.3 秒 | ||||||||||||||
|
|
||||||||||||||
| ### 转向与世界旋转对应关系 | ||||||||||||||
|
|
||||||||||||||
| | PS 手柄按键 | 蛇的逻辑转向(世界坐标) | 世界渲染反向旋转 | | ||||||||||||||
| | ----------- | ------------------------ | -------------------- | | ||||||||||||||
| | Dpad Up | 蛇向当前相对"上"(+Y)转 | 绕局部 X 轴旋转 −90° | | ||||||||||||||
| | Dpad Down | 蛇向当前相对"下"(−Y)转 | 绕局部 X 轴旋转 +90° | | ||||||||||||||
| | Dpad Left | 蛇向当前相对"左"(−X)转 | 绕局部 Y 轴旋转 +90° | | ||||||||||||||
| | Dpad Right | 蛇向当前相对"右"(+X)转 | 绕局部 Y 轴旋转 −90° | | ||||||||||||||
| | □ (Square) | 绕前进轴向左翻滚 | 绕局部 Z 轴旋转 −90° | | ||||||||||||||
| | ○ (Circle) | 绕前进轴向右翻滚 | 绕局部 Z 轴旋转 +90° | | ||||||||||||||
|
|
||||||||||||||
| > 注意:每次转向都是相对于蛇当前的朝向坐标系,而非世界绝对轴。旋转轴需在蛇的局部坐标系中计算后转换到世界空间。 | ||||||||||||||
|
|
||||||||||||||
| ### 蛇头位置的锚定 | ||||||||||||||
|
|
||||||||||||||
| - 蛇头在渲染空间始终位于固定坐标(如略微偏前,距相机约 0.6m 处) | ||||||||||||||
| - 世界中所有坐标 = `worldRotation * (worldPos - snakeHeadWorldPos)` + 渲染锚点 | ||||||||||||||
| - 这样旋转轴心固定在蛇头位置,转向时空间绕蛇头翻转 | ||||||||||||||
|
|
||||||||||||||
| --- | ||||||||||||||
|
|
||||||||||||||
| ## 文件结构 | ||||||||||||||
|
|
||||||||||||||
| ``` | ||||||||||||||
| vr-dive/Demos/Snake3D/ | ||||||||||||||
| ├── PLAN.md ← 本文件 | ||||||||||||||
| ├── Snake3DTypes.swift # 数据类型 & GPU 结构体 | ||||||||||||||
| ├── Snake3DGameLogic.swift # 游戏逻辑(网格、移动、碰撞) | ||||||||||||||
| ├── Snake3DRenderer.swift # Metal 渲染器(VisualPatternController) | ||||||||||||||
| └── Snake3DShaders.metal # 顶点/片段着色器 | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| --- | ||||||||||||||
|
|
||||||||||||||
| ## 各文件职责详述 | ||||||||||||||
|
|
||||||||||||||
| ### Snake3DTypes.swift | ||||||||||||||
|
|
||||||||||||||
| ```swift | ||||||||||||||
| // 6 个方向枚举 | ||||||||||||||
| enum SnakeDirection { case posX, negX, posY, negY, posZ, negZ } | ||||||||||||||
|
|
||||||||||||||
| // 游戏状态(纯值类型,线程安全拷贝) | ||||||||||||||
| struct Snake3DState { | ||||||||||||||
| var segments: [SIMD3<Int>] // 蛇体,index 0 = 头部 | ||||||||||||||
| var direction: SnakeDirection | ||||||||||||||
| var foods: [SIMD3<Int>] // 同时存在的食物列表 | ||||||||||||||
| var score: Int | ||||||||||||||
| var isGameOver: Bool | ||||||||||||||
| var gridSize: Int // 立方体网格边长(默认 20) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // GPU 实例缓冲区(蛇身节段) | ||||||||||||||
| struct SnakeSegmentInstance { | ||||||||||||||
| var position: SIMD3<Float> | ||||||||||||||
| var color: SIMD4<Float> // 头部亮绿,尾部渐暗 | ||||||||||||||
| var scale: Float | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // GPU 食物实例 | ||||||||||||||
| struct FoodInstance { | ||||||||||||||
| var position: SIMD3<Float> | ||||||||||||||
| var phase: Float // 动画相位(脉冲) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // CPU→GPU Scene Uniforms | ||||||||||||||
| struct Snake3DSceneUniforms { | ||||||||||||||
| var worldRotation: float4x4 // 世界旋转矩阵(累积) | ||||||||||||||
| var anchorOffset: SIMD3<Float> // 蛇头锚定偏移 | ||||||||||||||
| var time: Float | ||||||||||||||
| var layerCount: UInt32 | ||||||||||||||
| } | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| ### Snake3DGameLogic.swift | ||||||||||||||
|
|
||||||||||||||
| - **网格**:20×20×20,坐标范围 [0, 19]³ | ||||||||||||||
| - **蛇体存储**:`[SIMD3<Int>]`,每次前进 prepend 新头,pop 尾(若未吃食物) | ||||||||||||||
| - **食物**:随机生成,最多 3 个同时存在,不与蛇身重叠 | ||||||||||||||
|
Comment on lines
+94
to
+96
|
||||||||||||||
| - **网格**:20×20×20,坐标范围 [0, 19]³ | |
| - **蛇体存储**:`[SIMD3<Int>]`,每次前进 prepend 新头,pop 尾(若未吃食物) | |
| - **食物**:随机生成,最多 3 个同时存在,不与蛇身重叠 | |
| - **网格**:40×40×40,坐标范围 [0, 39]³(与 `Snake3DState.gridSize` 一致) | |
| - **蛇体存储**:`[SIMD3<Int>]`,每次前进 prepend 新头,pop 尾(若未吃食物),当前实现最大段数约 512(与 GPU 缓冲区一致) | |
| - **食物**:随机生成,最多 16 个同时存在,不与蛇身重叠(与 `Snake3DGameLogic.maxFoodCount` 一致) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plan states the slerp rotation animation duration is ~0.3s, but the implementation uses
rotationDuration = 3.0seconds. Please update PLAN.md or adjust the code so the documentation matches the shipped behavior.