# [特殊字符] 弹琴模拟器 — 鸿蒙ArkTS完整技术解析
·
应用定位:音乐创作模拟类小应用
技术栈:HarmonyOS NEXT + ArkTS + Stage模型
源码行数:113行
核心亮点:8音符音阶系统、录音回放、颜色编码按键、音符序列展示、阵列边界管理
一、引言
弹琴模拟器是系列中第一个引入录音回放功能的应用。它允许用户点击琴键弹奏音符,录制一段旋律,然后播放。
从技术角度看,弹琴模拟器的新概念包括:
- 8音阶系统:Do-Re-Mi-Fa-Sol-La-Si-Do
- 录音系统:将按下的音符存入数组
- 播放回放:展示录制的音符序列
- 颜色编码:每个音符用不同颜色表示
- 序列管理:限制序列长度(最多10个)
二、需求分析
2.1 功能需求
| 需求ID | 功能 | 描述 |
|---|---|---|
| F1 | 音符按键 | 8个彩色琴键,点击发声 |
| F2 | 音符名称 | 显示Do-Re-Mi-Fa-Sol-La-Si-Do |
| F3 | 音阶显示 | 实时显示已弹奏的音符序列 |
| F4 | 录音模式 | 开启后记录所有音符 |
| F5 | 播放录音 | 展示录制的音符序列 |
| F6 | 清空序列 | 重置已弹奏内容 |
2.2 数据结构
private notes: string[] = ['1', '2', '3', '4', '5', '6', '7', '1·'];
private noteNames: string[] = ['Do', 'Re', 'Mi', 'Fa', 'Sol', 'La', 'Si', 'Do·'];
private noteColors: string[] = ['#FF5722', '#FF9800', '#FFEB3B', '#4CAF50', '#2196F3', '#3F51B5', '#9C27B0', '#E91E63'];
三个数组通过索引关联——索引0对应音符’1’、名称’Do’、颜色红色。
三、琴键实现
3.1 琴键渲染
Row() {
ForEach(this.notes, (note: string, idx: number) => {
Column() {
Text(note)
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text(this.noteNames[idx])
.fontSize(10)
.margin({ top: 5 })
}
.width(40)
.height(80)
.backgroundColor(this.noteColors[idx])
.borderRadius(8)
.margin({ right: 3 })
.onClick(() => {
this.playNote(idx);
})
})
}
每个琴键是一个 Column 容器,包含音符数字和名称。8个琴键横向排列在 Row 中。
3.2 音符颜色设计
private noteColors: string[] = ['#FF5722', '#FF9800', '#FFEB3B', '#4CAF50', '#2196F3', '#3F51B5', '#9C27B0', '#E91E63'];
使用彩虹色系(红橙黄绿蓝靛紫粉),每个音符对应一个颜色。这种色彩编码符合音乐中的"音色"概念——不同音符听感不同,视觉上也不同。
四、录音系统
4.1 录音开关
Button('⏺️ ' + (this.isRecording ? '停止录音' : '开始录音'))
.backgroundColor(this.isRecording ? '#F44336' : '#4CAF50')
.onClick(() => {
this.isRecording = !this.isRecording;
if (this.isRecording) {
this.recordNotes = [];
this.message = '🔴 正在录音... 点击琴键录下旋律';
} else {
// 录音结束
}
})
按钮文字和颜色随录音状态动态变化:
- 未录音:绿色"开始录音"
- 录音中:红色"停止录音"
4.2 录制音符
playNote(idx: number) {
this.playedNotes.push(this.notes[idx]);
this.message = '🎵 弹奏了 ' + this.noteNames[idx] + ' (' + this.notes[idx] + ')';
if (this.isRecording) {
this.recordNotes.push(this.notes[idx]);
}
if (this.playedNotes.length > 10) {
this.playedNotes.shift();
}
}
录音分支:如果 isRecording 为 true,额外将音符存入 recordNotes 数组。
序列长度限制:playedNotes 超过10个时,使用 shift() 移除最老的音符。这是一种**FIFO(先进先出)**的队列行为。
五、音阶展示
if (this.playedNotes.length > 0) {
Text('🎼 当前音阶: ' + this.playedNotes.join(' → '))
.fontSize(13)
.fontColor('#333')
.padding(8)
.backgroundColor('#F5F5F5')
.borderRadius(8)
.width('90%')
}
使用 join(' → ') 将音符数组转换为字符串,箭头连接。
六、播放录音
if (this.recordNotes.length > 0) {
Button('▶️ 播放录音')
.onClick(() => {
this.message = '🎶 播放录音中... ' + this.recordNotes.join(' ');
})
}
当前版本中,"播放"只是展示录音内容。完整的播放功能需要配合定时器逐音符回放:
// 进阶播放实现
playRecording() {
let i = 0;
let playInterval = setInterval(() => {
if (i >= this.recordNotes.length) {
clearInterval(playInterval);
return;
}
this.message = '🎵 ' + this.recordNotes[i];
i++;
}, 500);
}
七、扩展思路
7.1 音高播放
使用 Web Audio API 或鸿蒙 AudioKit 播放实际音高:
import { audio } from '@kit.AudioKit';
playTone(frequency: number) {
// 播放对应频率的声音
}
7.2 简易乐谱
private songs: string[][] = [
['1', '2', '3', '1', '1', '2', '3', '1'], // 两只老虎
['3', '4', '5', '3', '4', '5'], // 小星星片段
];
7.3 和弦模式
同时按下多个键触发和弦:
// 需要支持多点触控
onTouch((event: TouchEvent) => {
if (event.type === TouchType.Down) {
// 检测按了哪些键
}
})
八、总结
弹琴模拟器展示了ArkTS在"音乐创作模拟"场景的开发模式:
- 颜色编码:8音符8种颜色对应
- 录音系统:状态开关 + 数组记录
- 队列管理:
shift()限制序列长度 - 音符展示:
join()序列化数组
更多推荐

所有评论(0)