HarmonyOS7应用《拼棋派对》实战:反应抢点的目标切换与双人计分
在一组图形中找到亮点,再尽快作出操作,反应抢点用很少的元素就能形成一场短比赛。《拼棋派对》提供入门、标准和挑战三档,分别增加点位数量与比赛轮数。实现的核心是当前目标、双方得分、轮次和结束状态怎样一起推进。
本文分析主应用1.0.19的实际实现,在HarmonyOS7 API26手机模拟器上完成入门8轮。当前玩法没有等待随机信号的倒计时,也没有抢跑判罚;这里聚焦已有的目标切换和计分,不把它描述成精确反应时间测量工具。
本文目录
用一个索引表示当前亮点
reactionTarget 是当前亮点索引,页面遍历所有格子,通过index是否等于目标决定背景和文字颜色。目标背景为绿色,文字用明确的深色,其他格子采用非激活背景。
.backgroundColor(index === this.reactionTarget
? '#92F536' : this.inactiveControlBg())
.border({
width: index === this.reactionTarget ? 3 : 1,
color: index === this.reactionTarget ? '#2E7600' : this.strokeColor()
})
.onClick(() => this.handleReactionCell(index))
这是当前 ReactionCell 的样式与事件节选。一个目标索引比每格保存一个独立“是否亮起”状态更容易维持唯一目标:索引变化后,旧目标自动变暗,新目标自动变亮。
图形符号只帮助区分格子,不决定分数。命中依赖索引而不是符号内容,避免同样图形重复出现时混淆目标。
点击点位与玩家抢答是两个入口
handleReactionCell 比较点击索引与reactionTarget。命中时调用 hitReaction('A'),未命中只给反馈,不加分、不推进轮次。因此直接点击棋盘亮点,当前归属玩家A。
页面另外提供“玩家A抢”和“玩家B抢”按钮,分别直接调用hitReaction。它们没有传入点位索引,也没有再验证是否点击了亮点。两个人使用按钮时,实际上是人工认定谁先抢到,而不是每人选择正确格子后由程序判定。
private handleReactionCell(index: number): void {
if (index === this.reactionTarget) {
this.hitReaction('A');
return;
}
this.pulseMiss();
this.notice = '没有抢到亮点,继续观察';
}
电脑的F、J键也分别进入A、B计分入口,heldKeyCodes避免按住一个键重复触发。该分支来自源码核对,本轮只用手机触摸操作,没有进行键盘实测。
这一区别影响产品说明:不能说“双方都必须点中亮点才能得分”。如果后续要实现双方各自点位选择,需要事件同时携带player与index,再统一验证命中。
先计分再推进轮次
hitReaction 先拒绝已经结束的比赛,然后给对应玩家加一分。到达最后一轮时直接结算,否则增加轮次并计算下一目标。
if (player === 'A') {
this.reactionScoreA += 1;
} else {
this.reactionScoreB += 1;
}
if (this.reactionRound >= this.reactionRoundTotal()) {
this.finishReactionTap();
return;
}
this.reactionRound += 1;
this.reactionTarget = this.nextReactionIndex(player === 'A' ? 2 : 5);
分数属于玩家,轮次和亮点属于整场比赛。若把轮次也拆成双方各一份,就会变成两个独立训练,而不是同一个亮点的竞争。
最后一轮先计分再结束,保证最终抢答计入成绩。提前设置finished再调用统一计分函数,可能导致末轮被入口保护拒绝。
目标切换与难度配置
| 难度 | 格子数量 | 比赛轮数 |
|---|---|---|
| 入门 | 2×2,共4格 | 8轮 |
| 标准 | 3×3,共9格 | 12轮 |
| 挑战 | 4×4,共16格 | 16轮 |
下一目标由当前索引、轮次和offset计算:
private nextReactionIndex(offset: number): number {
return Math.abs((this.reactionTarget * 5 +
this.reactionRound * 3 + offset) % this.reactionCellTotal());
}
这是确定性公式,不是均匀随机抽样,也没有显式排除与上一轮相同的目标。不能仅凭界面高亮位置改变过,就认为每轮一定不同。
“下一点位”工具会直接增加轮次,但不加任何一方的分数;最后一轮使用它则结束比赛。因此总分可能小于总轮数。如果需要“必须作答才能推进”,应改变这个工具的产品语义,而不是在结算时强行补分。
结束与重新开始
结算比较双方得分,相同为平局,较高者获胜。finishReactionTap标记finished,停止音乐,保存难度、比分与用时。它没有计算单次命中延迟,也没有每轮反应时间数组。
重开将轮次设为1、双方分数与用时归零,并根据时间取一个合法初始目标。初始目标始终位于当前格子数量范围内。难度变化需要检查格子数、轮数和目标范围同时一致,不能只换网格模板。
模拟器效果与改进方向
进入反应记忆分类,选择反应抢点,再切入门并重开。本次先点一个暗格,检查双方仍为0分;再点亮格,A加1分。后续交替使用双方抢答按钮完成8轮,结果为4:4平局,再来一局恢复零分。
动图把格子、比分和轮次放在同一条操作路径里。误点不能计分,命中后题面推进,结束后不能继续累计,这些比初始亮点是否好看更能说明玩法是否工作。
如果要把它升级成严格反应竞赛,建议增加准备、等待信号、允许响应和结束四个阶段;在允许响应时记录时间戳,并验证当前轮标识。倒计时期间输入应判抢跑或拒绝,双人输入必须竞争同一轮,结束后旧输入不能进入新局。这些属于下一步设计,本轮没有在应用中实现。
源码入口:pages/Index.ets 的 ReactionCell、handleReactionCell、hitReaction、nextReactionTarget 和 restartReactionTap。参考HarmonyOS官方文档。下一篇把同样的轮次和计分思想用于算术选答。
更多推荐
所有评论(0)