为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

第六章 SurfaceView动画

2018-09-11 6页 doc 26KB 9阅读

用户头像

is_593420

暂无简介

举报
第六章 SurfaceView动画第六章 SurfaceView动画 前 面介绍的内容,还是比较简单的,应用这些知识,可以完成一些非实时游戏,比如井字棋等,或者一些画面刷新不是很频繁、实时性不强的游戏,比如我们前面做的 扫雷。但是我们的目标是坦克大战,对操作的实时性要求比较高,更有很多的NPC需要处理,绘图的工作量也很大,所以我们要用一个新的视图类 SurfaceView代替View来完成显示工作。SurfaceView与View有一些不同,但是我们只用其中的一个特性:在主线程之外的线程中向 屏幕上绘图。这样就可以避免在画图任务繁重的时候造成主线程阻塞,从而提...
第六章 SurfaceView动画
第六章 SurfaceView动画 前 面介绍的内容,还是比较简单的,应用这些知识,可以完成一些非实时游戏,比如井字棋等,或者一些画面刷新不是很频繁、实时性不强的游戏,比如我们前面做的 扫雷。但是我们的目标是坦克大战,对操作的实时性要求比较高,更有很多的NPC需要处理,绘图的工作量也很大,所以我们要用一个新的视图类 SurfaceView代替View来完成显示工作。SurfaceView与View有一些不同,但是我们只用其中的一个特性:在主线程之外的线程中向 屏幕上绘图。这样就可以避免在画图任务繁重的时候造成主线程阻塞,从而提高程序的反应速度。 首先让我们重新定义一个GameView 类,让他继承自SurfaceView,并且要实现SurfaceHolder.Callback接口。为什么要实现Callback接口呢?因为使用 SurfaceView有一个原则,所有的绘图工作必须得在Surface被创建之后才能开始(Surface—表面,这个概念在图形编程中常常被提到。 基本上我们可以把它当作显存的一个映射,写入到Surface的内容可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface被 销毁之前必须结束。所以Callback中的surfaceCreated和surfaceDestroyed就成了绘图处理代码的边界。我们直接让 GameView类实现Callback接口,使程序更简洁一些。 GameView被创建,并补充了构造函数之后就是这个样子(创建类和添加构造函数的方法前面有介绍哦) package org.yexing.android.games.tank; import android.content.Context; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.SurfaceHolder.Callback; public class GameView extends SurfaceView implements Callback { public GameView(Context context) { super(context); // TODO Auto-generated constructor stub } public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub } public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub } } 这 里我们有看到了一个新的类SurfaceHolder,我们权且把它当作一个Surface的控制器,用它来操作Surface。因为我们现在还不需要直 接操作Surface,所以我们不做深入讲解。而唯一要使用的是SurfaceHolder.addCallback,即为SurfaceHolder添 加回调函数。原因前面我已经说明了,方法如下: public GameView(Context context) { super(context); // TODO Auto-generated constructor stub getHolder().addCallback(this); } 现在我们可以运行一下,跟第一次使用View一样,界面上什么也没有。因为我们还没有编写绘图的代码嘛。 前面说过,我们之所以使用SurfaceView代替View,是因为SurfaceView可以在主线程之外的线程中进行绘图操作,从而提高界面的反应速度。下面我们要做的就是创建一个用来绘图的线程。不过在这之前我们可以先了解一些关于游戏循环的知识: 我 们知道,一般的应用程序是用户驱动的,就是用户操作了,程序再来响应。而我们的游戏呢,不管用户有没有操作,都会有一些变化,最明显的就是npc会移动、 发生世界事件等。因此,我们可以说,游戏程序在一个无限循环当中,我们就把它叫做游戏循环。那么在游戏循环中要做哪些工作呢?让我们用一个图来说明游 戏循环的过程: 这只是我们假设的流程,不同的游戏肯定会都有些变化。而且细节上会有更多的差别。 了解了游戏循环,下面的工作就是建立一个线程,线程中包含一个游戏循环,在游戏循环中更新游戏的各种数据,并根据这些数据将游戏画面绘制在Surface上最终显示给玩家。 创 建线程的方法很简单,我们不需要知道Thread的很多高级特性。只需要知道,在线程中完成具体的工作需要重载run()函数。线程通过start()函 数启动。然后就会执行run()函数中的内容,run()函数执行结束后线程就会终止。因此我们将游戏循环放在run()函数中。通过start()启动 循环,并通过适当的方式结束循环进而结束整个线程。还要注意一点,所有对Surface的操作都必须要保证同步,因此我们会使用Synchronized 关键字,同步SurfaceHolder。 增加了GameThread后的代码如下: public class GameView extends SurfaceView implements Callback { public static final String tag = "GameView"; //声明GameThread类实例 GameThread gameThread; public GameView(Context context) { super(context); // TODO Auto-generated constructor stub //获取SurfaceHolder SurfaceHolder surfaceHolder = getHolder(); //添加回调对象 surfaceHolder.addCallback(this); //创建GameThread类实例 gameThread = new GameThread(surfaceHolder); } public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub Log.v(tag, "surfaceChanged"); } public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub Log.v(tag, "surfaceCreated"); //启动gameThread gameThread.start(); } public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub Log.v(tag, "surfaceDestroyed"); //通过结束run()函数的方法结束gameThread,详见GameThread类的定义 gameThread.run = false; } /** * GameThread的定义 * @author xingye * */ class GameThread extends Thread { SurfaceHolder surfaceHolder; //run()函数中控制循环的参数。 boolean run = true; public GameThread(SurfaceHolder surfaceHolder) { this.surfaceHolder = surfaceHolder; } @Override public void run() { // TODO Auto-generated method stub int i = 0; while(run) { Log.v(tag, "GameThread"); Canvas c = null; try { synchronized (surfaceHolder) { //我们在屏幕上显示一个计数器,每隔1秒钟刷新一次 c = surfaceHolder.lockCanvas(); c.drawARGB(255, 255, 255, 255); c.drawText("" + i++, 100, 100, new Paint()); Thread.sleep(1000); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (c != null) { surfaceHolder.unlockCanvasAndPost(c); } } } } } } 运行程序看一下效果
/
本文档为【第六章 SurfaceView动画】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索