您的位置:首页 > 移动开发 > Android开发

Android游戏开发之SurfaceView动画

2010-08-18 11:34 691 查看
前面介绍的内容,还是比较简单的,应用这些知识,可以完成一些非实时游戏,比如井字棋
等,或者一些画面刷新不是很频繁、实时性不强的游戏,比如我们前面做的扫雷。但是我们
的目标是坦克大战,对操作的实时性要求比较高,更有很多的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 会移动、发生世界事件等。
因此,我们可以说,游戏程序在一个无限循环当中,我们就把它叫做游戏循环。那么在游戏
循环中要做哪些工作呢?让我们用一个流程图来说明游戏循环的过程:
获取用户输入
移动主角
移动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);
}
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐