HarmonyOS7应用《拼棋派对》实战:双人24点的独立状态与抢答计分
同一组四张数字牌放在两个人面前,各自尝试组合,先得到24并提交的人得分。这就是《拼棋派对》的双人24点。把单人页面放两份只是第一步,更重要的是划清状态归属:双方牌面独立,题目与回合共同推进。
这一篇复用前面的运算规则,重点讲双人状态初始化、操作分发、错误提交冷却和抢答计分。布局朝向与电脑键盘会在后面的适配篇展开。
本文目录
哪些状态独立,哪些状态共享
先用表格把归属整理出来,再写页面和事件处理:
| 状态 | 归属 | 原因 |
|---|---|---|
| 牌槽数组、表达式 | A、B各一份 | 每个人有自己的计算路径 |
| 选中牌、运算符、撤销历史 | A、B各一份 | 一人的选择不能改变另一人的下一步 |
| 得分与错误冷却 | A、B各一份 | 计分和错误处理对应具体玩家 |
| 难度、题号、初始数字 | 双方共享 | 同一轮竞争相同题目 |
| 总计时与比赛结束状态 | 双方共享 | 描述同一场比赛 |
两个人可以处于不同的中间状态:A已经得到49,B仍然保留四张原始牌。这个差异是玩法正常工作的结果。
从同一题创建两份牌局
loadDuel24Question 先取当前题目的数字,再分别初始化:
const cards = this.duel24QuestionForRound(round).cards;
this.duel24SlotsA = createTwentyFourSlots(cards);
this.duel24SlotsB = createTwentyFourSlots(cards);
this.refreshTwentyFourSlotsSnapshot('duel', 'A', this.duel24SlotsA);
this.refreshTwentyFourSlotsSnapshot('duel', 'B', this.duel24SlotsB);
同一个 cards 可以作为只读输入,创建函数每次返回新的数组和新的牌槽对象。不要直接让两个玩家都引用同一个牌局数组,否则修改A的对象可能同时影响B。
接着清空双方选中索引、运算符和历史。这些步骤在每次共同换题时执行;累计分数和总用时保留到比赛结束。
双方从相同数字开始,每人有自己的运算符、撤销与提交入口。
把操作分发给正确玩家
公共选牌函数接收模式与玩家标识,先确定它要读取哪份状态:
const slots = mode === 'single'
? this.single24Slots
: this.duel24SlotsForPlayer(player);
双人状态读取函数保持明确:
private duel24SlotsForPlayer(player: string): TwentyFourSlot[] {
return player === 'A' ? this.duel24SlotsA : this.duel24SlotsB;
}
合并成功后,写回函数也按玩家分支更新,并刷新相应显示快照:
if (player === 'A') {
this.duel24SlotsA = slots;
} else {
this.duel24SlotsB = slots;
}
this.refreshTwentyFourSlotsSnapshot(mode, player, slots);
这些是公共函数中的相关节选。模型计算可以共用,状态读取和写回却必须始终携带玩家标识。
A连续合并得到24时,B仍保留原始四张牌;A提交后,双方共同进入下一题。
操作按钮还应检查整场比赛是否结束,以及本人是否处于冷却。检查只放在提交按钮上还不够:选牌和选择运算符同样需要遵守冷却规则。
错误提交只冷却本人
项目对未达成24的提交设置3秒冷却:
const slots = this.duel24SlotsForPlayer(player);
if (!isTwentyFourSolved(slots)) {
this.pulseMiss();
this.setDuel24Cooldown(player, 3);
this.notice = `玩家${player} 未达成 24,冷却 3 秒`;
return;
}
冷却属于具体玩家。A提交错误,B仍应能够选牌和运算。用一个全局 cooldown 会暂停双方,改变这场抢答的规则。
进入下一题时,双方冷却清零,因为题目已经变化。继续保留上一题的错误冷却,会让新题开局变得不对称。
答对后双方进入下一题
双人比赛每轮6题。提交正确后,先增加提交者的得分,再决定比赛结束还是共同换题:
if (player === 'A') {
this.duel24ScoreA += 1;
} else {
this.duel24ScoreB += 1;
}
if (this.duel24Round >= 6) {
this.finishDuel24();
return;
}
const nextRound = this.duel24Round + 1;
this.duel24Round = nextRound;
this.duel24CooldownA = 0;
this.duel24CooldownB = 0;
this.loadDuel24Question(nextRound);
this.notice = `玩家${player} 得分,进入第 ${this.duel24Round}/6 题`;
“共同换题”意味着一个玩家提交成功后,另一个玩家还没完成的旧计算也会结束。双方立即拿到下一题,这与各做各的独立训练不同。
页面要同时刷新双方牌面、表达式、选择状态、题号和得分。只把题号改成2,而B仍显示第一题的计算,就是一次部分更新。
下一题由B完成并提交,双方进入第3/6题,比分变为A 1 : 1 B。
比赛结束后停止总计时和音乐,并保存双方比分、胜负与用时。重开则恢复题号1与双方零分。
在模拟器中验证隔离
先让A做一步合法合并,检查B的四张牌是否保持原样;再让B撤销或清空,检查A的表达式是否保留。最后完成一方的解题与提交,观察双方是否共同换题。
| 操作 | A区域 | B区域 | 共同状态 |
|---|---|---|---|
| A合并两张牌 | 更新数字与表达式 | 保持 | 题号保持 |
| B清空本题 | 保持 | 恢复四张原始牌 | 分数保持 |
| A错误提交 | 进入本人冷却 | 可以继续操作 | 题号保持 |
| A正确提交 | 加1分、载入新题 | 载入同一新题 | 题号推进 |
对双人玩法来说,隔离检查与共同推进检查缺一不可。前者保证两个人可以各自计算,后者保证他们参加的是同一场比赛。
本次在API26三折叠模拟器展开形态中,分别让A、B完成一题。每步计算后检查对方牌面保持原样,提交后检查共同换题;两次提交后比分为A 1 : 1 B,题号进入3/6。
相关源码:pages/Index.ets 中的 loadDuel24Question、handleDuel24SlotTap、setTwentyFourSlots、submitDuel24 与 finishDuel24;计算与判定继续复用 common/GameLogic.ets。下一篇转向双人象棋,讲棋盘坐标、棋子身份和选子交互。
更多推荐
所有评论(0)