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

地图缓冲绘制算法

浏览 5854 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-03-05  
package redduke.ui;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
/**
 * 地图缓冲类,生成一个和屏幕显示大小相同的缓冲图片,根据地图移动,尽量少的重绘地图
 * @author redduke
 */
public abstract class BufferedImage{
	protected int x,y;// x,y坐标
	protected int w,h;// 宽度,高度
	protected int offx,offy;// 偏移量
	protected int Offx,Offy;// 当前偏移量
	protected Image buf;//缓冲图片
	protected Graphics bg;//缓冲绘制对象
	/**
	 * 构造方法,指定宽度和高度
	 */
	public BufferedImage(int w,int h) {
		this.w=w;
		this.h=h;
		buf=Image.createImage(w,h);
		bg=buf.getGraphics();
		bufferImpl(0,0,w,h);
	}
	/**
	 * 绘制方法,供Canvas的绘制调用
	 * @param g
	 */
	public final void paint(Graphics g) {
		int clipX=g.getClipX();
		int clipY=g.getClipY();
		int clipW=g.getClipWidth();
		int clipH=g.getClipHeight();
		int tempx=offx%w;
		int tempy=offy%h;
		{
			g.clipRect(x,y,w-tempx,h-tempy);
			g.drawImage(buf,x-tempx,y-tempy,0);
			g.setClip(clipX,clipY,clipW,clipH);
		}		
		if(tempx>0)
		{
			g.clipRect(x-tempx+w,y,tempx,h-tempy);
			g.drawImage(buf,x-tempx+w,y-tempy,0);
			g.setClip(clipX,clipY,clipW,clipH);
		}		
		if(tempy>0)
		{
			g.clipRect(x,y-tempy+h,w-tempx,tempy);
			g.drawImage(buf,x-tempx,y-tempy+h,0);
			g.setClip(clipX,clipY,clipW,clipH);
		}		
		if(tempx>0 && tempy>0)
		{
			g.clipRect(x-tempx+w,y-tempy+h,tempx,tempy);
			g.drawImage(buf,x-tempx+w,y-tempy+h,0);
			g.setClip(clipX,clipY,clipW,clipH);
		}		
	}
	/**
	 * 地图滚动
	 */
	public final void scroll(int dx,int dy)
	{
		Offx+=dx;
		Offy+=dy;
	}
	/**
	 * 滚动地图到指定坐标
	 */
	public final void scrollTo(int x,int y)
	{
		this.Offx=x;
		this.Offy=y;
	}
	/**
	 * 缓冲地图
	 * @param force,强制重新缓冲
	 */
	public final void buffer(boolean force)
	{
		/*
		 * 地图无变化,
		 */
		if(!force && Offx==offx && Offy==offy) return;
		/*
		 * 地图变化较大,则全部重新缓冲
		 */
		if(force || Math.abs(Offx-offx)>=w || Math.abs(Offy-offy)>=h)
			bufferImpl(0,0,w,h);
		else
		{
			int minX=Math.min(Offx%w,offx%w);
			int maxX=Math.max(Offx%w,offx%w);
			int minY=Math.min(Offy%h,offy%h);
			int maxY=Math.max(Offy%h,offy%h);
			if(Offx/w==offx/w && Offy/h==offy/h)
			{
				bufferImpl(minX,0,maxX-minX,minY);
				bufferImpl(0,minY,w,maxY-minY);
				bufferImpl(minX,maxY,maxX-minX,h-maxY);
			}
			else if(Offx/w==offx/w)
			{
				bufferImpl(0,0,w,minY);
				bufferImpl(minX,minY,maxX-minX,maxY-minY);
				bufferImpl(0,maxY,w,h-maxY);
			}
			else if(Offy/h==offy/h)
			{
				bufferImpl(0,0,minX,h);
				bufferImpl(minX,minY,maxX-minX,maxY-minY);
				bufferImpl(maxX,0,w-maxX,h);
			}
			else
			{
				bufferImpl(0,0,w,minY);
				bufferImpl(0,minY,minX,maxY-minY);
				bufferImpl(maxX,minY,w-maxX,maxY-minY);
				bufferImpl(0,maxY,w,h-maxY);
			}
		}
	}
	/*
	 * 缓冲具体实现,调用具体绘制方法 drawBuffer
	 */
	private final void bufferImpl(int clipX,int clipY,int clipW,int clipH)
	{
		if(clipW<=0 || clipH<=0) return;
		int tempx=Offx%w;
		int tempy=Offy%h;
		// A
		{
			bg.translate(-bg.getTranslateX(),-bg.getTranslateY());
			bg.translate(-(Offx-tempx),-(Offy-tempy));
			bg.setClip(Offx,Offy,w-tempx,h-tempy);			
			drawBuffer(bg);
		}
		// B
		if(tempx>0)
		{
			bg.translate(-bg.getTranslateX(),-bg.getTranslateY());
			bg.translate(-(Offx-tempx+w),-(Offy-tempy));
			bg.setClip(Offx-tempx+w,Offy,tempx,h-tempy);
			drawBuffer(bg);
		}		
		// C
		if(tempy>0)
		{
			bg.translate(-bg.getTranslateX(),-bg.getTranslateY());
			bg.translate(-(Offx-tempx),-(Offy-tempy+h));			
			bg.setClip(Offx,Offy-tempy+h,w-tempx,tempy);
			drawBuffer(bg);
		}
		// D
		if(tempx>0 && tempy>0)
		{
			bg.translate(-bg.getTranslateX(),-bg.getTranslateY());
			bg.translate(-(Offx-tempx+w),-(Offy-tempy+h));
			bg.setClip(Offx-tempx+w,Offy-tempy+h,tempx,tempy);
			drawBuffer(bg);
		}		
		offx=Offx;
		offy=Offy;
	}
	/**
	 * 缓冲绘制,子类实现
	 */
	protected abstract void drawBuffer(Graphics g);
}
   发表时间:2007-03-05  
缓冲绘制原理示意图
  • 大小: 29.3 KB
0 请登录后投票
论坛首页 移动开发技术版

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