[android游戏开发初学]简单的游戏引擎_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > [android游戏开发初学]简单的游戏引擎

[android游戏开发初学]简单的游戏引擎

 2013/9/7 21:12:25  boliu  博客园  我要评论(0)
  • 摘要:这两天,没事想学习游戏开发,看了一些资料之后准备开始。为了将来编码方便,先写了一个简单的游戏引擎方便自己以后做练习用。如果以后没有什么特殊的需求--比如opengl什么的,会尽量用这个简单框架来实现。有优化的地方会在这个里边一直更新,也希望有问题的地方希望大家帮忙提一些意见我的刷新线程基础类/***我的刷新线程*/abstractclassLoopThreadextendsThread{privatebooleanDEBUG=true;privateObjectlock=newObject()
  • 标签: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();
}

游戏的显示界面的基础类

logs_code_hide('46162149-0919-45b6-afd5-320a1b58db7f',event)" src="/Upload/Images/2013090721/2B1B950FA3DF188F.gif" alt="" />
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;
        }
    }
}

 

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

 

发表评论
用户名: 匿名