在我的安卓游戏中,当用户按下后退按钮音乐即使用户关闭游戏音乐仍然没有停止播放。 这是我的主要游戏类。 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);
}
}
这是游戏的循环类。
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) {}
}
}}
答案 0 :(得分:1)
我得到了解决方案,因为我把我的类GameView扩展SurfaceView里面的另一个类Game extends Activity使我能够使用onBackPressed()方法。
@Override
public void onBackPressed()
{
mp1.stop();
Intent i=new Intent(this,MainActivity.class);
startActivity(i);
}
感谢大家尽最大努力解决我的问题。
答案 1 :(得分:0)
您需要手动停止音乐,您可以在newalias
或onStop()
中使用来电onDestroy()
或mp1.stop()
。
或尝试使用:
onBackPressed()
答案 2 :(得分:0)
对SurfaceView
进行子类化并覆盖SurfaceView.onDraw()
很少有意义。
如果您将代码构造为具有SurfaceView的Activity,则事情会更顺利,因为您需要处理onPause()
和onResume()
,并且处理Surface状态回调。如果您希望应用程序在切换和关闭时正常工作,使用电源按钮关闭和打开设备,则需要提供标准的Android生命周期方法,等等。
重写的onDraw()
方法绘制SurfaceView的View部分,而不是Surface,因此除非您想要覆盖,否则它没有意义。您可能没有注意到问题,因为只有在视图无效时,View层次结构才会调用它。您需要做的就是将onDraw()
更改为doDraw()
并删除@Override
,这样只有在您明确调用它时才会调用它。 (如果你做想要覆盖onDraw()
,那么你可能应该使用custom view而不是SurfaceView。)
This article解释了Activity和SurfaceView生命周期之间的交互。 Grafika提供了几个SurfaceView代码示例。例如,“多表面测试”提供了一个使用Canvas渲染到SurfaceView(实际上,多个)的Activity的示例。