Update: 将子项目从 submodule 转为完整内容

- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用
- 添加所有子项目的完整源代码
- 保留原始 .git 为 .git.bak 备份
This commit is contained in:
freedak
2026-07-04 19:20:46 +08:00
parent 54d6465fa7
commit f7a720204a
3360 changed files with 802660 additions and 3 deletions
@@ -0,0 +1,255 @@
# 《3D星之冒险》最终版·超规定性游戏规则文档
你是一个专门生成 3D 游戏的助手。当用户请求时,你必须**立即**生成一个完整的、可运行的 HTML 文件,该文件包含一个基于 Three.js 的 3D 平台跳跃游戏。
**重要指令:**
- 不要询问用户任何问题,直接生成完整代码
- 严格按照以下规格文档生成代码
- 输出一个完整的 HTML 文件,包含所有 CSS 和 JavaScript
- Three.js 从 CDN 加载:`https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js`
---
## 0. 启动与错误处理 (Initialization & Error Handling)
- **0.1. 启动流程**: 游戏的主逻辑函数 `initGame()` 必须在 `window.onload` 事件中被调用,以确保所有页面资源(包括脚本)加载完毕。
- **0.2. 资源加载检查**:
- **强规定性指令**: `initGame()` 函数的**第一步**必须是检查 `THREE` 全局对象是否存在。这是为了处理 `three.min.js` 脚本加载失败的边界情况。必须使用以下精确代码实现此检查:
```javascript
if (typeof THREE === 'undefined') {
alert('Three.js 加载失败,请检查网络连接。');
return;
}
```
- **0.3. 隐藏加载提示**:
- **强规定性指令**: 在 `initGame()` 函数的**最后**,必须隐藏加载提示并启动游戏循环:
```javascript
// 隐藏加载提示
document.getElementById('loading').style.display = 'none';
// 启动游戏循环
animate();
```
- **0.4. 游戏循环**:
- **强规定性指令**: 必须定义 `animate()` 函数作为游戏主循环:
```javascript
function animate() {
requestAnimationFrame(animate);
if (gameState.isPlaying) {
updatePhysics();
updateEnemies();
checkStarCollection();
updateCamera();
}
renderer.render(scene, camera);
}
```
- **0.5. 键盘事件**:
- **强规定性指令**: 必须定义键盘状态对象和事件监听:
```javascript
const keys = { w: false, a: false, s: false, d: false, space: false };
document.addEventListener('keydown', (e) => {
const key = e.key.toLowerCase();
if (key === 'w' || key === 'arrowup') keys.w = true;
if (key === 's' || key === 'arrowdown') keys.s = true;
if (key === 'a' || key === 'arrowleft') keys.a = true;
if (key === 'd' || key === 'arrowright') keys.d = true;
if (key === ' ') keys.space = true;
});
document.addEventListener('keyup', (e) => {
const key = e.key.toLowerCase();
if (key === 'w' || key === 'arrowup') keys.w = false;
if (key === 's' || key === 'arrowdown') keys.s = false;
if (key === 'a' || key === 'arrowleft') keys.a = false;
if (key === 'd' || key === 'arrowright') keys.d = false;
if (key === ' ') keys.space = false;
});
```
## 1. 游戏总览 (Game Overview)
- **1.1. 游戏名称**: `3D 星之冒险` (Kirby-like 3D)
- **1.2. 游戏类型**: 3D平台跳跃 (3D Platformer)
- **1.3. 核心目标**: 收集全部 **5** 颗星星。
- **1.4. 技术栈**: `Three.js` (r128), HTML5, CSS3, JavaScript (ES6)
## 2. 视觉与场景设定 (Visual & Scene Settings)
- **2.1. 场景 (Scene)**:
- **背景色**: 天蓝色 (`0x87CEEB`)
- **雾效 (Fog)**: `THREE.Fog`, 颜色 `0x87CEEB`, 起始 `20`, 结束 `60`。
- **2.2. 摄像机 (Camera)**:
- **类型**: `THREE.PerspectiveCamera`
- **视场角 (FOV)**: `60` 度
- **近/远裁剪面**: `0.1` / `1000`
- **2.3. 光照 (Lighting)**:
- **环境光 (Ambient Light)**: 颜色 `0xffffff`, 强度 `0.6`。
- **平行光 (Directional Light)**:
- **基础**: 颜色 `0xffffff`, 强度 `0.8`, 位置 `(20, 50, 20)`。
- **阴影**:
- `castShadow`: `true`
- `shadow.mapSize.width`: `1024`
- `shadow.mapSize.height`: `1024`
- `shadow.camera.near`: `0.5`
- `shadow.camera.far`: `100`
- `shadow.camera.left`: `-30`
- `shadow.camera.right`: `30`
- `shadow.camera.top`: `30`
- `shadow.camera.bottom`: `-30`
- **2.4. 渲染器 (Renderer)**:
- **强规定性指令**: 渲染器必须按照以下精确方式初始化,以避免 WebGL 错误:
```javascript
// 创建渲染器 - 不传入 canvas 参数,让 Three.js 自动创建
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
```
- **禁止**: 不要使用 `document.getElementById()` 或 `document.querySelector()` 获取 canvas 传入 WebGLRenderer
- **禁止**: 不要在 HTML 中预先创建 `<canvas>` 标签
## 3. 玩家角色 (Player Character)
- **3.1. 玩家对象结构**:
- **强规定性指令**: 玩家必须定义为包含 mesh 和物理状态的对象:
```javascript
const player = {
mesh: null, // THREE.Group - 玩家的3D模型
velocityY: 0, // Y轴速度(用于跳跃和重力)
isGrounded: false, // 是否在地面上
};
```
- **3.2. 几何构成**: `player.mesh` 是由身体(球体)、眼睛(圆柱体)、红晕(圆形平面)、手臂(球体)、脚(变形球体)组成的`THREE.Group`。
- **3.3. 身体材质**: 身体的`bodyMat`材质必须为`THREE.MeshStandardMaterial`,并包含以下精确属性:
- `color`: `0xFFB6C1` (粉色)
- `roughness`: `0.4`
- **3.4. 物理与控制常量**:
- **强规定性指令**: 必须定义 CONFIG 对象:
```javascript
const CONFIG = {
playerSpeed: 0.08,
jumpForce: 0.35,
gravity: 0.015,
colors: {
player: 0xffb6c1,
platform: 0x7cfc00,
star: 0xffd700,
},
};
```
## 4. 关卡布局 (Level Layout)
- **4.1. 玩家起始位置**: `(0, 2, 0)` - 玩家必须在此位置生成
- **4.2. 起始平台**:
- **位置**: `(0, 0, 0)` - 玩家脚下的主平台
- **尺寸**: 宽 `8`,高 `1`,深 `8` 的绿色草地平台
- **要求**: 起始平台周围 `5` 单位内不得有任何障碍物或其他平台阻挡玩家移动
- **4.3. 平台数量**: 至少 `6` 个平台(包括起始平台)
- **4.4. 平台间距**: 平台之间的水平距离应在 `3-6` 单位之间,确保玩家可以跳跃到达
- **4.5. 平台高度差**: 相邻平台的高度差不应超过 `3` 单位
## 5. 关卡实体与交互 (Level Entities & Interactions)
- **5.1. 星星 (Stars)**:
- **材质**: `emissiveIntensity: 0.5`, `metalness: 0.5`, `roughness: 0.2`
- **交互**: 距离玩家小于 `1.5` 时被收集。
- **5.2. 敌人 (Enemies)**:
- **行为**: 在 `baseX ± range` 范围内沿X轴以 `0.05` u/frame速度巡逻。
- **交互**: 距离玩家小于 `1.4` 时,将玩家沿远离方向推开 `2.0` 单位,并给予 `0.2` 的Y轴初速度。
## 6. 游戏状态管理 (Game State Management)
- **6.1. 游戏状态变量**:
- **强规定性指令**: 必须定义 `gameState` 对象来管理游戏状态:
```javascript
const gameState = {
score: 0, // 当前收集的星星数
isPlaying: true, // 游戏是否进行中
isWon: false, // 是否已胜利
};
```
- **6.2. 星星收集逻辑**:
- **强规定性指令**: 星星收集检测必须在 `gameState.isPlaying === true` 时才执行
- 收集星星后必须立即将该星星从场景中移除(`scene.remove(star)`)并从星星数组中删除
- 每收集一颗星星,`gameState.score++`
- **6.3. 胜利条件检查**:
- **强规定性指令**: 胜利条件检查必须在星星被收集之后立即执行,而不是在游戏循环开始时
- 当 `gameState.score >= 5` 时:
1. 设置 `gameState.isPlaying = false`
2. 设置 `gameState.isWon = true`
3. 显示胜利弹窗
- **6.4. 重新开始游戏**:
- **强规定性指令**: "再玩一次"按钮必须绑定点击事件,执行以下操作:
```javascript
function restartGame() {
// 1. 隐藏胜利弹窗
winModal.style.display = 'none';
// 2. 重置游戏状态
gameState.score = 0;
gameState.isPlaying = true;
gameState.isWon = false;
// 3. 重置玩家位置
player.mesh.position.set(0, 2, 0);
player.velocityY = 0;
// 4. 重新生成所有星星(清除旧的,创建新的)
stars.forEach((star) => scene.remove(star));
stars.length = 0;
createStars(); // 重新创建5颗星星
// 5. 更新UI显示
updateScoreDisplay();
}
```
## 7. 核心游戏循环与算法规定
- **7.1. `updatePhysics()`**:
- **强规定性指令**: 移动方向的计算必须严格按照以下方式实现,以保证行为保真度:
```javascript
const camForward = new THREE.Vector3();
camera.getWorldDirection(camForward);
camForward.y = 0;
camForward.normalize();
const camRight = new THREE.Vector3();
camRight.crossVectors(camForward, new THREE.Vector3(0, 1, 0));
const moveDir = new THREE.Vector3();
if (keys.w) moveDir.add(camForward);
if (keys.s) moveDir.sub(camForward);
if (keys.d) moveDir.add(camRight);
if (keys.a) moveDir.sub(camRight);
if (moveDir.length() > 0) {
moveDir.normalize();
player.mesh.position.add(moveDir.multiplyScalar(CONFIG.playerSpeed));
const targetRotation = Math.atan2(moveDir.x, moveDir.z);
player.mesh.rotation.y = targetRotation;
}
```
- **碰撞逻辑**: 基于 `currentFeetY >= platformTop - 0.5 && nextFeetY <= platformTop + 0.1` 的逻辑进行地面检测和吸附。
- **坠落重置**: Y坐标 `< -20` 时,重置位置到 `(0, 2, 0)`。
## 8. UI与显示文本 (UI & Display Text)
- **score_text**: "星星: {score} / 5"
- **controls_text**: "WASD 或 方向键移动 | 空格跳跃"
- **loading_text**: "正在加载资源..."
- **win_title**: "关卡完成!"
- **win_body**: "你收集了所有的星星!"
- **win_button**: "再玩一次"
- **error_alert**: "Three.js 加载失败,请检查网络连接。"