# CubeCity 新手开发指南 🚀

欢迎加入 CubeCity 开发团队！这是一款基于 Three.js 和 Vue 3 的 2.5D 卡通城市模拟经营游戏。本指南将帮助你快速上手项目开发，成为一名优秀的 CubeCity 开发者。

---

## 📋 目录

1. [项目概述](#项目概述)
2. [技术栈介绍](#技术栈介绍)
3. [开发环境搭建](#开发环境搭建)
4. [项目结构解析](#项目结构解析)
5. [核心概念理解](#核心概念理解)
6. [开发规范](#开发规范)
7. [常见开发任务](#常见开发任务)
8. [调试与测试](#调试与测试)
9. [部署与发布](#部署与发布)
10. [常见问题解答](#常见问题解答)

---

## 🎯 项目概述

### 项目简介
CubeCity 是一款 2.5D 卡通风格的城市建设模拟游戏，玩家通过放置、管理各类建筑，经营并扩展属于自己的城市。

### 核心特性
- 🏗️ **3D 城市建设**：基于 Three.js 的 3D 场景渲染
- 🎮 **模拟经营**：RCI & ESG 多维建筑体系
- 💾 **本地存储**：自动保存游戏进度
- 📱 **响应式设计**：支持桌面端和移动端
- 🌍 **国际化**：支持中英文切换
- 🎨 **现代化 UI**：基于 Vue 3 + Tailwind CSS

### 开发目标
- 提供流畅的 3D 城市建设体验
- 实现复杂的建筑相互作用系统
- 构建可扩展的游戏架构
- 保持代码的可维护性和可读性

---

## 🛠️ 技术栈介绍

### 核心技术
| 技术 | 版本 | 用途 |
|------|------|------|
| **Vue 3** | 3.x | 前端框架，负责 UI 层 |
| **Three.js** | 0.172.0 | 3D 图形渲染引擎 |
| **Vite** | 5.4.0 | 构建工具和开发服务器 |
| **Pinia** | 3.0.3 | 状态管理 |
| **Tailwind CSS** | 3.4.9 | CSS 框架 |

### 辅助技术
| 技术 | 用途 |
|------|------|
| **GSAP** | 动画库，用于 UI 和 3D 动画 |
| **Cannon.js** | 物理引擎 |
| **Mitt** | 事件总线，用于组件通信 |
| **Vue I18n** | 国际化支持 |
| **Tweakpane** | 调试面板 |

### 开发工具
| 工具 | 用途 |
|------|------|
| **ESLint** | 代码质量检查 |
| **Prettier** | 代码格式化 |
| **Playwright** | 端到端测试 |
| **Husky** | Git hooks |
| **Commitlint** | 提交信息规范 |

---

## 🚀 开发环境搭建

### 1. 环境要求
- **Node.js**: >= 18.0.0
- **包管理器**: pnpm (推荐) 或 npm
- **编辑器**: VS Code (推荐)
- **浏览器**: Chrome/Edge (支持 WebGL)

### 2. 克隆项目
```bash
git clone https://github.com/your-username/CubeCity.git
cd CubeCity
```

### 3. 安装依赖
```bash
# 使用 pnpm (推荐)
pnpm install

# 或使用 npm
npm install
```

### 4. 启动开发服务器
```bash
pnpm dev
# 或
npm run dev
```

访问 `http://localhost:5173` 查看项目。

### 5. 其他常用命令
```bash
# 构建生产版本
pnpm build

# 预览生产版本
pnpm preview

# 代码检查
pnpm lint

# 代码格式化
pnpm lint:fix

# 运行测试
pnpm test:chrome
```

---

## 📁 项目结构解析

```
CubeCity/
├── docs/                    # 项目文档
│   ├── PRD.md              # 产品需求文档
│   ├── TD.md               # 技术设计文档
│   └── 新手指南.md         # 玩家指南
├── public/                  # 静态资源
│   ├── models/             # 3D 模型文件
│   ├── textures/           # 纹理文件
│   └── fonts/              # 字体文件
├── src/                     # 源代码
│   ├── components/         # Vue 组件
│   ├── js/                 # Three.js 相关代码
│   │   ├── components/     # 3D 组件
│   │   ├── tools/          # 工具类
│   │   ├── utils/          # 工具函数
│   │   └── world/          # 世界管理
│   ├── shaders/            # GLSL 着色器
│   ├── stores/             # Pinia 状态管理
│   ├── assets/             # 资源文件
│   └── css/                # 样式文件
├── tests/                   # 测试文件
├── package.json            # 项目配置
└── vite.config.js          # Vite 配置
```

### 核心文件说明

#### Vue 层 (src/components/)
- `App.vue`: 主应用组件
- `GameCanvas.vue`: 游戏画布组件
- `BuildingSidebar.vue`: 建筑选择面板
- `BuildingDetail.vue`: 建筑详情面板

#### Three.js 层 (src/js/)
- `experience.js`: 核心体验类，单例模式
- `camera.js`: 相机管理
- `renderer.js`: 渲染器管理
- `world.js`: 世界管理
- `components/`: 3D 组件
  - `tiles/`: 地皮系统
  - `buildings/`: 建筑系统
  - `effects/`: 特效系统

#### 状态管理 (src/stores/)
- `useGameState.js`: 游戏状态管理

---

## 🧠 核心概念理解

### 1. 架构设计模式

#### 单例模式 (Experience)
```javascript
// src/js/experience.js
export default class Experience {
  constructor() {
    if (Experience.instance) {
      return Experience.instance
    }
    Experience.instance = this

    // 初始化核心组件
    this.scene = new THREE.Scene()
    this.camera = new Camera()
    this.renderer = new Renderer()
    // ...
  }
}
```

#### 组件化设计
- **Vue 组件**: 负责 UI 交互和状态展示
- **Three.js 组件**: 负责 3D 场景渲染和逻辑
- **状态管理**: Pinia 统一管理游戏状态

### 2. 通信机制

#### Vue ↔ Three.js 通信
```javascript
// 使用 mitt 事件总线
import emitter from './utils/event-bus.js'

// Vue 组件发送事件
emitter.emit('ui:building-selected', { type: 'house' })

// Three.js 组件监听事件
emitter.on('ui:building-selected', (data) => {
  // 处理建筑选择逻辑
})
```

#### 状态同步
```javascript
// 使用 Pinia 进行状态管理
import { useGameState } from '@/stores/useGameState.js'

const gameState = useGameState()
gameState.setMode('build')
gameState.setSelectedBuilding({ type: 'house', level: 1 })
```

### 3. 资源管理

#### 资源加载
```javascript
// src/js/sources.js - 定义资源
export default [
  {
    name: 'house',
    type: 'gltfModel',
    path: 'models/house_level1.glb'
  }
]

// 使用资源
const houseModel = this.experience.resources.items.house
```

#### 着色器管理
```javascript
// src/shaders/ - GLSL 着色器
import fragmentShader from '@/shaders/fragment.glsl'
import vertexShader from '@/shaders/vertex.glsl'

const material = new THREE.ShaderMaterial({
  vertexShader,
  fragmentShader,
  uniforms: {
    time: { value: 0 }
  }
})
```

---

## 📝 开发规范

### 1. 代码风格

#### JavaScript/TypeScript
- 使用 ES6+ 语法
- 类名使用大驼峰命名
- 方法名使用小驼峰命名
- 常量使用大写下划线
- 必须添加中文注释

#### Vue 组件
- 组件名使用大驼峰命名
- 文件名与组件名一致
- 使用 Composition API
- 样式使用 Tailwind CSS

#### Three.js 组件
```javascript
export default class YourComponent {
  constructor() {
    // 获取 Experience 单例实例
    this.experience = new Experience()

    // 获取需要的核心组件
    this.scene = this.experience.scene
    this.resources = this.experience.resources
    this.debug = this.experience.debug

    // 初始化组件
    this.init()
  }

  init() {
    // 组件初始化逻辑
  }

  update() {
    // 更新逻辑
  }

  resize() {
    // 响应式调整
  }
}
```

### 2. 文件组织

#### 组件文件结构
```
src/js/components/
├── tiles/           # 地皮相关组件
├── buildings/       # 建筑相关组件
├── effects/         # 特效组件
└── ui/             # UI 相关组件
```

#### 工具文件结构
```
src/js/utils/
├── debug.js        # 调试工具
├── event-bus.js    # 事件总线
├── resources.js    # 资源管理
└── sizes.js        # 尺寸管理
```

### 3. 命名规范

#### 文件命名
- 组件文件: `PascalCase.js`
- 工具文件: `kebab-case.js`
- 着色器文件: `kebab-case.glsl`

#### 变量命名
```javascript
// 常量
const BUILDING_TYPES = ['house', 'factory', 'shop']

// 类名
class BuildingFactory {}

// 方法名
function createBuilding() {}

// 私有属性
this._privateProperty = value
```

### 4. 注释规范

#### 中文注释要求
```javascript
/**
 * 建筑工厂类
 * 负责创建和管理不同类型的建筑实例
 */
export default class BuildingFactory {
  /**
   * 创建建筑实例
   * @param {string} type - 建筑类型
   * @param {number} level - 建筑等级
   * @returns {Building} 建筑实例
   */
  createBuilding(type, level) {
    // 根据类型创建对应建筑
    switch (type) {
      case 'house':
        return new House(level)
      case 'factory':
        return new Factory(level)
      default:
        throw new Error(`未知建筑类型: ${type}`)
    }
  }
}
```

---

## 🔧 常见开发任务

### 1. 添加新建筑类型

#### 步骤 1: 定义建筑数据
```javascript
// src/constants/constants.js
export const BUILDING_DATA = {
  newBuilding: {
    name: { zh: '新建筑', en: 'New Building' },
    type: 'newBuilding',
    icon: '🏢',
    category: 'commercial',
    levels: {
      1: {
        displayName: { zh: '基础新建筑', en: 'Basic New Building' },
        cost: 500,
        coinOutput: 25,
        powerUsage: 10,
        pollution: 2,
        upgradeCost: 1000,
        nextLevel: 2,
        visible: true
      }
    }
  }
}
```

#### 步骤 2: 创建 3D 组件
```javascript
// src/js/components/buildings/new-building.js
import Building from './building.js'

export default class NewBuilding extends Building {
  constructor(level = 1) {
    super('newBuilding', level)

    // 加载模型
    this.model = this.resources.items.newBuilding
    this.scene.add(this.model)
  }

  // 重写特定方法
  getCoinOutput() {
    return this.buildingData.coinOutput * this.level
  }
}
```

#### 步骤 3: 添加模型资源
```javascript
// src/js/sources.js
export default [
  // ... 其他资源
  {
    name: 'newBuilding',
    type: 'gltfModel',
    path: 'models/new-building.glb'
  }
]
```

#### 步骤 4: 更新 UI 组件
```vue
<!-- src/components/BuildingSidebar.vue -->
<template>
  <div class="building-card" @click="selectBuilding('newBuilding')">
    <div class="building-icon">
      🏢
    </div>
    <div class="building-name">
      {{ t('newBuilding.name') }}
    </div>
    <div class="building-cost">
      {{ getBuildingCost('newBuilding') }}
    </div>
  </div>
</template>
```

### 2. 实现建筑相互作用

#### 步骤 1: 定义相互作用规则
```javascript
// src/constants/building-interactions.js
export const BUILDING_INTERACTIONS = {
  house: {
    park: {
      distance: 1,
      effect: 'maxPopulation',
      multiplier: 0.1, // +10%
      description: '相邻公园增加人口容量'
    },
    factory: {
      distance: 1,
      effect: 'maxPopulation',
      multiplier: -0.15, // -15%
      description: '相邻工厂减少人口容量'
    }
  }
}
```

#### 步骤 2: 实现相互作用逻辑
```javascript
// src/js/components/buildings/building.js
export default class Building {
  calculateInteractions() {
    const neighbors = this.getNeighborTiles()
    let bonus = 1.0

    neighbors.forEach((tile) => {
      if (tile.building) {
        const interaction = BUILDING_INTERACTIONS[this.type]?.[tile.building.type]
        if (interaction) {
          bonus += interaction.multiplier
        }
      }
    })

    return Math.max(0.5, bonus) // 最低 50% 效率
  }
}
```

### 3. 添加新特效

#### 步骤 1: 创建着色器
```glsl
// src/shaders/effects/new-effect/fragment.glsl
uniform float time;
uniform vec3 color;

varying vec2 vUv;

void main() {
  vec2 uv = vUv;
  float wave = sin(uv.x * 10.0 + time) * 0.5 + 0.5;
  gl_FragColor = vec4(color * wave, 1.0);
}
```

#### 步骤 2: 创建特效组件
```javascript
// src/js/components/effects/new-effect.js
import fragmentShader from '@/shaders/effects/new-effect/fragment.glsl'
import vertexShader from '@/shaders/effects/new-effect/vertex.glsl'

export default class NewEffect {
  constructor() {
    this.material = new THREE.ShaderMaterial({
      vertexShader,
      fragmentShader,
      uniforms: {
        time: { value: 0 },
        color: { value: new THREE.Color(0x00FF00) }
      },
      transparent: true
    })
  }

  update() {
    this.material.uniforms.time.value += 0.01
  }
}
```

### 4. 添加新 UI 功能

#### 步骤 1: 创建 Vue 组件
```vue
<!-- src/components/NewFeature.vue -->
<script setup>
import { ref } from 'vue'

const props = defineProps({
  title: {
    type: String,
    required: true
  }
})
</script>

<template>
  <div class="new-feature">
    <h3>{{ title }}</h3>
    <div class="content">
      <slot />
    </div>
  </div>
</template>

<style scoped>
.new-feature {
  @apply p-4 bg-white rounded-lg shadow-md;
}
</style>
```

#### 步骤 2: 集成到主应用
```vue
<!-- src/App.vue -->
<script setup>
import NewFeature from '@/components/NewFeature.vue'
</script>

<template>
  <div id="app">
    <!-- 现有内容 -->
    <NewFeature title="新功能" />
  </div>
</template>
```

---

## 🐛 调试与测试

### 1. 调试工具

#### 浏览器开发者工具
- **Console**: 查看日志和错误
- **Network**: 检查资源加载
- **Performance**: 分析性能问题
- **Application**: 查看本地存储

#### Three.js 调试
```javascript
// 启用调试面板
if (this.debug.active) {
  this.debugFolder = this.debug.ui.addFolder({
    title: '组件名称',
    expanded: true
  })

  this.debugFolder.addBinding(this.object, 'position', {
    label: '位置'
  })
}
```

#### Vue DevTools
- 安装 Vue DevTools 浏览器扩展
- 查看组件状态和事件
- 调试 Pinia 状态管理

### 2. 性能优化

#### 3D 场景优化
```javascript
// 使用对象池
class ObjectPool {
  constructor(createFn) {
    this.pool = []
    this.createFn = createFn
  }

  get() {
    return this.pool.pop() || this.createFn()
  }

  release(obj) {
    this.pool.push(obj)
  }
}

// 使用 LOD (Level of Detail)
const lod = new THREE.LOD()
lod.addLevel(highDetailMesh, 0)
lod.addLevel(mediumDetailMesh, 50)
lod.addLevel(lowDetailMesh, 100)
```

#### 内存管理
```javascript
// 正确释放资源
dispose() {
  // 释放几何体
  this.geometry.dispose()

  // 释放材质
  this.material.dispose()

  // 从场景中移除
  this.scene.remove(this.mesh)

  // 清空纹理
  this.texture.dispose()
}
```

### 3. 测试

#### 单元测试
```javascript
import BuildingCard from '@/components/BuildingCard.vue'
import { mount } from '@vue/test-utils'
// tests/components.test.js
import { describe, expect, it } from 'vitest'

describe('BuildingCard', () => {
  it('显示正确的建筑信息', () => {
    const wrapper = mount(BuildingCard, {
      props: {
        building: {
          name: '住宅',
          cost: 300
        }
      }
    })

    expect(wrapper.text()).toContain('住宅')
    expect(wrapper.text()).toContain('300')
  })
})
```

#### 端到端测试
```javascript
// tests/e2e/game.test.js
import { expect, test } from '@playwright/test'

test('建筑放置功能', async ({ page }) => {
  await page.goto('/')

  // 选择建筑
  await page.click('[data-testid="building-house"]')

  // 点击地皮放置
  await page.click('[data-testid="tile-0-0"]')

  // 验证建筑已放置
  await expect(page.locator('[data-testid="building-instance"]')).toBeVisible()
})
```

---

## 🚀 部署与发布

### 1. 构建生产版本
```bash
# 构建
pnpm build

# 预览构建结果
pnpm preview
```

### 2. 部署配置
```javascript
// vite.config.js
export default defineConfig({
  build: {
    outDir: 'dist',
    assetsDir: 'assets',
    sourcemap: false,
    minify: 'terser',
    rollupOptions: {
      output: {
        manualChunks: {
          three: ['three'],
          vendor: ['vue', 'pinia']
        }
      }
    }
  }
})
```

### 3. 性能优化
- 启用 Gzip 压缩
- 使用 CDN 加速
- 配置缓存策略
- 优化图片和模型资源

---

## ❓ 常见问题解答

### Q1: 如何快速理解项目架构？
A: 建议按以下顺序学习：
1. 阅读 `docs/PRD.md` 了解产品需求
2. 查看 `docs/TD.md` 理解技术设计
3. 从 `src/js/experience.js` 开始，理解核心架构
4. 查看 `src/components/App.vue` 了解 UI 结构

### Q2: 如何添加新的建筑类型？
A: 参考 [添加新建筑类型](#1-添加新建筑类型) 章节，需要：
1. 在 `constants.js` 中定义建筑数据
2. 创建对应的 3D 组件
3. 添加模型资源
4. 更新 UI 组件

### Q3: 如何调试 3D 场景问题？
A: 使用以下方法：
1. 启用调试面板查看对象属性
2. 使用浏览器开发者工具的 Console
3. 检查 Three.js 的 WebGL 错误
4. 使用 `console.log` 输出关键数据

### Q4: 如何处理性能问题？
A: 常见优化方法：
1. 使用对象池减少内存分配
2. 实现 LOD 系统
3. 合理使用纹理压缩
4. 优化渲染循环

### Q5: 如何实现国际化？
A: 使用 Vue I18n：
1. 在 `src/assets/i18n/` 中添加语言文件
2. 使用 `$t()` 函数包装文本
3. 通过 `useI18n()` 切换语言

### Q6: 如何提交代码？
A: 遵循项目规范：
1. 使用 `git add` 暂存更改
2. 使用 `git commit` 提交，遵循 commitizen 规范
3. 提交信息格式：`feat: 添加新建筑类型 (#issue)`

---

## 📚 学习资源

### 官方文档
- [Vue 3 官方文档](https://vuejs.org/)
- [Three.js 官方文档](https://threejs.org/docs/)
- [Vite 官方文档](https://vitejs.dev/)
- [Pinia 官方文档](https://pinia.vuejs.org/)

### 推荐阅读
- [Three.js 最佳实践](https://discoverthreejs.com/)
- [Vue 3 组合式 API](https://vuejs.org/guide/extras/composition-api-faq.html)
- [WebGL 基础](https://webglfundamentals.org/)

### 社区资源
- [Three.js 论坛](https://discourse.threejs.org/)
- [Vue.js 社区](https://forum.vuejs.org/)
- [GitHub Issues](https://github.com/your-username/CubeCity/issues)

---

## 🤝 贡献指南

### 开发流程
1. Fork 项目到个人仓库
2. 创建功能分支：`git checkout -b feature/new-feature`
3. 提交更改：`git commit -m "feat: 添加新功能"`
4. 推送到分支：`git push origin feature/new-feature`
5. 创建 Pull Request

### 代码审查
- 所有代码变更需要经过审查
- 确保代码符合项目规范
- 添加必要的测试用例
- 更新相关文档

### 问题反馈
- 使用 GitHub Issues 报告 Bug
- 提供详细的复现步骤
- 包含环境信息和错误日志
- 建议解决方案

---

## 📞 联系方式

- **项目地址**: [GitHub Repository](https://github.com/your-username/CubeCity)
- **问题反馈**: [GitHub Issues](https://github.com/your-username/CubeCity/issues)
- **讨论区**: [GitHub Discussions](https://github.com/your-username/CubeCity/discussions)

---

## 🎉 结语

恭喜你完成了 CubeCity 新手开发指南的学习！现在你已经具备了开始开发的基础知识。

记住：
- 🎯 **保持学习心态**：技术栈在不断发展，持续学习新知识
- 🤝 **团队协作**：与团队成员保持良好的沟通和协作
- 📝 **文档优先**：及时更新文档，帮助其他开发者
- 🐛 **质量第一**：注重代码质量和用户体验
- 🚀 **勇于创新**：在现有基础上提出改进建议

祝你在 CubeCity 项目中开发愉快，创造出优秀的作品！🌟

---

*最后更新：2024年12月*
