[android遊戲開發初學]簡單的遊戲框架

這兩天,沒事想學習遊戲開發,看了一些資料以後準備開始。爲了未來編碼方便,先寫了一個簡單的遊戲框架方便本身之後作練習用。
若是之後沒有什麼特殊的需求--好比opengl什麼的,會盡可能用這個簡單框架來實現。有優化的地方會在這個裏邊一直更新,也但願有問題的地方但願你們幫忙提一些意見canvas

個人刷新線程基礎類多線程

/**
 * 個人刷新線程
 */
abstract class LoopThread extends Thread{
    private boolean DEBUG = true;
    private Object lock = new Object();
    
    public static final int RUNNING = 1;
    public static final int PAUSE = 2;
    public static final int STOP = 0;
    public int runState = STOP;
    private WeakReference<CustomSurfaceViewCallBack> callbackRef ;
    public LoopThread(CustomSurfaceViewCallBack view){
        super();
        callbackRef = new WeakReference<CustomSurfaceViewCallBack>(view);
    }
    @Override
    public void run() {
        try {
            loop();
        } catch (InterruptedException e) {
            this.interrupt();
        }finally{
            this.runState = STOP;
            tRelase();
            if(DEBUG){
                System.out.println(this.getName()+" exit, lock="+lock);
            }
        }
    }
    private void loop() throws InterruptedException {
        while(runState!=STOP){
            synchronized (lock) {
                while (runState == RUNNING) {
                    
                    CustomSurfaceViewCallBack callBack = callbackRef.get();
                    if (callBack == null) {
                        runState = STOP;
                        break;
                    }
                    onLoop(callBack);
                    if (runState == RUNNING) {
                        lock.wait(500);
                    } else {
                        break;
                    }
                }
                if(runState==PAUSE){
                    lock.wait();
                }else if(runState==STOP){
                    lock.notifyAll();
                    return;
                }
            }
        }
    }
    public abstract void onLoop(CustomSurfaceViewCallBack callBack);
    
    public void tRelase(){
        callbackRef = null;
    }
    public void tResume(){
        synchronized (lock) {
            this.runState = LoopThread.RUNNING;
            lock.notifyAll();
        }
    }
    public void tPause(){
        synchronized (lock) {
            this.runState = LoopThread.PAUSE;
            lock.notifyAll();
        }
    }
    public boolean tStop(){
        synchronized (lock) {
            this.tRelase();
            this.runState = LoopThread.STOP;
            lock.notifyAll();
        }
        while(true){
            try {
                this.join();
                return true;
            } catch (InterruptedException e) {
                this.interrupt();
            }
        }
    }
}

 

刷新接口框架

public interface CustomSurfaceViewCallBack {

    public abstract boolean processing();

    public abstract void doDraw(Canvas canvas);

    public SurfaceHolder getSurfaceHolder();
}

遊戲的顯示界面的基礎類dom

abstract class CustomSurfaceView extends SurfaceView implements Callback,CustomSurfaceViewCallBack{
    private LoopThread dt;
    private ProcessThread pt;
    private SurfaceHolder sHolder;
    public CustomSurfaceView(Context context) {
        super(context);
        sHolder = getHolder();
        sHolder.addCallback(this);
    }
    private boolean singleThread = false;
    /**
     * 設置是否用單線程來刷新界面和處理數據。
     * 通常來講,爲了保證流暢性遊戲開發刷新界面的線程和數據處理線程是分開的。若是數據處理耗時,最好分開。若是數據處理耗時較少,可使用單線程
     * @param single
     */
    public void setSingleThread(boolean single){
        if(dt!=null){
            throw new UnsupportedOperationException("must invoke setSingleThread before surfaceCreated");
        }
        this.singleThread = single;
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        start();
    }
    
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        stop();
    }
    /**
     * 進行界面繪製操做
     * @param canvas
     */
    public abstract void doDraw(Canvas canvas);
    /**
     * 處理數據 並判斷是否進行界面重繪
     * @return 
     */
    public abstract boolean processing();
    @Override
    public SurfaceHolder getSurfaceHolder(){
        return getHolder();
    }
    public  void start(){
        if(singleThread){// 若是是單線程的話,初始化一個整合了數據處理和界面刷新一塊兒處理的線程
            stop();
            dt= new SingleThread(this);
            dt.runState = LoopThread.RUNNING;
            dt.start();
            return;
        }
        if(stop(dt)){
            dt = new DrawThread(this);
            dt.runState = LoopThread.RUNNING;
            dt.start();
        }
        if(stop(pt)){
            pt = new ProcessThread(this);
            pt.runState = LoopThread.RUNNING;
            pt.start();
        }
    }
    /**
     * 中止一個LoopThread 中止成功返回false
     * @param t
     * @return
     */
    private boolean stop(LoopThread t){
        if(t==null){
            return true;
        }
        return t.tStop();
    }
    /**
     * 遊戲中止
     */
    public void stop(){
        stop(dt);
        stop(pt);
    }
    /**
     * 遊戲暫停
     */
    public void pause(){
        if(dt!=null){
            dt.tPause();
        }
        if(pt!=null){
            pt.tPause();
        }
    }
    /**
     * 只能夠從遊戲暫停狀態讓遊戲開始
     */
    public void resume(){
        if(dt!=null){
            dt.tResume();
        }
        if(pt!=null){
            pt.tPause();
        }
    }
    /**
     * 界面繪製線程
     * @author cs
     */
    private static class DrawThread extends LoopThread{
        public DrawThread(CustomSurfaceView view) {
            super(view);
            this.setName("DrawThread--"+this.getId());
        }

        @Override
        public void onLoop(CustomSurfaceViewCallBack callBack) {
            drawByCallback(callBack);
        }
        
    }
    /**
     *  若是是單線程刷新的話,用到的線程類
     * @author cs
     */
    private static class SingleThread extends LoopThread{
        public SingleThread(CustomSurfaceView view) {
            super(view);
            this.setName("SingleThread--"+this.getId());
        }
        @Override
        public void onLoop(CustomSurfaceViewCallBack callBack) {
            callBack.processing();
            drawByCallback(callBack);
        }
    }
    /**
     * 數據處理以及邏輯判斷線程
     * @author cs
     */
    private static class ProcessThread extends LoopThread{
        public ProcessThread(CustomSurfaceViewCallBack callBack) {
            super(callBack);
            this.setName("ProcessThread--"+this.getId());
        }
        @Override
        public void onLoop(CustomSurfaceViewCallBack callBack) {
            if(callBack!=null){
                callBack.processing();
            }
        }
        
    }
    private static void drawByCallback(CustomSurfaceViewCallBack callBack) {
        Canvas canvas = null;
        try {
            canvas = callBack.getSurfaceHolder().lockCanvas();
            if (canvas != null) {
                callBack.doDraw(canvas);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (canvas != null)
                callBack.getSurfaceHolder().unlockCanvasAndPost(canvas);
        }
    }
}
View Code

 

顯示的實現仍是上篇中要顯示的貝塞爾曲線。固然,實現起來比原來代碼簡單多了ide

public class PathActivity extends Activity {
    private CustomSurfaceView pathView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pathView = new PathView(this);
        pathView.setSingleThread(false);
        this.setContentView(pathView);
    }
    private static class PathView extends CustomSurfaceView{
        private int vWidth;
        private int vHeight;
        private Paint pPaint;
        private Path mPath;
        private float endX;
        private float endY;
        private Random random;
        
        public PathView(Context context) {
            super(context);
            pPaint = new Paint();
            pPaint.setAntiAlias(true);
            pPaint.setColor(0xaf22aa22);
            pPaint.setStyle(Paint.Style.STROKE);
            mPath = new Path();
            random = new Random();
        }
        
        private void  init(){
            vWidth = getWidth();
            vHeight = getHeight();
            endX = 0.8f*vWidth;
            endY = 0.8f*vHeight;
        }
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            super.surfaceCreated(holder);
            init();
        }
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            super.surfaceChanged(holder, format, width, height);
            init();
        }
        @Override
        public void doDraw(Canvas canvas){
            canvas.drawColor(Color.BLACK);
            canvas.drawPath(mPath, pPaint);
        }
        @Override
        public boolean processing(){
            //這裏構建貝塞爾曲線
            mPath.reset();
            mPath.moveTo(50, 50);
            mPath.quadTo(random.nextInt(vWidth), random.nextInt(vHeight), endX/2, random.nextInt(vHeight));
            mPath.quadTo(random.nextInt(vWidth), random.nextInt(vHeight), endX, endY);
            return true;
        }
    }
}

 

但願你們多多指正。由於原本有好多線程同步的東西,有問題是不免的。oop

相關文章
相關標籤/搜索