您的位置: turnitin查重官网> 计算机 >> 软件开发 >试议程序设计架子鼓程序设计

试议程序设计架子鼓程序设计

收藏本文 2024-02-28 点赞:20805 浏览:94264 作者:网友投稿原创标记本站原创

摘要:文章介绍了一种Android应用程序:架子鼓的设计。该应用通过触摸屏幕上的相应区域模拟击打架子鼓时的效果,有逼真的声音和动画,最初是为茶几电视开发的应用,也可安装到Android手机和电视等设备,是一款可用于学习和娱乐的软件。
关键词:Android SoundPool;架子鼓;电视;手机;学习;娱乐
1009-3044(2012)27-6502-04
Drum Set Program Design
WANG Xiu-mei
(The Second Institute of Engineering Academy in R&D Headquarter of Skyworth RGB-Electronic Company Ltd., Shenzhen 518108,China)
Abstract: Drum set program design based on android is introduced. The effects including sound and animation are really lifelike by touching the right areas. The application is designed for tea table TV primly. But actually it can be installed on mobile phone, TV, PADS whose system is android. It can be used for study or entertainment.
Key words: Android SoundPool ; drum set; TV; mobile phone; study; entertainment
1开发背景
团队设计了一款茶几电视,顾名思义,就是电视嵌在茶几面上的,电视为水平摆放,操作系统为Android,需要开发一些应用来体现出该款电视的“水平”优势,架子鼓软件成为了公认的合适的应用之一。虽然网络上不乏架子鼓的软件,但是都是基于手机开发,有些不支持大屏幕的显示,界面小,有些虽可满屏显示,但是界面模糊,不美观。而且几乎所有应用都没有练习模式,对用户的粘滞度差。基于以上原因,开发了该款软件,该款软件设计要充分考虑用户的体验感,击鼓的速度可能很快,因此对触摸后的响应处理要即时,不能有感觉上的迟钝。否则就是失败的设计。由于时间关系,没有做练习模式的设计,但是因为源码是自己开发,以后可方便对功能进行扩展。
2素材的收集与加工
程序中需要的图片:一张无鼓无镲的底图,一张触摸区域控制图,如图2所示,7张未敲击时的鼓和镲图片,7张敲击后的鼓和镲图片。这些图片其实都源于一张架子鼓全图,如图1所示。为了体现真实性,程序使用了一张单反相机拍摄的架子鼓图片,通过photoshop软件进行处理,置换背景,提取鼓和镲的图片。通过ps的旋转画布功能获得击打后的图片。
因为录制真实的架子鼓声音比较困难,声音素材是从网络中获取的。

3程序设计

3.1基本原理

将需要触摸后有响应的区域通过photoshop软件的抠图功能选出来做成一个png图片,不同声音的区域用不同的纯色标志。通过colorMap.getPixel(i, j)获取颜色值来判断触摸的区域。
声音效果的实现:使用soundpool来播放声音,开始时程序采用的是mediaplayer,但由于mediaplayer资源占用量较高、延迟时间较长、不支持多个音频同时播放等缺点,比较之下选择了适合播放短音频,实时性好的soundpool,此外SoundPool还支持自行设置声音的品质、音量、播放比率等参数,支持通过ID对多个音频流进行管理。
动画效果的实现:击打鼓面时,使用imageview换一张击打后的图片,60ms后,再换回初始状态的图片。开始时曾使用Tween an? imation的旋转和渐变方式来表现鼓的变化,但是由于该种方式有不能忍受的延迟,因此弃用。

3.2布局

由于需要对鼓和镲的位置精确定位,否则整体图像会有割裂现象,整体采用绝对布局。布局文件如下:
1.0" encoding="utf-8"?> Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >
Android:src="@drawable/drumkit"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
/>
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:src="@drawable/bg_cha" //镲的图片
Android:layout_m

摘自:毕业论文 格式www.udooo.com

arginLeft="1394dip"
Android:layout_marginTop="7dip"
Android:layout_x="1394dip"
Android:layout_y="7dip"
/>
……//以此类推,此处省略其他鼓和镲的布局

3.3触摸事件的处理

支持多点触摸,启动类继承了activity,在该类中重写public boolean onTouchEvent(MotionEvent Event)方法,该方法在View类中定义,并且所有的View子类全部重写了该方法,应用程序可以通过该方法处理屏幕的触摸事件。
参数event为手机屏幕触摸事件封装类的对象,其中封装了该事件的所有信息,例如触摸的位置、触摸的类型以及触摸的时间等。该对象会在用户触摸屏幕时被创建。具体代码和注释如下所示:
public boolean onTouchEvent(MotionEvent Event)
{int i = Event.getPointerCount();//获取触摸点的数量
int j = Event.getAction();//获取触摸点的类型,包括ACTION_UP、ACTION_DOWN、ACTION_MOVE等
int k = Event.getPointerId(0);//获取触摸id
if (i > 1) //触摸点数大于1个
{j &= 0xFF;
k = (0xFF00 & Event.getAction()) >> 8;//根据Action值的高位获取触摸id
}
int l = Event.findPointerIndex(k);//根据触摸id获取触摸索引
if ((j == 0) || (j == 5)) //触摸动作为按下状态
{int i1 = (int) Event.getX(l);//获取触摸索引对应的x坐标int i2 = (int) Event.getY(l); //获取触摸索引对应的y坐标
findDrumType(i1, i2);//响应触摸函数
}
return super.onTouchEvent(Event);
}
private void findDrumType(float paramFloat1, float paramFloat2)
{int i = (int) (paramFloat1 * this.widthRatio);
int j = (int) (paramFloat2 * this.heightRatio);
Thread localThread = new Thread(this.runnable);
switch (this.colorMap.getPixel(i, j)) {//获取触摸点的颜色
case Color.BLACK: //黑色区域对应低音通鼓
this.snd.playbgmusic(1); //响应低音通鼓的声音
localThread.start();//响应低音通鼓的动画drumType=low_tomImage;
Rid[0]=R.drawable.low_tom; //击鼓后的图片
Rid=R.drawable.bg_low_tom; //击鼓前和恢复后图片
break;
……//以此类推,其他省略
}}
为节约空间和资源,触摸区域控制图为小图,通过变量widthRatio和heightRatio来等比控制实际触控区域。
程序中触摸索引与触摸id有如下区别:
触摸索引:当前手指是第几个触摸的手指,如果前面的手指离开了,索引会减少。比如原本是1但是前面的0离开了1就变成了0。
触摸ID:触摸后会分配ID,手指离开不会对其他触摸ID产生影响,但是新进入的手指ID会从0开始找到一个没有使用的ID(比如ID 0,1如果0离开了1不变,但是新进入的并不是2,而是重新使用0)。

3.4声音效果的实现

1)在启动类的onCreate()中,初始化SoundPool的设置:
private void initSounds()
{
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC
, 100);//创建一个SoundPool对象,最大音频流数目为10,流类型为STREAM_MUSIC,音频品质为100
soundPoolMap = new HashMap();//创建一个HashMap实例
soundPoolMap.put(Integer.valueOf(1),Integer.valueOf(this.soundPool.load(this.m_context, R.raw.low_tom, 1)));//把资源中的音效加载到指定的ID(播放的时候就播放对应的ID)
......//以此类推,省略其他

2)播放音频方法
public void playSound(int paramInt)
{float f = ((AudioManager) m_context.getSystemService("audio")).getStreamMaxVolume(AudioManager.STREAM_MUSIC);//获取STREAM_MUSIC流的最大音量
soundPool.play(((Integer) this.soundPoolMap.get(Integer.valueOf(paramInt))).intValue(), f, f, 1, 0, 1.0F); //播放音频,左右音量分别均为最大音量,优先级为1,不循环,正常速率播放
}
3)为避免声音延迟,声音的播放需开辟新的线程。

3.5动画效果的实现,使用Handler来实现UI线程的更新。

1)创建一个handler对象,重写其中的handleMessage方法,在里面接收消息,处理消息。handler = new Handler()
{public void handleMessage(Message paramMessage)
{
super.handleMessage(paramMessage);
switch (paramMessage.what)
{
case 1:
CrazyDrumActivity.this.drumType.setImageResource(CrazyDrumActivity.this.Rid[0]);//显示击鼓后图片
break;
case 2:
CrazyDrumActivity.this.drumType.setImageResource(CrazyDrumActivity.this.Rid);//显示未击鼓时图片
break;
}
return;
}};
2)开辟新线程,实现runnable接口,重写其中的run()方法,在该方法中会向handler发送消息。如下:
this.runnable = new Runnable()
{ public void run()
{ int i = 1;
while (true)
{
if (i > 2)
{
if (i > 2){
CrazyDrumActivity.this.handler.removeCallbacks(CrazyDrumActivity.this.runnable);//清除线程
}
return;
} try{ CrazyDrumActivity.this.handler.sendMessage(CrazyDrumActivity.this.handler.obtainMessage(i));//发送消息
++i;
try
{
myThread.sleep(60L);
}
catch (Exception localException2)
{}
}
catch (Exception localException1)
{}
} } };
}
4小结
本应用实时效果好,声音逼真,动画生动,缺点是还没有提示模式,后期会继续完善。
参考文献:
郭宏志.Android开发详解[M].北京:电子工业出版社,2012.

copyright 2003-2024 Copyright©2020 Powered by 网络信息技术有限公司 备案号: 粤2017400971号