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

1)       常用的绘制图像的方法

a)        View的invalidate()
直接调用onDraw()绘图

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

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

2)       SurfaceView

a)        说明

                                      i.             它支持OpenGL ES,2D和3D效果都能实现

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

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

b)       实现

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

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

3)       常见问题

a)        双缓存问题

                                      i.             原理:由于内存中存在着两个绘图区,每绘一次,显示其中一个绘图区(交替出现)

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

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

2. 例程

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

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

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

4)       核心代码及说明

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

(转载请注明出处)
posted on 2012-03-06 17:01  xieyan0811  阅读(20)  评论(0编辑  收藏  举报