Android 游戏中动画的实现

#移动开发 #Android

1.介绍
对于游戏等对界面要求较高的程序,一般需要控制 View 中的具体图像显示(如动画功能)下面介绍实现此功能常用的 SurfaceView 控制。

  1. 常用的绘制图像的方法
  1. View 的 invalidate()
    直接调用 onDraw() 绘图

  2. View 的 postInvalidate()
    通过消息调用 onDraw() 绘图

  3. SurfaceView
    画布的重绘是由一个单独的线程处理,所以不会阻塞,专门为游戏而实现的。

  1. SurfaceView
  1. 说明
  1. 它支持 OpenGL ES,2D 和 3D 效果都能实现

  2. 在游戏线程中画图(而非主线程):冻结画布 ->在画布上绘图 ->解冻画布 ->次画布内容绘制到屏幕上

  3. 采用双缓存,避免屏幕闪烁

  1. 实现
  1. 需要实现 Callback 接口,它可以用来监听 SurfaceView 的状态,而从开启和销毁游戏主线程

  2. 需要实现 Runnable 接口, 它实现了游戏绘图线程

  1. 常见问题
  1. 双缓存问题
  1. 原理:由于内存中存在着两个绘图区,每绘一次,显示其中一个绘图区 (交替出现)

  2. 问题:容易出现以下问题:有时只清除了其中一个绘图区,造成了画面叠加。只绘制了部分图像,与之前部分出现叠加。

  3. 解决方法::每次清屏后再画 (canvas.drawColor(Color.BLACK))

2.例程

  1. 功能
    使用 SurfaceView 的方式在控件中实现动画

  2. 关键字
    Android, SurfaceView, 动画,游戏

  3. 可从此处下载可独立运行的代码
    [http://download.csdn.net/detail/xieyan0811/4117465

](http://download.csdn.net/detail/xieyan0811/4117465)

  1. 核心代码及说明

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)

(转载请注明出处)