android游戏开发之SurfaceView-创新互联

SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。

创新互联是一家以网络技术公司,为中小企业提供网站维护、成都做网站、成都网站设计、网站备案、服务器租用、主机域名、软件开发、小程序开发等企业互联网相关业务,是一家有着丰富的互联网运营推广经验的科技公司,有着多年的网站建站经验,致力于帮助中小企业在互联网让打出自已的品牌和口碑,让企业在互联网上打开一个面向全国乃至全球的业务窗口:建站欢迎联系:028-86922220

surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。

你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。

surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:

1>所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。

2>由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。

注:摘自http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

接下来我们定义一个MySurfaceView类,用来实现拖动文本的效果。但是我们希望通过不停的定时刷新界面来达到我们想要的效果。

首先我们继承自SurfaceView,并实现android.view.SurfaceHolder.Callback接口。因为我们想不停的定时刷新界面所以这里也需要实现Runnable。

重写run()函数、surfaceCreated()函数、surfaceChanged()函数、surfaceDestroyed()函数、onTouchEvent()函数。

代码如下:

publicclass MySurfaceView extends SurfaceView implements Callback,Runnable{

private String tag = "MySurfaceView";

private SurfaceHolder surfaceHolder;

private Paint paint;

privateinttextX = 10,textY = 10;

private Thread mThread;

privatebooleanflag;//线程标识位

private Canvas canvas;

public MySurfaceView ( Context context )

{

super(context) ;

Log.d(tag, "MySurfaceView");

surfaceHolder = this.getHolder();

//一定要有addCallback()函数,没有则响应不了监听

surfaceHolder.addCallback(this);

paint = new Paint();

paint.setColor(Color.WHITE);

setFocusable(true);

}

@Override

publicvoid run()

{

while(flag){

Log.d(tag, "thread is run");

long start = System.currentTimeMillis();

myDraw();//绘图

long end = System.currentTimeMillis();

if(end - start < 50){

try

{

Thread.sleep(50 -(end - start));

}

catch ( InterruptedException e )

{

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

@Override

publicvoid surfaceCreated(SurfaceHolder holder)

{

// TODO Auto-generated method stub

Log.d(tag, "surfaceCreated");

flag = true;

mThread = new Thread(this);

mThread.start();

}

@Override

publicvoid surfaceChanged(SurfaceHolder holder, int format, int width, int height)

{

Log.d(tag, "surfaceChanged");

// TODO Auto-generated method stub

}

@Override

publicvoid surfaceDestroyed(SurfaceHolder holder)

{

Log.d(tag, "surfaceDestroyed");

flag = false;

}

publicvoid myDraw(){

Log.d(tag, "myDraw");

canvas = surfaceHolder.lockCanvas();

if(canvas != null){

Log.d(tag, "canvas is not null");

//每次绘画都给画布重新上色以覆盖上一次绘画的文本----刷屏

canvas.drawRGB(0, 0, 0);

canvas.drawText("GAME", textX, textY, paint);

surfaceHolder.unlockCanvasAndPost(canvas);

}else{

Log.d(tag, "canvas is null");

}

}

@Override

publicboolean onTouchEvent(MotionEvent event)

{

Log.d(tag,"onTouchEvent");

//获取滑动的坐标

textX = ( int ) event.getX();

textY = ( int ) event.getY();

returntrue ;

}

}

其实刷屏方式不止代码中用到的一种方法,还有以下三种:

1)、每次绘图都绘制一个等同于屏幕大小的图形覆盖在画布上。

publicvoid myDraw(){

Log.d(tag, "myDraw");

canvas = surfaceHolder.lockCanvas();

if(canvas != null){

Log.d(tag, "canvas is not null");

//每次绘画都给画布重新上色以覆盖上一次绘画的文本----刷屏

canvas.drawRect(0,0,this.getWith(),this.getHeight(),paint);

Paint paintText = new Paint();

paintText.setColor(Color.WHITE);

canvas.drawText("GAME", textX, textY, paintText);

surfaceHolder.unlockCanvasAndPost(canvas);

}else{

Log.d(tag, "canvas is null");

}

}

2)、每次绘图之前,在画布上填充一种颜色。

publicvoid myDraw(){

Log.d(tag, "myDraw");

canvas = surfaceHolder.lockCanvas();

if(canvas != null){

Log.d(tag, "canvas is not null");

//每次绘画都给画布重新上色以覆盖上一次绘画的文本----刷屏

canvas.drawColor(Color.BLACK);

canvas.drawText("GAME", textX, textY, paint);

surfaceHolder.unlockCanvasAndPost(canvas);

}else{

Log.d(tag, "canvas is null");

}

}

3)、每次绘图之前,绘制一张等同于屏幕大小的图片覆盖在画布上。

其实不管那种方法其原理都是在绘制画布之前对画布进行一次整体覆盖。就像小时候喜欢在书页角上画走动的小人一样,每翻过一页都将上一页覆盖掉,速度快了看起来就连贯了,其实这也是动画的原理。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章标题:android游戏开发之SurfaceView-创新互联
分享地址:http://hbruida.cn/article/dghjgs.html