feat: 情侣向焕新——主题、音效动效、战绩、表情互动与爱心彩蛋

- 四套主题(雅致木纹/心动粉/暗夜紫/水墨江南):CSS 变量 + Canvas 棋盘配色联动
- 落子弹跳、最后一手呼吸光晕、五连扫光动画、终局爱心跳动卡片
- Web Audio 合成音效 + 手机震动反馈(落子/胜利/悔棋/表情/爱心)
- 自定义昵称(服务端座位持久化)+ 房间战绩统计(局数/胜负/和棋/决胜手数)
- 长按棋盘随机发送甜蜜表情,实时漂浮同步给对手(3 秒冷却防刷)
- 爱心连珠彩蛋:服务端模板检测棋盘爱心形状(含旋转镜像),触发全场爱心雨
- 双击棋盘点燃小爱心;随机甜蜜结算文案;大厅双人剪影插画与浪漫渐变
- 首页暴露局域网地址(vite host: true)
This commit is contained in:
root
2026-09-11 16:11:22 +08:00
parent 59bfc98afa
commit 3b59c94fe8
11 changed files with 1248 additions and 91 deletions
+34 -1
View File
@@ -18,12 +18,26 @@ export type GameStatus = 'waiting' | 'playing' | 'over'
/** 终局原因:五连 / 和棋 / 认输 / 对手离线判负 */
export type EndReason = 'five' | 'draw' | 'resign' | 'offline'
/** 座位是否有人、是否在线 */
/** 座位是否有人、是否在线、昵称 */
export interface SeatInfo {
joined: boolean
online: boolean
/** 昵称,空串表示未设置(前端显示「黑棋/白棋」) */
nickname: string
}
/** 房间内累计战绩(进程内存,重启即清零) */
export interface RoomStats {
/** 当前进行的局数编号,从 1 起 */
round: number
blackWins: number
whiteWins: number
draws: number
}
/** 可发送给对手的表情符号 */
export const EMOJIS = ['❤️', '💕', '✨', '🌟', '💗', '😘', '🥰', '💌', '🍀', '💘'] as const
/**
* 完整对局状态(服务端权威,每次变更后全量下发)。
* 225 个格子的全量同步只有几百字节,用全量换掉增量同步的一致性风险。
@@ -46,6 +60,13 @@ export interface RoomState {
undoRequestedBy: Player | null
black: SeatInfo
white: SeatInfo
/**
* 本局是否已触发「爱心连珠」彩蛋及触发方。
* null = 未触发;否则前端播放爱心雨特效并提示。
*/
heartBy: Player | null
/** 房间累计战绩 */
stats: RoomStats
/** 接收者自己执子颜色,未入座为 null */
seat: Player | null
}
@@ -71,6 +92,10 @@ export const EV = {
claimOffline: 'game:claim-offline',
/** 再来一局,ack: ActionAck */
restart: 'game:restart',
/** 发送表情给对手(长按棋盘),ack: ActionAck */
emojiSend: 'emoji:send',
/** 服务端 → 客户端:收到对手表情 */
emojiRecv: 'emoji:recv',
/** 服务端 → 客户端:全量状态推送 */
state: 'game:state',
/** 服务端 → 客户端:一次性提示(错误/事件) */
@@ -109,6 +134,14 @@ export interface NoticePayload {
message: string
}
/** 发送表情载荷:emoji 必须是 EMOJIS 中的字符 */
export interface EmojiPayload {
emoji: string
}
/** 音效场景 */
export type SoundKind = 'place' | 'win' | 'undo' | 'emoji' | 'heart'
/** 悔棋请求自动失效时长 */
export const UNDO_TIMEOUT_MS = 60_000
/** 对手离线多久后允许判负 */