HarmonyOS7应用拼棋派对开发实战系列统一封面

同一组四张数字牌放在两个人面前,各自尝试组合,先得到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。

接着清空双方选中索引、运算符和历史。这些步骤在每次共同换题时执行;累计分数和总用时保留到比赛结束。

三折叠模拟器展开后,双人24点双方拥有相同题目和独立操作区

双方从相同数字开始,每人有自己的运算符、撤销与提交入口。

把操作分发给正确玩家

公共选牌函数接收模式与玩家标识,先确定它要读取哪份状态:

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,提交后双方共同换题

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独立答题提交,比分变为A1比B1并进入第三题

下一题由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。下一篇转向双人象棋,讲棋盘坐标、棋子身份和选子交互。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐