首页 / 操作系统 / Linux / Android游戏开发之处理音乐与音效太鼓达人游戏原理
同学们在玩游戏的时候应该都会发现游戏中会有两种形式来播放音乐 ,一般设置选项中会明确标明 设置游戏音乐 与设置游戏音效。 客观的分析一下这两种形式的音乐,游戏背景音乐同时只会播放一首也就是说两首背景音乐不会同时播放,除非一首播放完毕或者切换场景等 才会播放下一首。而游戏音效 比如主角与敌人挥动武器的声音 被攻击中的声音等,这些声音比较短而且播放很频繁很有可能会同时播放游戏音效。 1.使用MediaPlayer播放游戏音乐创建MediaPlayer对象 将Context与资源文件传入。 /**创建MediaPlayer对象**/ MediaPlayer mMediaPlayer = MediaPlayer.create(mContext, R.raw.v3); /**设置为循环播放**/ mMediaPlayer.setLooping(true ); 判断声音是否正在播放,如果没有播放则开始播放游戏音乐。 if (!mMediaPlayer.isPlaying()) { mMediaPlayer.start(); } 判断声音是否正在播放,如果正在播放则停止播放游戏音乐。 /**关闭音乐**/ if (mMediaPlayer.isPlaying()) { mMediaPlayer.stop(); } 这里强调一下MediaPlayer同一时间只能播放一个音乐 。
2.使用SoundPool播放游戏音效 Soundpool的加载: int load(Context context, int resId, int priority) //从资源中载入 比如 R.raw.id int load(FileDescriptor fd, long offset, long length, int priority) //从FileDescriptor 对象载入 int load(AssetFileDescriptor afd, int priority) //从AssetFileDescriptor 对象载入 int load(String path, int priority) //从完整文件路径名载入 第二个参数为优先级。 创建音效 /**创建一个声音播放池**/ //参数1为声音池同时播放的流的最大数量 //参数2为播放流的类型 //参数3为音乐播放效果 mSoundPool = new SoundPool(2 ,AudioManager.STREAM_MUSIC,100 ); //读取音效 mSound_0 = mSoundPool.load(mContext, R.raw.voic_p1, 0 ); mSound_1 = mSoundPool.load(mContext, R.raw.voic_p1, 0 ); 播放音效 play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) leftVolume 表示对左音量设置 rightVolume 表示右音量设置 , loop 表示 循环次数 rate表示速率最低0.5最高为2,1代表正常速度 mSoundPool.play(mSound_0, 1 , 1 , 0 , 0 , 1 ); 这里强调一下SoundPool可以同时播放多个音乐。 下面向大家介绍一下这个DEMO中的重点,太鼓达人游戏开发的原理,图片资源全部源于互联网。 进入游戏界面 使用MediaPlayer来播放背景声音, 玩家击打鼓盘使用soundpool播放游戏音效。配合这下面的DEMO 请大家继续阅读。 菜单界面 游戏界面 1.处理触摸点与鼓盘的碰撞 我们先分析一下鼓盘的组成结构,它是由两个圆形组成的一个大圆形中间一个小圆形。玩家触摸屏幕后会拿到触摸的X,Y坐标 然后利用数学公事 (x1 – x2)2 + (y1 – y2)2 < (r1 + r2)2 计算出点与大圆形的距离与小圆形的距离,根据两点之间的距离就可以计算出当前触摸的点是在蓝色的鼓盘中 还是红色的鼓盘中,判断一下X坐标在圆形左边还是右边就可以拿到触摸的是左边的鼓盘还是右边的鼓盘。 检测碰撞的部分源代码 private void Collision(int x, int y) { //在这里进行碰撞检测 //检测的原理是点与圆形的碰撞 //利用数学公事 (x1 – x2)2 + (y1 – y2)2 < (r1 + r2)2 //判断点是在蓝盘中还是红盘中 int Condition = ((x - mDrumCenterX) * (x - mDrumCenterX)) +((y - mDrumCenterY) * (y - mDrumCenterY)) ; int Result = mBlueRadius * mBlueRadius; if (Condition < Result) { int redResoult = mRedRadius*mRedRadius; if (Condition<redResoult) { //表明点在红盘区域 if (x <mDrumCenterX) { //红盘左边 mRedClipX = mDrumCenterX; mRedClipWidth = (mRed.getWidth() >> 1 ); mmDrumRedPosX = mDrumCenterX; mPonitState = POINT_RED_LEFT; }else { //红盘右边 mRedClipX = 0 ; mRedClipWidth = (mRed.getWidth() >> 1 ); mmDrumRedPosX=0 ; mPonitState = POINT_RED_RIGHT; } }else { //表明点在蓝盘区域 if (x <mDrumCenterX) { //蓝盘左边 mBlueClipX = mDrumCenterX; mBlueClipWidth = (mBlue.getWidth() >> 1 ); mmDrumBluePosX = mDrumCenterX; mPonitState = POINT_BLUE_LEFT; }else { //蓝盘右边 mBlueClipX = 0 ; mBlueClipWidth = (mBlue.getWidth() >> 1 ); mmDrumBluePosX=0 ; mPonitState = POINT_BLUE_RIGHT; } } CheckCollision(); } } /**检测玩家击鼓是否碰撞**/ private void CheckCollision() { Note mNoteTemp = null ; for (int i = 0 ; i < NOTE_COUNT; i++) { // 利用绝对值的方式寻找一个大概击中的范围 if (Math.abs(mNote[i].m_posX - mItemposX) <= mItemposW) { mNoteTemp = mNote[i]; } } boolean isCollision = false ; if (mNoteTemp != null ) { switch (mPonitState) { case POINT_RED_LEFT: case POINT_RED_RIGHT: if (mNoteTemp.getType() == Note.NOTE_STATE_RED) { //表明击中了红圆形 isCollision = true ; } break ; case POINT_BLUE_LEFT: case POINT_BLUE_RIGHT: if (mNoteTemp.getType() == Note.NOTE_STATE_BLUE) { //表明击中了蓝圆形 isCollision = true ; } break ; } } if (isCollision) { //设置状态 UI根据这个状态显示击打成功还是击打失败 mCollisionState = COLLISION_GREAT; //播放游戏音效 mSoundPool.play(mSound_0, 1 , 1 , 0 , 0 , 1 ); }else { mCollisionState = COLLISION_BAD; //播放游戏音效 mSoundPool.play(mSound_1, 1 , 1 , 0 , 0 , 1 ); } }
收藏该网址