使用 Android Studio 开发一款弹钢琴app

news2024/9/24 7:19:08

A. 项目描述

本项目主要实现了【钢琴键盘的模拟】、【弹奏引导】以及【乐曲库】等功能。
钢琴键盘模拟:提供全尺寸键盘,并且根据用户的喜好来调整键盘的颜色样式。
弹奏引导:用户可以根据键盘上的提示符号 👆 来学习演奏。对于钢琴萌新/小白来说这个功能太方便了,可以像老手一样轻松弹奏各种曲目。
乐曲库:内置了曲谱,包括经典音乐、流行歌曲。用户可以跟随引导演奏这些曲目。
总之,这个app可以使得学习钢琴变得有趣和便捷,无论是钢琴初学者还是已经有一定经验的音乐爱好者,都可以从中受益。

B. 开发工具

  • Android Studio Dolphin | 2021.3.1 Patch 1
  • Java , JDK 11.0.13
  • Gradle , gradle-7.4

C. 功能设计

钢琴键盘模拟

PianoCanvasView类实现了钢琴键盘的绘制,它继承SurfaceView,可以在子线程中更新UI;

  • draw_all_keys方法,绘制了钢琴的所有键;
    void draw_all_keys(final Canvas canvas) {
        // 重置 canvas
        {
            Paint p = new Paint();
            p.setColor(Color.BLACK);
            canvas.drawPaint(p);
        }

        if (KEY_COLORS == null || null == PRESSED_KEY_COLORS || KEY_COLORS.length <1 || PRESSED_KEY_COLORS.length <1) {
            setKeyboardStyleColorful();
        }

        for (int i = 0; i < piano.get_keys_count(); i += 2) {
            // 绘制大琴键
            final int col_idx = (i / 2) % KEY_COLORS.length;
            Paint big_key_paint = new Paint();
            big_key_paint.setColor(piano.is_key_pressed(i) ? PRESSED_KEY_COLORS[col_idx] : KEY_COLORS[col_idx]);
            Piano.Key key = piano.get_area_for_key(i);
            if (key != null) {
                draw_key(canvas, key, big_key_paint);

                piano.onDrawPianoKey(this, canvas, i, key);
            }
        }

        // 在大键之后绘制小键
        for (int i = 1; i < piano.get_keys_count(); i += 2) {
            // 绘制小琴键
            Paint flat_key_paint = new Paint();
            flat_key_paint.setColor(piano.is_key_pressed(i) ? Color.GRAY : 0xFF333333);
            Piano.Key key = piano.get_area_for_flat_key(i);
            if (key != null) {
                draw_key(canvas, key, flat_key_paint);
            }
        }

        appConfigHandler.onPianoRedrawFinish(this, canvas);
        piano.onPianoRedrawFinish(this, canvas);
    }
  • onTouchEvent 方法捕捉屏幕上手指按下、抬起等动作;

钢琴键盘

弹奏引导

app通过在钢琴键上绘制手指符号(👆)来引导用户弹奏曲目,用户每按下一个键就发出一个对应的琴音。跟随着手指符号(👆)的变化,用户就可以弹奏出一个完整的曲调了。

  1. PianoConst类中,note2keyIdx常量就保存了音符与琴键位置的映射关系;
  2. Piano类中,updateMelodyFromAssets方法将乐曲资源转换成音符集合;
  3. 通过 Piano类的draw_emoji_on_piano_key方法将引导手指符号(👆)绘制在对应的琴键上。
    private void draw_emoji_on_piano_key(PianoCanvasView piano, Canvas canvas, int key_idx) {
        if (piano == null || canvas == null || key_idx < 0) {
            return;
        }
        // black: 1, 3, 7, 9, 11, 15 —— 奇数
        // white: 偶数

        // 👆 ✋
        String emoji = "\uD83D\uDC46";
        if (key_idx % 2 == 1) {
            piano.draw_emoji_on_black_key(canvas, emoji, key_idx);
        } else {
            piano.draw_emoji_on_white_key(canvas, emoji, key_idx);
        }
    }

乐曲库

乐曲库是内置的,在assets/jsongs目录下,json格式文件保存;
乐曲选择界面是 SongsActivity,使用RecyclerView 展现乐曲列表,供用户选择;

乐曲选择

D. 项目演示

用 Android Studio 开发了一款弹钢琴app | 牛弹琴

E. 项目源码

project-cap

关注公众号『数字森林』,后台发送:弹钢琴,获取源码。
数字森林

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1110743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Win32 简单日志实现

简单实现日志保存, 支持设置日志文件数量, 单个日志文件大小上限, 自动超时保存日志, 日志缓存超限保存 CLogUtils.h #pragma once#include <string> #include <windows.h> #include <vector> #include <map> #include <mutex> #include <tc…

04、MySQL-------MyCat实现分库分表

目录 九、MyCat实现分库分表1、分库分表介绍&#xff1a;横向&#xff08;水平&#xff09;拆分**垂直分表**&#xff1a;水平分表&#xff1a;**分库分表** 纵向&#xff08;垂直&#xff09;拆分分表字段选择 2、分库分表操作&#xff1a;1、分析图&#xff1a;2、克隆主从3、…

【Docker从入门到入土 1】Docker管理命令

Part1 一、容器1.1 虚拟化技术的演变1.2 容器简介1.3 为什么要用到容器&#xff1f;1.4 常用的容器引擎1.5 容器和虚拟机 二、Docker2.1 什么是docker&#xff1f;&#xff08;面试题&#xff09;2.2 Docker和虚拟机的区别&#xff08;面试常问&#xff0c;记住&#xff09;2.3…

SLAM 14 notes

4.23 推导 f ( x ) f(x) f(x)在点a处的泰勒展开 f ( x ) ∑ n 0 ∞ f ( n ) a n ! ( x − a ) n f(x) \sum_{n0}^\infty \frac{f^{(n)}a}{n!}(x-a)^n f(x)∑n0∞​n!f(n)a​(x−a)n l n x lnx lnx的n阶导数 l n ( n ) x ( − 1 ) n − 1 ( n − 1 ) ! x n ln^{(n)}x \fr…

C++进阶语法之函数和指针【学习笔记(二)】

文章目录 1、C 函数1.1 函数的定义1.2 函数原型&#xff08;function prototypes&#xff09;1.3 参数&#xff08;parameter&#xff09;——值传递&#xff08;pass by value&#xff09;1.4 重载&#xff08;overloading&#xff09;1.5 函数传参——传递数组&#xff08;ar…

drawio都能做那些事情和模板示例

drawio都能做那些事情和模板示例 你可以使用drawio&#xff0c;并使用drawio提供的扩展模板库和大量的形状库&#xff0c;针对很多不同的工业领域创建不同类型的图表。 针对如下的内容中的所有的图&#xff0c;均可以下载源文件并导入到drawio中再次编辑&#xff08;供学习者…

如何远程通过内网穿透实现微信公众号在本地的完整调试

文章目录 前言1. 配置本地服务器2. 内网穿透2.1 下载安装cpolar内网穿透2.2 创建隧道 3. 测试公网访问4. 固定域名4.1 保留一个二级子域名4.2 配置二级子域名 5. 使用固定二级子域名进行微信开发 前言 在微信公众号开发中&#xff0c;微信要求开发者需要拥有自己的服务器资源来…

什么是兼容性测试? 重要性是什么?

在数字化时代&#xff0c;用户使用各种不同类型的设备和操作系统来访问应用程序和网站。为了确保用户体验的一致性和应用程序的可用性&#xff0c;兼容性测试变得至关重要。本文将深入探讨兼容性测试的概念及重要性。 一、什么是兼容性测试? 兼容性测试是一种软件测试方法&…

混入组件 (mixin)

1 什么是混入以及作用 *混入 (mixin) 提供了一种非常灵活的方式&#xff0c;来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时&#xff0c;所有混入对象的选项将被“混合”进入该组件本身的选项。作用&#xff1a;主要作用是继承和封装…

【python】什么是网络爬虫?

什么是网络爬虫&#xff1f; 网络爬虫是一种自动化程序&#xff0c;用于从互联网上抓取信息。这些信息可以是文本、图像、视频、数据表格等各种形式的数据。爬虫程序通过模拟浏览器的行为&#xff0c;自动访问网页、抓取内容&#xff0c;并将其保存或处理。这对于数据挖掘、搜索…

elasticsearch的docker安装与使用

安装 docker network create elasticdocker pull docker.elastic.co/elasticsearch/elasticsearch:8.10.4# 增加虚拟内存&#xff0c; 此处适用于linux vim /etc/sysctl.conf # 添加 vm.max_map_count262144 # 重新启动 sysctl vm.max_map_countdocker run --name es01 --net …

element中form表单验证

type&#xff1a;限定类型 pattern&#xff1a;添加正则表达式规则 transform&#xff1a;规则验证之前执行的函数 参考Element Ui使用技巧——Form表单的校验规则rules详细说明&#xff1b;element的 form 表单rules详细用法_橙cplvfx-技术踩坑记的技术博客_51CTO博客

【java】【重构二】分模块开发版本锁定以及耦合(打包)实战

目录 一、创建dependencyManagement标签 二、 将需要版本控制的依赖版本进行标签设置 三、将需要版本控制的依赖从各子模块迁移到此处 四、将父模块的依赖版本控制 五、删除子模块的全部版本 1、bocai-web-management模块 2、bocai-utils模块 六、打包 1、确定代码都…

三相电表倍率是什么?

三相电表的倍率是指电能表所匹配的互感器的倍率&#xff0c;也称为变比变流(压)比、电流(压)比&#xff0c;就是缩小的比例。 实际的用电量等于电能表的表值乘以倍率。 三相电能表是用来测量三相交流电路中电源输出(或负载消耗)的电能的电度表。 按用途可分为工业与民用表、电子…

QCA中质蕴项选择问题

一、关于质蕴项的基础知识 &#xff08;一&#xff09;什么是质蕴项&#xff1f; &#xff08;1&#xff09;质蕴项定义 逻辑余项是指缺少经验实例的构型&#xff0c;可以被纳入布尔最小化。——QCA设计原理与应用&#xff1a;超越定性与定记研究的新方法 &#xff08;2&…

黄金眼PAAS化数据服务DIFF测试工具的建设实践 | 京东云技术团队

一、背景介绍 黄金眼PAAS化数据服务是一系列实现相同指标服务协议的数据服务&#xff0c;各个服务间按照所生产指标的主题作划分&#xff0c;比如交易实时服务提供实时交易指标的查询&#xff0c;财务离线服务提供离线财务指标的查询。黄金眼PAAS化数据服务支撑了黄金眼APP、黄…

出租房水电表管理系统:实现节能减排与经济效益双赢

随着我国城市化进程的加速&#xff0c;出租房市场日益繁荣&#xff0c;房东与租户之间的水电费管理问题也日益凸显。传统的出租房水电费管理方式存在诸多不便&#xff0c;如收费不透明、数据不准确、浪费严重等问题。出租房水电表管理系统应运而生&#xff0c;那么今天小编就来…

AI四维彩超预测宝宝长相图片生成流量主小程序开发

AI四维彩超预测宝宝长相图片生成流量主小程序开发 以下是AI四维彩超预测宝宝长相图片生成流量主小程序的功能列表&#xff1a; 用户注册和登录功能&#xff1a;允许用户注册新账户或使用现有账户登录。用户上传宝宝四维彩超照片&#xff1a;用户可以上传宝宝的四维彩超照片&am…

标准模板库--STL

这里写目录标题 STL初始STL诞生STL基本概念STL六大组件STL中的容器、算法、迭代器容器算法迭代器初识vector存放内置数据类型vector存放自定义数据类型vector中嵌套vector 二级目录二级目录二级目录二级目录二级目录二级目录二级目录二级目录 STL初始 STL诞生 STL基本概念 STL…