拼棋派对开发实战系列封面

从一幅密集场景中找出三只鳄鱼,玩家需要知道自己点中了什么、还剩几个目标,以及这一关结束后能去哪里。《拼棋派对》的寻物挑战把这些反馈组织为关卡地图、游戏和结果三个阶段。点击规则与本地进度共同决定了连续闯关的体验。

本篇以第1关“恐龙丛林”为例,介绍20关配置、提示和通关进度。实操环境为HarmonyOS7 API26手机模拟器,主应用1.0.19。游戏实现位于独立的 HiddenObjectGame.ets,主页面通过回调接收进度、战绩和反馈。

本文目录

关卡配置包含规则

HiddenObjectCampaign.ets 声明20关。每关除了图片和目标列表,还有timeLimit、hintCount、starTime、starMistakes、mistakePenalty与hitAreaScale。增加关卡时不只是换图片,还要提供能对应实际内容的目标区域和规则。

第1关有3只鳄鱼,限时90秒、3次提示、误点增加2秒。目标保存图片百分比中的x、y、width、height,点击时以当前显示宽高换算。hitAreaScale进一步调节热区,避免矩形边界明显覆盖邻近非目标。

配置作用
targets实际需要找到的物体与区域
timeLimit达到此用时后失败
hintCount本关提示次数
starTime / starMistakes通关星级评价条件
mistakePenalty误点给用时增加的秒数
hitAreaScale目标热区的收缩比例

目标位置跟随图片,而不是跟随某一台设备的屏幕。新资源需要检查物体确实存在、缩小后仍可辨认,并逐个验证中心和边缘点击。数据检查不能代替实际看图。

开局统一重置状态

startLevel 读取当前关卡,创建与目标数量一致的found数组,清零用时和误点,恢复提示次数与运行状态。它还清除结果、选中反馈和旧提示回调的代数。

this.found = this.emptyFound(config.targets.length);
this.elapsed = 0;
this.mistakes = 0;
this.hintsLeft = config.hintCount;
this.hintIndex = -1;
this.running = true;
this.paused = false;
this.hintEpoch += 1;
this.setStage('game');

这是开局函数的节选。重开复用它,因此状态定义集中在一处。若只重新加载图片而不清除found,新局可能带着上一局已经找到的目标;若保留paused,则一进入就无法点击。

stage由父页面保存,组件通过onStageChange通知切换;关卡内的用时、提示和目标状态归组件。这样的分工把临时对局与长期进度分开,父页面不用了解每个点击的内部细节。

目标命中与误点惩罚

handleSceneTap把局部坐标换算为百分比,再按热区判断目标。handleTargetTap先拒绝暂停或结束状态。已找到的目标只提示“已锁定”,不会再次增加进度。

首次命中复制found数组并设置对应项;进度由true的数量推导。目标追踪列表与图片标记都读取这一状态,能让“已找到几个”和“圈住了哪些”保持一致。

未命中时,误点数增加,用时加上惩罚并封顶到timeLimit:

this.mistakes += 1;
const penalty = this.currentLevel().mistakePenalty;
this.elapsed = Math.min(this.currentLevel().timeLimit,
  this.elapsed + penalty);
if (this.elapsed >= this.currentLevel().timeLimit) {
  this.finishLevel(false);
}

惩罚改变的是用于限时判断的elapsed,不是另一个只展示的数字。玩家在剩余时间很少时误点,可能立即结束。验收需同时观察误点提示、用时和结果阶段。

提示与暂停的边界

showHint只在运行、未暂停且还有次数时执行。它找到第一个未完成目标,扣一次提示,短暂显示定位,但不把found设为true。玩家仍要点击那个物体才算找到。

高亮持续3秒,回调用hintEpoch保护。重开、返回地图或新提示改变代数后,旧回调不能把新局的提示清掉。下面是清理保护的核心:

const epoch = ++this.hintEpoch;
setTimeout(() => {
  if (epoch === this.hintEpoch && this.hintIndex === index) {
    this.hintIndex = -1;
    this.selectionState = 'idle';
    this.selectionIndex = -1;
    this.bumpRender();
  }
}, 3000);

暂停入口与目标入口都需要遵守paused。只停止计时但允许继续找物,会让玩家在无限思考时间里完成限时关。本组件的点击保护避免了这类规则漏洞;本轮正常操作演示未专门覆盖暂停期间快速点击。

通关以后保存什么

finishLevel成功时计算星级,保留本关最高星数和最快用时,并解锁下一关。最高星数使用Math.max,最快用时只在原记录为0或新成绩更快时更新。重玩较差成绩不会抹掉最好结果。

next.stars[index] = Math.max(next.stars[index], this.resultStars);
if (next.bestTimes[index] === 0 || this.elapsed < next.bestTimes[index]) {
  next.bestTimes[index] = this.elapsed;
}
next.unlockedLevel = Math.max(next.unlockedLevel, this.selectedLevel + 1);

实际源码在解锁前检查是否为最后一关。组件经onProgressChange把新进度交回父页面,再由本地存储服务保存。失败仅记录超时与当前找到数量,不走成功解锁路径。

关卡记录与当前局面也不同:保存星数不代表保存了某局暂停时的全部点击状态。介绍持久化时应明确存的是哪种数据。

第一关操作效果

从图片分类进入寻物挑战,在地图点“恐龙丛林”。本轮使用一次提示,观察次数从3变为2和目标定位;随后点击三只鳄鱼,进度依次到1/3、2/3,再进入完成结果。

寻物地图进入恐龙丛林,使用提示,找到三只鳄鱼并通关

模拟器已有第1关历史通关记录,所以地图初始就显示星数和已解锁第2关。本轮是重玩验证,不能把它称作首次安装后的解锁演示。演示确认的是本次提示与三次命中以及结果显示。

后续重点用例是误点加秒、暂停阻止输入、最后一关的下一关按钮和较差成绩不覆盖最好记录。它们各有不同状态边界,不应仅用正常通关的动图替代。

源码入口:components/HiddenObjectGame.ets 和 common/HiddenObjectCampaign.ets;主页面回调为 handleHiddenObjectProgressChange。参考HarmonyOS官方文档。下一篇讲成语字块的邻接路径与关卡结算。

Logo

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

更多推荐