跳到教程内容
教程首页
App Inventor 2 教程 我的钢琴
准备开始
动手创造 · PROJECT LAB

我的钢琴

准备探索你的新作品
0%
项目难度每一步,都离作品更近

先了解你将做出什么

应用介绍

做一台装在手机里的钢琴:屏幕上并排八个琴键,点哪个响哪个音,do re mi fa sol la si do 一个不少。

这是一篇很适合入门的教程,代码量极小,但会用到三样以后天天要用的东西: 组件重命名、宽高属性、以及”用过程消灭重复代码”

教程主图

界面示意图

连接你的应用

通过 WiFi 连接设备

使用 AI 伴侣连接后,可以在手机或平板上实时查看和测试应用。

AI 伴侣连接示意图

视频演示:

App Inventor 2 连接 AI 伴侣

安装 AI 伴侣

使用手机系统扫码器或浏览器扫描二维码,下载并安装 AI 伴侣。只需安装一次,以后可以直接使用。

AI 伴侣下载二维码

打开应用的连接二维码

在 App Inventor 2 中依次点击「连接」和「AI 伴侣」。

打开 AI 伴侣连接

连接手机

连接二维码会显示在电脑屏幕上。

应用连接二维码

在手机 AI 伴侣中点击蓝色的「scan QR code」按钮扫描二维码;也可以输入代码,再点击橙色的「connect with code」按钮。

AI 伴侣连接界面

使用模拟器连接

模拟器由 aiStarter 自动启动,不需要手机,但速度较慢、环境配置较复杂且 Android 版本较旧,一般不推荐作为首选方式。

App Inventor 2 连接模拟器

使用 USB 连接

aiStarter 可以通过 USB 调试连接手机,并自动启动手机上的 AI 伴侣。它的使用效果和扫描二维码连接基本相同。

App Inventor 2 使用 USB 连接

查看完整连接教程

下面的视频完整演示 AI 伴侣、模拟器和 USB 三种连接方式。不同方式的详细比较可以查看连接方式说明

App Inventor 2 完整连接教程

仍然无法连接?

可以前往中文社区查找解决方案或发帖提问。

我的钢琴教程(难度系数:★)

找素材并上传

需要八个音频文件,分别是 do 到高音 do 的八个音:

CNote.wavDNote.wavENote.wavFNote.wavGNote.wavANote.wavBNote.wavHighCNote.wav

(此步骤通过“项目指南” -> “开始学习” 已经完成了初始工作,八个音频都已经上传好,可以直接使用)

看一看模板里已经有什么

打开模板工程,你会看到:

  • 一个 水平布局_琴键行(水平布局),里面已经放了 六个按钮:按钮_E 按钮_F 按钮_G 按钮_A 按钮_B 按钮_高C
  • 一个 音频播放器_音符(音频播放器组件),非可视组件,排在屏幕下方。

模板界面示意图

注意到了吗——少了 按钮_C按钮_D。这两个得你自己加,正好熟悉一下设计器。

补上缺的两个琴键

从左侧「界面布局」里拖两个按钮水平布局_琴键行注意要拖到最左边,因为 C 和 D 是最低的两个音。

拖进去之后按钮默认叫 按钮1按钮2,右键(或用组件面板下方的「重命名」按钮)把它们改成 按钮_C按钮_D

因为写代码块时你看到的就是组件名。八个按钮如果都叫 按钮1按钮8, 写到第五个你就分不清哪个是哪个音了。

组件一拖进来就顺手改名,这是个能省下大量返工时间的好习惯。

调整琴键的大小和外观

八个键要平分屏幕、竖着占满,所以每个按钮都这样设:

属性 为什么
高度 充满 琴键竖着撑满整行
宽度 12% 八个键平分,八分之一大约就是 12%
显示文本 C D E 键面上的音名

宽度一定要用百分比,不要写固定像素。 手机屏幕宽窄不一,写死像素在别人手机上就会错位或者显示不全。

属性面板示意图

想让琴键更好看,可以先把 背景颜色 一个个设成不同的颜色。 真正的黑白键效果在后面「让它看起来像真钢琴」那一节做。

让第一个键响起来

切到「代码块」视图。让一个键发声只需要两步:先告诉播放器放哪个文件,再让它播。

when 按钮_C.Click() {
  音频播放器_音符.Source = "CNote.wav"
  音频播放器_音符.Start()
}

顺序不能反——先设 音源开始播放,不然播放器还不知道要放什么就被叫去播了。

这里的 "CNote.wav" 就是你上传的那个音频文件的文件名,一个字都不能错(含大小写和扩展名)。

先测一下

连上 AI伴侣,点一下 C 键,应该能听到一声 do

听不到的话,先查这三样:手机音量、文件名有没有打错、音源开始播放 的顺序。

剩下七个键

剩下七个键做的事情一模一样,只是文件名不同。你可以照着上面再写七遍——

但更好的办法是:右键点已经写好的那块,选「复制代码块」,复制出来之后 用下拉框把 按钮_C 改成 按钮_D,再把文件名改成 DNote.wav 就行了。

自己试试把八个键都做出来。

when 按钮_C.Click() {
  音频播放器_音符.Source = "CNote.wav"
  音频播放器_音符.Start()
}

when 按钮_D.Click() {
  音频播放器_音符.Source = "DNote.wav"
  音频播放器_音符.Start()
}

when 按钮_E.Click() {
  音频播放器_音符.Source = "ENote.wav"
  音频播放器_音符.Start()
}

when 按钮_F.Click() {
  音频播放器_音符.Source = "FNote.wav"
  音频播放器_音符.Start()
}

when 按钮_G.Click() {
  音频播放器_音符.Source = "GNote.wav"
  音频播放器_音符.Start()
}

when 按钮_A.Click() {
  音频播放器_音符.Source = "ANote.wav"
  音频播放器_音符.Start()
}

when 按钮_B.Click() {
  音频播放器_音符.Source = "BNote.wav"
  音频播放器_音符.Start()
}

when 按钮_高C.Click() {
  音频播放器_音符.Source = "HighCNote.wav"
  音频播放器_音符.Start()
}

进阶:用过程把重复代码收起来

上面那段能跑,但你有没有觉得别扭——同样的两句话写了八遍

万一哪天想加个音量控制,或者想在弹之前先停掉上一个音,你得改八个地方,漏一个就出bug。

这时候就该用过程了。把”重复的部分”抽出来,把”每次不一样的部分”做成参数:

procedure 弹一个音(音频文件) {
  音频播放器_音符.Source = 音频文件
  音频播放器_音符.Start()
}

when 按钮_C.Click() {
  弹一个音("CNote.wav")
}

when 按钮_D.Click() {
  弹一个音("DNote.wav")
}

八个按钮各调一次 弹一个音,每个只有一行。以后要改播放逻辑,只改过程里那一处

判断标准很简单:同样的几句话,你写了第三遍——那就该抽成过程了。

抽出来的好处有三个:改一处就够、代码短了容易看懂、名字本身就是注释 (弹一个音 比两行属性设置更能说明意图)。

进阶:加上黑键

现在这台钢琴只有 7 个自然音,弹不了带升降号的曲子。跟着下面的步骤把 5 个黑键补上:

先准备升音的音频

模板里只带了 7 个自然音,5 个升音(#C #D #F #G #A)需要你自己补上。

可以自己用录音软件录,也可以在网上找免费的钢琴单音素材。文件名建议按 CSharpNote.wavDSharpNote.wav 这样起,和按钮名对得上,写代码时不容易搞混。

准备好之后上传到「素材」里。

切到设计视图

切到设计视图

再加 5 个按钮

水平布局_琴键行 里再拖 5 个按钮, 每个升音键放在它对应的自然音后面—— #C 键 放在 按钮_C 后面,#A 键 放在 按钮_A 后面,以此类推。

记得重命名成 C升键D升键…… 名字和音频文件对得上,后面写代码会轻松很多。

加上升音按钮

想一想:现在一共有 13 个按钮了,要让宽度加起来正好占满一行,每个按钮的宽度该设成百分之几?(往下取整就行)

加上点击事件

切到代码块视图。

切到代码块视图

给 5 个新按钮各加一个 当按钮.被点击 事件。如果你已经写了 弹一个音 过程,这里每个只要一行—— 调用它,把对应的文件名传进去。

播放升音

注意:文件名要和你上传的完全一致,包括大小写和扩展名。弹下去没声音,八成就是这里错了。

试一试

连上 AI伴侣,把 13 个键挨个按一遍,听听音高是不是依次升上去的。

顺序对了的话,你已经有一台完整的一个八度的钢琴了。

进阶:让它看起来像真钢琴

13 个一模一样的方块按钮,说是钢琴还差点意思。把白键染白、黑键染黑、再让黑键矮一截:

把琴键染成黑白

切到设计视图。

切到设计视图

做起来很简单:把所有自然音按钮的背景颜色设成白色,所有升音按钮的背景颜色设成黑色

黑键上的字这时会看不见,所以还要把黑键的文本颜色改成白色。

修改按钮颜色

调整整行的布局

白键设成白色之后会和屏幕底色糊在一起,看不出边界。把 水平布局_琴键行背景颜色改成浅灰(或者别的深一点的颜色),白键就显出来了。

再把 水平布局_琴键行垂直对齐属性改成「顶端对齐」

修改布局属性

真钢琴上黑键比白键短,所以可以把升音按钮的高度调矮一些。 40% 是个不错的起点,你也可以多试几个值看哪个顺眼。

修改按钮高度

试一试

连上 AI伴侣看看效果。是不是比一排一模一样的按钮像钢琴多了?

顶端对齐之后,矮一截的黑键会正好卡在白键上方,和真钢琴的排布一致。

进阶:把你弹的曲子录下来

弹完了想给别人听?加三个按钮和一个录音机就行。这一段还会讲一个很重要的概念: 发起动作和拿到结果是两回事

添加组件

切到设计视图。

切到设计视图

拖一个水平布局到屏幕上,往里放 3 个按钮,按顺序重命名为 按钮_录音按钮_停止录音按钮_播放录音,并把各自的显示文本改成对应的字。

关键一步:按钮_停止录音按钮_播放录音启用 勾去掉。

取消勾选启用

为什么?因为还没开始录的时候,「停止」和「播放」是没意义的。 把当前用不上的按钮禁用掉,用户就不会点出一堆错误—— 这是界面设计里很常用的一招。

再从「多媒体」里拖一个录音机和一个音频播放器进来,把播放器重命名为 音频播放器_录音(别和弹琴用的 音频播放器_音符 混了)。

开始录音

切到代码块视图。

切到代码块视图

点「按钮_录音」时,让录音机开始录,同时把三个按钮的可用状态倒过来:

when 按钮_录音.Click() {
  录音机1.Start()
  按钮_录音.Enabled = false
  按钮_停止录音.Enabled = true
}

录音期间不能再点「录音」,所以把它禁用;「停止」这时才有意义,所以启用它。

停止录音

when 按钮_停止录音.Click() {
  录音机1.Stop()
  按钮_停止录音.Enabled = false
}

注意这里没有启用「按钮_播放录音」——因为录音文件还没保存好。

等录音文件真正就绪

录音机停下来之后,系统还要花一点时间把文件写好。写好的那一刻会触发 录音完成时 事件,并且把文件位置放在参数 sound 里。

when 录音机1.AfterSoundRecorded(sound) {
  音频播放器_录音.Source = sound
  按钮_录音.Enabled = true
  按钮_播放录音.Enabled = true
}

这是本篇最重要的一点:录音文件必须在这个事件里拿,不能在「停止」那一步就直接用。在文件还没写完时去播放,只会得到一段空白或者报错。

这种「我发起动作 → 完成事件里才拿结果」的写法,拍照、选图片、网络请求都是一样的套路。

播放录音

when 按钮_播放录音.Click() {
  音频播放器_录音.Start()
}

音源在上一步已经设好了,这里直接播就行。

试一试

连上 AI伴侣,弹一小段曲子并录下来,然后回放听听。

重点验证三个按钮的可用状态:一开始只有「录音」能点;录音中只有「停止」能点;停下来之后「录音」和「播放」都能点了。

剩余工作

一台像模像样的钢琴已经做好了,还能往下做的还有很多:

  • 显示简谱。点键的时候在上方标签里把 1 2 3 4 5 6 7 显示出来,边弹边认谱。
  • 跟弹小游戏。屏幕依次提示该按哪个键,按对了加分——这就是一个音乐版的”记忆挑战”了。
  • 和弦。同时响两三个音是什么效果?试试一个按钮触发多个播放器。

弹一首《小星星》试试:1 1 5 5 6 6 5,也就是 C C G G A A G,加油ヾ(◍°∇°◍)ノ゙