- 前言
Android游戏在App Market上是最火的一类应用,但是和iPhone游戏相比,Android游戏还有很大差距,除了与Android手机的市场占有率不高有关以外,Android游戏开发的资料较少也是制约因素之一。本系列教程将从实现Android SDK带的lunarLander游戏的实现为主轴,实现一个完整的Android游戏引擎。当然这个游戏引擎没有使用OpenGL ES 2.0中的功能,也不能处理3D游戏,但是对于一个小型Android游戏开发应该已经足够了。
在本集中,我将介绍Android中的图像绘制技术,这个是Android游戏的基础。
- 游戏视图
首先需要设计游戏的显示界面类A2dGameView(由于我们要实现一个完整的Android游戏引擎,A2d前缀代表使用Android本身图形类的游戏引擎,Egl2d是OpenGL ES 2D游戏引擎,Egl3d是OpenGL ES 3D游戏引擎),具体代码如下所示:
package com.bjcic.fage.a2d;
import com.bjcic.fage.game.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class A2dGameView extends SurfaceView implements SurfaceHolder.Callback {
public A2dGameView(Context context) {
super(context);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
renderThd = new A2dRenderThd(getHolder(), this);
}
@Override
public void onDraw(Canvas canvas) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(bmp, 10, 10, null);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
renderThd.setIsRunning(true);
renderThdWrapper = new Thread(renderThd);
renderThdWrapper.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
boolean retry = true;
renderThd.setIsRunning(false);
while (retry) {
try {
renderThdWrapper.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private A2dRenderThd renderThd = null;
private Thread renderThdWrapper = null;
}
其中需要指出的该类的onDraw函数,该函数在屏幕(10,10)坐标出绘制一个bmp图片。
在public void surfaceCreated(SurfaceHolder arg0) 函数中,初始化并启动界面渲染类,界面渲染类启动界面渲染线程,完成界面的绘制工作。
在surfaceDestroyed(SurfaceHolder arg0)函数中停止界面渲染线程。
- 渲染线程
package com.bjcic.fage.a2d;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class A2dRenderThd implements Runnable {
public A2dRenderThd(SurfaceHolder surfHolder, A2dGameView gameView) {
this.surfHolder = surfHolder;
this.gameView = gameView;
}
@Override
public void run() {
// TODO Auto-generated method stub
Canvas canvas = null;
while (isRunning) {
canvas = null;
try {
canvas = surfHolder.lockCanvas();
synchronized (surfHolder) {
gameView.onDraw(canvas);
}
} finally {
if (canvas != null) {
surfHolder.unlockCanvasAndPost(canvas);
}
}
}
}
public void setIsRunning(boolean isRunning) {
this.isRunning = isRunning;
}
private SurfaceHolder surfHolder = null;
private A2dGameView gameView = null;
private boolean isRunning = true;
}
由上面代码可以看出,渲染线程是一个无形循环,每次循环中调用GameView来实现界面的绘制。
最后是在启动类中加载游戏视图,代码如下所示:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//setContentView(R.layout.main);
setContentView(new A2dGameView(this));
}
- 总结
在本集中,我描述了游戏视图的绘制方法,以及游戏主循环的雏形。