在鸿蒙应用开发中,游戏类应用能很好地锻炼 UI 布局、状态管理与逻辑交互能力。本文将以一个随机迷宫游戏为例,详细拆解从首页设计到迷宫生成、角色控制、通关判定的完整开发流程,带你掌握 ArkUI 框架的核心应用技巧。

一、项目整体架构

本次开发的随机迷宫游戏包含两个核心页面,页面间通过router路由实现跳转,整体结构清晰,便于后续扩展维护:

页面名称页面功能核心组件 / 逻辑
UI_test1(首页)游戏入口,展示标题与开始按钮Column、Stack、Button、router.pushUrl
migong(迷宫页)随机迷宫生成、角色控制、通关判定Grid、@State 状态管理、BFS 路径检测、AlertDialog

二、首页开发:打造简洁的游戏入口

首页作为用户的第一个交互界面,需兼顾视觉吸引力与操作便捷性。我们采用背景图 + 居中布局的设计,突出 “迷宫游戏” 主题与 “开始游戏” 按钮。

界面演示:

1. 核心代码解析

typescript

import router from '@ohos.router'; // 导入路由模块,实现页面跳转
@Entry
@Component
struct UI_test1{build() {// 外层Column确保页面占满屏幕Column(){// Stack实现背景图与前景内容的层叠Stack(){// 背景图:宽度100%、高度100%,铺满整个页面Image($r("app.media.bg")).width('100%').height('100%')// 内层Column:居中展示标题与按钮Column(){// 游戏标题:白色、斜体、加粗,调整margin优化位置Text('迷宫游戏 ').fontColor(Color.White).fontSize(58).width(250).height(100).fontStyle(FontStyle.Italic).fontWeight(FontWeight.Bold).margin({ left: '12.00vp' })// 开始游戏按钮:淡蓝色背景、白色文字,点击跳转迷宫页Button('开始游戏').fontColor(Color.White).fontSize(30).width(200).height(50).backgroundColor('#9964f0fd').margin({ top: '400.00vp' }) // 向下偏移,与标题形成层次感.onClick(()=>{// 路由跳转:跳转到test_pages目录下的migong页面router.pushUrl({ url: "test_pages/migong" });});}.width('100%').height('100%').justifyContent(FlexAlign.Center) // 子组件垂直居中}}.width('100%').height('100%')}
}

2. 关键设计思路

  • 层叠布局(Stack):通过 Stack 将背景图与前景内容(标题、按钮)叠加,避免背景图被其他组件遮挡;
  • 路由跳转(router):使用router.pushUrl实现首页到迷宫页的跳转,url需与页面实际路径一致(此处为test_pages/migong);
  • 视觉优化:标题采用 “斜体 + 加粗” 组合提升辨识度,按钮使用半透明背景色(#9964f0fd,前两位99为透明度),避免与背景图产生强烈冲突。

三、迷宫页开发:核心逻辑与交互实现

迷宫页是整个游戏的核心,需实现随机迷宫生成、角色移动、路径检测、通关弹窗四大功能。下面分模块拆解实现细节。

1. 随机迷宫生成:确保有有效路径

迷宫本质是一个 20x20 的网格(1 表示墙壁,0 表示可通行区域),为避免生成 “死胡同” 迷宫,我们通过固定边界 + 随机填充 + 路径检测的逻辑,确保从 “入口(1,1)” 到 “出口(18,18)” 有有效路径。

界面演示:

(1)核心函数:generateRandomWall

typescript

// 生成随机迷宫数组
generateRandomWall() {const originalWall = [/* 初始迷宫数组,略 */]; // 基础迷宫模板const rows = 20; // 迷宫行数const cols = 20; // 迷宫列数let newWall: number[] = [];// 1. 固定边界:第一列、最后一列、第一行、最后一行保持为墙壁(1)// 固定第一行for (let i = 0; i < cols; i++) {newWall.push(originalWall[i]);}// 固定中间行的第一列和最后一列for (let r = 1; r < rows - 1; r++) {newWall.push(originalWall[r * cols]); // 第一列(墙壁)// 中间列随机填充:50%概率为可通行区域(0),50%为墙壁(1)for (let c = 1; c < cols - 1; c++) {let randomValue = Math.random() > 0.5 ? 1 : 0;// 固定入口(1,1)和出口(18,18)为可通行区域if (r === 1 && c === 1) randomValue = 0;if (r === rows - 2 && c === cols - 2) randomValue = 0;newWall.push(randomValue);}newWall.push(originalWall[r * cols + cols - 1]); // 最后一列(墙壁)}// 固定最后一行for (let i = cols * (rows - 1); i < cols * rows; i++) {newWall.push(originalWall[i]);}// 2. 路径检测:若当前迷宫无有效路径,重新生成while (!this.checkPathExists(newWall)) {let tempWall = this.generateRandomWall();newWall = tempWall.slice(); // 深拷贝新迷宫数组}return newWall;
}
(2)路径检测:BFS 算法确保连通性

使用广度优先搜索(BFS) 检测从入口到出口是否存在可通行路径,避免生成 “无法通关” 的迷宫:

界面演示:

typescript

// 检查迷宫是否存在有效路径(BFS算法)
checkPathExists(wall: number[]) {const rows = 20;const cols = 20;const startX = 1, startY = 1; // 入口坐标const endX = cols - 2, endY = rows - 2; // 出口坐标// visited数组:记录已访问的格子,避免重复检测let visited: boolean[][] = [];for (let i = 0; i < rows; i++) {visited[i] = new Array(cols).fill(false);}// 队列:存储待访问的格子坐标(BFS核心)let queue: [number, number][] = [];queue.push([startX, startY]);visited[startY][startX] = true;// 四个移动方向:上、下、左、右const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];while (queue.length > 0) {let item = queue.shift(); // 取出队列头部格子if (item) {const [x, y] = item;// 若到达出口,返回true(存在有效路径)if (x === endX && y === endY) return true;// 遍历四个方向,检测相邻格子是否可通行for (let direction of directions) {const newX = x + direction[0];const newY = y + direction[1];// 条件判断:1. 格子在迷宫范围内;2. 未被访问;3. 可通行(值为0)if (newX >= 0 && newX < cols && newY >= 0 && newY < rows && !visited[newY][newX] && wall[newY * cols + newX] === 0) {queue.push([newX, newY]);visited[newY][newX] = true;}}}}// 遍历完所有格子仍未到达出口,返回false(无有效路径)return false;
}

2. 迷宫渲染:使用 Grid 组件构建网格

通过Grid组件将wall数组(20x20)渲染为可视化迷宫,其中:

  • 值为 0 的格子:白色背景(可通行区域);
  • 值为 1 的格子:灰色背景(墙壁)。

核心代码:

typescript

// 迷宫网格渲染
Grid() {// ForEach:遍历wall数组,生成每个格子ForEach(this.wall, (item: number) => {GridItem() {if (item === 0) { // 可通行区域Text('').fontSize(32).backgroundColor(Color.White).width(18).height(21).textAlign(TextAlign.Center)} else if (item === 1) { // 墙壁Text('').fontSize(32).backgroundColor('#8a5e929b').width(18).height(21).textAlign(TextAlign.Center)}}})
}
// 网格配置:20列、20行,列间距与行间距为1(避免格子粘连)
.columnsTemplate('1fr 1fr ... 1fr') // 重复20次1fr,省略部分代码
.rowsTemplate('1fr 1fr ... 1fr')   // 重复20次1fr,省略部分代码
.columnsGap(1).rowsGap(1)
.width('90%').height(400) // 控制网格大小,适配屏幕
.backgroundColor(Color.White)

3. 角色控制:状态管理实现移动逻辑

通过@State装饰器管理角色的坐标(peoplexpeopley)与当前格子索引(positionnumber),点击方向按钮(←↑↓→)时更新角色位置,并判断是否撞墙(撞墙则回退位置)。

(1)状态定义

typescript

@State wall: number[] = this.generateRandomWall(); // 迷宫数组(初始生成)
@State peoplex: number = 34; // 角色初始X坐标
@State peopley: number = 100; // 角色初始Y坐标
@State positionnumber: number = 1; // 角色初始格子索引(对应入口)
@State over: boolean = false; // 通关状态标记
(2)方向按钮逻辑(以 “→” 和 “↓” 为例)

typescript

// 向右移动按钮
Button('→').backgroundColor('#20101010').height(60).width(60).onClick(() => {this.positionnumber += 1; // 索引+1(向右移动一格)// 若目标格子可通行(值为0),更新X坐标;否则回退索引if (this.wall[this.positionnumber] === 0) {this.peoplex += 16.4; // 每次移动的像素值(根据格子宽度计算)} else {this.positionnumber -= 1; // 撞墙,回退到原位置}})// 向下移动按钮(含通关判定)
Button('↓').backgroundColor('#20101010').height(60).width(60).onClick(() => {// 若当前位置是出口前一格,触发通关弹窗if (this.positionnumber === this.wall.length - 2) {AlertDialog.show({title: '游戏成功',message: '恭喜通关',autoCancel: true,alignment: DialogAlignment.Bottom,primaryButton: {value: '确定',action: () => console.info('通关弹窗-确定按钮点击')},secondaryButton: {value: '最优路径',action: () => router.pushUrl({ url: "test_pages/migong1" }) // 跳转最优路径页},cancel: () => console.info('弹窗关闭')});} else {// 普通向下移动逻辑(与向右类似)this.positionnumber += 20; // 索引+20(向下移动一行,共20列)if (this.wall[this.positionnumber] === 0) {this.peopley += 20;} else {this.positionnumber -= 20;}}})

4. 角色渲染与额外功能

  • 角色显示:使用Image组件加载角色图片,通过position属性绑定peoplexpeopley,实现角色随坐标更新而移动;
  • 返回首页:左上角添加 “返回” 图标,点击通过router跳转回首页;
  • 最优路径:底部添加 “解锁最优路径” 按钮,跳转至migong1页面(可扩展 Dijkstra 算法实现最优路径绘制)。

四、开发总结与优化方向

1. 核心技术点回顾

  • ArkUI 布局:灵活使用 Column、Stack、Grid 组件实现复杂 UI 结构;
  • 状态管理@State装饰器实现角色位置、迷宫数组的响应式更新;
  • 路由跳转router模块实现页面间的无缝切换;
  • 算法应用:BFS 算法确保迷宫连通性,为后续扩展最优路径(如 Dijkstra、A*)奠定基础。

2. 可优化方向

  1. 角色移动优化:当前通过固定像素值移动,可改为根据格子宽高动态计算,适配不同屏幕;
  2. 触摸控制:新增滑动手势控制角色移动(如左滑→向左移动),提升操作体验;
  3. 难度分级:增加 “简单(10x10)”“中等(20x20)”“困难(30x30)” 选项,动态调整迷宫大小;
  4. 路径可视化:在migong1页面中,通过改变格子背景色(如绿色)绘制最优路径,帮助用户理解迷宫逻辑。

        通过本次随机迷宫游戏开发,不仅能掌握 ArkUI 的核心语法与组件使用,还能将数据结构(如 BFS)与实际应用结合,为后续鸿蒙游戏或复杂应用开发积累经验。如果你有更多优化想法,欢迎在评论区交流!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/100362.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/100362.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/100362.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

石头科技出海升级:全球电商业财一体化与OMS实践

石头科技作为智能清洁设备领域的独角兽&#xff0c;2023 年海外收入占比超过 60%&#xff0c;产品销往全球 60 多个国家。然而&#xff0c;智能硬件出海的复杂性&#xff0c;让企业在业财管理上面临前所未有的挑战。智能硬件业财痛点 产品生命周期管理&#xff1a;研发、生产到…

《URP管线中后处理效果的创新应用与优化实践》

硬件性能的飞速提升与玩家对画面品质的高要求形成了相互推动的态势,而渲染效果作为游戏视觉体验的核心载体,直接决定了玩家对游戏的第一印象与沉浸感。后处理效果作为URP管线的“点睛之笔”,通过在渲染流程末尾对最终图像进行二次加工,能够模拟真实世界的光学现象(如光线散…

【Java 底层】JVM 垃圾回收机制深度剖析:从对象生死判定到收集器实战

【Java 底层】JVM 垃圾回收机制深度剖析&#xff1a;从对象生死判定到收集器实战 【Java 底层】JVM 垃圾回收机制深度剖析&#xff1a;从对象生死判定到收集器实战 Java 之所以被称为 “开发效率利器”&#xff0c;很大程度上得益于其自动内存管理机制 —— 开发者无需手动分配…

网络问题排查

网络连通性测试&#xff1a;ping ip持续性监测&#xff1a;ping -t ipnetstat 可以查看网络连接状态&#xff0c;可以看到显示系统的网络连接&#xff0c;路由表&#xff0c;接口等信息。netstat -nult 回车-t:显示的是tcp的连接-u:显示udp的连接-l:只显示监听状态的端口-n:显示…

tuple/dict/list 这三个数据类型在取值时候的区别

tuple&#xff08;元组&#xff09;、dict&#xff08;字典&#xff09;、list&#xff08;列表&#xff09;在取值时的区别。 1. list&#xff08;列表&#xff09; &#x1f449; 列表就是“一串有顺序的东西”&#xff0c;像排队的人。 取值方式&#xff1a;用 下标&#xf…

深度解析大模型服务性能评测:AI Ping平台助力开发者精准选型MaaS服务

深度解析大模型服务性能评测&#xff1a;AI Ping平台助力开发者精准选型MaaS服务 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff…

OpenCV物体跟踪:从理论到实战的全面解析

​ 一、引言​ 在计算机视觉的广阔领域中&#xff0c;物体跟踪技术宛如一颗璀璨的明星&#xff0c;散发着独特的魅力与价值&#xff0c;发挥着举足轻重的作用。它致力于在连续的图像帧或视频序列里&#xff0c;精准识别并持续定位特定的目标物体&#xff0c;这一过程看似简单…

【Python】OS模块操作目录

1、概述os模块是一个Python内置的操作目录和查看系统基础信息的模块&#xff0c;可用于让我们对目录进行批量操作&#xff0c;其中包括&#xff1a;查看系统信息&#xff08;环境变量、分隔符、换行符等&#xff09;&#xff0c;对目录进行创建、删除、重命名、查看目录内容等&…

JavaScript中 i++ 与 ++i

在 JavaScript 编程中&#xff0c;i&#xff08;前置自增&#xff09;和i&#xff08;后置自增&#xff09;是两个常用但极易混淆的运算符。它们看似都能实现变量自增 1 的功能&#xff0c;但其执行时机和返回值的差异&#xff0c;常常导致开发者在实际编码中出现逻辑错误。本文…

fastapi 中间件的使用

1. 中间件基础结构from starlette.middleware.base import BaseHTTPMiddlewareclass RequestLoggerMiddleware(BaseHTTPMiddleware):async def dispatch(self, request: Request, call_next):# 1. 请求处理前逻辑# 2. 调用后续处理response await call_next(request)# 3. 响应…

网络白菜包子手动安装 Arch Linux

大家好&#xff01;我是大聪明-PLUS&#xff01;针对初学者的 Arch Linux 安装详细教程。我曾经花了不少时间才搞清楚安装过程。本文旨在提供一种“捷径”&#xff0c;让每个人都能轻松上手&#xff0c;无论他们是否有 Linux 使用经验。Arch 的主要特点是极其灵活的系统配置&am…

Linux学习笔记(五)--Linux基础开发工具使用

在Linux中软件包通常是指一个包含了软件程序、元数据、依赖关系信息和安装脚本的压缩文件​​。因为在Linux上如果没有软件包管理器,那么想要下载软件会非常麻烦,不仅需要自己去手动编译和安装,而且难以卸载和管理,所以软件包的出现解决了这些问题.软件包一般是由程序文件(编译…

数据结构(陈越,何钦铭) 第十讲 排序(下)

10.1 快速排序 10.1.1 算法概述10.1.2 选主元10.1.3 子集划分10.1.4 算法实现10.2 表排序 10.2.1 算法概述10.2.2 物理排序10.3 基数排序 10.3.1 桶排序10.3.2 基数排序10.3.3 多关键字的排序10.4 排序算法的比较

vue 使用print.js 打印文本,HTML元素,图片,PDF

vue 使用print.js 打印文本,HTML元素,图片,PDF 安装 npm install print-js --save示例 <template><div class"print-example"><h2>Print.js 打印示例</h2><!-- 打印区域 --><div id"printableArea" class"printable…

jenkins审批机器人功能概述-Telegram版

Jenkins审批机器人 - 功能概述 代码链接&#xff0c;私聊可得 项目简介 Jenkins审批机器人是一个集成Jenkins CI/CD流程的自动化审批系统&#xff0c;通过Telegram机器人提供便捷的发布审批功能。该系统支持多环境部署审批、用户权限管理、构建结果通知等完整的DevOps审批流程。…

Rust : 关于解引用“*”

关于解引用*操作符&#xff0c;谨供参考&#xff01; 一、主要代码 use std::ops::Deref; fn main() {model_1();model_2();model_3();model_4();model_5();model_6();model_7();model_8();model_9(); }二、*操作符与常见的引用和解引用 fn model_1(){let reference:&St…

【高级终端Termux】在安卓手机/平板上使用Termux 搭建 Debian 环境并运行 PC 级 Linux 应用教程(含安装WPS,VS Code)

Termux 搭建 Debian 环境并运行 PC 级 Linux 应用教程 一、前言 1. 背景 众所周知&#xff0c;最新搭载澎湃OS和鸿蒙OS的平板都内置了PC级WPS&#xff0c;办公效率直接拉满&#xff08;板子终于从“泡面盖”升级为“生产力”了&#xff09;。但问题来了&#xff1a;如果不是这…

从循环到矩阵运算:矢量化加速机器学习的秘诀

矢量化实现全解析&#xff1a;从原理到实战 在学习数据科学、机器学习和深度学习的过程中&#xff0c;我们经常会听到一个高频词——矢量化&#xff08;Vectorization&#xff09;。很多库的官方文档、教程里也不断强调“要尽量使用矢量化操作&#xff0c;而不是显式循环”。那…

大数据毕业设计-大数据-基于大数据的热门游戏推荐与可视化系统(高分计算机毕业设计选题·定制开发·真正大数据)

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

从零到一:用 Qt + libmodbus 做一个**靠谱**的 Modbus RTU 小工具(实战总结)

文章目录从零到一&#xff1a;用 Qt libmodbus 做一个**靠谱**的 Modbus RTU 小工具&#xff08;实战总结&#xff09;你会得到什么快速背景&#xff1a;为什么是 Modbus RTU&#xff1f;协议速查&#xff08;够用不啰嗦&#xff09;工程结构与 UI 组织连接“三板斧”&#xf…