HarmonyOS7应用《拼棋派对》实战:记忆翻牌的配对规则与状态控制
翻开两张牌,记住图片的位置,下一轮争取找到配对。双人记忆挑战的难点不是图片显示,而是时间与状态:两张不相同的牌需要短暂保留,期间不能翻第三张;重开以后,上一局的延迟回调也不能把新牌盖回去。
《拼棋派对》使用12张牌、6组图片,配对成功得1分并继续翻牌,失败回盖后换人。本文在HarmonyOS7 API26手机模拟器中走完配对与结算,分析锁定标志和回合代数怎样配合。示例为主应用1.0.19。
本文目录
牌的身份与显示状态
createMemoryCards 为山湖、城市、星际、美食、音乐、竞速六组主题各生成两张牌,再按seed打乱。两张配对牌的id不同,value相同。图片资源是展示内容,value才是配对依据。
| 字段或状态 | 表达的含义 |
|---|---|
| id | 某一张牌的稳定身份 |
| value | 所属图片组,比较相等时配对 |
| flipped | 本回合已经翻开 |
| matched | 已经成功配对,保持公开 |
| memoryFirstIndex | 第一张待比较牌的位置 |
| memoryLocked | 两张失败牌等待回盖,禁止继续翻牌 |
| memoryCurrent | 当前行动玩家A或B |
如果把value直接作为列表唯一键,一对牌就会共享键,列表更新可能混淆。页面应该使用牌的id表达身份,用value比较组别。配对后matched保持true,避免已经得分的牌再次参与计算。
每次修改牌状态,项目用 cloneMemoryCards 克隆对象。只复制数组却继续修改数组里的同一对象,仍然会影响旧数据;克隆牌对象让前后状态的归属更清楚。
第一张和第二张分别处理
点击入口先拒绝锁定、比赛结束、越界、已配对或已翻开的牌。第一张只修改flipped与memoryFirstIndex,不增加回合数。第二张才构成一次尝试,回合数加一,比较两张value。
成功分支的核心代码如下,省略音效和提示:
if (cards[this.memoryFirstIndex].value === cards[index].value) {
cards[this.memoryFirstIndex].matched = true;
cards[index].matched = true;
this.memoryMatched += 1;
if (this.memoryCurrent === 'A') {
this.memoryScoreA += 1;
} else {
this.memoryScoreB += 1;
}
this.memoryCards = cards;
this.memoryFirstIndex = -1;
if (this.memoryMatched >= 6) {
this.finishMemoryFlip();
}
return;
}
成功后没有切换memoryCurrent,因此同一玩家继续翻下一组。只清理第一张索引,让下一次点击重新从“本回合第一张”开始。不要把清除索引与换人绑定在一个公共函数里,否则会改变玩法规则。
失败后锁住输入
不匹配时两张牌保持翻开720毫秒,让玩家有时间记住位置。设置memoryLocked以后,任何额外点击只给等待提示,不改变盘面。这可以防止第三张牌混进当前比较。
延迟回调需要保存firstIndex、secondIndex和currentPlayer,而不是在执行时读取可能已经变化的选择状态。回盖时克隆当前牌数组,只回盖仍未matched的对应牌,再解除锁定并切换玩家。
this.memoryLocked = true;
setTimeout(() => {
if (roundEpoch !== this.memoryRoundEpoch || this.memoryFinished) {
return;
}
const nextCards = this.cloneMemoryCards(this.memoryCards);
if (firstIndex >= 0 && firstIndex < nextCards.length &&
!nextCards[firstIndex].matched) {
nextCards[firstIndex].flipped = false;
}
if (secondIndex >= 0 && secondIndex < nextCards.length &&
!nextCards[secondIndex].matched) {
nextCards[secondIndex].flipped = false;
}
this.memoryCards = nextCards;
this.memoryLocked = false;
this.memoryCurrent = currentPlayer === 'A' ? 'B' : 'A';
}, 720);
代码节选保留了回调的主要保护条件。720毫秒是交互等待时间,不是答题倒计时,也不是帧率控制。
让旧回调失效
用户可能在两张失败牌尚未回盖时点击重开。新局已经重新发牌,如果旧定时器继续执行,就会改动新局同样索引处的牌,并把行动方切成上一局的对手。
项目使用memoryRoundEpoch标识当前有效回调。创建失败回调时增加代数并保存局部值;重开时再次增加代数。回调执行前发现局部值与当前值不同,就返回。
这个方式不依赖旧索引是否仍然有效。旧索引合法,也可能属于完全不同的新局;代数检查的是操作属于哪一次有效状态。提示高亮另外使用memoryHintEpoch,避免多个提示回调互相覆盖。
重开统一清空分数、回合、配对数、用时、第一张索引、提示列表、锁定与结束标志,并让A先翻。只重新生成cards而保留memoryLocked,会让新局看起来完整却无法操作。
提示、结算与重开
提示从未配对牌里找一组相同value,短暂标出两个位置,950毫秒后清除提示列表。它不直接计分,也不把牌标为matched。提示与真正配对走不同状态路径。
全部6组配完后,停止对局、计算胜者并记录双方比分、回合数与用时。两人分数相同为平局。成功继续行动、失败才换人的规则意味着一名玩家可能连拿多分,不能期待每两张牌就固定换人。
实际翻牌效果
进入“反应记忆→双人记忆挑战”,重开后观察12张背面牌。实操先逐张翻开记住图案,再按可见图片配对,走到六组完成和结果显示;随后重开检查双方分数恢复0。
动图中应同时观察三件事:翻开第二张后是否配对、成功配对数是否增加、当前玩家是否符合成功继续和失败换人的规则。仅检查图片出现,无法证明回合控制正确。
本轮完成了可见图片配对与结算取证。720毫秒锁定窗口中的第三次点击、回盖前重开和多次提示的回调竞争,仍需要专门的快速操作用例。本文解释其保护代码,不把正常配对过程当作这些边界都已验证。
源码入口:common/GameLogic.ets 的 createMemoryCards;pages/Index.ets 的 handleMemoryTap、memoryHint、restartMemoryFlip 和 finishMemoryFlip。参考HarmonyOS官方文档。下一篇分析反应抢点的亮点切换与得分入口。
更多推荐

所有评论(0)