Files
zp1/backend/PROJECT_DOCUMENTATION.md
2026-04-25 22:09:27 +08:00

400 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Zombie Crisis 3 - 项目技术文档
## 1. 项目概述
Zombie Crisis 3 是一款多人在线僵尸射击游戏,采用客户端-服务器架构,支持最多 4 名玩家同时游戏。
### 1.1 技术栈
| 层级 | 技术 | 说明 |
|------|------|------|
| 后端 | Java + Maven | 游戏逻辑服务器 |
| 前端 | JavaScript + Vite | Web 客户端 |
| 渲染 | Three.js | 3D 图形渲染 |
| 通信 | WebSocket | 实时双向通信 |
| 协议 | JSON | 消息序列化 |
### 1.2 项目结构
```
zp1/
├── backend/ # Java 游戏服务器
│ ├── pom.xml # Maven 配置
│ └── src/main/java/com/zombie/game/
│ ├── GameServerMain.java # 程序入口
│ ├── model/ # 数据模型
│ │ ├── GameWorld.java # 游戏世界主类
│ │ ├── GameMap.java # 地图与流向场
│ │ ├── Zombie.java # 僵尸实体
│ │ ├── Player.java # 玩家实体
│ │ ├── Bullet.java # 子弹实体
│ │ ├── Loot.java # 掉落物
│ │ ├── Room.java # 游戏房间
│ │ └── Constants.java # 常量定义
│ └── server/
│ ├── GameWebSocketServer.java # WebSocket 服务器
│ └── GameLoop.java # 游戏循环
├── frontend/ # JavaScript 客户端
│ ├── package.json
│ ├── vite.config.js
│ ├── index.html
│ └── src/
│ ├── main.js # 应用入口
│ ├── game/
│ │ ├── engine.js # 游戏引擎
│ │ └── scene.js # Three.js 场景
│ ├── network/
│ │ └── client.js # WebSocket 客户端
│ ├── ui/
│ │ ├── lobby.js # 大厅界面
│ │ ├── hud.js # 游戏 HUD
│ │ └── settings.js # 设置界面
│ └── utils/
│ ├── constants.js # 前端常量
│ ├── input.js # 输入管理
│ └── grid.js # 网格工具
└── FLOW_FIELD_NAVIGATION.md # 流向场寻路文档
```
---
## 2. 系统架构
### 2.1 整体架构图
```
┌─────────────────────────────────────────────────────────────┐
│ 客户端 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ LobbyUI │ │ HUD │ │ Scene │ │ Network │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ └────────────┴────────────┴────────────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ │GameEngine │ │
│ └─────┬─────┘ │
└──────────────────────────┼──────────────────────────────────┘
│ WebSocket (ws://:8080)
┌──────────────────────────┼──────────────────────────────────┐
│ │ 服务器 │
│ ┌─────┴─────┐ │
│ │GameWebSocketServer│ │
│ └─────┬─────┘ │
│ ┌──────────────────┼──────────────────┐ │
│ ┌────┴────┐ ┌─────┴─────┐ ┌────┴────┐ │
│ │ Room │ │ GameLoop │ │ GameWorld│ │
│ │ Manager │ │ (30 TPS) │ │ │ │
│ └─────────┘ └─────┬─────┘ └────┬────┘ │
│ │ │ │
│ ┌─────┴─────────────────┴─────┐ │
│ │ Model Entities │ │
│ │ Player | Zombie | Bullet │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 游戏循环
服务器以固定 30 TPS (Tick Per Second) 运行游戏逻辑:
```
每帧 (约33ms):
1. updateFlowField() - 更新流向场
2. updateZombies() - 更新所有僵尸
3. updateBullets() - 更新所有子弹
4. updateZombieBullets() - 更新僵尸子弹
5. checkBulletCollisions()- 子弹碰撞检测
6. checkZombieAttacks() - 僵尸攻击检测
7. checkLootCollection() - 拾取物收集
8. broadcastGameState() - 广播游戏状态
```
---
## 3. 核心模块详解
### 3.1 GameWorld
游戏世界主类,管理所有游戏实体和逻辑。
**主要职责**:
- 管理玩家、僵尸、子弹、掉落物集合
- 每帧调用所有实体的更新方法
- 处理实体间的碰撞检测
- 生成僵尸和管理难度
**关键方法**:
```java
public void update(float dt)
private void updateFlowField() // 更新流向场
private void updateZombies(float dt) // 更新僵尸
private void updateBullets(float dt) // 更新子弹
private void checkBulletCollisions() // 子弹碰撞
private void checkZombieAttacks() // 僵尸攻击
private void fireWeapon(Player, aimX, aimY) // 武器射击
```
### 3.2 GameMap
地图类,包含 32×32 格子地图和流向场寻路系统。
**流向场算法优势**:
- 一次计算,所有僵尸共享
- 自动适应多个玩家目标
- O(m) 复杂度m=地图格子数
### 3.3 Zombie
僵尸实体,采用流向场移动 + 碰撞解决机制。
**移动系统**:
1. 查询流向场获取移动方向
2. 选择目标网格中心
3. 检查格子预留/占用
4. 移动并处理碰撞分离
### 3.4 Player
玩家实体,支持客户端预测和服务器校验。
**输入处理**:
```java
applyMovement(dx, dy, map) // 移动
setAngle(aimX, aimY) // 瞄准方向
fireWeapon(player, aimX, aimY) // 射击
```
### 3.5 Bullet
子弹实体,支持两种模式:
| 模式 | 武器 | 特点 |
|------|------|------|
| 弹道 | 手枪/机枪/霰弹枪 | 直线飞行,有射程限制 |
| 抛物线 | 手雷 | 弧线弹道,触地爆炸 |
### 3.6 Room
游戏房间,管理玩家列表和游戏状态。
**房间状态**:
- 等待中:玩家加入、准备
- 游戏中:所有玩家加载游戏
- 结束:所有玩家离开或游戏结束
---
## 4. 通信协议
### 4.1 消息格式
所有消息使用 JSON 格式:
```json
{
"type": "MESSAGE_TYPE",
"data": { ... }
}
```
### 4.2 消息类型
#### 客户端 → 服务器
| 消息类型 | 说明 | 数据 |
|---------|------|------|
| `create_room` | 创建房间 | `{playerName}` |
| `join_room` | 加入房间 | `{roomId, playerName}` |
| `leave_room` | 离开房间 | - |
| `ready` | 准备状态切换 | - |
| `start_game` | 开始游戏 | - |
| `player_input` | 玩家输入 | `{dx, dy, aimX, aimY, firing, weaponIndex, seq}` |
#### 服务器 → 客户端
| 消息类型 | 说明 | 数据 |
|---------|------|------|
| `room_list` | 房间列表 | `{rooms: [{id, hostName, playerCount}]}` |
| `room_state` | 房间状态 | `{roomId, hostId, players: [...]}` |
| `game_started` | 游戏开始 | `{playerId, mapData, players: [...]}` |
| `game_state` | 游戏状态 | `{players, zombies, bullets, ...}` |
| `error` | 错误消息 | `{message}` |
### 4.3 游戏状态同步
每帧广播的游戏状态包含:
```java
{
"players": [{id, x, y, angle, health, weaponIndex}],
"zombies": [{id, x, y, angle, health, isElite}],
"bullets": [{id, x, y, z, angle, weapon, ownerId}],
"zombieBullets": [...],
"loots": [{id, x, y, type}],
"explosions": [{x, y, radius}],
"removedBullets": [id1, id2, ...],
"gameTime": 120.5,
"waveNumber": 3,
"score": 1250
}
```
---
## 5. 武器系统
### 5.1 武器配置
| 武器 | 伤害 | 射速 | 弹药 | 特点 |
|------|------|------|------|------|
| 手枪 | 50 | 400ms | ∞ | 单发,精准 |
| 机枪 | 15 | 100ms | 100 | 自动,略微散布 |
| 霰弹枪 | 20×6 | 800ms | 20 | 6发弹丸高散布 |
| 手雷 | 120 | 1500ms | 10 | 可蓄力,范围伤害 |
### 5.2 手雷机制
- **蓄力**长按射击键蓄力最多2秒
- **射程**蓄力0-100%对应3-15格距离
- **弹道**:抛物线飞行
- **爆炸**范围3格伤害
---
## 6. 僵尸系统
### 6.1 僵尸类型
| 类型 | 生命值 | 速度 | 特殊能力 |
|------|--------|------|----------|
| 普通 | 100+ | 2.0+ | 近战攻击 |
| 精英 | 800 | 1.5 | 远程射击 |
### 6.2 精英僵尸攻击
- **攻击范围**8格
- **攻击间隔**2秒
- **子弹伤害**30
- **子弹速度**6
### 6.3 难度递增
每30秒波次增加
- 僵尸生命值 +20
- 僵尸速度 +0.1
- 生成间隔 -0.3秒最低0.8秒)
---
## 7. 前端渲染
### 7.1 Three.js 场景
**摄像机**:
- 透视摄像机45度FOV
- 偏移量 (0, 25, 18)
- 平滑跟随玩家
**光照**:
- 环境光0x404060
- 方向光0xffeedd带阴影
- 点光源0xff4400
### 7.2 实体模型
| 实体 | 几何体 | 颜色 |
|------|--------|------|
| 玩家 | 圆柱体+球头 | 蓝/红/绿/黄 |
| 普通僵尸 | 圆柱体+球头 | 0x446633 |
| 精英僵尸 | 同上+发光球 | 0x882222 |
| 墙体 | 立方体 | 0x555577 |
### 7.3 特效系统
- **爆炸**:白色闪光 + 多层球体 + 碎片
- **枪口火焰**:黄色球体 + 光点
- **击中效果**:红色球体 + 火花粒子
- **掉落物**:旋转立方体
---
## 8. 客户端预测
### 8.1 预测机制
1. 客户端发送输入(含序列号)
2. 客户端立即本地预测执行
3. 服务器执行并返回 `lastProcessedSeq`
4. 客户端回滚并重放未确认输入
### 8.2 输入结构
```javascript
{
dx: -1~1, // 移动方向 X
dy: -1~1, // 移动方向 Y
aimX: worldX, // 瞄准位置 X
aimY: worldY, // 瞄准位置 Y
firing: boolean, // 是否射击
weaponIndex: 0-3, // 武器索引
grenadeCharge: 0-1, // 手雷蓄力
grenadeReleased: boolean,
seq: number // 序列号
}
```
---
## 9. 常量配置
### 9.1 服务器常量 (Java)
```java
GRID_SIZE = 32 // 地图尺寸
PLAYER_SIZE = 0.8f // 玩家碰撞半径
ZOMBIE_SIZE = 0.8f // 僵尸碰撞半径
PLAYER_SPEED = 5.0f // 玩家移动速度
ZOMBIE_BASE_SPEED = 2.0f // 僵尸基础速度
TICK_RATE = 30 // 服务器Tick率
```
### 9.2 客户端常量 (JavaScript)
与服务器保持一致的定义在 `constants.js`
---
## 10. 启动与部署
### 10.1 服务器启动
```bash
cd backend
mvn package
java -jar target/zombie-crisis-server-1.0.0.jar [port]
# 默认端口 8080
```
### 10.2 客户端启动
```bash
cd frontend
npm install
npm run dev
# 访问 http://localhost:5173
```
### 10.3 依赖版本
- **Java**: 17+
- **Maven**: 3.6+
- **Node.js**: 16+
- **Three.js**: (通过 npm)
---
## 11. 相关文档
- [流向场寻路系统技术文档](./FLOW_FIELD_NAVIGATION.md) - 僵尸AI寻路详细说明