开发者

Problem ending my game (UI Thread won't let me open a new Activity)

I'm having trouble tying off my program (ending it up). I have a SurfaceView in an Activity, and in that SurfaceView when you lose three lives the game is supposed to end. I have tried opening up a new Activity but I get a keyDispatchingTimedOut error. I know it has to do with my UIThread. I have been told to create a handler in my activity and then accessible to my surfaceview. Then I can send a message to my handler and it can update the UI(or launch a new activity) in the main UI Thread. However...I have no idea how to do this! Which activity do I create the handler in? The one I want to launch the new Activity from? I'm really lost here, and this is the last piece I need to make my program cohesive. If nothing else, how could I just CLOSE the activity? My UI Thread is causing a lot of problems :(

Surface View

public class BoardView extends SurfaceView implements SurfaceHolder.Callback{
Context mContext;

// thread initialization
private BoardThread thread;
Thread timer;
Thread timer2;

// box variables
Bitmap box = 
    (BitmapFactory.decodeResource
            (getResources(), R.drawable.box));
private int box_x = 140;
private int box_y = 378;
private int boxWidth = box.getWidth();
private int boxHeight = box.getHeight();

// storage
private Vector<Blossom> blossomVector = new Vector<Blossom>();
Iterator<Blossom> dataIterator = blossomVector.iterator();

// counters
private int blossomNum = 0;
private String score;
private int currentScore = 0;
private int lives = 3;

boolean mode = false;
boolean game = false;

OutputStreamWriter out = null;
FileOutputStream fOut = null;

private static final String TAG = "Debug";
final Paint scorePaint = new Paint();

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

    scorePaint.setColor(Color.BLACK);
    scorePaint.setTextSize(12);
    scorePaint.setTypeface(Typeface.MONOSPACE);


    //surfaceHolder provides canvas that we draw on
    getHolder().addCallback(this);

    //set up read/write data
    File root = Environment.getExternalStorageDirectory();


    // controls drawings
    thread = new BoardThread(getHolder(),this, blossomVector, dataIterator, box_x, box_y, 
            boxWidth, boxHeight);

    timer2 = new Thread(){
        public void run(){
            while(game == false){
                uiCallback.sendEmptyMessage(0);
                try{
                    Thread.sleep(5000); // change to be random
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    };

    timer = new Thread(){
        public void run(){
            //makes sure the player still has 3 lives left
            while(game == false){
                uiCallback.sendEmptyMessage(0);
                try {
                    Thread.sleep(2000); // wait two seconds before drawing the next flower
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } //sleep for 2 seconds
            }
        }
    };
    timer.start();
    timer2.start();


    //intercepts touch events
    setFocusable(true);

}


@Override

public void onDraw(Canvas canvas){
    canvas.drawColor(Color.WHITE);
    score = "" + currentScore;

    //note: pay attention to order you draw things
    //don't change order or else blossoms will fall
    //on top of box, not "into" it.

    //display the scoreboard
    canvas.drawText("Score: " + score,240,420,scorePaint);
    // uses a synchronized method to prevent concurrent modification
    DrawBlossoms(canvas);
    canvas.drawBitmap(box, box_x, box_y, null);

}

@Override
public boolean onTouchEvent(MotionEvent event){
    //handles movement of box
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        if(event.getX() > box_x & event.getY() > box_y & 
                event.getX() < box_x + boxWidth & event.getY() < box_y + boxHeight)
        {
            mode = true;
        }
    }

    if(event.getAction() == MotionEvent.ACTION_MOVE) {
        if(event.getX() > box_x & event.getY() > box_y & 
                event.getX() < box_x + boxWidth & event.getY() < box_y + boxHeight)
        {
            mode = true;
        }
        if(mode == true){
            box_x = (int)event.getX();
        }   

    }

    if(event.getAction() == MotionEvent.ACTION_UP){
        mode = false;
    }

    invalidate();
    return true;
}

@Override
public void surfaceChanged(SurfaceHolder holder, 
        int format, int width, int height ){
    Log.v(TAG, "Surface Changed");
    //somehow these don't seem to be working
}

@Override
public void surfaceCreated(SurfaceHolder holder){
    thread.startRunning(true);
    thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder){
    Log.v(TAG, "Surface Destroyed");
    try {
    thread.join();
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

}

private Handler uiCallback = new Handler(){
    public synchronized void handleMessage(Message msg){
        //add a new blossom to the blossom Vector!!
        blossomVector.add(new Blossom( 
            (BitmapFactory.decodeResource
                    (getResources(), R.drawable.blossom))));
        dataIterator = blossomVector.iterator();
        blossomNum++;
        Log.v(TAG, "Number of Blossoms =" + blossomNum);
    }
};


private synchronized void DrawBlossoms(Canvas c) // method to draw flowers on screen and test for collision
{
    Canvas canvas = c;
    dataIterator = blossomVector.iterator();
    while (dataIterator.hasNext())
    {
        Blossom tempBlossom = dataIterator.next();
      开发者_开发技巧  tempBlossom.Draw(canvas);
        if (tempBlossom.hit(box_x,box_y, box_x + boxWidth, box_y + boxHeight, blossomVector) == true)
        {
            Log.v(TAG, "ITERATOR WORKS!");
            dataIterator.remove();
            currentScore += 100;
        }

        if (tempBlossom.dropped() == true)
        {
            dataIterator.remove();
            Log.v(TAG, "Blossom dropped");
            lives--;
        }
        if (lives == 0)
        {
            // stop the thread that makes blossoms
            game = true;
            //save the highscore
            try {
                File root = Environment.getExternalStorageDirectory();
                if(root.canWrite()){
                File highscoresFile = new File(root, "score.txt");
                FileWriter writer = new FileWriter(highscoresFile, true);
                BufferedWriter out = new BufferedWriter(writer);
                //out.newLine();
                out.append(score);
                out.newLine();
                out.close();
                }
            } catch (FileNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }





        try {
            thread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        }

    }
}

}

Thread

public class BoardThread extends Thread {

private SurfaceHolder surfaceHolder;
private BoardView boardView;

private Vector<Blossom> blossomVector;
private int boxX;
private int boxY;
private int boxWidth;
private int boxHeight;
private boolean mrun =false;
private Iterator<Blossom> iterator;

private static final String TAG = "Debug";

public BoardThread(SurfaceHolder holder, BoardView boardView2, 
        Vector<Blossom> blossomVector1, Iterator<Blossom> dataIterator,
        int box_x, int box_y, int boxW, int boxH) {

    surfaceHolder = holder;
    boardView=boardView2;

    blossomVector = blossomVector1;
    iterator = dataIterator;
    boxX = box_x;
    boxY = box_y;
    boxW = boxWidth;
    boxH = boxHeight;
}

public void startRunning(boolean run) {

    mrun=run;
}

@Override
public void run() {

    super.run();
     Canvas canvas;
     while (mrun) {
        canvas=null;
         try {
             canvas = surfaceHolder.lockCanvas(null);
              synchronized (surfaceHolder) {
                 //update position
                 //Position(blossomVector, boxX, boxY, boxWidth, boxHeight);
                 // draw flowers
                 boardView.onDraw(canvas);
             }
         } finally {
                 if (canvas != null) {
                 surfaceHolder.unlockCanvasAndPost(canvas);
             }
         }
     }
  }


Which activity do I create the handler in? 

From the activity where your are showing SurfaceView or BoardView in your case.

Modify the constructor of BoardView to

public BoardView(Context context, Handler mHandler)

now you can do any thing by using Handler

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜