同学们在玩游戏的时候应该都会发现游戏中会有两种形式来播放音乐 ,一般设置选项中会明确标明 设置游戏音乐 与设置游戏音效。 客观的分析一下这两种形式的音乐,游戏背景音乐同时只会播放一首也就是说两首背景音乐不会同时播放,除非一首播放完毕或者切换场景等 才会播放下一首。而游戏音效 比如主角与敌人挥动武器的声音 被攻击中的声音等,这些声音比较短而且播放很频繁很有可能会同时播放游戏音效。
1.使用MediaPlayer播放游戏音乐
创建MediaPlayer对象 将Context与资源文件传入。
- /**创建MediaPlayer对象**/
- MediaPlayer mMediaPlayer = MediaPlayer.create(mContext, R.raw.v3);
- /**设置为循环播放**/
- mMediaPlayer.setLooping(true);
判断声音是否正在播放,如果没有播放则开始播放游戏音乐。
- if(!mMediaPlayer.isPlaying()) {
- mMediaPlayer.start();
- }
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) {
- mNotemNoteTemp = 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);
- }
- }
- public class Note {
- /** 音符的X轴速度 **/
- static final int NOTE_STEP_X = 15;
- /** 红色音符**/
- static final int NOTE_STATE_RED = 0;
- /** 蓝色音符**/
- static final int NOTE_STATE_BLUE = 1;
- /** 音符的XY坐标 **/
- public int m_posX = 0;
- public int m_posY = 0;
- /**音符类型**/
- private int mType = 0;
- /** 音符的动画 **/
- private Animation mAnimation = null;
- Context mContext = null;
- /**控制**/
- private boolean mFauce = false;
- public Note(Context context) {
- mContext = context;
- mFauce = false;
- }
- /**重置音符**/
- public void initStart(Bitmap[] frameBitmap, int type,int x, int y) {
- mAnimation = new Animation(mContext, frameBitmap, true);
- mType = type;
- m_posX = x;
- m_posY = y;
- mFauce = true;
- }
- /** 绘制音符 **/
- public void DrawNote(Canvas Canvas, Paint paint) {
- if (mFauce) {
- mAnimation.DrawAnimation(Canvas, paint, m_posX, m_posY);
- }
- }
- /** 更新音符的坐标点 **/
- public void UpdateNote() {
- if (mFauce) {
- m_posX -= NOTE_STEP_X;
- }
- }
- //获得音符类型
- public int getType(){
- return mType;
- }
- /**是否显示**/
- public void setFacus(boolean facus) {
- mFauce = facus;
- }
- }
玩家击打某个鼓盘后 瞬间鼓点图片会消失 然后在显示这样会让玩家感觉自己已经点中鼓盘。 这个效果可以根据clipRext来把图片切割出来显示在屏幕中。
- /** * 绘制图片中的一部分图片 *
- * @param bitmap
- * @param x
- * @param y
- * @param src_x
- * @param src_y
- * @param src_width
- * @param src_Height
- */
- private void DrawClipImage(Bitmap bitmap, int x, int y, int src_x, int src_y, int src_xp, int src_yp) {
- mCanvas.save();
- mCanvas.clipRect(x, y, x + src_xp, y + src_yp);
- mCanvas.drawBitmap(bitmap, x - src_x, y - src_y, mPaint);
- mCanvas.restore();
- }
游戏效果图
- private void updateGame() {
- if (mPlayID < NOTE_COUNT) {
- Long now = System.currentTimeMillis();
- if (now - mStartTime >= START_TIME) {
- mStartTime =now;
- int random = UtilRandom(0, 2);
- int type = 0;
- if (random == 0) {
- type = Note.NOTE_STATE_RED;
- } else {
- type = Note.NOTE_STATE_BLUE;
- }
- mNote[mPlayID].initStart(
- new Bitmap[] { mNoteBitmap[random] }, type,
- mNotePosX, mNotePosY);
- mPlayID++;
- }
- } else {
- mPlayID = 0;
- }
-
- for(int i =0 ; i <NOTE_COUNT; i ++) {
- mNote[i].UpdateNote();
- if(mNote[i].m_posX <= mItemposX) {
- mNote[i].setFacus(false);
- }
- }
- }
以后写教程每个demo的代码量会越来越多 所以贴代码在博客中可能大家看的就不是很清楚,不过我会尽量在博客中把原理说清楚 还是建议大家都去下载我的源码来阅读学习。源代码中我会写详细的注释,还是那句老话在漂亮的语言不如普通实用的代码片段,老规矩每篇文章都会附带源代码,最后如果你还是觉得我写的不够详细 看的不够爽 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习雨松MOMO希望可以和大家一起进步。
- public void renderGame() {
- /** 绘制游戏菜单 **/
- mCanvas.drawBitmap(mBitGameBG, 0, 0, mPaint);
- /**绘制小人动画**/
- mNpcAnim.DrawAnimation(mCanvas, mPaint, mNpcPosX, mNpcPosY);
- /**绘制鼓盘**/
- mCanvas.drawBitmap(mDrum, 0, mDrumPosY, mPaint);
- /**蓝**/
- DrawClipImage(mBlue,mmDrumBluePosX,mmDrumEffectPosY,mBlueClipX,0,mBlueClipWidth,mBlueClipHeight);
- /**红**/
- DrawClipImage(mRed,mmDrumRedPosX,mmDrumEffectPosY,mRedClipX,0,mRedClipWidth,mRedClipHeight);
- /**击打区域**/
- mCanvas.drawBitmap(mBitGameItem, mItemposX, mItemposY, mPaint);
- /**绘制音符**/
- for(int i =0 ; i <NOTE_COUNT; i ++) {
- mNote[i].DrawNote(mCanvas, mPaint);
- }
- /**播放点击动画**/
- if(mCollisionState == COLLISION_GREAT ) {
- mCanvas.drawBitmap(mGreat, 0,0, mPaint);
- }else if(mCollisionState == COLLISION_BAD) {
- mCanvas.drawBitmap(mBad, 0,0, mPaint);
- }
- setDrumPoint();
- }