切换活动时遇到问题

时间:2016-04-26 02:55:33

标签: android

我有两个活动:菜单和游戏。我将它们都设置为表面视图,当我单击菜单活动上的“开始”按钮时,它会启动游戏活动。然后我希望它保存得分并在播放器崩溃时返回菜单活动。这两个活动都有以活动开头的单独线程,因此当我尝试从游戏中重新启动菜单活动时,我得到一个异常,即该线程已经启动。所以为了避免这种情况,我让游戏活动在启动时完成菜单活动,以便重新启动菜单活动也会重新启动线程。现在我得到一个异常,即画布已被锁定。在完成活动之前,我是否需要解锁画布?我是否有更好的方法来处理活动之间的切换?

MainActivity:

package com.mikey.******;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {

    public static Activity activity;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = this;
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(new GamePanel(this));
    }
}

GamePanel布局:

package com.mikey.*****;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.util.AttributeSet;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;

import java.util.ArrayList;
import java.util.Random;

public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {

    private static SharedPreferences prefs;
    public static int width;
    public static int height;
    public static int screenX, screenY;
    private Canvas c;
    private MainThread thread;
    private Background bg;
    private Scoreboard sb;
    public int moveSpeed = 10;
    private Player player;
    private ArrayList<Smokepuff> smoke;
    private Plunger plunger;
    private Plunger plunger1;
    private long smokeStart;
    private long smokeTime;
    public int score = 0;
    public boolean isPlaying;
    private Bitmap bgImg;
    private Bitmap b;
    private int scaleFactor = 2;
    private long timer;
    private long timeStart;
    private Paint paint;
    private ArrayList<Coin> coin;
    private long coinTime;
    private int coinDelay;
    private Bitmap coinImg;
    public boolean playable;
    public int distance;
    private int plungerDelay;
    private int plungerReset;
    private long plungerTime;
    private int coinSet;
    private Menu endMenu;


    public GamePanel(Context context){
        super(context);

        prefs = PreferenceManager.getDefaultSharedPreferences(getContext());

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        screenX=size.x;
        screenY=size.y;

        getHolder().addCallback(this);

        thread = new MainThread(getHolder(), this);
        setFocusable(true);
        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        paint.setTextSize(40);
    }

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

    @Override
    public void surfaceDestroyed(SurfaceHolder holder){
        boolean retry = true;
        int count = 0;
        while(retry&&count<1000){
            try{thread.setRunning(false);
                thread.join();
                retry=false;

            }catch(InterruptedException e){}

            count++;
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder){

        thread.setRunning(true);
        thread.start();
        //moveSpeed = -20;

        bgImg = BitmapFactory.decodeResource(getResources(), R.drawable.bg2);
        width = bgImg.getWidth();
        height = bgImg.getHeight();
        bg = new Background(bgImg);
        sb = new Scoreboard(getContext());
        plunger = new Plunger(BitmapFactory.decodeResource(getResources(), R.drawable.plunger));
        plunger1 = new Plunger(BitmapFactory.decodeResource(getResources(),R.drawable.plunger));
        player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.potty));
        smoke = new ArrayList<Smokepuff>();
        coin = new ArrayList<Coin>();
        //Random r = new Random();
        coinImg = BitmapFactory.decodeResource(getResources(),R.drawable.coin2);
        coin.add(new Coin(coinImg));
        coinDelay = 5;
        playable = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){

        if(event.getAction()==MotionEvent.ACTION_DOWN){
            if(!isPlaying&&playable){
                isPlaying=true;
                smokeStart = System.nanoTime();
                timeStart = System.nanoTime();
                plungerReset = distance;
                plungerDelay = 100;
                coinSet = distance;
            }
            player.setAccelerate(true);
            player.setUp(true);
            return true;
        }
        else if(event.getAction()==MotionEvent.ACTION_UP){
            player.setAccelerate(false);
            player.setUp(false);
            return true;
        }
        return super.onTouchEvent(event);
    }


    public void update(){
        if(isPlaying) {

            timer = (System.nanoTime() - timeStart) / 1000000;
            distance+=(timer*moveSpeed)/1000;

            if (timer > 50) {
                if(player.getAccelerate()&&!player.maxAlt) {
                    moveSpeed += 1;
                }else if(!player.getAccelerate()&&!player.maxAlt){
                    if(moveSpeed>0){
                        if(distance<200){
                            moveSpeed-=.05;
                        }else {
                            moveSpeed -= .18;
                        }
                    }
                }
                timeStart = System.nanoTime();
            }
            //moveSpeed += score;

            smokeTime = (System.nanoTime()-smokeStart)/1000000;
            if(smokeTime>100){
                smoke.add(new Smokepuff(player.getX(),player.getY()+5));
                smokeStart=System.nanoTime();
            }

            if(distance>300&&plungerDelay+plungerReset<distance){
                plunger.setX(screenX);
                plunger1.setX(screenX+500);

                Random q = new Random();
                plungerDelay = q.nextInt(150)+100;
                plungerReset = distance;
            }

            if(distance-coinSet>coinDelay) {
                Random z = new Random();
                int num = z.nextInt(3) + 1;

                for (int i = 0; i < num; i++) {
                    coin.add(new Coin(coinImg));
                }
                Random r = new Random();
                coinDelay = r.nextInt(50) + 1;
                coinSet=distance;
            }


            plunger.update(moveSpeed);
            plunger1.update(moveSpeed);
            int dy = player.update();

            bg.update(moveSpeed, dy);




            for(int i=0;i<coin.size();i++){
                coin.get(i).update(moveSpeed);
                if(coin.get(i).getX()<-10){
                    coin.remove(i);
                }else if (collision(coin.get(i), player)) {
                    coin.remove(i);
                    score+=10;
                }
            }

            if(collision(player,plunger)){
                plunger.setX(player.getX() + player.getWidth() - 1);
                plunger.setY(player.getY()+player.height/2);
                if(!plunger.attached){
                    plungerTime = System.nanoTime();
                    plunger.attached = true;
                }
                if(moveSpeed>10){
                    moveSpeed--;
                }
            }
            if(plunger.getX()<-100){
                plunger.reset();
            }

            if(collision(player,plunger1)){
                plunger1.setX(player.getX() + player.getWidth()-1);
                plunger1.setY(player.getY()+player.height/2);
                if(!plunger1.attached) {
                    plungerTime = System.nanoTime();
                    plunger1.attached=true;
                }
                if(moveSpeed>10){
                    moveSpeed--;
                }
            }
            if(plunger1.getX()<-100){
                plunger1.reset();
            }

            if((System.nanoTime()-plungerTime)/1000000>750){
                if(collision(plunger,player)){
                    plunger.reset();
                    plunger.attached = false;
                }
                if(collision(plunger1,player)){
                    plunger1.reset();
                    plunger1.attached = false;
                }
            }

            for(int i=0;i<smoke.size();i++){
                smoke.get(i).update(moveSpeed);
                if(smoke.get(i).getX()<-10||smoke.get(i).getY()<0){
                    smoke.remove(i);
                }
            }

            sb.update(score, distance);

            if(2*player.getY()>screenY-300){
                SharedPreferences.Editor editor = prefs.edit();
                if(!prefs.contains("highscore")) {
                    editor.putInt("highscore", score);
                    //return;
                }else if(prefs.getInt("highscore",0)<score){
                    editor.putInt("highscore",score);
                }
                editor.commit();

                isPlaying=false;
                playable=false;
                endGame();
                //NavUtils.navigateUpFromSameTask(MainActivity.activity);
                Intent intent = new Intent(getContext(),Menu.class);
                getContext().startActivity(intent);
            }

        }
    }

    public boolean collision(GameObject a, GameObject b){
        if(Rect.intersects(a.getRect(),b.getRect())){
            return true;
        }
        return false;
    }

    @Override
    public void draw(Canvas canvas){

        final float scaleFactorX = (float) 2;
        final float scaleFactorY = (float) 2;

        if(canvas!=null){
            c = canvas;

            final int savedState = canvas.save();
            canvas.scale(scaleFactorX, scaleFactorY);
            bg.draw(canvas);
            for(Coin c:coin){
                c.draw(canvas);
            }
            plunger.draw(canvas);
            plunger1.draw(canvas);
            for(Smokepuff sp:smoke){
                sp.draw(canvas);
            }
            player.draw(canvas);
            if((isPlaying&&playable)||(!isPlaying&&!playable)) {
                sb.draw(canvas);
            }
            canvas.restoreToCount(savedState);
            canvas.drawText(Integer.toString(moveSpeed), screenX-100,40,paint);
        }
        //bg.draw(canvas);

    }

    public void endGame(){
        SharedPreferences.Editor editor = prefs.edit();
        if(!prefs.contains("highscore")) {
            editor.putInt("highscore", score);
            return;
        }else if(prefs.getInt("highscore",0)<score){
            editor.putInt("highscore",score);
        }
        editor.commit();

        Intent intent = new Intent(getContext(),Menu.class);
        getContext().startActivity(intent);
    }

}

菜单活动:

package com.mikey.*****;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;

public class Menu extends Activity{

    //private ImageButton upgrade;
    private int screenY;
    private int screenX;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        screenY = getWindow().getDecorView().getHeight();
        screenX = getWindow().getDecorView().getWidth();
        setContentView(new MenuLayout(this));
        /*upgrade = (ImageButton) findViewById(R.id.upgrade);
        upgrade.setX(-150);
        upgrade.setY(1080-130);
        upgrade.setScaleX(4);
        upgrade.setScaleY(4);*/
    }

    @Override
    protected void onPause(){
        super.onPause();
        finish();
    }
}

MenuLayout:

package com.mikey.*****;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.preference.PreferenceManager;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;

import java.util.ArrayList;
import java.util.Random;

public class MenuLayout extends SurfaceView implements SurfaceHolder.Callback {

    private static SharedPreferences prefs;
    private MenuThread thread;
    private boolean played;
    private int screenX, screenY;
    private Bitmap upgrade;
    private Bitmap map;
    private Bitmap bg;
    private Bitmap launch;
    private Bitmap potty;
    private Bitmap cloudA;
    private Bitmap cloudB;
    private ArrayList<Cloud> cloud;
    private UpgradeBtn upgradeBtn;
    private MapBtn mapBtn;
    private LaunchBtn launchBtn;
    //private Paint bg;
    private Paint feature;
    private Paint border;
    private Paint featureRad;
    private Paint stick;
    private Paint text;
    private Paint shadow;

    private int x;
    private int y;
    private boolean upg;
    private boolean showmap;
    private boolean start;

    public MenuLayout(Context context){
        super(context);

        prefs = PreferenceManager.getDefaultSharedPreferences(getContext());

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);

        getHolder().addCallback(this);

        thread = new MenuThread(getHolder(),this);
        setFocusable(true);


        screenX=size.x;
        screenY=size.y;

        upgrade = BitmapFactory.decodeResource(getResources(),R.drawable.blueprint);
        map = BitmapFactory.decodeResource(getResources(),R.drawable.map);
        launch = BitmapFactory.decodeResource(getResources(),R.drawable.launch);
        bg = BitmapFactory.decodeResource(getResources(),R.drawable.menu_bg);
        potty = BitmapFactory.decodeResource(getResources(),R.drawable.potty1);
        cloudA = BitmapFactory.decodeResource(getResources(),R.drawable.cloud1);
        cloudB = BitmapFactory.decodeResource(getResources(),R.drawable.cloud2);

        upgradeBtn = new UpgradeBtn(upgrade,screenY);
        mapBtn = new MapBtn(map);
        launchBtn = new LaunchBtn(launch,screenX,screenY);

        cloud = new ArrayList<>();

        for(int i =0;i<4;i++){
            addCloud();
        }
        start = true;

        //bg = new Paint();
        //bg.setColor(Color.WHITE);

        shadow = new Paint();
        shadow.setAntiAlias(true);
        shadow.setColor(Color.WHITE);
        shadow.setTextSize(45.0f);
        shadow.setStrokeWidth(2.0f);
        shadow.setStyle(Paint.Style.STROKE);
        shadow.setShadowLayer(10.0f, 20.0f, -20.0f, Color.BLACK);

        Shader shader = new LinearGradient(0, 0, 0, 90, Color.LTGRAY, Color.DKGRAY, Shader.TileMode.CLAMP);
        feature = new Paint();
        feature.setShader(shader);

        border = new Paint();
        border.setColor(Color.BLACK);
        border.setStyle(Paint.Style.STROKE);
        border.setStrokeWidth(8);

        Shader shader1 = new RadialGradient(screenX-60,60,150,Color.LTGRAY,Color.DKGRAY, Shader.TileMode.MIRROR);
        featureRad = new Paint();
        featureRad.setShader(shader1);

        stick = new Paint();
        stick.setColor(Color.BLACK);
        stick.setStrokeWidth(20);

        text = new Paint();
        text.setColor(Color.WHITE);
        text.setTextSize(50);
    }

    public void addCloud(){

        Bitmap img;
        Random r = new Random();
        Random p = new Random();
        Random q = new Random();

        int s = r.nextInt(10);
        if(s>5){
            Matrix m = new Matrix();
            float h = r.nextFloat()+1;
            m.setRectToRect(new RectF(0, 0, cloudA.getWidth(), cloudA.getHeight()),
                    new RectF(0, 0, cloudA.getWidth()*h, cloudA.getHeight()*h), Matrix.ScaleToFit.CENTER);
            img = Bitmap.createBitmap(cloudA, 0, 0, cloudA.getWidth(), cloudA.getHeight(), m, true);
        }else{
            img = cloudB;
        }
        if(start){
            x = -img.getWidth();
        }
        else{
            x = p.nextInt(screenX);
        }

        cloud.add(new Cloud(img,x,p.nextInt(screenY-750)+100,q.nextInt(8)+1,screenX));

    }

    public Bitmap highlightImage(Bitmap src, int color,boolean x, boolean y) {
        int xMod;
        int yMod;
        if(x){
           xMod = 4;
        }else{
            xMod = -1;
        }
        if(y){
            yMod = 2;
        }
        else{
            yMod = -1;
        }
        // create new bitmap, which will be painted and becomes result image
        Bitmap bmOut = Bitmap.createBitmap(src.getWidth()*5/4+30, src.getHeight()*5/4+30, Bitmap.Config.ARGB_8888);
        // setup canvas for painting
        Canvas canvas = new Canvas(bmOut);
        canvas.scale(1.25f,1.25f);

        // setup default color
        canvas.drawColor(0, PorterDuff.Mode.CLEAR);
        // create a blur paint for capturing alpha
        Paint ptBlur = new Paint();
        ptBlur.setMaskFilter(new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL));
        int[] offsetXY = new int[2];
        // capture alpha into a bitmap
        Bitmap bmAlpha = src.extractAlpha(ptBlur, offsetXY);
        // create a color paint
        Paint ptAlphaColor = new Paint();
        ptAlphaColor.setColor(color);
        // paint color for captured alpha region (bitmap)
        canvas.drawBitmap(bmAlpha, xMod*offsetXY[0]/2, yMod*offsetXY[1], ptAlphaColor);
        // free memory
        bmAlpha.recycle();

        // paint the image source
        canvas.drawBitmap(src, 0, 0, null);

        // return out final image
        return bmOut;
    }

    public void launchUpgrade(){
        upg = true;
        upgradeBtn.setImg(upgrade);
    }

    public void launchMap(){
        showmap = true;
        mapBtn.setImg(map);
    }

    public void launchProfile(){

    }

    public void startGame(){
        launchBtn.setImg(launch);
        Intent myIntent = new Intent(getContext(), MainActivity.class);
        //myIntent.putExtra("key", value); //Optional parameters
        getContext().startActivity(myIntent);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if(!thread.getRunning()) {
            thread.setRunning(true);
            thread.start();
        }
    }

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

    @Override
    public void surfaceDestroyed(SurfaceHolder holder){
        boolean retry = true;
        int count = 0;
        if(thread.getRunning()) {
            thread.interrupt();
        }
        /*while(retry&&count<1000){
            try{thread.setRunning(false);
                thread.join();
                retry=false;

            }catch(InterruptedException e){}

            count++;
        }*/
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        x =(int) event.getX();
        y =(int) event.getY();

        if (x < 710 && y > 780) {
            upgradeBtn.setImg(highlightImage(upgrade,Color.BLUE,false,true));
        }else{
            upgradeBtn.setImg(upgrade);
        }
        if (x < 520 && y < 275) {
            mapBtn.setImg(highlightImage(map,Color.YELLOW,true,false));
        }else{
            mapBtn.setImg(map);
        }
        if(x>1500&&y>700){
            launchBtn.setImg(highlightImage(launch,Color.RED,true,true));
        }else{
            launchBtn.setImg(launch);
        }


        if(event.getAction()==MotionEvent.ACTION_UP) {
            if (x < 710 && y > 780) {
                launchUpgrade();
                return true;
            }

            if (x < 520 && y < 275) {
                launchMap();
                return true;
            }

            if(x>1700&&y<235){
                launchProfile();
                return true;
            }
            if(x>1500&&y>700){
                startGame();
            }
        }

        return true;
    }

    public void update(){

        for(int i=0;i<cloud.size();i++){
            cloud.get(i).update();
            if(cloud.get(i).getX()>screenX){
                cloud.remove(i);
                addCloud();
            }
        }
    }

    @Override
    public void draw(Canvas canvas){

        if(canvas!=null) {
            canvas.drawBitmap(bg,-3,0,null);
            for(int i=0;i<cloud.size();i++){
                cloud.get(i).draw(canvas);
            }
            canvas.drawBitmap(potty, screenX / 2 - 190, screenY / 2 - 190, null);
            //canvas.drawBitmap(upgrade, -235, screenY - upgrade.getHeight() + 300, null);
            canvas.drawRoundRect(screenX - 550, 5, screenX - 150, 105, 15, 15, feature);
            canvas.drawRoundRect(screenX - 550, 5, screenX - 150, 105, 25, 25, border);
            canvas.drawCircle(screenX - 60, 60, 150, featureRad);
            canvas.drawCircle(screenX - 60, 60, 150, border);
            canvas.drawCircle(screenX / 2 + 230, screenY / 2 + 110, 50, stick);
            canvas.drawLine(screenX / 2 + 220, screenY / 2 + 110, screenX / 2 + 185, screenY / 2 + 340, stick);
            canvas.drawLine(screenX / 2 + 185, screenY / 2 + 340, screenX / 2 + 270, screenY/2+440,stick);
            canvas.drawLine(screenX/2+270,screenY/2+440,screenX/2+270,screenY,stick);
            canvas.drawLine(screenX/2+270,screenY/2+440,screenX/2+340,screenY,stick);
            canvas.drawLine(((screenX / 2 + 220)+(screenX / 2 + 185))/2,screenY/2+230,screenX/2+210,
                    screenY/2+250,stick);
            canvas.drawLine(screenX/2+185,screenY/2+250,screenX/2+245,screenY/2+235,stick);
            canvas.drawLine(screenX / 2 + 235, screenY / 2 + 245, ((screenX / 2 + 220) + (screenX / 2 + 185)) / 2,
                    screenY / 2 + 230, stick);

            canvas.drawText(Integer.toString(prefs.getInt("highscore", 0)), 1000, 50, text);

            upgradeBtn.draw(canvas);
            mapBtn.draw(canvas);
            launchBtn.draw(canvas);

            canvas.drawText(Integer.toString(x)+","+Integer.toString(y),50,50,text);

            /*if(upg){
                canvas.drawText("UPGRADE",540,400,text);
                canvas.drawBitmap(highlightImage(upgrade), -235, screenY - upgrade.getHeight() + 300,null);
            }*/
            if(showmap){
                canvas.drawText("MAP",540,500,text);
            }
        }
    }


}

我确信我的代码有很多错误,而不仅仅是我遇到的问题因为我对此很新,所以如果你有任何一般建议来清理我的代码,我会爱也能听到这些。

0 个答案:

没有答案