Android游戏中动画的实现
Android 游戏中动画的实现
#移动开发 #Android
1.介绍
对于游戏等对界面要求较高的程序,一般需要控制 View
中的具体图像显示(如动画功能)下面介绍实现此功能常用的 SurfaceView
控制。
- 常用的绘制图像的方法
View 的 invalidate()
直接调用 onDraw() 绘图View 的 postInvalidate()
通过消息调用 onDraw() 绘图SurfaceView
画布的重绘是由一个单独的线程处理,所以不会阻塞,专门为游戏而实现的。
- SurfaceView
- 说明
它支持 OpenGL ES,2D 和 3D 效果都能实现
在游戏线程中画图(而非主线程):冻结画布 ->在画布上绘图 ->解冻画布 ->次画布内容绘制到屏幕上
采用双缓存,避免屏幕闪烁
- 实现
需要实现 Callback 接口,它可以用来监听 SurfaceView 的状态,而从开启和销毁游戏主线程
需要实现 Runnable 接口, 它实现了游戏绘图线程
- 常见问题
- 双缓存问题
原理:由于内存中存在着两个绘图区,每绘一次,显示其中一个绘图区 (交替出现)
问题:容易出现以下问题:有时只清除了其中一个绘图区,造成了画面叠加。只绘制了部分图像,与之前部分出现叠加。
解决方法::每次清屏后再画 (canvas.drawColor(Color.BLACK))
2.例程
功能
使用 SurfaceView 的方式在控件中实现动画关键字
Android, SurfaceView, 动画,游戏可从此处下载可独立运行的代码
[http://download.csdn.net/detail/xieyan0811/4117465
](http://download.csdn.net/detail/xieyan0811/4117465)
- 核心代码及说明
package com.demo.game;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.content.Context;
import android.util.AttributeSet;
public class GameView extends SurfaceView implements Callback,Runnable {
private boolean mIsRunning= false;
private Canvas mCanvas =null;
private SurfaceHoldermSurfaceHolder = null;
private Thread mThread =null;
private Paint mPaint =null;
private int mY = 0;
public GameView(Contextcontext, AttributeSet attr) {
super(context,attr);
mPaint = newPaint();
mPaint.setColor(0xffff0000);
mPaint.setStrokeWidth(3);
mPaint.setAntiAlias(true);
mSurfaceHolder =getHolder();
mSurfaceHolder.addCallback(this);
}
**public voidsurfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{ **
}
public voidsurfaceCreated(SurfaceHolder arg0) { //控制动画开始
mIsRunning = true;
mThread = newThread(this);
mThread.start();
}
public voidsurfaceDestroyed(SurfaceHolder arg0) { //控制动画结束
mIsRunning =false;
try {
mThread.join();
} catch (Exceptione) {
e.printStackTrace();
}
}
public void run() { // 绘图线程
while (mIsRunning){
try {
Thread.sleep(40);
} catch(InterruptedException e) {
e.printStackTrace();
}
synchronized(mSurfaceHolder) {
mCanvas= mSurfaceHolder.lockCanvas();
Draw();
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
}
private void Draw() { // 绘图函数
mCanvas.drawColor(Color.BLACK); // 清空 buffer,以避免图像叠加
mCanvas.drawLine(0,mY, 300, mY, mPaint);
mY++;
if (mY > 300)
mY = 0;
}
};
3.参考
[http://www.uml.org.cn/mobiledev/201110205.asp
](http://www.uml.org.cn/mobiledev/201110205.asp)
(转载请注明出处)