地图分块加载的实现
2011-12-30 14:52
232 查看
首先我们确定几个关键点:
窗口大小: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);
窗口大小: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); } } } }
相关文章推荐
- Flash网页游戏中实现的地图分块加载(卡马克地图)
- 关于分块地图加载缩放前后重新选择地图索引的思路
- MVC中使用Echart后台加载数据 实现饼图、折线图、全国地图数据,单击双击事件等
- cocos2dx 大地图分块加载的研究(初)
- flash地图图片分块加载
- 如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
- Android 加载百度地图 实现在地图上新增一个点
- arcgis runtime for iOS100.0 加载地图 按坐标加载点 objective-c实现
- 大地图分块加载
- ArcGIS API For Javascript之地图基本加载与显示,地图切换、缩放、定位、比例尺、鹰眼图、坐标显示、查询搜索功能实现
- 大地图分块加载处理
- 四个步骤实现在ESRI ArcMap中加载17.6G离线卫星地图的方法
- 虚幻4中异步加载Pak中地图实现场景切换的动态加载画面
- 用AjaxMethod 方法实现动态加载地图
- ArcEngine实现动态加载地图
- 游戏地图分块加载资源篇——切图工具
- MVC中使用Echart后台加载数据 实现饼图、折线图、全国地图数据,单击双击事件等
- ArcGIS for Android实现地图加载、放大缩小及定位功能
- 四个步骤实现在ESRI ArcMap中加载17.6G离线卫星地图的方法
- 室外大场景渲染技术研究与实现 游戏地图加载