• 用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);
            }
    }

     最后真机测试如下图

  • 相关阅读:
    HDU 1394Minimum Inversion Number 数状数组 逆序对数量和
    2016中国大学生程序设计竞赛(长春)-重现赛 1010Ugly Problem 回文数 模拟
    Codeforces 723C. Polycarp at the Radio 模拟
    hihoCode 1078 : 线段树的区间修改
    hihocode 1077 : RMQ问题再临-线段树
    POJ 2352Stars 树状数组
    Codeforces 714C. Sonya and Queries Tire树
    Codeforces 710C. Magic Odd Square n阶幻方
    Codeforces 709C 模拟
    ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) D. The Door Problem 2-SAT
  • 原文地址:https://www.cnblogs.com/tomboy/p/2683413.html
Copyright © 2020-2023  润新知