• [android游戏开发初学]简单的游戏框架


    这两天,没事想学习游戏开发,看了一些资料之后准备开始。为了将来编码方便,先写了一个简单的游戏框架方便自己以后做练习用。
    如果以后没有什么特殊的需求--比如opengl什么的,会尽量用这个简单框架来实现。有优化的地方会在这个里边一直更新,也希望有问题的地方希望大家帮忙提一些意见

    我的刷新线程基础类

    /**
     * 我的刷新线程
     */
    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();
    }

    游戏的显示界面的基础类

    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

    显示的实现还是上篇中要显示的贝塞尔曲线。当然,实现起来比原来代码简单多了

    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;
            }
        }
    }

    希望大家多多指正。因为本来有好多线程同步的东西,有问题是难免的。

  • 相关阅读:
    Linux 命令后台运行
    Linux Mint,Ubuntu 18 ,Deepin15.7 安装mysql 没有提示输入密码,修改root用户密码过程
    爬虫第一篇基本库的使用——urllib
    Python开发第五篇
    php 5.6 安装openssl extension 出现编译错误
    bash 中的变量可以这么用
    查表法现实数学函数
    封装boto3 api用于服务器端与AWS S3交互
    python 打包详解
    Python使用boto3操作AWS S3中踩过的坑
  • 原文地址:https://www.cnblogs.com/boliu/p/3307624.html
Copyright © 2020-2023  润新知