SurfaceView做游戏开发
框架核心:
SurfaceView + SurfaceHolder + Thread
SurfaceView:是View的子类,等同于TextView、ImageView等一系列控件。
核心功能是可以通过子线程进行界面的绘制。
绘制需要注意的内容:
①所有SurfaceView和SurfaceHolder.Callback的方法都应该在主线程中调用。渲染线程(子线程)所要访问的各种变量应该作同步处理。
②由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。
绘制动画的操作:
Surface操作:
①锁定Canvas。
②在锁定的Canvas上进行界面绘制。绘制动画时,必须要先绘制背景,要不然会出现脏读(之前的动作一直显示)。
③解锁Canvas并更新界面。解锁后不执行post()或postAll()方法,界面就不会更新。
public class GameUI extends SurfaceView implements SurfaceHolder.Callback {
// 渲染线程
private RenderThread renderThread;
private boolean isRender = true;
private SurfaceHolder holder;
public GameUI(Context context) {
super(context);
holder = this.getHolder();
holder.addCallback(this);
renderThread = new RenderThread();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
renderThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isRender = false;
}
private class RenderThread extends Thread {
@Override
public void run() {
while (isRender) {
// 绘制动画
Canvas canvas = null;
try {
canvas = holder.lockCanvas();
drawUI(canvas);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
}
}
public void drawUI(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(10, 10, 300, 300, paint);
}
}
帧率
FPS即Frames per Second,每秒显示的帧数,俗称帧率。如果FPS<30的话,游戏会显得不连贯。
循环时移除List中的元素:
加强for循环遍历List的时候做移除操作,系统会报ConcurrentModificationException异常。
为了顺利移除元素,在定义List的时候,用CopyOnWriteArrayList即可。如:
List<Monkey> monkeys= new CopyOnWriteArrayList<Monkey>();
for(Monkey item : monkeys){
if(monkey.age >40)
monkeys.remove(item);
}