论坛首页 移动开发技术论坛

Android游戏开发之爆炸效果

浏览 23808 次
该帖已经被评为精华帖
作者 正文
   发表时间:2009-09-15  
vlinux 写道
是,那个代码我干掉了,我想完善点再丢上来的。总觉得真相就在手边了。

好,一起加油!
0 请登录后投票
   发表时间:2009-09-20  
回来的路上就在想,是不是对SurfaceView的理解严重有误呢。一下飞机马上就开始实现设想,终于找到解决办法了。
使用SurfaceView就命中注定了一切从头开始自己动手创建、动手释放、动手画,不应该再抱有类似AnimationDrawable一样用法的幻想。

写了一个DEMO,Kuba这类的游戏要做也只是时间问题。

作为绘画核心的DrawRunning线程
/**
 * 绘画线程
 * 
 * @author vlinux
 * 
 */
public class DrawRunning implements Runnable {

	private List<AnimationDraw> animationDraws;//所有需要画动画的集合
	private List<AnimationDraw> buffers;//缓存前台传入需要展示的动画
	private SurfaceHolder surfaceHolder;
	private boolean running;

	public DrawRunning(SurfaceHolder surfaceHolder) {
		this.surfaceHolder = surfaceHolder;
		animationDraws = new ArrayList<AnimationDraw>();
		buffers = new ArrayList<AnimationDraw>();
		running = true;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (running) {
			synchronized (surfaceHolder) {
				Canvas canvas = null;
				try {
					canvas = surfaceHolder.lockCanvas(null);
					doDraw(canvas);
				} finally {
					if (null != canvas) {
						surfaceHolder.unlockCanvasAndPost(canvas);
					}// if
				}// try
			}// syn
		}// while
	}

	private void doDraw(Canvas canvas) {
		synchronized(this) {
			//检查缓存中是否有需要加入的动画
			if( !buffers.isEmpty() ) {
				animationDraws.addAll(buffers);//加入animationDraws
				buffers.clear();//清空缓存
			}//if
		}//syn
		if( animationDraws.isEmpty() ) {
			return;//如果animationDraws里面是空的那就不用画了
		}//if
		//---这里开始绘画
		Iterator<AnimationDraw> bombIt = animationDraws.iterator();
		while (bombIt.hasNext()) {
			AnimationDraw bomb = bombIt.next();
			Bitmap nextFrame = bomb.nextFrame();
			if (null == nextFrame) {
				//下一Frame为null,说明动画序列已经结束
				//该动画已经完成,从动画集合中删除
				bombIt.remove();
				continue;//while
			}// if
			canvas.drawBitmap(nextFrame, bomb.getX(), bomb.getY(), null);
		}// while
	}

	public void addAnimationDraw(AnimationDraw bomb) {
		synchronized(this) {
			//尽量减少这个的同步响应时间,因为这个方法是前台响应的
			//多0.1秒都会直接反应到用户感知
			buffers.add(bomb);//将需要显示动画的内容加入到缓存
		}//syn
	}

	public void stopDrawing() {
		running = false;
	}

}
1 请登录后投票
   发表时间:2009-09-21  
vlinux 写道
回来的路上就在想,是不是对SurfaceView的理解严重有误呢。一下飞机马上就开始实现设想,终于找到解决办法了。
使用SurfaceView就命中注定了一切从头开始自己动手创建、动手释放、动手画,不应该再抱有类似AnimationDrawable一样用法的幻想。

写了一个DEMO,Kuba这类的游戏要做也只是时间问题。

作为绘画核心的DrawRunning线程
/**
 * 绘画线程
 * 
 * @author vlinux
 * 
 */
public class DrawRunning implements Runnable {

	private List<AnimationDraw> animationDraws;//所有需要画动画的集合
	private List<AnimationDraw> buffers;//缓存前台传入需要展示的动画
	private SurfaceHolder surfaceHolder;
	private boolean running;

	public DrawRunning(SurfaceHolder surfaceHolder) {
		this.surfaceHolder = surfaceHolder;
		animationDraws = new ArrayList<AnimationDraw>();
		buffers = new ArrayList<AnimationDraw>();
		running = true;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (running) {
			synchronized (surfaceHolder) {
				Canvas canvas = null;
				try {
					canvas = surfaceHolder.lockCanvas(null);
					doDraw(canvas);
				} finally {
					if (null != canvas) {
						surfaceHolder.unlockCanvasAndPost(canvas);
					}// if
				}// try
			}// syn
		}// while
	}

	private void doDraw(Canvas canvas) {
		synchronized(this) {
			//检查缓存中是否有需要加入的动画
			if( !buffers.isEmpty() ) {
				animationDraws.addAll(buffers);//加入animationDraws
				buffers.clear();//清空缓存
			}//if
		}//syn
		if( animationDraws.isEmpty() ) {
			return;//如果animationDraws里面是空的那就不用画了
		}//if
		//---这里开始绘画
		Iterator<AnimationDraw> bombIt = animationDraws.iterator();
		while (bombIt.hasNext()) {
			AnimationDraw bomb = bombIt.next();
			Bitmap nextFrame = bomb.nextFrame();
			if (null == nextFrame) {
				//下一Frame为null,说明动画序列已经结束
				//该动画已经完成,从动画集合中删除
				bombIt.remove();
				continue;//while
			}// if
			canvas.drawBitmap(nextFrame, bomb.getX(), bomb.getY(), null);
		}// while
	}

	public void addAnimationDraw(AnimationDraw bomb) {
		synchronized(this) {
			//尽量减少这个的同步响应时间,因为这个方法是前台响应的
			//多0.1秒都会直接反应到用户感知
			buffers.add(bomb);//将需要显示动画的内容加入到缓存
		}//syn
	}

	public void stopDrawing() {
		running = false;
	}

}

这段代码写得好,很好的思路,非常感谢!
0 请登录后投票
   发表时间:2009-09-21  
学习一下... 希望有一天开发出自己心仪的游戏
0 请登录后投票
   发表时间:2009-10-08  
一直在考虑SurfaceView的动画显示问题。看了vlinux的代码豁然开朗。顶
0 请登录后投票
   发表时间:2010-01-08  
在这里学到了不少知识,谢谢几位老大的无私奉献
0 请登录后投票
   发表时间:2010-02-09  
这位老大写得不错,多谢楼主分享
0 请登录后投票
   发表时间:2010-03-22  
那么问一下,如果屏幕上有多个地方需要上Animation,比如说飞行射击的时候,或者是多个物体碰撞的时候,这个时候应该怎么弄?View只能定义一个Animation啊?
0 请登录后投票
   发表时间:2010-07-30  
正好需要学习这方面的技术,把代码下下来看看,感谢几位老大的无私奉献。
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics