组件说明
本页列出 app/game/components/ 下所有 UI 组件的职责与使用方式。
顶层组件
GamePhaseRenderer
根据 GameState.phase 渲染对应的阶段组件,是游戏 UI 的核心分发器。
tsx
// 简化逻辑
switch (state.phase) {
case "waiting": return <WaitingRoom />;
case "speaking": return <SpeakingPhase />;
case "team_select": return <TeamSelectPhase />;
// ...
}PhaseAnnouncement
阶段切换时的全屏动画公告覆盖层,由 framer-motion 驱动,约 2 秒后自动消失。
RoleRevealModal
游戏开始时弹出的角色公示弹窗,展示本人角色及可见的其他玩家身份。
Phase 组件
| 组件 | 阶段 | 说明 |
|---|---|---|
WaitingRoom | waiting | 玩家列表 + 开始游戏按钮 |
SpeakingPhase | speaking | 发言输入框(轮流制) |
TeamSelectPhase | team_select | 领袖选队成员面板 |
TeamVotePhase | team_vote | 赞成/反对投票按钮 |
MissionPhase | mission | 成功/破坏任务按钮(仅队员) |
AssassinPhase | assassin | 刺客指定目标面板 |
GameOver | game_over | 胜负结算 + 身份公开 |
常驻 UI 组件 (ui/)
PhaseHeader
顶部状态栏,展示当前阶段名称、任务编号和领袖信息。在所有非 waiting 阶段均可见。
MissionTracker
5 个任务进度圆点,好人/邪恶胜利分别用不同颜色标注。悬停可查看该任务的详细信息(参与者、票数)。
RoleCard
左列顶部的本人角色卡,展示角色名称、阵营和可见的其他玩家身份。
PlayerCard
单个玩家卡片,包含 DiceBear Notionists 头像(按 user_id 确定性生成)、用户名及游戏内状态标注(如"领袖"、"发言中")。
PlayerList
玩家列表容器,在部分阶段作为主要交互区域(如 team_select 阶段的选人界面)。
SpeechHistorySidebar
发言记录面板,在 speaking、team_select、team_vote、mission 阶段展示上一轮或当前轮的完整发言历史。
VoteResult
TEAM_VOTE_RESULT 到达后弹出的临时 overlay,展示各玩家投票结果,几秒后自动消失。
MissionResult
MISSION_RESULT 到达后弹出的临时 overlay,展示任务成功/失败及票数,几秒后自动消失。
ToastNotification
ERROR 消息触发的 Toast 提示,固定显示在屏幕角落,支持手动关闭。
组件与状态的交互规范
所有组件只通过以下两种方式与游戏状态交互:
- 读取状态:
const { state } = useGame() - 发送消息:
const { sendMessage } = useGame()
禁止在组件内部维护与服务端业务逻辑相关的 useState,所有业务状态均由 gameReducer 统一管理。