Android进阶-游戏开发基础
- 游戏开发的核心API
- SurfaceView
- SurfaceView是View的子类,等同于TextView、ImageView等一系列控件。
- 核心功能可以通过子线程进行界面的绘制.
绘制需要注意的内容:
所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。
由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface
- SurfaceView是View的子类,等同于TextView、ImageView等一系列控件。
- SurfaceView
- SurfaceHolder
- 对象获取:SurfaceView. getHolder();
- 用于管理Surface,核心的内容是Callback接口,我们需要依据绘图中提到的注意内容确保Callback中的方法是在UI线程中调用。
- Callback的调用:使用SurfaceHolder.addCallback(Callback callback)方法进行调用
- Thread(渲染线程)
- 在这个线程中来绘制界面
- 如上所述,线程必须要在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效
编程思想
- 游戏中每个界面可以看做一帧图片
- 开发中的每个游戏对象都是一个基本单位,一般称之为Sprite
- 一般每个Sprite都具有两个属性和一个行为
- 显示的位置
- 显示的图片
- 在画布上绘制自己
- 游戏开发中是不需要layout文件的,基本上所有的元素都是手动绘制在界面上的
基本知识
- 帧数: 一秒钟绘制多少次界面
- 当游戏的帧数大于30时,在人看来游戏的界面就是比较流畅的了(30帧和60帧并没太大区别)
- 帧数: 一秒钟绘制多少次界面
一般框架如下:
//MainActivity中,确保所有SurfaceView和SurfaceHolder.Callback在UI线程调用
//将onTouchEvent交个GameUI处理
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameUI = new GameUI(getApplicationContext());
setContentView(gameUI);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
gameUI.handleTouch(event);
return true;
}
//GameUI 自定义处理游戏界面的类
public class GameUI extends SurfaceView implements SurfaceHolder.Callback {
private RenderThread renderThread;
public GameUI(Context context) {
super(context);
holder = getHolder();
holder.addCallback(this); // 保证surfaceCreated,surfaceChanged,surfaceDestroye生效
}
//渲染线程
private class RenderThread extends Thread {
@Override
public void run() {
while (flag) {
try {
//渲染界面
drawUI();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// 绘制
public void drawUI() {
// 1. 锁定画布
Canvas lockCanvas = holder.lockCanvas();
// 绘制了整个屏幕大小的矩形,把之前绘制的全部盖在下面, 以实现每次绘制都是绘制一个新的图片
lockCanvas.drawRect(0, 0, getWidth(), getHeight(), paint);
//绘制界面元素(Sprite)
//............................
// 解锁画布并提交 如果不执行的话 上面的代码 都没有效果
holder.unlockCanvasAndPost(lockCanvas);
}
// 当Surface创建的时候调用
@Override
public void surfaceCreated(SurfaceHolder holder) {
init(); //初识化游戏界面所需元素
renderThread = new RenderThread();
flag = true;
renderThread.start();// 开启渲染线程了
}
private void init()
{
//TODO
}
// 当Surface销毁的时候调用
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
flag = false; //停止渲染线程
}
// 当Surface改变时候调用
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
/**
* 处理屏幕的点击事件
*/
public void handleTouch(MotionEvent event) {
//TODO
}
}