最佳实践 - 基于 ArkUI 鸿蒙五子棋开发:从 0 到 1 构建全场景轻应用
最佳实践 - 基于 ArkUI 鸿蒙五子棋开发:从 0 到 1 构建全场景轻应用
前言
本文以 "鸿蒙五子棋" 案例,从项目架构搭建、核心模块开发,到技术原理拆解与调试工具应用,呈现从 0 到 1 构建鸿蒙轻应用全流程,为开发者提供 "理论 + 实战" 参考,帮助小伙伴们快速掌握 ArkUI 开发范式与鸿蒙全场景适配思路。
项目目录
核心文件 | 核心作用 | 定位 |
---|---|---|
EntryAbility.ts | 应用启动、生命周期管理 | 应用启动器 |
Index.ets | 加载游戏组件、全屏展示 | 首页载体 |
GobangGame.ets | 棋盘渲染、落子 / 判赢 / 重置逻辑 | 游戏核心功能区 |
用户操作链路:点击 APP 图标 → EntryAbility触发 onCreate生命周期 → onWindowStageCreate加载 Index页面 → Index通过 RelativeContainer全屏渲染 GobangGame 组件 → 用户交互(落子 / 重置)→ GobangGame 内部状态驱动 UI 刷新
ArkUI 鸿蒙五子棋开发
应用入口:EntryAbility.ts 启动与生命周期管理
1、EntryAbility.ts 应用入口,管理生命周期并通过 onWindowStageCreate 加载 pages/Index 页面
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } onDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); }); } onWindowStageDestroy(): void { // Main window is destroyed, release UI related resources hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { // Ability has brought to foreground hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } }
首页载体:Index.ets 加载游戏组件与全屏适配
2、Index.ets UI 入口页,引入核心游戏组件 GobangGame,在 RelativeContainer 全屏布局中加载该组件,用户打开应用后能直接看到并进入五子棋界面;同时承接 EntryAbility 的启动流程
import GobangGame from './GobangGame'; @Entry @Component struct Index { @State message: string = 'Hello World'; build() { RelativeContainer() { GobangGame(); } .height('100%') .width('100%') } }
游戏核心:GobangGame.ets 完整玩法实现
3、GobangGame.ets五子棋核心组件,通过 @State 管理 15×15 棋盘状态与游戏进程,用嵌套布局渲染网格棋盘,结合触摸事件实现落子逻辑,通过四向检测判定胜负,还提供重置功能,完整实现五子棋核心玩法
@Entry @Component struct GobangGame { @State board: number[][] = Array(15).fill(null).map(() => Array(15).fill(0)) @State currentPlayer: number = 1 // 1: 黑棋, 2: 白棋 @State gameOver: boolean = false build() { Column() { // 游戏标题 Text(this.gameOver ? '游戏结束' : `当前玩家: ${this.currentPlayer === 1 ? '黑棋' : '白棋'}`) .fontSize(20) .margin(10) // 重新开始按钮 Button('重新开始') .onClick(() => this.resetGame()) .margin(5) // 棋盘 Column() { ForEach(this.board, (row: number[], rowIndex: number) => { Row() { ForEach(row, (cell: number, colIndex: number) => { Column() .width(30) .height(30) .border({ width: 1, color: '#999' }) .backgroundColor(this.getCellColor(cell)) .onTouch((event: TouchEvent) => { if (event.type === TouchType.Down) { this.handleClick(rowIndex, colIndex) } }) }, (colIndex: number) => colIndex.toString()) } }, (rowIndex: number) => rowIndex.toString()) } .margin(10) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } // 获取单元格颜色 private getCellColor(value: number): ResourceColor { return value === 1 ? '#000' : value === 2 ? '#fff' : '#CBA' } // 处理点击事件 private handleClick(row: number, col: number) { if (this.gameOver || this.board[row][col] !== 0) return let newBoard = [...this.board] newBoard[row][col] = this.currentPlayer this.board = newBoard if (this.checkWin(row, col)) { this.gameOver = true AlertDialog.show({ message: `${this.currentPlayer === 1 ? '黑棋' : '白棋'}获胜!` }) } else { this.currentPlayer = this.currentPlayer === 1 ? 2 : 1 } } // 检查胜利条件 private checkWin(row: number, col: number): boolean { const directions = [ [[-1, 0], [1, 0]], // 垂直 [[0, -1], [0, 1]], // 水平 [[-1, -1], [1, 1]], // 主对角线 [[-1, 1], [1, -1]] // 副对角线 ] for (let direction of directions) { let count = 1 for (let i = 0; i < direction.length; i++) { let dx = direction[i][0] let dy = direction[i][1] let x = row + dx let y = col + dy while (x >= 0 && x < 15 && y >= 0 && y < 15 && this.board[x][y] === this.currentPlayer) { count++ x += dx y += dy } } if (count >= 5) return true } return false } // 重置游戏 private resetGame() { this.board = Array(15).fill(null).map(() => Array(15).fill(0)) this.currentPlayer = 1 this.gameOver = false } } export default GobangGame;
核心技术拆解:从功能到场景化延伸
ArkUI 响应式状态管理:数据驱动 UI 的核心实现
@State 修饰 board(棋盘状态)、currentPlayer(当前玩家)、gameOver(游戏结束状态)三个核心变量,是 ArkUI 框架 "状态驱动 UI" 核心特性
- 状态与 UI 联动:当 handleClick 中修改 this.board = newBoard(落子)、this.currentPlayer = 1/2(切换玩家)、this.gameOver = true(游戏结束)时,鸿蒙框架会自动识别依赖这些状态的 UI 元素(如棋盘单元格颜色、标题文本),并触发对应 UI 刷新,无需手动操作界面
- 逻辑与 UI 解耦:无需写 "更新单元格颜色、修改标题文本" 代码,只需维护 @State 变量状态,框架自动完成 UI 同步,符合 ArkUI 声明式开发范式
@State board: number[][] = Array(15).fill(null).map(() => Array(15).fill(0)) @State currentPlayer: number = 1 // 1: 黑棋, 2: 白棋 @State gameOver: boolean = false
五子棋胜负判定算法:性能优化的关键实践
checkWin 方法通过 "四向遍历 + 边界控制" 实现五子连珠检测,是性能优化的关键逻辑,避免无效计算:
- 方向向量遍历:用 directions 数组定义 “垂直、水平、两条对角线”4 个关键方向,仅遍历可能形成五子连珠的方向,不做无意义的全局扫描;
- 边界与终止控制:通过 x >= 0 && x < 15 && y >= 0 && y < 15 控制遍历不超出棋盘范围(避免数组越界),同时一旦检测到非当前玩家棋子,立即终止该方向遍历,减少计算耗时;
- 提前返回:任一方向满足 “连续 5 子” 即 return true,不继续遍历其他方向,进一步提升判定效率
// 检查胜利条件 private checkWin(row: number, col: number): boolean { const directions = [ [[-1, 0], [1, 0]], // 垂直 [[0, -1], [0, 1]], // 水平 [[-1, -1], [1, 1]], // 主对角线 [[-1, 1], [1, -1]] // 副对角线 ] for (let direction of directions) { let count = 1 for (let i = 0; i < direction.length; i++) { let dx = direction[i][0] let dy = direction[i][1] let x = row + dx let y = col + dy while (x >= 0 && x < 15 && y >= 0 && y < 15 && this.board[x][y] === this.currentPlayer) { count++ x += dx y += dy } } if (count >= 5) return true } return false }
游戏交互逻辑设计:稳定性保障的核心策略
handleClick 方法通过 "前置校验 + 状态隔离" 确保游戏交互稳定,避免异常操作与数据错误:
- 前置校验防异常:落子前先判断如下代码,"禁止 游戏结束后落子、已有棋子位置重复落子" 避免逻辑冲突
this.gameOver || this.board[row][col] !== 0
- 状态隔离防污染:用 let newBoard = [...this.board] 复制棋盘数组,在新数组中修改落子状态后再赋值给 this.board,避免直接修改原数组导致的状态污染(如并发操作下的数组异常)
- 结果闭环控制:落子后要么触发 “胜利判定→游戏结束→弹窗提示”,要么 “切换玩家→继续游戏”,每个操作都有明确结果,无逻辑断点
// 处理点击事件 private handleClick(row: number, col: number) { if (this.gameOver || this.board[row][col] !== 0) return let newBoard = [...this.board] newBoard[row][col] = this.currentPlayer this.board = newBoard if (this.checkWin(row, col)) { this.gameOver = true AlertDialog.show({ message: `${this.currentPlayer === 1 ? '黑棋' : '白棋'}获胜!` }) } else { this.currentPlayer = this.currentPlayer === 1 ? 2 : 1 } }
开发效率工具:ArkUI Inspector 调试应用
ArkUI Inspector 是 DevEco Studio 内置的鸿蒙 UI 调试工具,核心作用是帮开发者可视化解析 ArkUI 应用的组件层级、实时查看 / 修改组件属性布局、样式、状态值、追踪组件重渲染与渲染耗时,还能快速定位 UI 元素对应的代码位置,高效解决布局异常、样式不符、UI 卡顿等问题,鸿蒙 UI 开发与优化的核心辅助工具
✅UI 结构可视化,问题定位快:以树形结构直观展示组件层级,点击节点即可在设备上高亮对应 UI 元素,快速打通 "视觉元素 - 代码节点" 映射,解决层级混乱、元素定位难的问题
✅属性实时调试,样式验证高效:支持实时查看组件真实渲染属性(如布局、样式、状态值),且可直接修改属性并即时生效,无需反复改代码、重编译,大幅缩短样式验证周期
✅性能问题可感知,优化有方向:能标记组件重渲染状态(闪烁提示)、统计渲染耗时,直观定位 "频繁重渲染、耗时组件" 等性能瓶颈,为 UI 性能优化提供明确依据
总结
鸿蒙五子棋开发项目以 "启动器 - 首页 - 游戏核心" 三层模块化架构快速搭建应用骨架,通过 ArkUI 的 @State 响应式状态管理、四向遍历性能优化算法、"前置校验 + 状态隔离" 稳定性设计,解决 UI 同步、性能损耗、异常操作等实际开发问题,再结合 ArkUI Inspector 工具高效调试 UI,掌握 ArkUI 声明式开发范式。
👉想解锁更多鸿蒙开发干货、获取项目源码与实战案例,立即加入鸿蒙知识共建交流群:https://work.weixin.qq.com/gm/afdd8c7246e72c0e94abdbd21bc9c5c1
更多推荐
所有评论(0)