当用户按下后退按钮时,游戏音乐不会在我的 android 游戏中停止

Game music doesnt stop in my android game when user press back button

在我的 android 游戏中,当用户按下后退按钮时音乐不会停止,即使用户关闭游戏音乐仍在播放。 这是我的主要 class 游戏。 MediaPlayer mp1 用于播放音乐。

public class GameView extends SurfaceView{
      Bitmap bmp,pause;
      Bitmap background,kinfe,note1,appleimg,note2;
      Bitmap run1;
      Bitmap run2;
      Bitmap run3;
      Bitmap coin;
      Bitmap exit;

      private SurfaceHolder holder;
      private int x = 0,y=0,z=0,delay=0,getx,gety,sound=1;
      int show=0,sx,sy;
      int cspeed=0,kspeed=0,gameover=0;
      int score=0,health=100,reset=0;
      int pausecount=0,volume,power=0,applerun=0,shieldrun=0;


    @SuppressWarnings("deprecation")
    @SuppressLint("NewApi")
    public GameView(Context context) 
      {
          super(context);

          gameLoopThread = new GameLoop(this);
          holder = getHolder();

             holder.addCallback(new SurfaceHolder.Callback() {
            @SuppressWarnings("deprecation")
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) 
            {
                 //for stoping the game
                gameLoopThread.setRunning(false);
                gameLoopThread.getThreadGroup().interrupt();
             }

            @SuppressLint("WrongCall")
            @Override
            public void surfaceCreated(SurfaceHolder holder) 
            {
                  //for starting the game
                  gameLoopThread.setRunning(true);
                  gameLoopThread.start();

             }
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format,int width, int height) 
                    {
                    }
             });

             //getting the screen size 
          //   Display display = getWindowManager().getDefaultDisplay();

        //  sx = display.getWidth();
        //  sy = display.getHeight();;

             Display display = getWindowManager().getDefaultDisplay();
             Point size = new Point();
             display.getSize(size);
             sx = size.x;
             sy = size.y;
            cspeed=sx/2;
            kspeed=sx/2;
            applerun=(3*sx/4);
            shieldrun=sx/8;
          background = BitmapFactory.decodeResource(getResources(), R.drawable.cold);
          run1=BitmapFactory.decodeResource(getResources(), R.drawable.run1);
          run2=BitmapFactory.decodeResource(getResources(), R.drawable.run2);
          run3=BitmapFactory.decodeResource(getResources(), R.drawable.run3);
          coin=BitmapFactory.decodeResource(getResources(), R.drawable.coin);
          exit=BitmapFactory.decodeResource(getResources(), R.drawable.exit);
          kinfe=BitmapFactory.decodeResource(getResources(), R.drawable.kinfe);
          note1=BitmapFactory.decodeResource(getResources(), R.drawable.note1);
          pause=BitmapFactory.decodeResource(getResources(), R.drawable.pause);
          appleimg=BitmapFactory.decodeResource(getResources(), R.drawable.power);
          note2=BitmapFactory.decodeResource(getResources(), R.drawable.note2);

          exit=Bitmap.createScaledBitmap(exit, 25,25, true);
          pause=Bitmap.createScaledBitmap(pause, 25,25, true);
          appleimg=Bitmap.createScaledBitmap(appleimg, 25,25, true);
          note2=Bitmap.createScaledBitmap(note2, sx,sy, true);
          run1=Bitmap.createScaledBitmap(run1, sx/9,sy/7, true);
          run2=Bitmap.createScaledBitmap(run2, sx/9,sy/7, true);
          run3=Bitmap.createScaledBitmap(run3, sx/9,sy/7, true);
          coin=Bitmap.createScaledBitmap(coin, sx/16,sy/24, true);
          background=Bitmap.createScaledBitmap(background, 2*sx,sy, true);
          //health dec
          note1=Bitmap.createScaledBitmap(note1, sx,sy, true);

          mp1=MediaPlayer.create(Game.this,R.raw.game);
          jump=MediaPlayer.create(Game.this,R.raw.jump);
          takecoin=MediaPlayer.create(Game.this,R.raw.cointake);
      }

      // on touch method

      @Override
        public boolean onTouchEvent(MotionEvent event) {

            if(event.getAction()==MotionEvent.ACTION_DOWN)
            {
                show=1;

                getx=(int) event.getX();
                gety=(int) event.getY();
                //exit
                if(getx<25&&gety<25)
                {
                    //high score
                    SharedPreferences pref = getApplicationContext().getSharedPreferences("higher", MODE_PRIVATE);
                    Editor editor = pref.edit();
                    editor.putInt("score", score);
                    editor.commit(); 
                    System.exit(0);

                }
                // restart game
                if(getx>91&&gety<25)
                {
                    if(health<=0)
                    {
                        gameLoopThread.setPause(0);
                        health=100;
                        score=0;

                    }
                }
                //pause game
                if((getx>(sx-25)&&gety<25&&pausecount==0))
                {

                    gameLoopThread.setPause(1);
                    mp1.stop();
                    pausecount=1;
                }
                else if(getx>(sx-25)&&gety<25&&pausecount==1)
                {
                    gameLoopThread.setPause(0);
                    mp1.start();
                    pausecount=0;
                }
            }

            return true;
        }


        @SuppressLint("WrongCall")
        @Override
          protected void onDraw(Canvas canvas) 
          {

          //volume 
            SharedPreferences pref = getApplicationContext().getSharedPreferences("higher", MODE_PRIVATE);
            Editor editor = pref.edit();
            volume=pref.getInt("vloume", 0);
            if(volume==0)
            {
                sound=0;
            }

            canvas.drawColor(Color.BLACK);

            //background moving
            z=z-10;
            if(z==-sx)
            {
                z=0;
                canvas.drawBitmap(background, z, 0, null);

            }
            else
            {
                canvas.drawBitmap(background, z, 0, null);  
            }

            //running player 

                 x+=5;
                 if(x==20)
                 {
                     x=5;
                 }

                  if(show==0)
                  {
                      if(x%2==0)
                      {
                          canvas.drawBitmap(run3, sx/16, 15*sy/18, null);

                      }
                      else 
                      {
                          canvas.drawBitmap(run1, sx/16, 15*sy/18, null);

                      }


                     //kinfe hit
                     if(kspeed==20)
                      {
                          kspeed=sx;
                          health-=25;
                          canvas.drawBitmap(note1, 0, 0, null);
                      }

                     //power take
                     if(applerun==30)
                        {
                          applerun=3*sx;
                          health+=25;
                          canvas.drawBitmap(note2, 0, 0, null);
                        }
                  }
                //power
                     applerun=applerun-10;
                     canvas.drawBitmap(appleimg, applerun, 15*sy/18, null);

                     if(applerun<0)
                     {
                         applerun=3*sx/4;
                     }

                //kinfe
                     kspeed=kspeed-20;
                     canvas.drawBitmap(kinfe, kspeed, 15*sy/18, null);
                     if(kspeed<0)
                     {
                         kspeed=sx;
                     }

                // for jump
                 if(show==1)
                 {
                     if(sound==1)
                     {
                     jump.start();
                     }

                          canvas.drawBitmap(run2, sx/16, 4*sy/7, null);
                          //score
                          if(cspeed<=sx/8&&cspeed>=sx/16)
                          {
                              if(sound==1)
                             {
                                  takecoin.start();

                             }
                              cspeed=sx/2;
                              score+=10;

                          }



                    // jump-hold
                     delay+=1;
                     if(delay==3)
                     {
                     show=0;
                     delay=0;
                     }
                 }

                  //for coins
                  cspeed=cspeed-5;
                    if(cspeed==-sx/2)
                    {
                        cspeed=sx/2;
                        canvas.drawBitmap(coin, cspeed, 3*sy/4, null);

                    }
                    else
                    {
                        canvas.drawBitmap(coin, cspeed, 3*sy/4, null);  
                    }




                    //score
                        Paint paint = new Paint();
                        paint.setColor(Color.BLUE);
                        paint.setAntiAlias(true);
                        paint.setFakeBoldText(true);
                        paint.setTextSize(25);
                        paint.setTextAlign(Align.LEFT);
                        canvas.drawText("Score :"+score, 3*sx/4, 20, paint);
                    //exit
                        canvas.drawBitmap(exit, 0, 0, null);
                          if(sound==1)
                          {
                          mp1.start();
                          mp1.setLooping(true);
                          }
                          else
                          {
                             mp1.stop();
                          }
                  //health
                    Paint myPaint = new Paint();
                     myPaint.setColor(Color.RED);
                     myPaint.setStrokeWidth(10);
                     myPaint.setAntiAlias(true);
                     myPaint.setFakeBoldText(true);
                     paint.setTextSize(25);
                    canvas.drawText("Health :"+health, 0, (sy/8)-5, myPaint);
                    canvas.drawRect(0, sy/8, health, sy/8+10, myPaint);

                  //game over
                    if(health<=0)
                    {
                        gameover=1;
                        mp1.stop();
                        sound=0;

                        //high score
                        editor.putInt("score", score);
                        editor.commit(); 

                        myPaint.setColor(Color.BLACK);
                        myPaint.setFakeBoldText(true);
                        canvas.drawText("GAME OVER", sx/2, sy/2, myPaint);
                        canvas.drawText("YOUR SCORE : "+score, sx/2, sy/4, myPaint);
                        canvas.drawText("RESTART", 91, 25, myPaint);
                        gameLoopThread.setPause(1);
                        canvas.drawBitmap(background, sx, sy, null);
                    }
                   // restart

                    if(reset==1)
                    {
                        gameLoopThread.setPause(0);
                        health=100;
                        score=0;
                        mp1.start();
                    }

                    canvas.drawBitmap(pause, (sx-25), 0, null);
              }

          }

这是游戏的循环class。

public class GameLoop extends Thread {

   private GameView view;
   static final long FPS = 10;
   private boolean running = false;
   boolean isPaused;

   public GameLoop(GameView view) {
         this.view = view;
   }

   public void setRunning(boolean run) {

         running = run;
   }

   public void setPause(int i)
   {
       synchronized (view.getHolder()) 
       {


        if(i==0)
        {
            isPaused=false;
        }
        if(i==1)
        {
            isPaused = true;
        }
        }
   }


@SuppressLint("WrongCall")
@Override

  public void run() {
       long ticksPS = 100;
       long startTime = 0;
       long sleepTime;
          while (running) {
              //pause and resume

            if (isPaused) 
            {
                  try 
                  {
                      this.sleep(50);
                  } 
                  catch (InterruptedException e) 
                  {
                    e.printStackTrace();
                  }
            }
            else
            {
                 Canvas c = null;
                 startTime = System.currentTimeMillis();
                 try {

                        c = view.getHolder().lockCanvas();

                        synchronized (view.getHolder()) 
                        {
                            view.onDraw(c);
                        }

                      } 
                 finally 
                 {
                     if (c != null) 
                        {
                            view.getHolder().unlockCanvasAndPost(c);
                        }
                 }
               }
                 sleepTime = ticksPS-(System.currentTimeMillis() - startTime); 

                 try {

                        if (sleepTime > 0)
                           sleep(sleepTime);
                        else
                           sleep(10);
                    } 
            catch (Exception e) {}
          }
    }}

您需要手动停止音乐,您可以在onStop()onDestroy()中调用mp1.stop(),或在onBackPressed().

中使用

或尝试使用:

            @Override
            public boolean onKeyDown(int keyCode, KeyEvent event) {
                mp1.stop();
                return super.onKeyDown(keyCode, event);
            }

子类化 SurfaceView 和覆盖 SurfaceView.onDraw(),很少有意义。

如果您将代码构造为具有 SurfaceView 的 Activity,事情会进行得更顺利,因为您需要处理 onPause()onResume(),并处理表面状态回调。如果您希望应用程序在关闭和返回、使用电源按钮关闭和打开设备等时正常工作,则需要提供标准的 Android 生命周期方法。

重写的 onDraw() 方法在 SurfaceView 的 View 部分而不是 Surface 上绘制,因此除非您想要覆盖,否则它没有意义。您可能不会注意到一个问题,因为只有当某些东西使视图无效时,它才会被视图层次结构调用。您需要做的就是将 onDraw() 更改为 doDraw() 并删除 @Override,以便仅在您显式调用它时才调用它。 (如果您 想要覆盖 onDraw(),那么您可能应该使用 custom view,而不是 SurfaceView。)

This article explains the interaction between the Activity and SurfaceView lifecycles. Grafika 提供了几个 SurfaceView 代码示例。例如,"multi-surface test" 提供了一个 Activity 使用 Canvas 渲染到 SurfaceView(实际上,不止一个)的示例。

我得到了解决方案,因为我将我的 class GameView extends SurfaceView 放在另一个 class Game extends Activity 中,使我能够使用 onBackPressed() 方法。

@Override
public void onBackPressed() 
{
    mp1.stop();
    Intent i=new Intent(this,MainActivity.class);
    startActivity(i);
}

感谢大家为解决我的问题所做的最大努力。