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()方法。
@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开始》。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。