2048小游戏
| Files | Last commit | Last update |
|---|---|---|
| 8 days ago | ||
| 7 days ago | ||
| 7 days ago | ||
| 8 days ago | ||
| 7 days ago | ||
| 7 days ago | ||
| 8 days ago | ||
| 8 days ago | ||
| 8 days ago |
2048 滑块合并游戏
用 HarmonyOS ArkTS + ArkUI 实现一个纯端侧 2048 滑块合并游戏:四方向统一压缩-合并算法、GameState 四态切换、PanGesture 手势识别、Preferences 断线续玩与撤销栈,零网络、零云端依赖。

| 项目 | 内容 |
|---|---|
| 适合谁 | 已掌握 ArkTS 基本语法、能使用 DevEco Studio 或命令行构建运行的 HarmonyOS 开发者 |
| 难度与耗时 | 进阶;快速体验约 30 分钟,完整实践约 4 小时(均为估计值,不含环境准备) |
| 你将学到 | 压缩-合并-填充算法、GameState 四态状态管理、PanGesture 手势方向判定、Preferences 本地持久化 |
| 你将完成 | 一个可运行的 2048 游戏:滑动合并计分、撤销一步、断线续玩、胜负弹层与方向提示 |
| 实践环境 | HarmonyOS SDK 6.1.1+;DevEco Studio 或 hvigorw 命令行工具;本地模拟器或真机(二选一) |
1. 案例概览
本案例实现了一个完整的 2048 滑块合并游戏。你将实践网格游戏的通用建模方式(二维数组 + 方向变换)、一套被四个方向复用的核心算法,以及 ArkUI 中状态管理、手势、动画和本地持久化的标准做法。这些能力可直接迁移到棋类、滑块类等网格型应用。
核心功能与体验
- 上下左右滑动 → 所有数字块向对应方向移动,相同数值碰撞合并为两倍值并计分
- 每次有效移动 → 随机空格生成新块(90% 为 2,10% 为 4)
- 达到 2048 → 胜利弹层,可选继续挑战或重新开始;棋盘填满且无可合并块 → Game Over 弹层
- 撤销按钮 → 恢复上一步棋盘与分数;底部实时提示当前可移动方向;杀进程重启后自动恢复进度
技术方案一览
flowchart LR
A["滑动手势"] --> B["Index 主页面"]
B --> C["GameModel 核心逻辑"]
C --> D["GamePreferences 持久化"]
C --> E["TileStyles 样式映射"]
一次滑动操作的处理链路:PanGesture 在 onActionEnd 判定方向 → GameModel 将棋盘按方向变换后执行压缩-合并-填充 → 计分与胜负判定 → syncState() 同步到 UI → GamePreferences 写入本地。
| 层级 | 技术 | 作用 |
|---|---|---|
| 端侧 UI | ArkTS / ArkUI(ForEach + Stack) | 4×4 网格渲染、手势、动画与弹层 |
| 逻辑层 | ArkTS(GameModel 单例) | 移动/合并算法、胜负判定、计分、撤销栈 |
| 数据 | @ohos.data.preferences | 棋盘、分数、最高分与游戏状态的本地持久化 |
边界说明
- 本案例用于学习单点技术(算法、状态管理、手势、持久化),为纯端侧演示应用:无账号、无支付、无网络请求;数值配色上限为 2048。
2. 开始之前
先确认下面的准备条件。本案例不涉及任何计费云资源、账号或密钥配置。
环境与资源
| 项目 | 要求 | 检查或获取方式 |
|---|---|---|
| 基础知识 | ArkTS 基本语法、DevEco Studio 或命令行的基本使用 | 可先阅读 HarmonyOS 官方入门文档 |
| 开发工具 | DevEco Studio,或 hvigorw + HarmonyOS Command Line Tools | 官方下载安装;hvigorw --version 可验证命令行可用 |
| SDK 版本 | HarmonyOS SDK 6.1.1 及以上(工程 compileSdkVersion/compatibleSdkVersion 均为 6.1.1) | 见工程 build-profile.json5 |
| 测试设备 | 本地模拟器或 HarmonyOS 真机 | DevEco Studio 模拟器管理器创建,或 hdc list targets 确认真机连接 |
云端与本地是两种开发入口,选择其一即可。设备需先准备好并确认可被识别,再进行安装运行。
3. 快速体验
选择云端或本地环境,编译打包并安装运行现成的 2048 游戏。完成后,你可以体验"滑动 → 合并 → 计分 → 撤销"的核心闭环。快速体验约需 30 分钟(估计值)。想理解每一行代码怎么来的,请看完整实践。
云端快速体验
使用鸿蒙开发实践中心的在线开发环境,无需在本机安装开发工具。
第一步:创建项目并导入案例
从案例详情页点击 "云端开发环境",平台会自动带入案例信息并打开项目创建窗口。核对信息后,点击 "创建"。
如果直接进入作业中心,则点击 "新建项目":
- 填写项目名称,例如"2048 实践"。
- 技术模板选择 "空项目"。
- 在 "案例仓地址" 中填写:
https://gitcode.com/harmony-practice-center/2048.git
"Git 仓库地址"用于管理你自己的代码,快速体验时可以留空。
完成标志:进入开发环境后,可以看到工程源码目录 entry/src/main/ets(含 GameModel.ets、Index.ets 等)与案例资料目录 cases。
第二步:让 AI 编译打包
在开发环境的 AI 对话中输入:
请解析当前 HarmonyOS 2048 游戏工程,找到工程入口,
检查现有 SDK、依赖和构建工具,然后编译生成 HAP。
如果遇到依赖或编译问题,请根据日志修复并重新构建,
保持案例现有业务功能和包名(com.example.game2048)。
完成后告诉我 HAP 的保存位置,以及安装所需的设备系统和签名条件。
完成标志:构建成功,AI 给出生成的 HAP 路径(entry/build/default/outputs/default/entry-default-unsigned.hap)。
第三步:创建云手机
在开发环境中进入 "设备管理 → 鸿蒙云手机",选择符合工程要求的系统镜像(API 版本不低于工程兼容版本),申请创建云手机。
等待云手机进入运行状态,并完成设备连接。
完成标志:云手机已运行,开发环境能够识别该设备。
第四步:让 AI 安装并打开
在 AI 对话中输入:
请识别当前已连接的鸿蒙云手机,将刚才生成的 HAP 推送到该设备,
完成安装,并启动 2048 游戏应用(bundleName 为 com.example.game2048)。
如果发现多个设备,先列出设备名称让我选择。
如果安装或启动失败,请根据错误信息定位原因并处理。
完成后告诉我使用的设备,以及应用是否已打开。
完成标志:云手机上出现 2048 首页(得分 0、最高分 0,棋盘上有两个随机数字块)。
第五步:体验核心功能
在云手机上完成以下操作:
- 观察初始棋盘:两个随机数字块(2 或 4),底部显示可移动方向提示
- 上下左右滑动:数字块移动合并,得分与最高分实时更新
- 点击撤销:棋盘和分数恢复到上一步
- 点击新游戏:棋盘重置重新开始
完成标志:能够完成一次"滑动 → 合并 → 计分 → 撤销"的最短业务闭环。
体验结束后,保存工程,并按平台操作停止不再使用的开发环境和云手机。
本地快速体验
使用 DevEco Studio 或 hvigorw 命令行工具,在本机完成编译和模拟器运行。
第一步:准备开发工具
按照官方指导安装并准备 DevEco Studio(或仅安装 HarmonyOS Command Line Tools 使用命令行构建),并配置 HarmonyOS SDK 6.1.1 及以上版本。
完成标志:hvigorw --version 可以正常执行。
第二步:获取案例代码
将本仓库克隆到本地任意目录:
git clone https://gitcode.com/harmony-practice-center/2048.git
cd 2048
完成标志:本地能看到 entry/src/main/ets/ 下的源码目录与根目录 build-profile.json5。
第三步:编译打包
在工程根目录执行:
hvigorw assembleHap --no-daemon
生成的 HAP 包位于:entry/build/default/outputs/default/entry-default-unsigned.hap。
完成标志:构建成功且上述 HAP 文件存在。
第四步:准备模拟器
按照 DevEco Studio 模拟器创建指导,创建并启动符合工程要求的模拟器(系统 API 版本不低于 6.1.1)。启动后确认:
hdc list targets
完成标志:命令输出中能看到已连接的设备。
第五步:安装并打开
hdc install entry/build/default/outputs/default/entry-default-unsigned.hap
hdc shell aa start -a EntryAbility -b com.example.game2048
完成标志:模拟器上出现 2048 首页(得分 0、最高分 0,棋盘上有两个随机数字块)。
第六步:体验核心功能
在模拟器上完成与云端体验第五步相同的操作:观察初始棋盘 → 滑动合并 → 撤销 → 新游戏。
完成标志:能够完成一次"滑动 → 合并 → 计分 → 撤销"的最短业务闭环。
保存本地工程后,可以继续阅读完整实践,理解每个模块的实现。
4. 完整实践
这条路线从空项目开始,借助 AI 分阶段完成全部应用代码。云端在作业中心手工新建"空项目",案例仓地址留空;本地在 DevEco Studio 新建空工程或在码道 IDE 打开一个空文件夹。不要克隆完整案例工程,也不要以复制现有应用代码代替独立构建。
下面的提示词按顺序使用。每阶段先核对完成标志,失败时让 AI 定位并修复,再继续下一阶段。
统一教学素材
为保证不同 AI 能构建出相似的业务和界面,统一提供成品视觉参考。应用代码由 AI 在空项目中创建。
| 素材 | 参考文件 | 说明 |
|---|---|---|
| 首页视觉参考 | cases/preview-phone.png | 真机截图:得分/最高分栏、新游戏/撤销/分享按钮、4×4 棋盘、底部方向提示;界面文案与配色以此为基准 |
| 配色基准 | 见步骤 5 的数值配色表 | 与 2048 经典配色一致的映射规则 |
步骤 1:检查空项目与开发环境
目标:知道当前工具与设备条件,保持工作区为空。
复制给 AI:
我要从当前空项目制作 HarmonyOS 2048 滑块合并游戏,产品形态为 HarmonyOS 应用。
请先只读检查当前工作区、操作系统和可用的 HarmonyOS 开发工具。
列出 SDK/API 版本、Node、构建工具及设备连接情况,确认工程可以创建和构建。
本阶段只检查环境,使用已有工具;应用工程将在后续阶段创建。
有缺项时给出具体缺项和官方准备方式;已有工具则使用实际路径。
完成标志:得到环境清单(SDK ≥ 6.1.1),知道下一步在哪里创建工程。
步骤 2:确定产品规则与视觉方案
目标:固定玩法规则与界面要求,让后续实现有明确依据。
复制给 AI:
请为 HarmonyOS 2048 游戏制定需求和视觉方案,先不要写业务代码。
业务目标:纯端侧 2048 滑块合并游戏,零网络、零账号。
主要流程:启动 → 初始棋盘(两个随机块)→ 滑动合并 → 计分 → 胜负判定 → 弹层。
固定规则:
1. 4×4 棋盘,number[][] 表示,0 为空格;
2. 相同数值块碰撞合并为两倍值,每块每次移动最多合并一次;
3. 每次有效移动后在随机空格生成新块,90% 为 2,10% 为 4;
4. 得分为每次合并值的累加;最高分跨游戏保留;
5. 任意块达到 2048 胜利;无空格且无相邻可合并块则失败;
6. 撤销最多保留 1 步历史;滑动方向判定阈值 30px;
7. 断线续玩:重启恢复棋盘、分数与状态。
固定文案:得分、最高分、新游戏、撤销、分享、滑动方向来移动数字块、
可移动方向提示(←左 右→ ↑上 ↓下)、胜利与失败弹层按钮。
视觉规范:背景 #FAF8EF,棋盘 #BBADA0,空格 #CDC1B4;
数值配色:2=#EEE4DA、4=#EDE0C8、8=#F2B179、16=#F59563、32=#F67C5F、
64=#F65E3B、128=#EDCF72、256=#EDCC61、512=#EDC850、1024=#EDC53F、
2048=#EDC22E;8 及以上白字,2/4 用 #776E65 深色字;字号随位数自适应。
布局规范:棋盘居中正方形,上方标题与分数栏,下方操作按钮与方向提示。
请把确认的需求、规则和视觉方案保存到你的工作区,供后续阶段使用。
完成标志:需求覆盖全部固定规则与文案,视觉方案包含完整配色表。
步骤 3:创建可编译的原生工程
目标:先建立可构建的工程和页面骨架。
复制给 AI:
依据已确认的需求和视觉方案,创建原生 ArkTS/ArkUI 工程。
bundleName 使用 com.example.game2048,目标/兼容 API 为 6.1.1。
在 entry/src/main/ets/ 下建立 model/、common/、persistence/、pages/ 目录,
创建 EntryAbility 入口与 Index 主页面骨架(标题、分数栏、棋盘容器、按钮区)。
当前仅做工程和页面骨架,业务逻辑后续接入,页面使用原生 ArkUI 组件实现。
执行调试构建,依据日志修复错误,告诉我构建结果和 HAP 路径。
完成标志:构建成功且 HAP 文件存在,页面骨架可在预览器或设备上查看。
步骤 4:实现棋盘模型与核心算法
目标:完成 2048 的关键算法层(对应 GameModel.ets)。
复制给 AI:
继续实现 GameModel,使用我工作区已确认的规则。
1. 棋盘建模:number[][] 二维数组,0 表示空格;
2. 实现 compressAndMerge(row):压缩(移除0)→ 合并(相邻相同值相加并累计得分)
→ 填充(补0到长度4);
3. 方向变换:LEFT 直接取行,RIGHT 取反转行,UP/DOWN 取列及反转,
四个方向复用同一套 compressAndMerge,处理后按对应方向写回;
4. 每次有效移动后在随机空格生成新块(90% 为 2,10% 为 4);
5. 胜负判定:出现 2048 即 VICTORY;无空格且无相邻相同值即 GAME_OVER;
6. saveState() 深拷贝棋盘与分数入栈(最多 1 步),undo() 弹栈恢复。
以固定输入验证:[2,2,2,2] 向左合并应为 [4,4,0,0] 且得分增加 8;
边界验证:满盘无可合并必须判负。报告实际验证结果。
完成标志:给定固定棋盘输入,四个方向输出正确;胜负判定与撤销逻辑通过验证。
步骤 5:实现本地持久化
目标:完成断线续玩(对应 GamePreferences.ets)。
复制给 AI:
基于 @ohos.data.preferences 实现持久化封装,保存并加载:
棋盘 JSON、当前分数、最高分、游戏状态。
应用启动时自动检测并恢复上次进度;最高分跨游戏保留,新游戏不清除最高分。
使用 await + flush() 确保写入落盘;所有读写做异常兜底,不能因持久化失败导致崩溃。
验证:保存后模拟重启,棋盘与分数能完整恢复。
完成标志:保存后重启应用能恢复棋盘与分数。
步骤 6:实现主页面 UI、手势与动画
目标:完成界面渲染与交互(对应 Index.ets 与 TileStyles.ets)。
复制给 AI:
按确认的视觉方案完成主页面:
1. TileStyles:数字→背景色/字体色/字号映射,按步骤 2 的配色表实现,字号随位数自适应;
2. ForEach 嵌套渲染 4×4 网格,每格 Stack 叠加背景与数字;
3. PanGesture 捕获滑动,onActionEnd 比较 |dx| 与 |dy| 判定方向,
30px 阈值过滤误触;方向有效才调用 GameModel;
4. .animation() 三类动画:格子过渡 150ms EaseInOut、数字出现 200ms EaseOut、
分数变化 300ms EaseOut;
5. 底部实时显示可移动方向(←左 右→ ↑上 ↓下),无可移动方向时对应箭头置灰;
6. 撤销、新游戏、分享按钮:撤销调用 undo(),无历史时按钮置灰。
在设备上实际滑动验证四个方向与合并效果。
完成标志:滑动手势、合并动画、方向提示与按钮行为符合预期。
步骤 7:胜负弹层与分享
目标:完成状态切换的界面呈现。
复制给 AI:
完善 GameState 四态的界面呈现:
1. VICTORY 弹层:显示"你赢了 2048!",提供"继续挑战"和"重新开始"两个按钮;
继续挑战后不再重复弹窗;
2. GAME_OVER 弹层:显示本局得分与最高分,提供"撤销一步"和"重新开始";
撤销后恢复为 PLAYING;
3. 分享:生成包含本局得分与最高分的文本,使用系统分享能力。
检查所有弹层出现时棋盘不可继续滑动,关闭方式符合状态机定义。
完成标志:胜负弹层按状态正确出现,按钮行为与状态机一致。
步骤 8:运行并检查完整流程
目标:把自己的作品安装到设备,体验完整流程并解决运行问题。
按第 3 章的设备准备方式创建、启动并连接模拟器或云手机,然后输入:
复制给 AI:
请编译并运行我当前从空项目构建的作品,检查完整使用流程。
执行构建,告诉我构建结果、HAP 路径和设备安装条件。
识别已连接设备,推送安装包、安装并启动。
逐项实际操作以下场景:
1. 连续滑动 20 步,状态无错乱,分数正确累计;
2. 满盘无合并时正确判定 Game Over;
3. 连续合并 2→4→8→16→32 链式正确;
4. 撤销恢复到上一步;杀进程重启后棋盘和分数恢复;
5. 达到 2048 显示胜利弹层。
检查运行日志,修复能复现的问题,再重新操作对应流程。
最后告诉我 HAP 的实际位置、已能完成的功能,以及遇到问题时应如何继续处理。
完成标志:构建成功,应用在设备上打开,五组场景全部通过。
5. 功能检查与排障
体验检查
在设备上按下表体验,确认核心流程和状态切换符合预期。快速体验和从空项目实践都可使用这些检查项。
| # | 操作 | 预期结果 | 检查方式 |
|---|---|---|---|
| 1 | 首次打开应用 | 得分/最高分为 0,棋盘有两个随机数字块,底部显示方向提示 | 打开页面核对初始状态 |
| 2 | 上下左右滑动 | 数字块整体移动、相同值合并一次、空格生成新块并计分 | 连续操作并观察棋盘与得分 |
| 3 | 点击撤销 | 棋盘和分数恢复到上一步;无历史时按钮置灰或无效 | 对照操作前后的状态 |
| 4 | 杀进程后重新打开 | 恢复上次棋盘、分数与游戏状态 | 重启应用对照状态 |
| 5 | 满盘且无可合并块 | 弹出 Game Over 弹层,可撤销恢复或重新开始 | 用满盘局面验证 |
| 6 | 某块达到 2048 | 弹出胜利弹层,可选继续或重新开始 | 达成 2048 或用高值初始数据验证 |
运行检查
| 项目 | 内容 |
|---|---|
| 版本匹配 | 核对工程 6.1.1 与运行设备系统版本是否匹配 |
| 工程入口 | 确认 AppScope/app.json5(bundleName)与 entry/src/main/module.json5 存在 |
| 构建产物 | 构建结束后能在 entry/build/default/outputs/default/ 找到 HAP |
| 设备连接 | hdc list targets 能识别选定的模拟器或云手机 |
| 体验流程 | 按"体验检查"表逐项核对 |
| 问题恢复 | Game Over / 撤销 / 重启恢复均有效 |
高频问题
| 现象/错误 | 环节 | 常见原因 | 处理与恢复标志 |
|---|---|---|---|
| 撤销按钮点击无效果 | 业务 | 撤销栈最多 1 步且仅在有效移动后有历史 | 先滑动一次再撤销;属预期行为 |
| 重启后棋盘重置 | 业务 | 卸载重装清除本地数据,或上次点了新游戏 | 不卸载直接重开即可恢复 |
| hvigorw 构建失败 | 构建 | SDK 版本低于 6.1.1 或环境变量问题 | 核对 build-profile.json5 与本机 SDK,按日志修复 |
| hdc 找不到设备 | 安装 | 模拟器未启动或未授权 | hdc list targets 确认;重启模拟器后再试 |
| 安装后启动闪退 | 安装 | 设备系统版本低于 compatibleSdkVersion | 换用符合版本的镜像或设备 |
排查顺序:工程与配置 → 工具与构建 → 设备与版本 → 业务状态。
6. 安全与清理
实践中的安全注意事项
本案例为纯端侧应用:无网络请求、无账号体系、不涉及任何凭据或计费能力。
| 项目 | 本案例实践配置 | 操作注意事项 |
|---|---|---|
| 数据 | 仅将棋盘、分数、最高分与游戏状态保存在本机 Preferences | 不含个人信息;无需额外保护 |
清理资源
结束实践前,先保存源码与需要保留的 HAP。
- 保存工程源码与构建产物(如需保留)。
- 关闭本地模拟器或按平台指导停止云手机。
- 清理本地数据:卸载应用即清除全部本地游戏数据;如需保留最高分请勿卸载。
- 清理构建产物:可删除
entry/build/目录释放磁盘空间。 - 云资源清理:不适用(本案例未创建任何云资源)。
完成标志:工程与所需资料已保存,不再使用的设备已停止或关闭。
7. 项目导览与进阶
关键目录
2048/
├── README.md # 案例入口与学习主线
├── AppScope/app.json5 # 应用级配置(bundleName)
├── build-profile.json5 # 工程构建配置(SDK 版本)
├── entry/src/main/ets/
│ ├── entryability/EntryAbility.ets # 入口 Ability
│ ├── pages/Index.ets # 主页面:棋盘 UI、手势、动画、弹层
│ ├── model/GameModel.ets # 核心逻辑:移动/合并/判定/计分/撤销
│ ├── common/TileStyles.ets # 数字→颜色/字体样式映射
│ └── persistence/GamePreferences.ets # Preferences 本地持久化
├── entry/src/main/resources/ # 图标与资源配置
└── cases/ # 案例发布资料(封面、预览图、教程)
完成回顾
完成本案例后,你已经:
- 掌握网格游戏的通用建模方式:二维数组 + 方向变换 + 统一压缩-合并-填充算法
- 会用 GameState 状态机与 @State 驱动 ArkUI 界面切换
- 会用 PanGesture 做滑动方向判定并用 .animation() 做过渡动画
- 会用 @ohos.data.preferences 实现断线续玩与最高分保留
- 产出一个可运行、可继续扩展的 2048 游戏
深入阅读与扩展
以下扩展方向均锚定在本工程真实代码入口上,可按需选做:
- 多步撤销:将 GameModel 中撤销栈的"最多保留 1 步"扩展为可配置的 N 步历史(
saveState()/undo()),注意深拷贝成本与内存占用。 - 扩展配色与数值上限:在 TileStyles 的映射表中增加 4096、8192 及更高数值的配色与字号,验证长数字布局自适应。
- 棋盘尺寸可配:将 4×4 的行列数提取为常量参数,验证 5×5、6×6 下算法与胜负判定仍然正确。
- 动画增强:为合并动作增加缩放脉冲效果,为弹层增加入场动画,对比不同动画曲线的体验差异。
可用下面的提示词给自己的作品做一处独立改造:
请在我已经运行并检查过的 2048 作品里增加 <具体新功能,例如:多步撤销>。
先根据现有实现说明修改范围(涉及 GameModel 的哪些方法)及新增功能的检查方法。
再做最小修改,不要破坏现有滑动合并与断线续玩逻辑。
完成后验证 <新功能的具体操作与结果>,并回归原有核心流程,
说明新功能如何使用,以及检查时发现的问题和处理结果。
8. 参考与维护
官方资料与帮助
- HarmonyOS 开发文档:ArkTS/ArkUI 语法、状态管理(@State)、手势(PanGesture)与 @ohos.data.preferences 的官方说明可按目录检索
- DevEco Studio 下载与使用:见 HarmonyOS 开发文档"工具"章节
- 使用问题:可在本仓库提交 Issue 反馈
- 安全问题:不要在公开 Issue 中披露安全漏洞细节,请联系维护者
维护信息
| 项目 | 内容 |
|---|---|
| 维护者 | yinzheng001 |
| 当前案例版本 | v1.0.0 |
| 文档更新日期 | 2026-10-31 |
| 代码获取方式 | 使用默认分支最新内容 |
| 实践路径 | 快速体验与完整实践见正文第 3、4 章 |
| 兼容限制 | 需要 HarmonyOS SDK 6.1.1 及以上;数值配色上限为 2048 |
案例迭代记录
- v1.0.0(2026-10-31):首次发布;按案例中心规范重构案例资料(README 八章、practice.html 五段、case.json 平台字段)。
许可证
本案例采用 Apache License 2.0 开源协议。