252 lines
7.2 KiB
Plaintext
252 lines
7.2 KiB
Plaintext
《"36字花" 前端开发对接与交互逻辑说明书》
|
||
适用对象
|
||
:前端开发工程师 (React / Vue / 移动端 H5 开发者)
|
||
核心要求
|
||
:极高的渲染性能(移动端务必保持 60FPS,禁止重绘卡顿),极致的状态同步(30秒循环状态机绝对不可发生状态错乱)。
|
||
一、 全局架构与技术栈建议 (Architecture Guidelines)
|
||
状态管理 (State Management)
|
||
:由于游戏状态极其复杂(连赢限额、统一下注金额、倒计时同步),强烈推荐使用全局状态管理库(如 React的
|
||
Redux/Zustand
|
||
或 Vue的
|
||
Pinia
|
||
),将
|
||
“业务逻辑数据层”
|
||
与
|
||
“UI渲染层”
|
||
完全解耦。
|
||
动画性能 (Animation Performance)
|
||
:
|
||
盘面的 10 种状态切换和高频边框动画,
|
||
严禁使用 JS 帧动画操作 DOM
|
||
。
|
||
必须全部采用
|
||
CSS3
|
||
transition
|
||
、
|
||
animation
|
||
、
|
||
box-shadow
|
||
或
|
||
SVG (
|
||
stroke-dasharray
|
||
)
|
||
。
|
||
涉及到全屏爆金币的粒子特效 (Particle Effects),建议直接调用轻量级 Canvas 动画库(如
|
||
tsparticles
|
||
或
|
||
PixiJS
|
||
)。
|
||
时间同步 (Time Sync)
|
||
:绝对不要信任客户端(手机/浏览器)的本地时间!游戏倒计时必须以 WebSocket/API 下发的服务器时间戳为基准进行倒推补偿。
|
||
二、 核心状态机:30秒生命周期 (The 30s Lifecycle) 注意⚠️这个时间后台可配置
|
||
前端的整个游戏循环被严格划分为 4 个生命周期,请在代码中建立全局的
|
||
GameState
|
||
枚举,并根据状态驱动 UI 渲染:
|
||
GameState.BETTING
|
||
|
||
(0 - 20秒:下注期)
|
||
行为
|
||
:允许用户点击格子、选筹码、点确认。
|
||
UI
|
||
:倒计时递减。背景跑马灯常态运转。
|
||
GameState.LOCKED
|
||
|
||
(20.0秒:封盘锁定)
|
||
行为
|
||
:
|
||
前端立即进行物理锁盘
|
||
。无论网络是否有延迟,只要本地计算到达20.0秒,立即禁用所有输入框、点击事件和按钮。
|
||
UI
|
||
:弹出
|
||
[停止下注]
|
||
提示,未点击确认的预选状态 (
|
||
PRE_SELECTED
|
||
) 格子全部强制清除。
|
||
GameState.DRAWING
|
||
|
||
(20 - 25秒:算票与开奖)
|
||
行为
|
||
:等待后端 WebSocket 推送开奖结果。
|
||
UI
|
||
:收到结果后,前端触发 3 秒的高频加速跑马灯,最后 0.5 秒光圈定格在中奖格子上,触发
|
||
WINNING
|
||
状态大爆动画。
|
||
GameState.PAYOUT
|
||
|
||
(25 - 30秒:结算派彩)
|
||
行为
|
||
:监听余额变更推送,更新连赢 (Streak) 状态。
|
||
UI
|
||
:播放中奖特效,更新底部走势图 (红蓝圆点),准备进入下一局。
|
||
三、 组件级交互逻辑:36字花主键盘 (The 36-Grid System)
|
||
前端需要封装一个
|
||
<Cell />
|
||
组件,该组件接收一个
|
||
status
|
||
属性(范围 0-9),并根据该枚举值切换对应的 CSS Class。
|
||
📌 10 种状态枚举 (CellStatus Enum) 映射逻辑
|
||
IDLE
|
||
(闲置):默认状态,深色,偶发微光 CSS 动画。
|
||
MARQUEE
|
||
(跑马灯焦点):全局维护一个
|
||
activeCellIndex
|
||
每 0.1秒随机变更,命中的组件亮起青色霓虹边框。
|
||
HOVER
|
||
(悬浮):
|
||
:hover
|
||
伪类触发(仅 PC)。
|
||
PRE_SELECTED
|
||
(预选中):前端本地状态数组。显示筹码图标,金边流光。
|
||
LOCKED
|
||
(已确认):调用
|
||
place_bet
|
||
API 成功后切换至此状态。显示锁定印章,绿色边框。
|
||
DISABLED
|
||
(禁用):封盘时,或已选中数量达标(5个)时,其余格子强制渲染黑色 60% 遮罩。
|
||
ERROR
|
||
(错误抖动):触发 CSS
|
||
shake
|
||
动画,维持 0.5s 后回退到上一个状态。
|
||
WINNING
|
||
(中奖大爆):开奖目标,Z-index 置顶,放大 1.25 倍,播放强脉冲 CSS。
|
||
LOSER
|
||
(落选陪跑):透明度设为
|
||
opacity: 0.2
|
||
。
|
||
AUTO_ACTIVE
|
||
(自动托管中):全局遮罩下,该格子穿透遮罩,显示紫色虚线动画与
|
||
AUTO
|
||
印章。
|
||
📌 核心防呆交互逻辑 (必须用代码写死限制)
|
||
统一下注金额联动 (Chip Sync)
|
||
:
|
||
全局维护一个
|
||
currentChipValue
|
||
(当前选中的筹码)。
|
||
如果用户修改了
|
||
currentChipValue
|
||
,前端必须
|
||
遍历所有状态为
|
||
PRE_SELECTED
|
||
的格子,将它们显示的筹码瞬间同步为新金额
|
||
。
|
||
数量限制校验 (Max 5 Limit)
|
||
:
|
||
实时计算:
|
||
count(PRE_SELECTED) + count(LOCKED)
|
||
必须
|
||
<= 5
|
||
。
|
||
等于 5 时,其余 31 个
|
||
IDLE
|
||
状态的格子必须变成
|
||
DISABLED
|
||
状态。如果强行点击,触发
|
||
ERROR
|
||
动画。
|
||
连赢上限校验 (Streak Bet Limit)
|
||
:
|
||
如果玩家上一局赢了,API 会下发一个
|
||
streakMaxBetLimit
|
||
(连赢最高下注总额,如 💎 100)。
|
||
前端需要写一个
|
||
useEffect
|
||
/
|
||
watch
|
||
:实时计算
|
||
当前选中数字数量 * currentChipValue
|
||
。如果这个乘积
|
||
> streakMaxBetLimit
|
||
,或者当前账户余额不足,左下角的那个筹码图标必须添加
|
||
disabled
|
||
属性(变灰不可点)。
|
||
四、 核心中控台交互 (Control Panel & Actions)
|
||
1.
|
||
[✅ 确定下注 Confirm]
|
||
主按钮的状态机
|
||
这是全场最重要的按钮,前端必须维护它独立的四态机:
|
||
Disabled
|
||
:未选中任何格子时。
|
||
Ready (高亮呼吸)
|
||
:选中格子 > 0,且总注金 <= 余额。绑定
|
||
onClick -> handleSubmit
|
||
。
|
||
Error (红色)
|
||
:总注金 > 余额。文字变成“余额不足”。
|
||
Success (绿色)
|
||
:收到 API 200 成功响应后,维持绿色直到本局结束。
|
||
1.
|
||
Auto-Spin(自动托管)逻辑流
|
||
数据层
|
||
:调用
|
||
/api/auto_spin
|
||
告知后端要买哪些数字、金额和局数。
|
||
UI 层
|
||
:前端进入
|
||
AUTO_MODE
|
||
全局变量。
|
||
整个盘面外层盖一个
|
||
<div className="glass-overlay" />
|
||
,
|
||
pointer-events: none
|
||
(阻断一切鼠标点击)。
|
||
只有目标格子的状态被设为
|
||
AUTO_ACTIVE
|
||
,并使用 CSS
|
||
z-index
|
||
穿透遮罩。
|
||
监听后端 WebSocket 下发的每一局扣款成功事件,更新底部控制台的进度条(如
|
||
3/50 局
|
||
)。
|
||
3.
|
||
Red/Blue 路子图渲染逻辑 (Trend Chart)
|
||
接收一个含有最近 30 期开奖数字的 Array
|
||
[08, 15, 36, ...]
|
||
。
|
||
渲染判断
|
||
:
|
||
item % 2 === 0
|
||
(偶数) 渲染蓝色圆圈;
|
||
item % 2 !== 0
|
||
(奇数) 渲染红色圆圈。
|
||
入场动画
|
||
:当有新数字加入 Array 时,最后一个圆圈必须带有
|
||
slide-in
|
||
或
|
||
pop-in
|
||
动画。
|
||
五、 网络延迟与极端异常处理 (Edge Cases & Fallbacks)
|
||
博彩游戏的前端,对异常处理的要求极高,请前端必须实现以下机制:
|
||
首屏强制公告 (Welcome Pop-out)
|
||
进页面时调用
|
||
/api/user/announcement
|
||
。如果有未读公告,弹出
|
||
<Modal />
|
||
。
|
||
“进入游戏”的
|
||
Button
|
||
绑定
|
||
disabled={!isChecked}
|
||
。不勾选绝对不给进。
|
||
压秒网络卡顿防错 (The 19.9s Click)
|
||
场景
|
||
:倒计时剩 0.1 秒,玩家点击了【确定下注】,前端发起了 HTTP/Socket 请求,但因为网络差,请求还没到服务器,本地倒计时先归零了。
|
||
处理方案
|
||
:前端立即锁盘进入
|
||
LOCKED
|
||
状态,并显示 Loading (spinner)。当 2 秒后收到后端的 400 Bad Request(提示已封盘)时,前端必须
|
||
清除这个格子的状态,并弹窗提示
|
||
[网络延迟,下注失败,未扣款]
|
||
。千万不能强行把它变成
|
||
LOCKED
|
||
绿勾。
|
||
断线重连恢复 (Reconnection Recovery)
|
||
场景
|
||
:玩家切出微信看消息,5分钟后切回浏览器。
|
||
处理方案
|
||
:前端检测到
|
||
visibilitychange
|
||
或者 Socket 断开,必须立刻重新发起
|
||
/api/game/current_status
|
||
全量拉取请求。根据服务器返回的数据,瞬间重置本地的倒计时、当前连胜数、走势图数据。
|
||
绝对不要依赖本地时间的积累运算。 |