andriod遊戲音效
同學們在玩遊戲的時候應該都會發現遊戲中會有兩種形式來播放音樂 ,一般設置選項中會明確標明 設置遊戲音樂 與設置遊戲音效。 客觀的分析一下這兩種形式的音樂,遊戲背景音樂同時隻會播放一首也就是說兩首背景音樂不會同時播放,除非一首播放完畢或者切換場景等 才會播放下一首。而遊戲音效 比如主角與敵人揮動武器的聲音 被攻擊中的聲音等,這些聲音比較短而且播放很頻繁很有可能會同時播放遊戲音效。
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) //從完整文件路徑名載入 第二個參數為優先級。
創建音效
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代表正常速度
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 請大家繼續閱讀。
下麵向大家介紹一下這個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) {
- 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);
- }
- }
2 .音符的移動
遊戲中我們可以發現各種音符會從屏幕左邊向右移動,我覺得原作肯定是有一個音符編輯器 在開發中策劃來編輯這個音符包括 位置 出現的是頻率 時間 音符的類型 等等 最後編輯器會把數據生成出來 在程序中去讀取這些數據並顯示出來,作為學習來說我們沒必要想那麼多我強調的還是開發的原理 任何平台的遊戲它使用的算法 數據結構 基本都是一樣的,今後我會在教程中陸續向大家貫穿這些思想。
代碼實現上我把音符一樣封成一個音符類,和上節教程類似每一個音符由又向左移動 根據隨機數 來設置音符的類型 為紅色還是藍色。 程序中一樣隻申請了5塊 音符的對象,玩家點擊鼓盤後然後以音符對象檢測它的XY坐標是是否在點擊區域 如果在點點擊區域 在判斷玩家敲打的鼓盤音符與當前音符是否類型一樣如果一樣則表示擊打成功 屏幕中顯示good圖片,如果失敗則顯示bad圖片。被擊中的鼓點 或者沒有擊中向左超過擊打範圍 直接重置它們的坐標 讓它們進入下一個輪回判定中。
簡單的音符類實現 現在隻有兩種音符 一個是紅色 一個是藍色
代碼實現上我把音符一樣封成一個音符類,和上節教程類似每一個音符由又向左移動 根據隨機數 來設置音符的類型 為紅色還是藍色。 程序中一樣隻申請了5塊 音符的對象,玩家點擊鼓盤後然後以音符對象檢測它的XY坐標是是否在點擊區域 如果在點點擊區域 在判斷玩家敲打的鼓盤音符與當前音符是否類型一樣如果一樣則表示擊打成功 屏幕中顯示good圖片,如果失敗則顯示bad圖片。被擊中的鼓點 或者沒有擊中向左超過擊打範圍 直接重置它們的坐標 讓它們進入下一個輪回判定中。
簡單的音符類實現 現在隻有兩種音符 一個是紅色 一個是藍色
- 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);
- }
- }
- }
遊戲的繪製
- 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();
- }
最後更新:2017-04-03 08:26:11
上一篇:
oracle安裝過程之 刪除用戶oracle
下一篇:
Vmware Tools怎麼安裝
C# 獲取Excel工作薄中Sheet頁(工作表)名集合
ListView中getView中放置多個item和getItemViewType的用法
ubuntu11.10配置IPV6
SQL Server on Linux BCP工具導出RDS SQL Server數據
London Book Fair to focus on China
機械硬盤不會輕易離去:大存儲需求旺盛
[新聞爆料]【xin站大全】域名iot.xin一口價3萬被秒
C#中comboBox控件的一些基本用法小結
HTAP數據庫 PostgreSQL 場景與性能測試之 1 - (OLTP) 點查
打開word文檔到richtextbox