首页 > 代码库 > Android 游戏开发(二)SurfaceView初探
Android 游戏开发(二)SurfaceView初探
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()方法。
@Overridepublic 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初探
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。