欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图





1.1 应用简介
AR寻宝探险游戏是一款游戏娱乐类应用,将现实世界变成探险乐园。应用以金色为主色调,象征宝藏与荣耀。界面设计采用游戏化风格,让用户在逛街、游玩的同时享受寻宝乐趣。
应用在公园、商场、街道等地点设置AR寻宝点,用户通过完成任务获得积分和奖励。支持多种任务类型,包括AR扫描、拍照打卡、答题挑战、收集物品等,把日常逛街变成一场精彩的探险游戏。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 雷达地图 | 实时显示附近宝藏 | CustomPaint绘制 |
| 宝藏列表 | 分类展示所有宝藏 | 数据模型存储 |
| AR扫描 | 模拟扫描发现宝藏 | 动画效果展示 |
| 任务系统 | 多种任务类型挑战 | 任务逻辑处理 |
| 奖励系统 | 积分徽章优惠券 | 奖励兑换机制 |
| 排行榜 | 玩家积分排名 | 排序展示 |
1.3 宝藏地点类型定义
| 序号 | 类型名称 | Emoji | 颜色 | 描述 |
|---|---|---|---|---|
| 1 | 公园 | 🌳 | 绿色 | 户外自然探险 |
| 2 | 商场 | 🛍️ | 粉红 | 室内购物探险 |
| 3 | 街道 | 🛣️ | 蓝灰 | 城市漫步探险 |
| 4 | 博物馆 | 🏛️ | 紫色 | 文化历史探险 |
| 5 | 校园 | 🏫 | 蓝色 | 知识探索探险 |
| 6 | 景区 | 🏔️ | 青色 | 风景观光探险 |
1.4 任务类型定义
| 序号 | 任务名称 | Emoji | 颜色 | 描述 |
|---|---|---|---|---|
| 1 | AR扫描 | 📷 | 金色 | 扫描发现宝藏 |
| 2 | 拍照打卡 | 📸 | 粉红 | 拍摄指定场景 |
| 3 | 答题挑战 | ❓ | 蓝色 | 回答趣味问题 |
| 4 | 收集物品 | 📦 | 绿色 | 收集虚拟物品 |
| 5 | 探索发现 | 🧭 | 橙色 | 到达指定地点 |
| 6 | 解谜任务 | 🧩 | 紫色 | 解开神秘谜题 |
1.5 奖励类型定义
| 序号 | 奖励名称 | Emoji | 颜色 |
|---|---|---|---|
| 1 | 积分 | ⭐ | 金色 |
| 2 | 徽章 | 🏅 | 粉红 |
| 3 | 优惠券 | 🎫 | 绿色 |
| 4 | 礼品 | 🎁 | 橙色 |
| 5 | 经验值 | 📈 | 蓝色 |
1.6 难度等级定义
| 序号 | 难度名称 | 等级 | 颜色 | 图标 |
|---|---|---|---|---|
| 1 | 简单 | 1 | 绿色 | 😊 |
| 2 | 中等 | 2 | 橙色 | 😐 |
| 3 | 困难 | 3 | 红色 | 😟 |
| 4 | 专家 | 4 | 紫色 | ⭐ |
1.7 宝藏状态定义
| 序号 | 状态名称 | Emoji | 颜色 |
|---|---|---|---|
| 1 | 未发现 | ❓ | 灰色 |
| 2 | 已发现 | 👁️ | 蓝色 |
| 3 | 已完成 | ✅ | 绿色 |
| 4 | 已锁定 | 🔒 | 橙色 |
1.8 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 自定义绘制 | CustomPainter | - |
| 动画系统 | AnimationController | - |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.9 项目结构
lib/
└── main_ar_treasure_hunt.dart
├── ARTreasureHuntApp # 应用入口
├── TreasureLocation # 宝藏地点枚举
├── TaskType # 任务类型枚举
├── RewardType # 奖励类型枚举
├── Difficulty # 难度等级枚举
├── TreasureStatus # 宝藏状态枚举
├── TreasurePoint # 宝藏点模型
├── Reward # 奖励模型
├── Player # 玩家模型
├── QuizQuestion # 答题问题模型
├── ARTreasureHuntHomePage # 主页面(底部导航)
├── _buildMapPage # 地图页面
├── _buildTreasuresPage # 宝藏页面
├── _buildRewardsPage # 奖励页面
├── _buildLeaderboardPage # 排行榜页面
└── RadarMapPainter # 雷达地图绘制器
二、系统架构
2.1 整体架构图
Data Layer
Business Layer
Presentation Layer
主页面
ARTreasureHuntHomePage
地图页
宝藏页
奖励页
排行榜页
雷达地图
附近宝藏
快速统计
分类列表
宝藏详情
任务执行
徽章展示
奖励兑换
积分管理
前三名展示
完整排行
我的排名
扫描引擎
ScanEngine
任务管理器
TaskManager
奖励系统
RewardSystem
排行榜管理
LeaderboardManager
TreasurePoint
宝藏点
Reward
奖励
Player
玩家
QuizQuestion
问题
2.2 类图设计
located at
has
has
has
offers
type
ARTreasureHuntApp
+Widget build()
<<enumeration>>
TreasureLocation
+String label
+IconData icon
+Color color
+String description
+park()
+mall()
+street()
+museum()
+campus()
+scenic()
<<enumeration>>
TaskType
+String label
+IconData icon
+Color color
+String description
+scan()
+photo()
+quiz()
+collect()
+explore()
+puzzle()
<<enumeration>>
Difficulty
+String label
+int level
+Color color
+IconData icon
+easy()
+medium()
+hard()
+expert()
<<enumeration>>
TreasureStatus
+String label
+IconData icon
+Color color
+hidden()
+discovered()
+completed()
+locked()
TreasurePoint
+String id
+String name
+String description
+TreasureLocation location
+double latitude
+double longitude
+TaskType taskType
+Difficulty difficulty
+TreasureStatus status
+int rewardPoints
+List<Reward> rewards
+String hint
+double distance
+DateTime discoveredAt
+DateTime completedAt
Reward
+String id
+String name
+RewardType type
+int value
+String description
+bool isClaimed
Player
+String id
+String name
+int level
+int exp
+int totalPoints
+int treasuresFound
+int treasuresCompleted
+List<String> badges
+int rank
+int expToNextLevel
+double expProgress
QuizQuestion
+String question
+List<String> options
+int correctIndex
+String explanation
RewardType
2.3 页面导航流程
地图
宝藏
奖励
排行
应用启动
地图页
底部导航
查看雷达地图
选择附近宝藏
开始AR扫描
完成任务
浏览宝藏列表
查看宝藏详情
开始任务
查看我的奖励
兑换奖品
查看排行榜
查看玩家详情
2.4 寻宝流程
奖励系统 任务系统 AR扫描 地图页 用户 奖励系统 任务系统 AR扫描 地图页 用户 打开应用 显示雷达地图 展示附近宝藏 选择宝藏 显示宝藏详情 开始扫描 播放扫描动画 发现宝藏 显示任务 完成任务 发放奖励 获得积分奖励
三、核心模块设计
3.1 数据模型设计
3.1.1 宝藏地点枚举 (TreasureLocation)
dart
enum TreasureLocation {
park('公园', Icons.park, Color(0xFF4CAF50), '户外自然探险'),
mall('商场', Icons.shopping_bag, Color(0xFFE91E63), '室内购物探险'),
street('街道', Icons.add_road, Color(0xFF607D8B), '城市漫步探险'),
museum('博物馆', Icons.museum, Color(0xFF9C27B0), '文化历史探险'),
campus('校园', Icons.school, Color(0xFF2196F3), '知识探索探险'),
scenic('景区', Icons.landscape, Color(0xFF00BCD4), '风景观光探险');
final String label;
final IconData icon;
final Color color;
final String description;
}
3.1.2 任务类型枚举 (TaskType)
dart
enum TaskType {
scan('AR扫描', Icons.qr_code_scanner, Color(0xFFFFD700), '扫描发现宝藏'),
photo('拍照打卡', Icons.camera_alt, Color(0xFFE91E63), '拍摄指定场景'),
quiz('答题挑战', Icons.quiz, Color(0xFF2196F3), '回答趣味问题'),
collect('收集物品', Icons.inventory_2, Color(0xFF4CAF50), '收集虚拟物品'),
explore('探索发现', Icons.explore, Color(0xFFFF9800), '到达指定地点'),
puzzle('解谜任务', Icons.extension, Color(0xFF9C27B0), '解开神秘谜题');
final String label;
final IconData icon;
final Color color;
final String description;
}
3.1.3 宝藏点模型 (TreasurePoint)
dart
class TreasurePoint {
final String id; // 宝藏ID
final String name; // 宝藏名称
final String description; // 描述
final TreasureLocation location; // 地点类型
final double latitude; // 纬度
final double longitude; // 经度
final TaskType taskType; // 任务类型
final Difficulty difficulty; // 难度等级
final TreasureStatus status; // 宝藏状态
final int rewardPoints; // 奖励积分
final List<Reward> rewards; // 奖励列表
final String hint; // 提示
final double distance; // 距离
final DateTime? discoveredAt; // 发现时间
final DateTime? completedAt; // 完成时间
}
3.1.4 玩家模型 (Player)
dart
class Player {
final String id; // 玩家ID
final String name; // 昵称
final int level; // 等级
final int exp; // 经验值
final int totalPoints; // 总积分
final int treasuresFound; // 发现宝藏数
final int treasuresCompleted; // 完成宝藏数
final List<String> badges; // 徽章列表
final int rank; // 排名
int get expToNextLevel; // 升级所需经验
double get expProgress; // 经验进度
}
3.1.5 任务类型分布
25% 20% 18% 15% 12% 10% 任务类型分布 AR扫描 拍照打卡 答题挑战 收集物品 探索发现 解谜任务
3.2 页面结构设计
3.2.1 主页面布局
ARTreasureHuntHomePage
IndexedStack
地图页
宝藏页
奖励页
排行榜页
NavigationBar
地图 Tab
宝藏 Tab
奖励 Tab
排行 Tab
3.2.2 地图页结构
地图页
SliverAppBar
雷达地图
快速统计
附近宝藏
雷达扫描动画
宝藏点标记
位置提示
发现数
完成数
积分
3.2.3 宝藏页结构
宝藏页
SliverAppBar
提示卡片
分类列表
公园宝藏
商场宝藏
街道宝藏
其他宝藏
横向卡片列表
任务图标
难度标签
积分奖励
3.2.4 排行榜页结构
排行榜页
SliverAppBar
前三名展示
完整排行
第一名
第二名
第三名
排名列表
玩家头像
等级信息
积分显示
3.3 AR扫描流程
答题挑战
其他任务
正确
错误
点击开始扫描
显示扫描动画
播放2秒动画
更新宝藏状态
状态变为已发现
任务类型判断
显示答题界面
直接完成任务
答题结果
显示解释
发放奖励
更新积分
显示成功提示
3.4 任务完成逻辑
AR扫描
拍照打卡
答题挑战
收集物品
探索发现
解谜任务
是
否
是
否
开始任务
任务类型
播放扫描动画
打开相机界面
显示问题
显示收集界面
导航到地点
显示谜题
完成任务
答案正确?
谜题解开?
显示提示
继续尝试
发放奖励
更新状态
3.5 积分计算逻辑
简单
中等
困难
专家
是
否
完成任务
获取宝藏难度
难度等级
基础积分 × 1
基础积分 × 1.5
基础积分 × 2
基础积分 × 3
计算最终积分
更新玩家积分
检查升级
经验足够?
等级提升
保持等级
四、UI设计规范
4.1 配色方案
应用以金色为主色调,象征宝藏与荣耀:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #FFD700 | 导航、主题元素 |
| 辅助色 | #FFA000 | 渐变、背景 |
| 成功色 | #4CAF50 | 完成状态 |
| 进行色 | #2196F3 | 进行中状态 |
| 警告色 | #FF9800 | 中等难度 |
| 危险色 | #F44336 | 困难难度 |
4.2 任务类型颜色
| 任务类型 | 色值 | 视觉效果 |
|---|---|---|
| AR扫描 | #FFD700 | 金色闪耀 |
| 拍照打卡 | #E91E63 | 粉红活力 |
| 答题挑战 | #2196F3 | 蓝色智慧 |
| 收集物品 | #4CAF50 | 绿色生机 |
| 探索发现 | #FF9800 | 橙色冒险 |
| 解谜任务 | #9C27B0 | 紫色神秘 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 白色 |
| 宝藏名称 | 16px | SemiBold | #000000 |
| 积分显示 | 18px | Bold | 金色 |
| 难度标签 | 11px | Regular | 难度颜色 |
| 提示文字 | 12px | Regular | #666666 |
4.4 组件规范
4.4.1 雷达地图界面
┌─────────────────────────────────────┐
│ [雷达扫描动画] │
│ ○ ○ ○ │
│ ○ ● ○ │
│ ○ ● ● ○ ← 宝藏点 │
│ ○ ● ○ │
│ ○ ○ ○ │
│ │
│ [📍 附近发现 3 个宝藏] [刷新] │
└─────────────────────────────────────┘
4.4.2 宝藏卡片
┌─────────────────────────────────────┐
│ [🌳] 神秘古树 [未发现] │
│ 公园 · AR扫描 · 简单 │
├─────────────────────────────────────┤
│ 📍 0.5km ⭐ 150积分 │
└─────────────────────────────────────┘
4.4.3 任务详情弹窗
┌─────────────────────────────────────┐
│ [📷] AR扫描 │
├─────────────────────────────────────┤
│ 神秘古树 │
│ │
│ 公园深处有一棵百年古树... │
│ │
│ 💡 提示:寻找树龄超过100年的大树 │
│ │
│ [任务类型] [奖励积分] │
│ AR扫描 150 │
│ │
│ [ 📷 开始AR扫描 ] │
└─────────────────────────────────────┘
4.4.4 排行榜前三名
┌─────────────────────────────────────┐
│ [🥈] [🥇] [🥉] │
│ 第二名 第一名 第三名 │
│ 寻宝达人 探险王者 冒险家 │
│ 12300分 15800分 10500分 │
└─────────────────────────────────────┘
五、核心功能实现
5.1 AR扫描实现
dart
void _startScan(TreasurePoint treasure) {
setState(() {
_isScanning = true;
_selectedTreasure = treasure;
});
Future.delayed(const Duration(seconds: 2), () {
if (mounted) {
setState(() {
_isScanning = false;
final index = _treasures.indexOf(treasure);
if (index != -1) {
_treasures[index] = treasure.copyWith(
status: TreasureStatus.discovered,
discoveredAt: DateTime.now(),
);
}
});
_showTaskDialog(treasure);
}
});
}
5.2 任务完成实现
dart
void _completeTreasure(TreasurePoint treasure) {
setState(() {
final index = _treasures.indexOf(treasure);
if (index != -1) {
_treasures[index] = treasure.copyWith(
status: TreasureStatus.completed,
completedAt: DateTime.now(),
);
_currentPlayer = Player(
id: _currentPlayer.id,
name: _currentPlayer.name,
level: _currentPlayer.level,
exp: _currentPlayer.exp + treasure.rewardPoints,
totalPoints: _currentPlayer.totalPoints + treasure.rewardPoints,
treasuresFound: _currentPlayer.treasuresFound + 1,
treasuresCompleted: _currentPlayer.treasuresCompleted + 1,
badges: _currentPlayer.badges,
);
}
});
}
5.3 答题任务实现
dart
void _showQuizDialog(TreasurePoint treasure) {
final questions = [
const QuizQuestion(
question: '这座城市建于哪一年?',
options: ['公元前221年', '公元589年', '公元960年', '公元1368年'],
correctIndex: 1,
explanation: '这座城市始建于隋朝开皇九年(公元589年)',
),
];
int selectedOption = -1;
bool answered = false;
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => StatefulBuilder(
builder: (context, setState) => AlertDialog(
title: const Text('答题挑战'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(questions[0].question),
...questions[0].options.asMap().entries.map((entry) {
// 选项渲染
}),
],
),
actions: [
FilledButton(
onPressed: selectedOption >= 0
? () {
setState(() => answered = true);
if (selectedOption == questions[0].correctIndex) {
_completeTreasure(treasure);
}
}
: null,
child: const Text('提交答案'),
),
],
),
),
);
}
5.4 雷达地图绘制实现
dart
class RadarMapPainter extends CustomPainter {
final Animation<double> animation;
final List<TreasurePoint> treasures;
RadarMapPainter(this.animation, this.treasures) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final maxRadius = min(size.width, size.height) / 2 - 20;
// 绘制同心圆网格
for (int i = 1; i <= 3; i++) {
canvas.drawCircle(center, maxRadius * i / 3, gridPaint);
}
// 绘制雷达扫描效果
final radarPaint = Paint()
..shader = SweepGradient(
colors: [
const Color(0xFFFFD700).withOpacity(0.3),
const Color(0xFFFFD700).withOpacity(0.0),
],
transform: GradientRotation(animation.value * 2 * pi),
).createShader(Rect.fromCircle(center: center, radius: maxRadius));
canvas.drawCircle(center, maxRadius, radarPaint);
// 绘制宝藏点
for (final treasure in treasures) {
final random = Random(treasure.id.hashCode);
final distance = maxRadius * (0.3 + random.nextDouble() * 0.6);
final angle = random.nextDouble() * 2 * pi;
final point = Offset(
center.dx + distance * cos(angle),
center.dy + distance * sin(angle),
);
canvas.drawCircle(point, 8, pointPaint);
}
}
}
5.5 经验进度计算
dart
int get expToNextLevel => level * 100;
double get expProgress => (exp % expToNextLevel) / expToNextLevel;
六、交互设计
6.1 寻宝流程
任务弹窗 扫描动画 地图页 用户 任务弹窗 扫描动画 地图页 用户 打开应用 显示雷达地图 展示附近宝藏 点击宝藏 显示详情弹窗 点击扫描 启动动画 动画完成 显示任务
6.2 任务执行流程
AR扫描
答题
拍照
是
否
选择宝藏
查看详情
开始任务
任务类型
扫描动画
答题界面
相机界面
完成任务
答案正确
显示解释
获得奖励
更新积分
6.3 奖励兑换流程
选择奖励
积分不够
积分足够
继续积累
浏览奖励
检查积分
积分不足
确认兑换
扣除积分
发放奖励
七、扩展功能规划
7.1 后续版本规划
2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 基础UI框架 宝藏点展示 任务系统 真实AR功能 多人实时对战 社交分享 商家合作 主题活动 成就系统 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 AR寻宝探险游戏开发计划
7.2 功能扩展建议
7.2.1 真实AR功能
AR功能:
- 摄像头实时画面
- 宝藏虚拟叠加
- 空间定位识别
- 交互式动画
7.2.2 多人对战
对战功能:
- 实时竞速模式
- 团队协作任务
- 宝藏争夺战
- 好友邀请
7.2.3 商家合作
合作功能:
- 商家优惠券
- 店铺寻宝点
- 会员积分互通
- 专属活动
八、注意事项
8.1 开发注意事项
-
动画控制:雷达扫描动画需要正确管理AnimationController
-
状态同步:完成任务后需同步更新宝藏状态和玩家积分
-
积分计算:根据难度计算最终积分奖励
-
定时器管理:扫描动画定时器需要在dispose时取消
-
数据持久化:玩家进度需要本地存储
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 扫描无反应 | 状态未更新 | 检查_startScan |
| 积分不增加 | 状态未刷新 | 调用setState |
| 排行榜错乱 | 数据未排序 | 检查排序逻辑 |
| 动画卡顿 | 控制器未释放 | 检查dispose |
8.3 使用技巧
🎮 寻宝探险技巧 🎮
探索建议
- 关注附近宝藏提示
- 选择合适难度任务
- 合理规划寻宝路线
- 组队效率更高
任务技巧
- AR扫描保持稳定
- 答题仔细阅读题目
- 拍照注意构图
- 探索注意安全
积分攻略
- 优先完成简单任务
- 连续完成有加成
- 邀请好友获奖励
- 参与限时活动
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
| Web浏览器 | Chrome 90+ |
9.2 运行命令
bash
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_ar_treasure_hunt.dart --web-port 8144
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_ar_treasure_hunt.dart
# 代码分析
flutter analyze lib/main_ar_treasure_hunt.dart
十、总结
AR寻宝探险游戏应用通过雷达地图、宝藏列表、奖励系统、排行榜四大模块,为用户提供了一个沉浸式的寻宝探险体验。应用支持6种宝藏地点、6种任务类型、5种奖励类型、4种难度等级,让用户在日常逛街中享受探险乐趣。
核心功能涵盖AR扫描、任务挑战、积分奖励、排行榜竞争四大模块。宝藏地点包括公园、商场、街道、博物馆、校园、景区等,覆盖常见活动场所;任务类型涵盖AR扫描、拍照打卡、答题挑战、收集物品、探索发现、解谜任务等,提供多样化游戏体验;奖励系统支持积分、徽章、优惠券、礼品等多种形式,激励用户持续参与。
应用采用 Material Design 3 设计规范,以金色为主色调,象征宝藏与荣耀。通过本应用,希望能够让用户在日常活动中发现更多乐趣,把逛街变成一场精彩的探险游戏。
AR寻宝探险游戏------把逛街变成探险游戏