码迷,mamicode.com
首页 > 移动开发 > 详细

Android 游戏开发(二)SurfaceView初探

时间:2014-08-26 22:54:36      阅读:379      评论:0      收藏:0      [点我收藏+]

标签:des   android   style   blog   color   os   使用   io   for   

SurfaceView游戏框架在游戏开发当中有举足轻重的地位。
SurfaceHolder类是用来控制SurfaceView的大小、格式,并且主要用于监听Surface的状态。
SurfaceView好像就是一块内存数据里面记录着数据,更改数据而是由SurfaceHolder来控制,使用SurfaceHolder的lockCanvas()函数来获取SurfaceView的Canvas对象。然后在Canvas上绘制内容来修改SurfaceView中的数据。

 

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView implements Callback {

    //该类主要是用来监听SurfaceView的状态
    private SurfaceHolder holder;
    private Paint paint;
    
    public MySurfaceView(Context context) {
        super(context);
        holder = this.getHolder();
        //为Surface添加监听状态
        holder.addCallback(this);
        //实例一只画笔
        paint = new Paint();
        //将画笔设置为白色
        paint.setColor(Color.WHITE);
    }

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

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        myDraw();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
    }

    private void myDraw() {
        //lockCanvas不仅仅是得到Canvas,并且对Canvas加锁
        //防止在绘制过程中遭到破坏
        Canvas mCanvas = holder.lockCanvas();
        mCanvas.drawText("Game", 50, 10, paint);
        holder.unlockCanvasAndPost(mCanvas);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawText("Game", 50, 50, paint);
        super.onDraw(canvas);
    }

}

 

在SurfaceView中重载的onDraw()方法并不会执行,更加能够说明了SurfaceView是通过SurfaceHolder来修改数据的,所以SurfaceView即使重写了onDraw()方法也不会执行到。接下来重复上一次View的操作,重写onTouchEvent()方法。

@Override
public boolean onTouchEvent(MotionEvent event) {
    posX = (int) event.getX();
    posY = (int) event.getY();
    myDraw();
    return true;
}

 

发现重写onTouchEvent()方法后,屏幕绘制变得乱七八糟。跟上一次重写后的效果完全不一样。其主要原因是画布没有刷新,将每次绘制的文本全部都显示了出来。解决方法就是对画布进行“刷屏”。

private void myDraw() {
    Canvas mCanvas = holder.lockCanvas();
    //就是在重绘之前用一张背景,将原来的覆盖掉
    paint.setColor(Color.BLACK);
    mCanvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);
    paint.setColor(Color.WHITE);
    mCanvas.drawText("Game", posX, posY, paint);
    holder.unlockCanvasAndPost(mCanvas);
}


SurfaceView视图添加线程
在游戏中,基本上不会等用户触发了某个事件才去重绘画布,而是一个较短的固定周期去重绘画布;比如动态的花花草草,流水等场景,这些游戏元素并不会跟玩家进行交互。但是这些元素都是动态的。所以游戏开发中,都会有一个线程不停的去重新绘制。

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView implements Callback , Runnable{

    //该类主要是用来监听SurfaceView的状态
    private SurfaceHolder holder;
    private Paint paint;
    private int posX = 100;
    private int posY = 100;
    private int flag;
    private Canvas canvas;
    private int screenW, screenH;
    
    public MySurfaceView(Context context) {
        super(context);
        holder = this.getHolder();
        //为Surface添加监听状态
        holder.addCallback(this);
        //实例一只画笔
        paint = new Paint();    
        //将画笔设置为白色
        paint.setColor(Color.WHITE);
        paint.setTextSize(50f);
        //设置焦点
        setFocusable(true);
    }

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

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        screenH = this.getHeight();
        screenW = this.getWidth();
        flag = 1;
        new Thread(this).start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        flag = 0;
    }

    private void myDraw() {
        try {
            canvas = holder.lockCanvas();
            if(canvas!=null){
                //就是在重绘之前用一张背景,将原来的覆盖掉
                paint.setColor(Color.BLACK);
                canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);
                paint.setColor(Color.WHITE);
                canvas.drawText("Game", posX, posY, paint);
            }
        } catch (Exception e) {
        }finally{
            if(canvas!=null){
                holder.unlockCanvasAndPost(canvas);
            }
        }
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        posX = (int) event.getX();
        posY = (int) event.getY();
        myDraw();
        return true;
    }

    private void logic(){}//游戏逻辑
    @Override
    public void run() {
        while(flag==1){
            long start = System.currentTimeMillis();
            myDraw();
            logic();
            long end = System.currentTimeMillis();
            try {
                //保证重绘的最小周期是50
                if(end - start < 50){
                    Thread.sleep(50 - (end -start));
                }
            } catch (InterruptedException e) {
            }
        }
    }

}

 

一般游戏的刷新时间是50-100毫秒,也就是每秒10-20帧左右。

最后感谢百度、感谢《游戏编程之从0开始》。

 

Android 游戏开发(二)SurfaceView初探

标签:des   android   style   blog   color   os   使用   io   for   

原文地址:http://www.cnblogs.com/chenjianxiang/p/3938343.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!