-
房间系统
- 创建/加入房间
- 房间列表实时更新
- 房主权限管理
- 断线重连处理
-
游戏流程
- 摸牌阶段:自动发牌、展示手牌
- 埋底阶段:房主指定埋底玩家
- 出牌阶段:有序/自由两种模式
- 展示底牌:所有玩家确认
- 游戏结束:分数/等级调整、重新开始
-
实时通信
- WebSocket 实时同步
- 状态自动广播
- 断线检测与通知
-
用户界面
- 精美的卡牌显示
- 流畅的动画效果
- 响应式布局
- 房间列表管理
- 牌组:2副标准扑克牌(含大小王)共108张
- 玩家:2-4人
- 阶段:等待 → 摸牌 → 埋底 → 出牌 → 揭底 → 结束
- 出牌模式:
- 有序模式:按顺序轮流出牌
- 自由模式:抢先出牌
详细规则请参考 游戏设计文档
- Node.js >= 18.0.0
- npm >= 9.0.0
git clone <repository-url>
cd Tractor# 安装后端依赖
cd tractor-game-simulator/server
npm install
# 安装前端依赖
cd ../client
npm install# 在 tractor-game-simulator/server 目录
npm start服务器将运行在 http://localhost:5001
注意:端口使用5001而非5000,以避免与macOS AirPlay Receiver冲突
在新的终端窗口:
# 在 tractor-game-simulator/client 目录
npm run dev前端将运行在 http://localhost:3000
- 打开浏览器访问
http://localhost:3000 - 点击"创建房间"或从房间列表"加入房间"
- 等待其他玩家加入
- 房主点击"开始游戏"
| 技术 | 版本 | 用途 |
|---|---|---|
| Node.js | 18+ | 运行环境 |
| Express | 4.x | Web框架 |
| Socket.IO | 4.x | WebSocket通信 |
| UUID | 9.x | 唯一ID生成 |
| 技术 | 版本 | 用途 |
|---|---|---|
| React | 18 | UI框架 |
| Vite | 5.x | 构建工具 |
| Ant Design | 5.x | UI组件库 |
| Socket.IO Client | 4.x | 实时通信 |
| Zustand | 4.x | 状态管理 |
Tractor/
├── tractor-game-simulator/ # 主项目目录
│ ├── client/ # 前端项目
│ │ ├── src/
│ │ │ ├── components/ # React组件
│ │ │ │ ├── Game/ # 游戏组件
│ │ │ │ │ ├── Card.jsx # 卡牌组件
│ │ │ │ │ ├── Hand.jsx # 手牌组件
│ │ │ │ │ └── GameBoard.jsx # 游戏主界面
│ │ │ │ └── Room/ # 房间组件
│ │ │ │ ├── CreateRoomModal.jsx
│ │ │ │ ├── JoinRoomModal.jsx
│ │ │ │ └── RoomList.jsx
│ │ │ ├── services/ # 服务层
│ │ │ │ └── socket.js # Socket.IO客户端
│ │ │ ├── store/ # 状态管理
│ │ │ │ └── gameStore.js # Zustand store
│ │ │ ├── utils/ # 工具函数
│ │ │ │ └── constants.js # 常量定义
│ │ │ ├── styles/ # 样式文件
│ │ │ ├── App.jsx # 主应用
│ │ │ └── main.jsx # 入口文件
│ │ ├── package.json
│ │ └── vite.config.js
│ │
│ └── server/ # 后端项目
│ ├── src/
│ │ ├── models/ # 数据模型
│ │ │ ├── Card.js # 卡牌模型
│ │ │ ├── Player.js # 玩家模型
│ │ │ ├── Room.js # 房间模型
│ │ │ └── GameState.js # 游戏状态
│ │ ├── services/ # 业务逻辑
│ │ │ ├── DeckService.js # 牌组服务
│ │ │ ├── RoundManager.js # 回合管理
│ │ │ ├── DrawingPhaseManager.js # 摸牌阶段
│ │ │ ├── GameEngine.js # 游戏引擎
│ │ │ └── RoomManager.js # 房间管理
│ │ ├── socket/ # Socket处理
│ │ │ ├── handlers/
│ │ │ │ ├── roomHandlers.js # 房间事件
│ │ │ │ ├── gameHandlers.js # 游戏事件
│ │ │ │ └── playerHandlers.js # 玩家事件
│ │ │ └── index.js # Socket初始化
│ │ ├── utils/ # 工具函数
│ │ │ └── logger.js # 日志工具
│ │ └── index.js # 服务器入口
│ ├── package.json
│ └── .env # 环境变量
│
├── docs/ # 文档目录
│ ├── FINAL_GAME_DESIGN.md # 完整游戏设计
│ ├── DETAILED_IMPLEMENTATION.md # 实现细节
│ ├── SIMULATOR_DESIGN.md # 初始设计
│ ├── TEST_REPORT.md # 测试报告
│ └── archive/ # 归档文件
│
├── TESTING_GUIDE.md # 测试指南
├── README.md # 本文件
└── .gitignore
# 服务器端口(改为5001以避免与macOS AirPlay冲突)
PORT=5001
# 客户端URL(CORS配置)
CLIENT_URL=http://localhost:3000
# 日志级别 (ERROR, WARN, INFO, DEBUG)
LOG_LEVEL=INFO在 client/.env 中配置(可选):
VITE_SERVER_URL=http://localhost:5001| 事件 | 参数 | 说明 |
|---|---|---|
create_room |
{name, playerName, config} |
创建房间 |
join_room |
{roomId, playerName} |
加入房间 |
leave_room |
{roomId} |
离开房间 |
get_room_list |
- | 获取房间列表 |
start_game |
{roomId} |
开始游戏 |
show_cards |
{roomId, cardIds} |
展示手牌 |
set_burying_player |
{roomId, playerId} |
设置埋底玩家 |
bury_cards |
{roomId, cardIds} |
埋底 |
set_first_player |
{roomId, playerId} |
设置首发玩家 |
play_cards |
{roomId, cardIds} |
出牌 |
pass_turn |
{roomId} |
跳过 |
confirm_reveal |
{roomId} |
确认查看底牌 |
update_score |
{roomId, playerId, newScore} |
更新分数 |
update_level |
{roomId, playerId, newLevel} |
更新等级 |
restart_game |
{roomId} |
重新开始 |
| 事件 | 参数 | 说明 |
|---|---|---|
room_created |
{room, player} |
房间创建成功 |
room_joined |
{room, player} |
加入房间成功 |
room_updated |
{room} |
房间状态更新 |
room_list |
{rooms} |
房间列表 |
player_joined |
{player} |
玩家加入 |
player_left |
{playerName} |
玩家离开 |
game_started |
{gameState} |
游戏开始 |
card_dealt |
{card} |
收到手牌 |
cards_shown |
{playerName, cards} |
玩家展示手牌 |
burying_player_set |
{playerName} |
埋底玩家已设置 |
bottom_cards_received |
{bottomCards} |
收到底牌(私密) |
cards_buried |
{playerName} |
埋底完成 |
first_player_set |
{playerName} |
首发玩家已设置 |
cards_played |
{playerName, cards} |
玩家出牌 |
turn_passed |
{playerName} |
玩家跳过 |
turn_changed |
{currentPlayerName} |
回合切换 |
bottom_revealed |
{bottomCards} |
展示底牌 |
game_finished |
{players, duration} |
游戏结束 |
score_updated |
{playerId, newScore} |
分数已更新 |
level_updated |
{playerId, newLevel} |
等级已更新 |
game_restarted |
- | 游戏重新开始 |
error |
{message} |
错误消息 |
详细的事件定义和参数说明请参考 游戏设计文档
# 检查端口占用
lsof -i :5001
# 检查Node.js版本
node -v # 应该 >= 18.0.0
# 检查环境变量
cat server/.env- 确保后端服务器正在运行
- 检查
vite.config.js中的代理配置 - 查看浏览器控制台错误
- 确认防火墙未阻止端口
- 确认服务器URL正确
- 检查CORS配置(
server/.env中的CLIENT_URL) - 查看服务器日志
- 检查
room_updated事件是否正确接收 - 查看后端日志确认事件已发送
- 确认所有客户端都在同一个Socket.IO房间
- 项目架构搭建
- 后端核心功能
- 前端基础框架
- 房间系统
- 游戏流程(所有阶段)
- 卡牌UI组件
- 实时状态同步
- 房间列表与加入功能
- 牌型验证规则
- 胜负判定逻辑
- 手牌拖拽排序
- 游戏音效
- 聊天系统
- 观战模式
- 游戏回放
- 排行榜系统
- Docker化
- CI/CD配置
- 生产环境优化
- 性能优化
- 安全加固
欢迎提交Issue和Pull Request!
在提交PR前,请确保:
- 代码通过ESLint检查
- 所有测试通过
- 更新相关文档
MIT License
如有问题或建议,请提交Issue。
Made with ❤️ by the Tractor Game Team