地图分块加载的实现

来源:互联网 发布:淘宝导航条怎么换颜色 编辑:程序博客网 时间:2024/06/06 03:37

首先我们确定几个关键点:

窗口大小:windowW:Number,windowH:Number; 指的是可视区域的大小 我们可以把他想成客户端的分别率

单位地图大小: uintPicW:Number,uintPicH:Number; 指的是你切割的地图图片的单元大小。

当前地图坐标:position:point;这里大家就可以想成是你人物的当前所处坐标

清楚了上面的几个关键点,我们再来看下面的这个图:



阴影区域就是可视区域 A、B、C、D就是切割的单元地图

我们可以很容易的求出窗口的4个点,所占的地图的索引:
x0 = position.x - windowW/2;
x1 = position.x + windowW/2;
y0 = position.y - windowH/2;
y1 = position.y + windowH/2;

mapIndexX0 = uint(x0/256);
mapIndexX1 = uint(x1/256);
mapIndexY0 = uint(y0/256);

mapIndexY1 = uint(y1/256);


package com.heptaFish.common.game.map.layers{import com.heptaFish.common.config.Config;import com.heptaFish.common.core.BaseDisplayObject;import com.heptaFish.common.game.map.impl.GameMap;import com.heptaFish.common.hack.HeptaFishGC;import com.heptaFish.common.loader.impl.ImageLoader;import com.heptaFish.common.map.impl.HashMap;import flash.display.Bitmap;import flash.events.Event;import flash.events.IOErrorEvent;import flash.events.ProgressEvent;import flash.geom.Point;//地图层 图片public class MapLayer extends BaseDisplayObject{  //图片读取器  private var _imageLoader:ImageLoader;  //地图图片 用于整块加载模式  private var _image:Bitmap;  //地图图片数组 用于栅格式加载地图模式  private var _imageMap:HashMap;  //小地图图片  private var _simage:Bitmap;  //  private var _map:GameMap;  private var _loadType:int;//加载类型 0:整块加载 1:栅格加载  private var _visualWidth:Number;//地图可视宽度  private var _visualHeight:Number;//地图可视高度  private var _sliceWidth:Number;//地图切割单元宽度  private var _sliceHeight:Number;//地图切割单元高度  private var _preloadX:Number;//横向预加载屏数  private var _preloadY:Number;//纵向预加载屏数  private var _loadingMap:HashMap;//正在加载的屏map  private var _waitLoadingArr:Array;//等待加载的loadermap    private var _loadingNo:int = Config.getInt("concurrencyImageLoader");    private var _screenImageRow:int;//一屏需要加载的横向图片数  private var _screenImageCol:int;//一屏需要加载的纵向图片数  private var _row:int;//总横向节点数  private var _col:int;//总纵向节点数    private var _nowPlayerPointoint;//当前人物所处的屏    public function MapLayer(map:GameMap)  {   _map = map;    _loadType = parseInt(_map.mapXML.@loadType);  }  //读取地图图片  public function load():void{   //加载小地图   var imageLoader:ImageLoader = new ImageLoader();   var fileName:String =Config.getValue("mapLib") + _map.name + "/map_s.jpg";   imageLoader.load(fileName);   imageLoader.addEventListener(Event.COMPLETE,loadSmallSuccess);   imageLoader.addEventListener(ProgressEvent.PROGRESS,loadingHandler);   imageLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);     }  //读取大地图成功  private function loadBigSuccess(evet:Event):void{   var imageLoader:ImageLoader = ImageLoader(evet.target);   var image:Bitmap = new Bitmap(imageLoader._data);   addChild(image);   if(_simage != null && _simage.parent == this){    removeChild(_simage);    _simage = null;   }   this.width = image.width;   this.height = image.height;   imageLoader.removeEventListener(Event.COMPLETE,loadBigSuccess);   imageLoader.removeEventListener(ProgressEvent.PROGRESS,loadingHandler);   imageLoader.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);   imageLoader = null;   dispatchEvent(evet);   HeptaFishGC.gc();  }  //读取小地图成功  private function loadSmallSuccess(evet:Event):void{   var imageLoader:ImageLoader = ImageLoader(evet.target);   var image:Bitmap = new Bitmap(imageLoader._data);   image.width = _map.mapWidth;   image.height = _map.mapHeight;   addChild(image);   this.width = image.width;   this.height = image.height;   imageLoader.removeEventListener(Event.COMPLETE,loadSmallSuccess);   imageLoader.removeEventListener(ProgressEvent.PROGRESS,loadingHandler);   imageLoader.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);   imageLoader = null;   dispatchEvent(evet);   HeptaFishGC.gc();      switch(_loadType){    case 0://整块加载         //加载大地图     var bfileName:String =Config.getValue("mapLib") + _map.name + "/map.jpg";     var bLoader:ImageLoader = new ImageLoader();      bLoader.load(bfileName);     bLoader.addEventListener(Event.COMPLETE,loadBigSuccess);     bLoader.addEventListener(ProgressEvent.PROGRESS,loadingHandler);     bLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);     break;    case 1:     _loadingMap = new HashMap();     _imageMap = new HashMap();     _waitLoadingArr = new Array();     _visualWidth = _map.app.screen.size.x;     _visualHeight = _map.app.screen.size.y;     _sliceWidth = parseFloat(_map.mapXML.@sliceWidth);     _sliceHeight = parseFloat(_map.mapXML.@sliceHeight);     _preloadX = parseFloat(_map.mapXML.@preloadX);     _preloadY = parseFloat(_map.mapXML.@preloadY);     _screenImageRow = Math.round(_visualWidth/_sliceWidth);     _screenImageCol = Math.round(_visualHeight/_sliceHeight);     _row = Math.ceil(_map.mapWidth/_sliceWidth);     _col = Math.ceil(_map.mapHeight/_sliceHeight);     loadSliceImage(_map.initPlayerPoint);     break;    default:     break;        }  }    //根据player坐标读取周边指定屏数地图  private function loadSliceImage(playerPointoint):void{   var nowX:int = Math.floor(playerPoint.x/_sliceWidth);//现在所处的索引X   var nowY:int = Math.floor(playerPoint.y/_sliceHeight);//现在所处的索引Y   var nowScreenX:int = Math.floor(nowX/_screenImageRow);//现在所处的屏索引X   var nowScreenY:int = Math.floor(nowY/_screenImageCol);//现在所处的屏索引Y//   trace("nowScreenX:" + nowScreenX);//   trace("nowScreenY:" + nowScreenY);   _nowPlayerPoint = new Point(nowScreenX,nowScreenY);   loadScreenImage(nowScreenX,nowScreenY);//   removeScreenImage(nowScreenX,nowScreenY);   var startX:int = (nowScreenX - _preloadX < 0 ? 0 : nowScreenX - _preloadX);   var startY:int = (nowScreenY - _preloadY < 0 ? 0 : nowScreenY - _preloadY);      var endX:int = (nowScreenX + _preloadX > _row ? _row : nowScreenX + _preloadX);   var endY:int = (nowScreenY + _preloadY > _col ? _col : nowScreenY + _preloadY);      for(var xx:int = startX; xx < endX;xx++){    for(var yy:int = startY; yy < endY;yy++){     if(xx == nowScreenX && yy == nowScreenY){      continue;     }else{      loadScreenImage(xx,yy);     }    }   }  }  //加载指定屏的地图图片  private function loadScreenImage(screenX:int,screenY:int):void{   var starX:int = _screenImageRow*screenX < 0 ? 0 : _screenImageRow*screenX;   var starY:int = _screenImageCol*screenY < 0 ? 0 : _screenImageCol*screenY;   var endX:int = _screenImageRow*(screenX+1) > _row - 1 ? _row -1 : _screenImageRow*(screenX+1);   var endY:int = _screenImageCol*(screenY+1) > _col-1  ? _col-1 : _screenImageCol*(screenY+1);   for(var yy:int=starY;yy<endY+1;yy++){    for(var xx:int = starX;xx<endX+1;xx++){     var tempKey:String = yy+"_"+xx;     if(!_loadingMap.containsValue(tempKey) && !_imageMap.containsKey(tempKey)){      _waitLoadingArr.push(tempKey);     }    }    _waitLoadingArr.reverse();    loadImage();   }  }    private function loadImage():void{   if(_waitLoadingArr.length > 0){    for(var i:int = 0;i<_loadingNo - _loadingMap.size();i++){     var key:String = _waitLoadingArr.pop();     var imageLoader:ImageLoader = new ImageLoader();     var fileName:String = Config.getValue("mapLib") + _map.name +"/" + key  + ".jpg";//     trace("fileName:" + fileName);     _loadingMap.put(imageLoader,key);     imageLoader.addEventListener(Event.COMPLETE,loadScreenImageSuccess);     imageLoader.addEventListener(ProgressEvent.PROGRESS,loadingHandler);     imageLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);     imageLoader.load(fileName);    }   }  }    //成功加载某屏的图片  private function loadScreenImageSuccess(evet:Event):void{   var imageLoader:ImageLoader = ImageLoader(evet.target);   var tempStr:String = String(_loadingMap.getValue(imageLoader));   var tempStrArr:Array = tempStr.split("_");   var yy:int = tempStrArr[0];   var xx:int = tempStrArr[1];   _loadingMap.remove(imageLoader);   var image:Bitmap = new Bitmap(imageLoader._data);   image.x = _sliceWidth*xx;   image.y = _sliceHeight*yy;   this.addChild(image);   _imageMap.put(yy+"_"+xx,image);   imageLoader.removeEventListener(Event.COMPLETE,loadScreenImageSuccess);   imageLoader.removeEventListener(ProgressEvent.PROGRESS,loadingHandler);   imageLoader.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);   imageLoader = null;   loadImage();  }  //卸载指定屏的地图图片  private function removeScreenImage(screenX:int,screenY:int):void{   var startX:int = (screenX - _preloadX < 0 ? 0 : screenX - _preloadX);   var startY:int = (screenY - _preloadY < 0 ? 0 : screenY - _preloadY);      var endX:int = (screenX + _preloadX > _row ? _row : screenX + _preloadX);   var endY:int = (screenY + _preloadY > _col ? _col : screenY + _preloadY);   var keyArr:Array = _imageMap.keys();   for(var i:int = 0;i < keyArr.length;i++){    var key:String = keyArr;    var tempStrArr:Array = key.split("_");    var yy:int = tempStrArr[0];    var xx:int = tempStrArr[1];    if(xx < startX*_screenImageRow || xx > endX * _screenImageRow || yy < startY*_screenImageCol || yy > endY*_screenImageCol){     var image:Bitmap = Bitmap(_imageMap.getValue(key));     this.removeChild(image);     image = null;     _imageMap.remove(key);    }   }   HeptaFishGC.gc();  }    //检查是否需要加载  public function checkLoad(pointoint):void{   var nowX:int = Math.floor(point.x/_sliceWidth);//现在所处的索引X   var nowY:int = Math.floor(point.y/_sliceHeight);//现在所处的索引Y   var nowScreenX:int = Math.floor(nowX/_screenImageRow);//现在所处的屏索引X   var nowScreenY:int = Math.floor(nowY/_screenImageCol);//现在所处的屏索引Y   if(nowScreenX != _nowPlayerPoint.x || nowScreenY != _nowPlayerPoint.y){    loadSliceImage(point);   }     }}}