HarmonyOS 小游戏《对战五子棋》开发第31篇 - TwoPlayerPage双人对战(三):结果弹窗与游戏结束处理 游戏结束时的仪式感——结果弹窗的层叠设计游戏截图Stack层叠布局build(){Stack({alignContent:Alignment.TopStart}){// 第一层游戏界面Column(){// 导航栏、状态栏、棋盘、按钮...}.width(100%).height(100%).backgroundColor(#F5F0E8)// 第二层结果弹窗条件渲染if(this.showResultDialog){Column(){// 弹窗内容...}.width(70%).padding(32).backgroundColor(#FFFFFF).borderRadius(16)}}.width(100%).height(100%)}Stack的层叠原理Stack ├── Column (游戏界面) ← 底层 └── Column (结果弹窗) ← 上层覆盖游戏界面Stack中的子组件按声明顺序层叠——后声明的在上层。弹窗声明在后面所以覆盖游戏界面。条件渲染if(this.showResultDialog){Column(){/* 弹窗内容 */}}showResultDialog为true时弹窗渲染为false时不渲染。ArkUI的条件渲染会完全创建/销毁组件。弹窗触发时机privateonCellClick(row:number,col:number):void{if(this.result!GameResult.PLAYING)return;constsuccessthis.engine.placePiece(row,col,this.currentPlayer);if(success){this.refreshBoardData();if(this.result!GameResult.PLAYING){this.showResultDialogtrue;// 游戏结束时显示弹窗}}}落子后如果result不再是PLAYING有人获胜或平局设置showResultDialog true。弹窗内容设计Column(){Text(this.resultGameResult.DRAW?平局:游戏结束).fontSize(24).fontWeight(FontWeight.Bold).fontColor(#333333).margin({bottom:8})Text(this.getStatusText()).fontSize(18).fontColor(#E63946).margin({bottom:4})Text(共${this.moveCount}手).fontSize(14).fontColor(#888888).margin({bottom:24})Row({space:16}){Button(返回首页).fontSize(16).fontColor(#555555).backgroundColor(#E8E0D5).borderRadius(24).height(44).onClick((){router.back();})Button(再来一局).fontSize(16).fontColor(#FFFFFF).backgroundColor(#4A90D9).borderRadius(24).height(44).onClick((){this.restart();})}}.width(70%).padding(32).backgroundColor(#FFFFFF).borderRadius(16).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)弹窗信息层级┌─────────────────────────┐ │ │ │ 游戏结束 │ ← 24px Bold 主标题 │ 黑方获胜 │ ← 18px 红色 结果 │ 共 47 手 │ ← 14px 灰色 统计 │ │ │ [返回首页] [再来一局] │ ← 44px 按钮 │ │ └─────────────────────────┘弹窗按钮逻辑返回首页Button(返回首页).onClick((){router.back();})调用router.back()返回Index首页。当前页面的组件和引擎实例会被销毁。再来一局Button(再来一局).onClick((){this.restart();})privaterestart():void{this.engine.reset();// 重置引擎this.showResultDialogfalse;// 关闭弹窗this.refreshBoardData();// 刷新UI}restart关闭弹窗并重置游戏——弹窗通过showResultDialog false消失棋盘清空。弹窗样式.width(70%)// 宽度70%两侧留边.padding(32)// 内边距32.backgroundColor(#FFFFFF)// 白色背景.borderRadius(16)// 圆角.justifyContent(FlexAlign.Center)// 垂直居中.alignItems(HorizontalAlign.Center)// 水平居中Stack的alignContentStack({alignContent:Alignment.TopStart})Alignment.TopStart让未指定对齐方式的子组件弹窗从左上角开始排列。但弹窗设置了justifyContent(Center)和alignItems(Center)所以内容在弹窗内部居中。注意Stack默认居中对齐子组件。如果想让弹窗覆盖全屏并居中可以Stack({alignContent:Alignment.Center}){Column(){/* 游戏界面 */}if(this.showResultDialog){Column(){/* 弹窗 */}// 自动居中}}本项目TwoPlayerPage使用TopStart让游戏界面从顶部开始弹窗通过Stack默认行为居中显示。对比AIBattlePage的弹窗AIBattlePage的弹窗更复杂——有半透明遮罩层BuilderresultDialog(){Stack({alignContent:Alignment.Center}){// 半透明遮罩Column().width(100%).height(100%).backgroundColor(#00000066)// 40%透明黑// 弹窗内容Column(){...}}}TwoPlayerPage没有遮罩层AIBattlePage有——设计上的差异。总结结果弹窗的设计要点Stack层叠弹窗覆盖在游戏界面上方条件渲染if (showResultDialog)控制显示信息层级主标题→结果→统计→按钮弹窗样式70%宽度、32内边距、16圆角按钮逻辑返回首页或再来一局弹窗是游戏结束的仪式感——它让用户感受到对局的完整闭环。

相关新闻

最新新闻

从零构建技能创建器:低代码自动化工具的设计与实现

从零构建技能创建器:低代码自动化工具的设计与实现

1. 项目概述:为什么我们需要一个“技能创建器”?如果你是一名开发者,或者对自动化、智能助手领域感兴趣,你肯定不止一次有过这样的想法:“要是能让我的设备/应用学会做这个就好了”。这个“这个”,可能是一…

2026/8/27 3:42:38
云端部署Qwen3.6-Plus:基于PAI-DSW与vLLM的高效推理实践

云端部署Qwen3.6-Plus:基于PAI-DSW与vLLM的高效推理实践

1. 项目概述:为什么选择PAI-DSW来跑通Qwen3.6-Plus?最近在折腾大模型本地部署的朋友,估计都绕不开一个名字:Qwen。通义千问团队开源的Qwen系列模型,从1.5到2.5,再到最近的3.6,性能提升肉眼可见&…

2026/8/27 3:42:37
基于FPGA的DDS正弦波发生器设计:从原理到VHDL实现与优化

基于FPGA的DDS正弦波发生器设计:从原理到VHDL实现与优化

1. 项目缘起:从需求到FPGA选型最近在做一个无线通信模块的前期验证,需要生成一个频率和相位都可灵活调整的高质量正弦波信号。一开始图省事,直接用实验室的现成信号发生器,但很快就遇到了瓶颈:一是需要频繁手动调整参数…

2026/8/27 3:42:37
OCR It:打通纸质文档到LLM数据管线的轻量级文本抽取工具

OCR It:打通纸质文档到LLM数据管线的轻量级文本抽取工具

很多做 LLM 应用的朋友都遇到过同一个痛点:手里有一堆扫描件、PDF、截图、纸质书翻拍图,里面的文字根本不能直接复制。想把这些内容喂给大模型做摘要、做 RAG、做知识库,第一步就得先把“不能复制的文字”变成“能复制的文本”。今天要聊的OC…

2026/8/27 3:42:37
1.9万预算AMD 9800X3D配5070Ti 4K游戏主机装机攻略

1.9万预算AMD 9800X3D配5070Ti 4K游戏主机装机攻略

最近好多朋友在问 1.9W 预算怎么装一台能畅玩 4K 游戏的主机,点名要我聊聊 AMD 9800X3D 和 5070Ti 这套组合。说实话,这组 CPU 和显卡的搭配逻辑非常清晰,一个负责“游戏帧率的底线”,一个负责“高分辨率下的画面上限”&#xff0…

2026/8/27 3:42:37
C++ vector增删查改实战:从内存管理到迭代器失效的深度解析

C++ vector增删查改实战:从内存管理到迭代器失效的深度解析

1. 从“容器”到“瑞士军刀”:为什么vector是C开发者的首选如果你写过C,几乎不可能没用过std::vector。它太常见了,常见到很多新手把它当作一个“会自动变长的数组”来用,增删查改,按部就班。但在我十多年的C开发生涯里…

2026/8/27 3:37:37