开发者

Updating player score in an android game

After updating the adt and having eclipse act a little more stable. I decided the next logical step would be adding a score system to my pong game. There is not collision detection yet but when the ball moves across the screen, it updates the score. The problem i realized is that the score might update in my thread class but never in the oncreate method. How can i modify my code to allow score updating outside of the thread? Here is the code

Here is the main class with on create

package com.TheGame;


import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import com.TheGame.gameview.LunarThread;
import android.graphics.*;
import android.widget.*;
public class basicgame extends Activity {
    /** Called when the activity is first created. */





    /** A handle to the thread that's actually running the animation. */
    private LunarThread mLunarThread;

    /** A handle to the View in which the game is running. */
    private gameview mLunarView;



    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


       // score.setTextSize(20);

        mLunarView = (gameview) findViewById(R.id.lunar);
        TextView score =(TextView)findViewById(R.id.scoreview);
        score.setText(mLunarView.playerscore);
        mLunarView.postInvalidate();
       // score.setTextColor(Color.RED);
        //setContentView(mLunarView);
       // setContentView(linearLayout);
       // mLunarView.addView(score);
        //mLunarThread = mLunarThread.getThread();


        // give the LunarView a handle to the TextView used for messages



    }
}

and here is the thread and view class

package com.TheGame;

import android.content.Context;
import android.graphics.*;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.util.*;
import android.view.*;
import android.app.Activity;
import android.view.Window;
import android.util.DisplayMetrics;
import android.graphics.drawable.BitmapDrawable;


public class gameview extends SurfaceView implements SurfaceHolder.Callback
{
    public float player1y =0;
    public float player2y =0;
    public String playerscore = "";
     int player1score =0;
        int player2score = 0;
    public class LunarThread extends Thread {           



           int x =0;
           int y = 0;
           int velx = 3;
           int vely = 3;



           DisplayMetrics display = new DisplayMetrics();



           Drawable background;
            private Drawable mBackgroundImage;


            private Drawable player1;
            private Drawable player2;




            /** Message handler used by thread to interact with TextView */
            private Handler mHandler;


            /** Indicate whether the surface has been created & is ready to draw */
            private boolean mRun = false;

            /** Scratch rect object. */


            /** Handle to the surface manager object we interact with */
            private SurfaceHolder mSurfaceHolder;



            public LunarThread(SurfaceHolder surfaceHolder, Context context,
                    Handler handler) {

                // get handles to some important objects
                mSurfaceHolder = surfaceHolder;
                mHandler = handler;
                mContext = context;

                Resources res = context.getResources();
                // cache handles to our key sprites & other drawables

                playerscore = "Player 1: "+ player1score +" Player 2: " + player2score;
                // load background image as a Bitmap instead of a Drawable b/c
                // we don't need to transform it and it's faster to draw this way
                mBackgroundImage = getResources().getDrawable(R.drawable.icon);
                background = getResources().getDrawable(R.drawable.kittens);
                 player1 = getResources().getDrawable(R.drawable.paddle);
                 player2 = getResources().getDrawable(R.drawable.paddle);

            }




            @Override
            public void run() {
                while (mRun) {

                    Canvas c = null;
                    try {
                        c = mSurfaceHolder.lockCanvas(null);
                        synchronized (mSurfaceHolder) {

                            doDraw(c);

                        }
                    } finally {
                        // do this in a finally so that if an exception is thrown
                        // during the above, we don't leave the Surface in an
                        // inconsistent state
                        if (c != null) {
                            mSurfaceHolder.unlockCanvasAndPost(c);
                        }
                    }

                }
            }


            public void setRunning(boolean b) {
                mRun = b;
            }


            public void setSurfaceSize(int width, int height) {
                // synchronized to make sure these all change atomically
                synchronized (mSurfaceHolder) {



                }
            }


            boolean doKeyDown(int keyCode, KeyEvent msg) {
                synchronized (mSurfaceHolder) {




                    return false;
                }
            }


            private void doDraw(Canvas canvas) {

                canvas.save();


                canvas.drawColor(Color.BLACK);
                //Rect moverrect = mBackgroundImage.copyBounds();
                background.setBounds(0,0,canvas.getWidth(),canvas.getHeight());
                mBackgroundImage.setBounds(x, y,x+ 100,y+ 100);

                player1.setBounds(0, (int)player1y, 50, (int)player1y+75);
                player2.setBounds(canvas.getWidth()-50,(int)player2y,canvas.getWidth(),(int)player2y+75);
               // Log.i("game","X "+x + " Y "+y );
                background.draw(canvas);
                mBackgroundImage.draw(canvas);
                player1.draw(canvas);
                player2.draw(canvas);
                if(player1y<0)
                {
                player1y =0;
                }
                if(player1y>canvas.getHeight()-75)
                {
                 player1y = canvas.getHeight()-75;
                }
                if(player2y<0)
                {
                player2y =0;
                }
                if(player2y>canvas.getHeight()-75)
                {
                 player2y = canvas.getHeight()-75;
                }
                int sizex = canvas.getWidth()-100;
                int sizey = canvas.getHeight()-100;

                x+=velx;
                y+=vely;


                if(x<0)
                {
                //x=0;
                //velx*=-1;
                x = canvas.getWidth()/2;
                player2score++;

                }
                if(y<0)
                {
                y=0;
                vely*=-1;
                }
                if(x>sizex)
                {
                //x=sizex;
                //velx*=-1;
                x = canvas.getWidth()/2;
                player1score++; 
                }
                if(y>sizey)
                {
                y=sizey;
                vely*=-1;
                }



                canvas.restore();
               // 
               // invalidate();

            }              

        public LunarThread getThread() {
            return thread;
        }

        private float mPosX;
        private float mPosY;

        private float mLastTouchX;
        private float mLastTouchY;

        private static final int INVALID_POINTER_ID = -1;

     // The ‘active pointer’ is the one currently moving our object.
     private int mActivePointerId = INVALID_POINTER_ID;



        /* Callback invoked when the surface dimensions change. */
        public void surfaceChanged(SurfaceHolder holder, in开发者_开发百科t format, int width,
                int height) {
            thread.setSurfaceSize(width, height);
        }

        /*
         * Callback invoked when the Surface has been created and is ready to be
         * used.
         */
        public void surfaceCreated(SurfaceHolder holder) {
            // start the thread here so that we don't busy-wait in run()
            // waiting for the surface to be created
            thread.setRunning(true);
            thread.start();
        }

        /*
         * Callback invoked when the Surface has been destroyed and must no longer
         * be touched. WARNING: after this method returns, the Surface/Canvas must
         * never be touched again!
         */
        public void surfaceDestroyed(SurfaceHolder holder) {
            // we have to tell thread to shut down & wait for it to finish, or else
            // it might touch the Surface after we return and explode
            boolean retry = true;
            thread.setRunning(false);
            while (retry) {
                try {
                    thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }
}
    }

    /** Handle to the application context, used to e.g. fetch Drawables. */
    private Context mContext;

    /** Pointer to the text view to display "Paused.." etc. */
    private TextView mStatusText;
    @Override
     public boolean onTouchEvent(MotionEvent ev) {
            final int action = ev.getAction();

            switch (action) {

            case MotionEvent.ACTION_MOVE: {
                // Find the index of the active pointer and fetch its position
            int pointerCount = ev.getPointerCount(); 


            for (int i = 0; i < pointerCount; i++) { 
            float p1y = ev.getY(i);
            float p1x = ev.getX(i);
                if(p1x<300)
                {
                  player1y = p1y;
                }
                else if(p1x>300)
                {
                  player2y = p1y;
                }
            }
               //player1y = p1y;

                invalidate();
                break;
            }

            }
            return true;


        }

    /** The thread that actually draws the animation */
    public LunarThread thread;

        public gameview(Context context, AttributeSet attrs) 
        {
            super(context, attrs);

            // register our interest in hearing about changes to our surface
            SurfaceHolder holder = getHolder();
            holder.addCallback(this);

            // create thread only; it's started in surfaceCreated()
            thread = new LunarThread(holder, context, new Handler());






           // setFocusable(true); // make sure we get key events
            this.setFocusableInTouchMode(true);
        }
        public void surfaceDestroyed(SurfaceHolder holder) {
            // we have to tell thread to shut down & wait for it to finish, or else
            // it might touch the Surface after we return and explode
            boolean retry = true;
            thread.setRunning(false);
            while (retry) {
                try {
                    thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }
        }
        public void surfaceCreated(SurfaceHolder holder) {
            // start the thread here so that we don't busy-wait in run()
            // waiting for the surface to be created
            thread.setRunning(true);
            thread.start();
        }
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            thread.setSurfaceSize(width, height);
        }
        @Override
        public void onDraw(Canvas canvas) 
        {

        }



}

Keep in mind I am new to android game development and tried to model the way it looked from my knowledge of xna development. I kindof gutted the lunar landing code to try to make a background happen and work from there. I wanted to try to start with the most basic game code but I might have deleted important methods in my gutting. That is why variables have the lunar word in them.

Thanks

EDIT

As someone who is still new to the site my comments did not really work out. The code was not formatted at all in my copy and paste. My question is how would you implement the handler to have the score and text update? Is there any examples online how i can easily integrate it or did i put myself in a hole?

Thanks


There's a few approaches you can use here:

  1. Use AsyncTask for the background processing
  2. Create a Handler in the GUI (main) thread, and post Runnables or messages to it.
  3. Use Activity.runOnUiThread

If you're likely to port to another platform, using a Runnable makes sense, as with the right abstraction, you can use javax.microedition.lcdui.Display.callSerially on J2ME, or javax.swing.SwingUtilities.invokeLater on J2SE

Hope this helps,

Phil Lello


Not sure if you have looked at Asynctask. http://developer.android.com/reference/android/os/AsyncTask.html

I have found this to be the best way of communication between UI thread and the non-UI thread.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜