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

一款游戏只有一个玩法时,首页放一个开始按钮就够了。《拼棋派对》有15个玩法入口,玩家还可能一个人练习,或者两个人同屏对战。大厅需要帮助玩家尽快选到合适玩法,同时让推荐、分类和底部导航进入一致的业务流程。

这一篇结合“大厅→数字游戏→单人24点”和“对局目录→棋类游戏→双人象棋”的实际路径,讲配置数据、组件回调与页面状态如何连接。开发环境沿用API26工程与V1状态管理。

三折叠模拟器展开后的大厅与侧边导航

展开窗口中,大厅使用侧边导航和分类入口;手机单屏则采用另一套紧凑布局。

本文目录

用稳定ID组织入口

项目在 GameModels.ets 中定义 ModeItem:

export interface ModeItem {
  id: string;
  title: string;
  subtitle: string;
  tag: string;
  accent: string;
  media: Resource;
  available: boolean;
}

标题给玩家阅读,ID给程序识别。单人24点使用 single24,双人24点使用 duel24。即使将来把标题改成“24点训练”,仍然可以用相同ID连接入口与状态。

配置文件 GameConfig.ets 保存玩法列表与分类。将显示数据集中管理,让推荐条、分类页与其他入口读取同一份标题、资源与可用标志。

这一步同时降低一个常见问题:入口文字已经修改,页面分支却仍然依赖旧标题。业务判断使用ID,显示使用标题,两者各有用途。

分类负责筛选

数字游戏分类聚合单人24点、双人24点、1024和算术对战。点击分类后,页面保存筛选ID,并打开目录:

private openHomeCategory(categoryId: string): void {
  this.pulseTap();
  this.modeCategoryFilter = categoryId;
  this.homeCatalogOpen = true;
  this.notice = '已按分类整理玩法';
  this.invalidateUi();
  this.resetContentScroll();
}

这里没有开始对局。它先改变筛选条件,再进入选择页面,玩家点具体卡片才选择玩法。

resetContentScroll 让新分类从正确位置开始显示。用户可能刚在其他分类浏览到底部,如果只替换内容却保留滚动位置,新分类的前几个入口就可能落在可见区域之外。

数字游戏分类中的四个玩法入口

同一分类页集中展示单人24点、双人24点、1024与算术对战。

组件负责展示与回调

导航组件 GameBottomTabs 接收选中ID、项目列表、颜色和布局参数,并通过 onSelect 将点击交回父页面:

@Prop selectedId: string;
onSelect?: (tabId: string) => void;

在列表项中,选中态由 selectedId === item.id 决定;点击时检查回调是否存在:

.onClick(() => {
  if (this.onSelect) {
    this.onSelect(item.id);
  }
})

组件可以被不同页面复用,父页面仍然负责选择之后的业务行为。比如点击“对局”时需要先打开玩法目录,不能直接把当前玩法无条件开成新局。

列表渲染还使用 item.id 作为键。与数组位置相比,稳定ID能够更准确地标识导航项身份。

手机新版大厅采用 PixelLockedLobby:一张完整背景图配合推荐条、文字层与透明点击区域。它为分类和导航提供百分比热区,并给按钮明确的 accessibilityText。这种实现需要特别检查视觉位置与实际点击区域是否重合,屏幕尺寸变化后是否还能准确命中。

其他窗口布局还有由普通ArkUI组件组成的大厅。讲解时应对照实际显示分支,不能只看某一个Builder就推断所有设备显示完全相同。

进入玩法需要一起更新哪些状态

主页面使用 activeTab 选择大厅、对局、战绩或设置;对局内部使用 activeMode 选择具体玩法。进入24点时,两层状态都需要更新。

openMode 开头的处理顺序是:

const mode = MODE_ITEMS.find((item: ModeItem) => item.id === modeId);
if (mode === undefined) {
  return;
}
this.ensureGameplayState();
this.homeCatalogOpen = false;
this.playCatalogOpen = false;
this.heldKeyCodes.clear();
this.activeMode = modeId;
this.pageKey += 1;
this.setActiveTab('play');

先确认ID存在,再准备游戏状态,关闭目录,清理键盘按键记录,最后切换具体玩法与主标签。

关闭目录标志很重要。否则 activeMode 虽然变成 single24,页面仍可能被“目录打开”的分支覆盖。清理按键记录则避免电脑用户在切页后,被上一页遗留的长按状态影响新玩法。

PlayPage 根据ID选择对应Builder。下面是从原有分支节选的两种24点入口:

} else if (this.activeMode === 'single24') {
  this.SingleTwentyFourPage();
} else if (this.activeMode === 'duel24') {
  this.DuelTwentyFourPage();
}

这个片段位于已有条件链中。项目当前通过组件内状态切换玩法,页面注册表只有 pages/Index,阅读时不要把它与独立路由页面混在一起。

返回大厅与检查路径

返回大厅时,项目关闭目录、停止当前游戏音乐,并切回 home。这一过程保留组件中的既有对局状态。需要明确的是,内存中的状态保留和应用重启后恢复完整棋局属于不同能力,不能仅凭返回按钮提示就认为两者都实现了。

可以在模拟器里按下面的路径检查入口:

路径检查结果
大厅→数字游戏打开数字分类,显示四个入口
数字游戏→单人24点显示单人题号与工具按钮
退出→大厅→再次进入进入预期玩法,目录不覆盖游戏
底部“对局”→选择玩法先出现目录,再打开具体玩法
切换分类分类选中态、内容和滚动位置一致
大厅打开对局目录,筛选棋类,进入象棋并返回大厅

动图展示从大厅打开对局目录、筛选棋类、进入双人象棋并返回大厅。数字游戏和棋类游戏复用同一套分类与进入流程。

大厅最有价值的组织方式,是让多个视觉入口最终收敛到同一个玩法ID和进入函数。这样新增游戏时,可以先补配置与页面分支,再验证所有入口,而不必在推荐、分类和导航中各自写一套开局逻辑。

下一篇进入单人24点,继续讲牌槽模型、两牌运算和答对判定。相关源码:common/GameConfig.ets、components/PixelLockedLobby.ets、components/GameNavigation.ets 与 pages/Index.ets。基础资料可参考华为ArkTS简介。

Logo

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

更多推荐