用SurfaceView制作简单的android游戏 : 重力小球(1)创建游戏整体框架

在android平台制作游戏可以用view或者是SurfaceView,前者是当用户产生点击或其他动作,view才会做出相应的更新,可以看成是被动的;

SurfaceView是开一线程让画面在其中描绘(可以看成是缓冲区),每隔一定时间再把描绘好的画面更新到主画面

具体更详细的研究可以点击这里查看.

本文代码参考自某日文教程,可以点击这里查看, 游戏名为IrairaBar, 开发环境为sdk2.2,

因为涉及重力感应器的使用所以需要真机测试

整个游戏的运行逻辑如下图

            

update负责确定物体位置,检测碰撞,计算各种数值之类的工作, draw就只负责描画

1.首先新建项目后再创建两个文件,如下图

IrairaBarActivity.java代码

public class IrairaBarActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//把目标activity设置为GameSurfaceView
                setContentView( new GameSurfaceView(this) );
    }
}

 

GameSurfaceView.java代码

View Code
class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
        Thread _thread;

        public GameSurfaceView(Context context) {
                super(context);
//获取holder并传给callback函数
                getHolder().addCallback(this);
        }

//这个函数是当SurfaceView的大小改变了才会调用,这里暂时没用
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
//新开线程
                _thread = new Thread(this);            
                _thread.start();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
                _thread = null;
        }

        @Override
        public void run() {
//游戏运行的主循环
                while (_thread!=null) {
                        onDraw(getHolder());
                }
        }

        private void onDraw(SurfaceHolder holder) {
                Canvas c = holder.lockCanvas();
//这里用来描绘画面元素
                holder.unlockCanvasAndPost(c);
        }
}

2.然后添加一些类来控制fps

Task.java  (纯粹是用来继承的抽象类)

public abstract class Task {

    public boolean onUpdate() {
        return true;
    }

    public void onDraw(Canvas c) {
    }
}

 FpsController.java (用来控制fps的, 继承task)

View Code
public class FpsController extends Task {

    private long _startTime = 0; // 开始时间
    private int _cnt = 0; // 计数
    private Paint _paint = new Paint(); // paint情报
    private float _fps; // fps
    private final static int N = 60; // 平均数
    private final static int FONT_SIZE = 20; // 字体大小

    public FpsController() {
        _paint.setColor(Color.BLUE); // 设定字体为蓝色
        _paint.setTextSize(FONT_SIZE); // 设定字体大小
    }

    @Override
    public boolean onUpdate() {
        if (_cnt == 0) { // 第一幀开始记录当前系统时间
            _startTime = System.currentTimeMillis();
        }
        if (_cnt == N) { // 第六十幀时计算平均帧数
            long t = System.currentTimeMillis();
            _fps = 1000.f / ((t - _startTime) / (float) N);
            _cnt = 0;
            _startTime = t;
        }
        _cnt++;
        return true;
    }

    @Override
    public void onDraw(Canvas c) {

        c.drawText(String.format("%.1f", _fps), 0, FONT_SIZE-2, _paint);
    }

}

GameMgr.java (顾名思义,gameManager, 管理所有update和draw)

View Code
public class GameMgr {

//用来装task的容器
        private LinkedList<Task> _taskList = new LinkedList<Task>();

//添加task        
        GameMgr(){
                _taskList.add( new FpsController() );
        }
        

//逐一更新tasklist里面的任务
        public boolean onUpdate() {
                for(int i=0; i<_taskList.size(); i++){
//更新失败的话就把task移除
                        if(_taskList.get(i).onUpdate() == false){
                                _taskList.remove(i);            
                                i--;
                        }
                }
                return true;
        }

//逐一描画
        public void onDraw(Canvas c) {
//把屏幕涂白,相当于清屏的作用
                c.drawColor(Color.WHITE);       
                for(int i=0; i<_taskList.size(); i++){
                        _taskList.get(i).onDraw(c);
                }
        }

}

3.最后把gameManager加到GameSurfaceView里面去

代码如下,注释部分为需要加进去的代码(请自行去掉注释的//)

View Code
class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
//        private GameMgr _gameMgr = new GameMgr();
        private Thread _thread;

        public GameSurfaceView(Context context) {
                super(context);
                getHolder().addCallback(this);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
                _thread = new Thread(this);
                _thread.start();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
                _thread = null;
        }

        @Override
        public void run() {
                while (_thread!=null) {
//                        _gameMgr.onUpdate();
                        onDraw(getHolder());
                }
        }

        private void onDraw(SurfaceHolder holder) {
                Canvas c = holder.lockCanvas();
 //               _gameMgr.onDraw(c);
                holder.unlockCanvasAndPost(c);
        }
}

 最后真机测试如下图

原文地址:https://www.cnblogs.com/tomboy/p/2683413.html