扫码寻宝
先了解你将做出什么
游戏介绍
在家里、教室或者小区里藏几张二维码,App 给你一条谜语线索,你猜出地点、跑过去、扫码验证—— 扫对了才解锁下一关。这是一个要满屋子跑的寻宝游戏,藏宝图就在你手机里。
生日会、班级活动、家里带小朋友玩,都能直接用上。你还可以改线索,做成给某个人的专属寻宝路线。

技术上它只做三件事:读二维码、比对暗号、记住你闯到第几关。但组合起来就是一个能玩很久的游戏。
扫码寻宝教程(难度系数:★★)
准备工作:做几张二维码
这一步在电脑上做,不用写代码。
二维码里存的不是网址,就是一个词——我们叫它”暗号”。比如藏在钟表旁边的那张,
里面就存着 钟表 两个字。
去任意一个免费的二维码生成网站(搜「二维码生成」就有),选”文本”类型, 输入暗号,生成、下载、打印出来。这一关的暗号是什么,就写什么。
本教程默认用这四个暗号,对应四个藏宝点:
| 关卡 | 暗号(二维码里的内容) | 贴在哪里 |
|---|---|---|
| 1 | 钟表 |
挂钟或闹钟旁边 |
| 2 | 书架 |
书架上 |
| 3 | 洗手台 |
洗手池的镜子上 |
| 4 | 冰箱 |
冰箱门上 |
能,而且建议写复杂点。
如果暗号就是 冰箱 两个字,聪明的小朋友随便找个二维码生成器自己做一张就”通关”了。
想防作弊,暗号可以写成 bx-7h2k 这种没人猜得到的乱码——反正玩家看到的是线索,
不是暗号,暗号长什么样根本不重要。
App基本逻辑设计
- App 里存两个一一对应的列表:一个放线索(给玩家看的谜语),一个放暗号(用来对答案)。
- 玩家看线索 → 找到地点 → 点”扫一扫” → 扫码 → 和当前关卡的暗号比对。
- 对了就进入下一关,并且把进度存起来;错了提示再找找。
- 下次打开 App,从存的进度接着玩,不用重头来。
两个并排的列表
这是本篇最值得学的一个技巧:用两个列表存同一批东西的不同侧面,靠下标对应起来。
global 线索 = []
global 暗号 = []
global 关卡 = 1
线索 的第 1 项,配的就是 暗号 的第 1 项。只要 关卡 是 1,两边取的都是第 1 项,永远对得上。
这个套路在很多地方都能用:一个列表存题目、一个存答案;一个存商品名、一个存价格。
也可以——App Inventor 里可以做”列表的列表”,每一项是 ["线索", "暗号"] 这样一小对。
两种都对。并排列表的好处是取值简单(select(线索, 关卡) 一眼就懂),
缺点是加一关要同时改两个地方,容易漏。
数据一多、每项的字段一多(比如再加个”提示图片”“得分”),就该换成列表的列表或者字典了。 现在只有两个字段,用并排列表最省事。
显示当前关卡的线索
把”显示”这件事抽成过程,因为进入下一关、重新开始、App 启动,三个地方都要用。
procedure 显示线索() {
if 关卡 > length(线索) {
标签_关卡.Text = "全部通关!"
标签_线索.Text = "恭喜你找到了所有宝藏!"
} else {
标签_关卡.Text = join("第 ", 关卡, " 关 / 共 ", length(线索), " 关")
标签_线索.Text = select(线索, 关卡)
}
}
注意开头那个 if 关卡 > length(线索)——这是防止程序崩溃的关键。
最后一关通过后 关卡 会变成 5,而列表只有 4 项,这时候再去 select(线索, 5) 就会报错。
凡是拿变量当下标去取列表项,都要先想一想:这个下标会不会超出范围?
App 启动时读取进度
when Screen1.Initialize() {
线索 = ["我会滴答滴答,抬头就能看见我", "我住在装满书的格子里", "你每天早晚都来找我刷牙", "我很冷,肚子里装满了吃的"]
暗号 = ["钟表", "书架", "洗手台", "冰箱"]
关卡 = 微数据库_进度.GetValue("关卡", 1)
显示线索()
}
微数据库_进度.获取值("关卡", 1) 里的第二个参数 1 是默认值:
第一次打开 App,微数据库里还什么都没有,就用 1(从第一关开始)。
有默认值这件事很重要。 如果不给默认值,第一次打开时读到的是空字符串, 后面拿它当下标就全乱了。
扫码并比对
when 按钮_扫码.Click() {
条码扫描器1.DoScan()
}
when 条码扫描器1.AfterScan(result) {
if 关卡 > length(暗号) {
标签_线索.Text = "已经通关啦,点「重新开始」再玩一次。"
} else if result = select(暗号, 关卡) {
关卡 = 关卡 + 1
微数据库_进度.StoreValue("关卡", 关卡)
文本朗读器1.Speak("答对了")
显示线索()
} else {
标签_线索.Text = join("扫到的是「", result, "」,不是这一关的宝藏,再找找~")
}
}
扫码是两步的:点按钮只是 执行扫描,把摄像头叫起来;
真正扫到东西是稍后 扫描结束时 这个事件被触发,扫到的内容在参数 result 里。
这种”我发起请求 → 过一会儿结果才回来”的写法,在网络请求、拍照、选图片时到处都是, 是个必须习惯的思维方式。
答对之后马上 微数据库_进度.存储值("关卡", 关卡) 存进度。存早不存晚——
万一玩家手机没电了,至少这一关的成果保住了。
重新开始
when 按钮_重来.Click() {
关卡 = 1
微数据库_进度.StoreValue("关卡", 1)
显示线索()
}
变量和微数据库两个都要改。只改变量的话,下次打开 App 又跳回原来的关卡了。
开始测试
先在桌上把四张二维码摊开,一关一关试:
- 扫对的码,是不是进入下一关?
- 扫错的码(比如第 1 关去扫”冰箱”),是不是提示”再找找”,关卡没变?
- 扫个别的二维码(随便找个商品条码),会不会崩?应该只是提示不对。
- 关键一步:闯到第 2 关,把 App 完全退出再打开,是不是还在第 2 关?
- 四关全过之后,再扫一次码,会不会报错?(有那个
if挡着,应该好好的) - 点”重新开始”,退出重进,是不是真的回到第 1 关了?
第 4 步和第 6 步是这个 App 最容易出问题的地方,一定要试。
剩余工作
- 加计时。记下开始时间,通关时算出总用时,比比谁找得快。
- 加提示。卡住超过 2 分钟,出个按钮给更直白的提示(但要扣分)。
- 拍照留念。每关找到后用照相机拍一张,通关时做成一个相册。
- 自己编线索。加一个”出题模式”,让玩家自己输入线索和暗号, 存进微数据库,就能给朋友出一套专属的寻宝路线了。
- 换成室外版。配合位置传感器,走到指定坐标附近才允许扫码,做成一场城市定向赛。
做完记得真的藏一次给家里人玩,比自己测试有意思多了ヾ(◍°∇°◍)ノ゙
卡在哪一步?直接查操作
不用退出当前教程。速查会在新页面打开,查完回来继续刚才的进度。