feat: 添加完整的项目设计文档,替换旧的原型需求文档
This commit is contained in:
668
01_文档/初步设计文档.md
Normal file
668
01_文档/初步设计文档.md
Normal file
@@ -0,0 +1,668 @@
|
||||
# 打飞机小程序技术选型与功能架构设计文档
|
||||
|
||||
> **撰写人**: 移动端产品架构专家 | 苹果设计奖获得者
|
||||
> **文档版本**: v1.0
|
||||
> **创建日期**: 2024年9月11日
|
||||
> **项目**: 打飞机对战小程序
|
||||
|
||||
## 1. 项目概述与原型分析
|
||||
|
||||
### 1.1 核心功能模块
|
||||
基于原型设计分析,项目包含以下核心功能:
|
||||
|
||||
**页面结构**:
|
||||
- 入口页面:用户登录、游戏模式选择
|
||||
- 房间管理:创建房间、加入房间、房间等待
|
||||
- 游戏核心:飞机布置、实时对战
|
||||
- 用户系统:个人信息、战绩统计
|
||||
|
||||
**设计特色**:
|
||||
- 深色科技主题UI设计
|
||||
- 移动优先的交互体验
|
||||
- 高度优化的触控操作
|
||||
- 实时对战能力
|
||||
|
||||
### 1.2 MVP原则遵循
|
||||
严格按照原型设计实现,不增加额外功能:
|
||||
- 基础双人对战游戏
|
||||
- 房间制匹配模式
|
||||
- 简洁用户界面
|
||||
- 核心游戏机制
|
||||
|
||||
## 2. 技术选型方案
|
||||
|
||||
### 2.1 前端技术栈
|
||||
|
||||
#### 2.1.1 小程序框架选择
|
||||
**推荐:Taro 4.x + React 18**
|
||||
|
||||
```typescript
|
||||
// 技术栈配置
|
||||
{
|
||||
"framework": "Taro 4.x",
|
||||
"ui": "React 18 + TypeScript",
|
||||
"css": "Sass + CSS Modules",
|
||||
"state": "Zustand",
|
||||
"http": "Taro.request + axios适配",
|
||||
"websocket": "Taro WebSocket API"
|
||||
}
|
||||
```
|
||||
|
||||
**选择理由**:
|
||||
- 一码多端,可快速扩展到H5/APP
|
||||
- React生态成熟,组件复用度高
|
||||
- TypeScript保证代码质量
|
||||
- 与原型设计的现代化风格匹配
|
||||
|
||||
#### 2.1.2 状态管理
|
||||
**Zustand** - 轻量级状态管理
|
||||
|
||||
```typescript
|
||||
// 游戏状态Store结构
|
||||
interface GameStore {
|
||||
// 用户状态
|
||||
user: UserInfo | null
|
||||
// 房间状态
|
||||
room: RoomInfo | null
|
||||
// 游戏状态
|
||||
gameState: GameState | null
|
||||
// 连接状态
|
||||
connectionState: 'connected' | 'connecting' | 'disconnected'
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.1.3 UI组件设计
|
||||
基于原型的深色科技主题:
|
||||
|
||||
```scss
|
||||
// 设计Token
|
||||
$primary-color: #6366f1;
|
||||
$secondary-color: #40e0d0;
|
||||
$bg-primary: #0f1419;
|
||||
$gradient-bg: linear-gradient(135deg, #0f0f1a 0%, #1a1a2e 30%, #16213e 70%, #0f3460 100%);
|
||||
```
|
||||
|
||||
### 2.2 后端技术架构
|
||||
|
||||
#### 2.2.1 服务端选择
|
||||
**Node.js + TypeScript + Fastify**
|
||||
|
||||
```typescript
|
||||
// 服务端架构
|
||||
{
|
||||
"runtime": "Node.js 18+",
|
||||
"framework": "Fastify",
|
||||
"language": "TypeScript",
|
||||
"websocket": "ws + socket.io",
|
||||
"database": "MongoDB + Redis",
|
||||
"deployment": "Docker + PM2"
|
||||
}
|
||||
```
|
||||
|
||||
**架构优势**:
|
||||
- 高性能异步处理
|
||||
- WebSocket原生支持
|
||||
- TypeScript类型安全
|
||||
- 快速开发迭代
|
||||
|
||||
#### 2.2.2 数据存储设计
|
||||
|
||||
```typescript
|
||||
// MongoDB数据模型
|
||||
interface User {
|
||||
_id: ObjectId
|
||||
openid: string
|
||||
nickname: string
|
||||
avatar: string
|
||||
stats: {
|
||||
totalGames: number
|
||||
wins: number
|
||||
winRate: number
|
||||
}
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
interface Room {
|
||||
_id: ObjectId
|
||||
roomCode: string
|
||||
hostId: string
|
||||
guestId?: string
|
||||
status: 'waiting' | 'playing' | 'finished'
|
||||
gameData?: GameData
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
interface GameSession {
|
||||
_id: ObjectId
|
||||
roomId: string
|
||||
players: [string, string]
|
||||
gameState: GameStateData
|
||||
moves: Move[]
|
||||
result?: GameResult
|
||||
}
|
||||
```
|
||||
|
||||
```redis
|
||||
// Redis缓存策略
|
||||
ROOM:{roomCode} -> RoomData (TTL: 1小时)
|
||||
USER_ONLINE:{userId} -> ConnectionInfo (TTL: 30分钟)
|
||||
GAME_SESSION:{sessionId} -> GameState (TTL: 2小时)
|
||||
```
|
||||
|
||||
### 2.3 实时通信方案
|
||||
|
||||
#### 2.3.1 WebSocket架构
|
||||
基于原型的实时对战需求:
|
||||
|
||||
```typescript
|
||||
// WebSocket消息协议
|
||||
interface GameMessage {
|
||||
type: 'JOIN_ROOM' | 'PLACE_PLANES' | 'ATTACK' | 'GAME_STATE_SYNC'
|
||||
roomCode: string
|
||||
userId: string
|
||||
data: any
|
||||
timestamp: number
|
||||
}
|
||||
|
||||
// 实时功能支持
|
||||
- 房间状态同步
|
||||
- 对手攻击实时显示(原型中的实时瞄准提示)
|
||||
- 游戏状态广播
|
||||
- 断线重连机制
|
||||
```
|
||||
|
||||
## 3. 核心功能架构设计
|
||||
|
||||
### 3.1 游戏核心逻辑
|
||||
|
||||
#### 3.1.1 飞机模型设计
|
||||
基于原型设计需求:
|
||||
|
||||
```typescript
|
||||
// 飞机几何模型
|
||||
interface Plane {
|
||||
id: string
|
||||
center: Position
|
||||
direction: 'UP' | 'DOWN' | 'LEFT' | 'RIGHT'
|
||||
positions: Position[] // 11个位置
|
||||
isDestroyed: boolean
|
||||
parts: {
|
||||
head: Position
|
||||
wings: Position[] // 5个位置
|
||||
body: Position[] // 2个位置
|
||||
tail: Position[] // 3个位置
|
||||
}
|
||||
}
|
||||
|
||||
// 10x10棋盘表示
|
||||
interface GameBoard {
|
||||
cells: Cell[][] // 10x10网格
|
||||
planes: Plane[] // 3架飞机
|
||||
}
|
||||
|
||||
interface Cell {
|
||||
position: Position
|
||||
state: 'EMPTY' | 'PLANE_PART' | 'ATTACKED_MISS' | 'ATTACKED_HIT'
|
||||
planeId?: string
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.1.2 攻击逻辑
|
||||
```typescript
|
||||
// 攻击结果类型
|
||||
interface AttackResult {
|
||||
type: 'MISS' | 'HIT' | 'DESTROY'
|
||||
position: Position
|
||||
planeId?: string
|
||||
gameEnded?: boolean
|
||||
winner?: string
|
||||
}
|
||||
|
||||
// 攻击处理逻辑
|
||||
class GameEngine {
|
||||
processAttack(
|
||||
board: GameBoard,
|
||||
position: Position
|
||||
): AttackResult {
|
||||
// 1. 检查位置有效性
|
||||
// 2. 判断攻击结果(miss/hit/destroy)
|
||||
// 3. 更新游戏状态
|
||||
// 4. 检查游戏结束条件
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 页面功能模块
|
||||
|
||||
#### 3.2.1 入口页面模块
|
||||
基于 [`01_入口页面.html`](01_文档/原型设计/01_入口页面.html) 设计:
|
||||
|
||||
```typescript
|
||||
// 入口页面功能
|
||||
interface EntryPageFeatures {
|
||||
// 用户信息显示
|
||||
userProfile: {
|
||||
avatar: string
|
||||
nickname: string
|
||||
level?: number
|
||||
}
|
||||
|
||||
// 游戏模式选择
|
||||
gameMode: {
|
||||
quickStart: () => void // AI对战
|
||||
onlineMatch: () => void // 自动匹配
|
||||
createRoom: () => void // 创建房间
|
||||
joinGame: () => void // 加入游戏
|
||||
}
|
||||
|
||||
// 游戏规则显示
|
||||
rulesDisplay: boolean
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2.2 房间管理模块
|
||||
基于原型设计的房间功能:
|
||||
|
||||
```typescript
|
||||
// 房间管理功能
|
||||
interface RoomManager {
|
||||
// 创建房间
|
||||
createRoom(): Promise<{roomCode: string}>
|
||||
|
||||
// 加入房间
|
||||
joinRoom(roomCode: string): Promise<boolean>
|
||||
|
||||
// 房间状态同步
|
||||
syncRoomState(): void
|
||||
|
||||
// 玩家准备状态
|
||||
setPlayerReady(ready: boolean): void
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2.3 游戏对战模块
|
||||
基于原型的对战页面设计:
|
||||
|
||||
```typescript
|
||||
// 对战功能模块
|
||||
interface BattleModule {
|
||||
// 飞机布置阶段
|
||||
placementPhase: {
|
||||
placePlane(center: Position, direction: Direction): boolean
|
||||
autoPlace(): void
|
||||
confirmPlacement(): void
|
||||
}
|
||||
|
||||
// 攻击阶段
|
||||
attackPhase: {
|
||||
selectTarget(position: Position): void
|
||||
confirmAttack(): void
|
||||
showAttackResult(result: AttackResult): void
|
||||
}
|
||||
|
||||
// 实时功能(原型中的实时瞄准显示)
|
||||
realTimeFeatures: {
|
||||
showOpponentAiming(position: Position): void
|
||||
hideOpponentAiming(): void
|
||||
syncGameState(): void
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 数据流架构
|
||||
|
||||
#### 3.3.1 状态管理流程
|
||||
```
|
||||
用户操作 -> Action派发 -> Store更新 -> 组件重渲染
|
||||
|
|
||||
WebSocket同步
|
||||
|
|
||||
服务端处理 -> 状态广播 -> 对手端更新
|
||||
```
|
||||
|
||||
#### 3.3.2 游戏流程设计
|
||||
基于原型页面流程:
|
||||
|
||||
```typescript
|
||||
// 游戏状态机
|
||||
enum GamePhase {
|
||||
WAITING = 'waiting', // 等待对手
|
||||
PLACING = 'placing', // 布置飞机
|
||||
BATTLING = 'battling', // 对战中
|
||||
FINISHED = 'finished' // 游戏结束
|
||||
}
|
||||
|
||||
// 回合控制
|
||||
interface TurnManager {
|
||||
currentPlayer: string
|
||||
phase: GamePhase
|
||||
timeLimit: number
|
||||
switchTurn(): void
|
||||
checkGameEnd(): boolean
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 技术实现细节
|
||||
|
||||
### 4.1 小程序适配策略
|
||||
|
||||
#### 4.1.1 页面路由设计
|
||||
```typescript
|
||||
// 页面路由配置
|
||||
const pages = [
|
||||
'pages/entry/index', // 入口页面
|
||||
'pages/room/create', // 创建房间
|
||||
'pages/room/join', // 加入房间
|
||||
'pages/room/waiting', // 等待房间
|
||||
'pages/game/prepare', // 准备页面
|
||||
'pages/game/battle' // 对战页面
|
||||
]
|
||||
|
||||
// 路由管理
|
||||
class Navigator {
|
||||
static toRoomCreate() {
|
||||
wx.navigateTo({ url: '/pages/room/create' })
|
||||
}
|
||||
|
||||
static toGameBattle(roomCode: string) {
|
||||
wx.navigateTo({
|
||||
url: `/pages/game/battle?roomCode=${roomCode}`
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.1.2 原生API集成
|
||||
```typescript
|
||||
// 微信小程序API封装
|
||||
class WxAPI {
|
||||
// 用户授权
|
||||
static async getUserInfo(): Promise<UserInfo> {
|
||||
const {userInfo} = await wx.getUserProfile({
|
||||
desc: '用于显示用户信息'
|
||||
})
|
||||
return userInfo
|
||||
}
|
||||
|
||||
// 震动反馈(基于原型的触觉反馈)
|
||||
static vibrate(): void {
|
||||
wx.vibrateShort({ type: 'light' })
|
||||
}
|
||||
|
||||
// 分享功能
|
||||
static onShareAppMessage() {
|
||||
return {
|
||||
title: '打飞机对战',
|
||||
path: '/pages/entry/index'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 性能优化方案
|
||||
|
||||
#### 4.2.1 渲染优化
|
||||
基于原型的复杂UI需求:
|
||||
|
||||
```typescript
|
||||
// 游戏棋盘优化渲染
|
||||
class BoardRenderer {
|
||||
private shouldUpdate = false
|
||||
private renderQueue: Position[] = []
|
||||
|
||||
// 批量更新棋盘状态
|
||||
batchUpdateCells(updates: CellUpdate[]): void {
|
||||
updates.forEach(update => {
|
||||
this.renderQueue.push(update.position)
|
||||
})
|
||||
|
||||
if (!this.shouldUpdate) {
|
||||
this.shouldUpdate = true
|
||||
this.nextTick(() => this.flushUpdates())
|
||||
}
|
||||
}
|
||||
|
||||
private flushUpdates(): void {
|
||||
// 批量DOM更新
|
||||
this.renderQueue.forEach(pos => this.updateCell(pos))
|
||||
this.renderQueue = []
|
||||
this.shouldUpdate = false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2.2 网络优化
|
||||
```typescript
|
||||
// 请求优化和缓存
|
||||
class NetworkManager {
|
||||
private cache = new Map<string, any>()
|
||||
private pending = new Map<string, Promise<any>>()
|
||||
|
||||
async request<T>(
|
||||
url: string,
|
||||
options?: RequestOptions
|
||||
): Promise<T> {
|
||||
const cacheKey = `${url}:${JSON.stringify(options)}`
|
||||
|
||||
// 检查缓存
|
||||
if (this.cache.has(cacheKey)) {
|
||||
return this.cache.get(cacheKey)
|
||||
}
|
||||
|
||||
// 检查pending请求
|
||||
if (this.pending.has(cacheKey)) {
|
||||
return this.pending.get(cacheKey)
|
||||
}
|
||||
|
||||
// 发起新请求
|
||||
const promise = this.makeRequest<T>(url, options)
|
||||
this.pending.set(cacheKey, promise)
|
||||
|
||||
try {
|
||||
const result = await promise
|
||||
this.cache.set(cacheKey, result)
|
||||
return result
|
||||
} finally {
|
||||
this.pending.delete(cacheKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 错误处理和监控
|
||||
|
||||
#### 4.3.1 错误边界
|
||||
```typescript
|
||||
// React错误边界组件
|
||||
class GameErrorBoundary extends React.Component {
|
||||
state = { hasError: false, error: null }
|
||||
|
||||
static getDerivedStateFromError(error: Error) {
|
||||
return { hasError: true, error }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||
// 错误上报
|
||||
this.reportError(error, errorInfo)
|
||||
}
|
||||
|
||||
private reportError(error: Error, errorInfo: ErrorInfo) {
|
||||
// 上报到监控系统
|
||||
wx.reportMonitor('game_error', {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
componentStack: errorInfo.componentStack
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return <ErrorFallback onRetry={() => this.setState({ hasError: false })} />
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 部署和运维方案
|
||||
|
||||
### 5.1 开发环境配置
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "taro build --type weapp --watch",
|
||||
"build": "taro build --type weapp",
|
||||
"build:h5": "taro build --type h5",
|
||||
"deploy": "npm run build && npm run upload"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tarojs/taro": "^4.0.0",
|
||||
"@tarojs/plugin-react": "^4.0.0",
|
||||
"react": "^18.2.0",
|
||||
"zustand": "^4.4.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 服务端部署
|
||||
```dockerfile
|
||||
# 服务端Docker配置
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
COPY . .
|
||||
EXPOSE 3000
|
||||
CMD ["node", "dist/server.js"]
|
||||
```
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
version: '3.8'
|
||||
services:
|
||||
game-server:
|
||||
build: .
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- MONGODB_URI=${MONGODB_URI}
|
||||
- REDIS_URI=${REDIS_URI}
|
||||
depends_on:
|
||||
- mongodb
|
||||
- redis
|
||||
|
||||
mongodb:
|
||||
image: mongo:6.0
|
||||
volumes:
|
||||
- mongo_data:/data/db
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
```
|
||||
|
||||
### 5.3 监控和日志
|
||||
```typescript
|
||||
// 游戏性能监控
|
||||
class PerformanceMonitor {
|
||||
// 游戏关键指标监控
|
||||
trackGameMetrics() {
|
||||
// 游戏启动时间
|
||||
const startTime = Date.now()
|
||||
|
||||
// 页面加载性能
|
||||
wx.reportPerformance(1001, {
|
||||
category: 'page_load',
|
||||
name: 'entry_page',
|
||||
value: Date.now() - startTime
|
||||
})
|
||||
|
||||
// 游戏操作响应时间
|
||||
this.trackUserInteraction()
|
||||
}
|
||||
|
||||
// WebSocket连接质量监控
|
||||
trackConnectionQuality() {
|
||||
let pingStart = Date.now()
|
||||
|
||||
this.websocket.ping()
|
||||
this.websocket.onPong(() => {
|
||||
const latency = Date.now() - pingStart
|
||||
wx.reportPerformance(1002, {
|
||||
category: 'network',
|
||||
name: 'websocket_latency',
|
||||
value: latency
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 开发计划和里程碑
|
||||
|
||||
### 6.1 开发阶段规划
|
||||
```
|
||||
第一阶段 (1周):
|
||||
- 项目搭建 (2天)
|
||||
- 基础UI开发 (5天)
|
||||
|
||||
第二阶段 (2周):
|
||||
- 用户系统 (3天)
|
||||
- 房间功能 (4天)
|
||||
- 游戏核心逻辑 (6天)
|
||||
- 实时通信 (3天)
|
||||
|
||||
第三阶段 (1周):
|
||||
- 功能测试 (3天)
|
||||
- 性能优化 (2天)
|
||||
- 发布准备 (1天)
|
||||
```
|
||||
|
||||
### 6.2 关键里程碑
|
||||
- **Week 1**: 完成基础框架搭建和UI实现
|
||||
- **Week 2**: 实现房间管理和游戏核心逻辑
|
||||
- **Week 3**: 完成实时对战功能和测试优化
|
||||
- **Week 4**: 发布上线和后续迭代
|
||||
|
||||
## 7. 风险评估和应对策略
|
||||
|
||||
### 7.1 技术风险
|
||||
| 风险项 | 影响程度 | 应对策略 |
|
||||
|-------|---------|----------|
|
||||
| WebSocket连接稳定性 | 高 | 实现自动重连+离线缓存 |
|
||||
| 小程序包体积限制 | 中 | 代码分包+资源CDN |
|
||||
| 游戏状态同步复杂度 | 高 | 状态机设计+冲突解决 |
|
||||
|
||||
### 7.2 用户体验风险
|
||||
| 风险项 | 影响程度 | 应对策略 |
|
||||
|-------|---------|----------|
|
||||
| 网络延迟影响体验 | 中 | 乐观更新+加载动画 |
|
||||
| 不同设备适配问题 | 中 | 响应式设计+设备测试 |
|
||||
| 游戏规则理解困难 | 低 | 新手引导+操作提示 |
|
||||
|
||||
## 8. 总结
|
||||
|
||||
本设计文档基于提供的原型设计,严格遵循MVP原则,提出了一套完整的微信小程序技术解决方案:
|
||||
|
||||
**核心优势**:
|
||||
- 与原型设计高度一致的技术选型
|
||||
- 现代化的前端架构和深色科技主题UI
|
||||
- 高性能的实时对战体验
|
||||
- 完善的错误处理和监控机制
|
||||
- 清晰的开发计划和风险控制
|
||||
|
||||
**实现要点**:
|
||||
- 使用Taro + React实现跨端能力
|
||||
- Node.js + WebSocket保证实时性能
|
||||
- MongoDB + Redis提供数据支撑
|
||||
- 完整的状态管理和错误处理
|
||||
|
||||
本方案将为您的打飞机小程序提供坚实的技术基础,确保项目按时高质量交付。
|
||||
|
||||
---
|
||||
**文档状态**: ✅ 完成
|
||||
**技术评审**: 待进行
|
||||
**下一步**: 开始技术选型实施
|
||||
Reference in New Issue
Block a user