`

Flex地图分块加载的实现

阅读更多

在家上网赚钱更容易

首先我们确定几个关键点:
窗口大小: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);

明白了上面的这些 下面这个类 相信大家都能看明白

  1. package com.heptaFish.common.game.map.layers
  2. {
  3. import com.heptaFish.common.config.Config;
  4. import com.heptaFish.common.core.BaseDisplayObject;
  5. import com.heptaFish.common.game.map.impl.GameMap;
  6. import com.heptaFish.common.hack.HeptaFishGC;
  7. import com.heptaFish.common.loader.impl.ImageLoader;
  8. import com.heptaFish.common.map.impl.HashMap;
  9. import flash.display.Bitmap;
  10. import flash.events.Event;
  11. import flash.events.IOErrorEvent;
  12. import flash.events.ProgressEvent;
  13. import flash.geom.Point;
  14. //地图层 图片
  15. public class MapLayer extends BaseDisplayObject
  16. {
  17.   //图片读取器
  18.   private var _imageLoader:ImageLoader;
  19.   //地图图片 用于整块加载模式
  20.   private var _image:Bitmap;
  21.   //地图图片数组 用于栅格式加载地图模式
  22.   private var _imageMap:HashMap;
  23.   //小地图图片
  24.   private var _simage:Bitmap;
  25.   //
  26.   private var _map:GameMap;
  27.   private var _loadType:int;//加载类型 0:整块加载 1:栅格加载
  28.   private var _visualWidth:Number;//地图可视宽度
  29.   private var _visualHeight:Number;//地图可视高度
  30.   private var _sliceWidth:Number;//地图切割单元宽度
  31.   private var _sliceHeight:Number;//地图切割单元高度
  32.   private var _preloadX:Number;//横向预加载屏数
  33.   private var _preloadY:Number;//纵向预加载屏数
  34.   private var _loadingMap:HashMap;//正在加载的屏map
  35.   private var _waitLoadingArr:Array;//等待加载的loadermap
  36.   
  37.   private var _loadingNo:int = Config.getInt("concurrencyImageLoader");
  38.   
  39.   private var _screenImageRow:int;//一屏需要加载的横向图片数
  40.   private var _screenImageCol:int;//一屏需要加载的纵向图片数
  41.   private var _row:int;//总横向节点数
  42.   private var _col:int;//总纵向节点数
  43.   
  44.   private var _nowPlayerPointoint;//当前人物所处的屏
  45.   
  46.   public function MapLayer(map:GameMap)
  47.   {
  48.    _map = map;
  49.    _loadType = parseInt(_map.mapXML.@loadType);
  50.   }
  51.   //读取地图图片
  52.   public function load():void{
  53.    //加载小地图
  54.    var imageLoader:ImageLoader = new ImageLoader();
  55.    var fileName:String =Config.getValue("mapLib") + _map.name + "/map_s.jpg";
  56.    imageLoader.load(fileName);
  57.    imageLoader.addEventListener(Event.COMPLETE,loadSmallSuccess);
  58.    imageLoader.addEventListener(ProgressEvent.PROGRESS,loadingHandler);
  59.    imageLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
  60.    
  61.   }
  62.   //读取大地图成功
  63.   private function loadBigSuccess(evet:Event):void{
  64.    var imageLoader:ImageLoader = ImageLoader(evet.target);
  65.    var image:Bitmap = new Bitmap(imageLoader._data);
  66.    addChild(image);
  67.    if(_simage != null && _simage.parent == this){
  68.     removeChild(_simage);
  69.     _simage = null;
  70.    }
  71.    this.width = image.width;
  72.    this.height = image.height;
  73.    imageLoader.removeEventListener(Event.COMPLETE,loadBigSuccess);
  74.    imageLoader.removeEventListener(ProgressEvent.PROGRESS,loadingHandler);
  75.    imageLoader.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
  76.    imageLoader = null;
  77.    dispatchEvent(evet);
  78.    HeptaFishGC.gc();
  79.   }
  80.   //读取小地图成功
  81.   private function loadSmallSuccess(evet:Event):void{
  82.    var imageLoader:ImageLoader = ImageLoader(evet.target);
  83.    var image:Bitmap = new Bitmap(imageLoader._data);
  84.    image.width = _map.mapWidth;
  85.    image.height = _map.mapHeight;
  86.    addChild(image);
  87.    this.width = image.width;
  88.    this.height = image.height;
  89.    imageLoader.removeEventListener(Event.COMPLETE,loadSmallSuccess);
  90.    imageLoader.removeEventListener(ProgressEvent.PROGRESS,loadingHandler);
  91.    imageLoader.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
  92.    imageLoader = null;
  93.    dispatchEvent(evet);
  94.    HeptaFishGC.gc();   
  95.    switch(_loadType){
  96.     case 0://整块加载   
  97.      //加载大地图
  98.      var bfileName:String =Config.getValue("mapLib") + _map.name + "/map.jpg";
  99.      var bLoader:ImageLoader = new ImageLoader();
  100.      bLoader.load(bfileName);
  101.      bLoader.addEventListener(Event.COMPLETE,loadBigSuccess);
  102.      bLoader.addEventListener(ProgressEvent.PROGRESS,loadingHandler);
  103.      bLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
  104.      break;
  105.     case 1:
  106.      _loadingMap = new HashMap();
  107.      _imageMap = new HashMap();
  108.      _waitLoadingArr = new Array();
  109.      _visualWidth = _map.app.screen.size.x;
  110.      _visualHeight = _map.app.screen.size.y;
  111.      _sliceWidth = parseFloat(_map.mapXML.@sliceWidth);
  112.      _sliceHeight = parseFloat(_map.mapXML.@sliceHeight);
  113.      _preloadX = parseFloat(_map.mapXML.@preloadX);
  114.      _preloadY = parseFloat(_map.mapXML.@preloadY);
  115.      _screenImageRow = Math.round(_visualWidth/_sliceWidth);
  116.      _screenImageCol = Math.round(_visualHeight/_sliceHeight);
  117.      _row = Math.ceil(_map.mapWidth/_sliceWidth);
  118.      _col = Math.ceil(_map.mapHeight/_sliceHeight);
  119.      loadSliceImage(_map.initPlayerPoint);
  120.      break;
  121.     default:
  122.      break;
  123.      
  124.    }
  125.   }
  126.   
  127.   //根据player坐标读取周边指定屏数地图
  128.   private function loadSliceImage(playerPointoint):void{
  129.    var nowX:int = Math.floor(playerPoint.x/_sliceWidth);//现在所处的索引X
  130.    var nowY:int = Math.floor(playerPoint.y/_sliceHeight);//现在所处的索引Y
  131.    var nowScreenX:int = Math.floor(nowX/_screenImageRow);//现在所处的屏索引X
  132.    var nowScreenY:int = Math.floor(nowY/_screenImageCol);//现在所处的屏索引Y
  133. //   trace("nowScreenX:" + nowScreenX);
  134. //   trace("nowScreenY:" + nowScreenY);
  135.    _nowPlayerPoint = new Point(nowScreenX,nowScreenY);
  136.    loadScreenImage(nowScreenX,nowScreenY);
  137. //   removeScreenImage(nowScreenX,nowScreenY);
  138.    var startX:int = (nowScreenX - _preloadX < 0 ? 0 : nowScreenX - _preloadX);
  139.    var startY:int = (nowScreenY - _preloadY < 0 ? 0 : nowScreenY - _preloadY);
  140.    
  141.    var endX:int = (nowScreenX + _preloadX > _row ? _row : nowScreenX + _preloadX);
  142.    var endY:int = (nowScreenY + _preloadY > _col ? _col : nowScreenY + _preloadY);
  143.    
  144.    for(var xx:int = startX; xx < endX;xx++){
  145.     for(var yy:int = startY; yy < endY;yy++){
  146.      if(xx == nowScreenX && yy == nowScreenY){
  147.       continue;
  148.      }else{
  149.       loadScreenImage(xx,yy);
  150.      }
  151.     }
  152.    }
  153.   }
  154.   //加载指定屏的地图图片
  155.   private function loadScreenImage(screenX:int,screenY:int):void{
  156.    var starX:int = _screenImageRow*screenX < 0 ? 0 : _screenImageRow*screenX;
  157.    var starY:int = _screenImageCol*screenY < 0 ? 0 : _screenImageCol*screenY;
  158.    var endX:int = _screenImageRow*(screenX+1) > _row - 1 ? _row -1 : _screenImageRow*(screenX+1);
  159.    var endY:int = _screenImageCol*(screenY+1) > _col-1  ? _col-1 : _screenImageCol*(screenY+1);
  160.    for(var yy:int=starY;yy
  161.     for(var xx:int = starX;xx
  162.      var tempKey:String = yy+"_"+xx;
  163.      if(!_loadingMap.containsValue(tempKey) && !_imageMap.containsKey(tempKey)){
  164.       _waitLoadingArr.push(tempKey);
  165.      }
  166.     }
  167.     _waitLoadingArr.reverse();
  168.     loadImage();
  169.    }
  170.   }
  171.   
  172.   private function loadImage():void{
  173.    if(_waitLoadingArr.length > 0){
  174.     for(var i:int = 0;i<_loadingNo - _loadingMap.size();i++){
  175.      var key:String = _waitLoadingArr.pop();
  176.      var imageLoader:ImageLoader = new ImageLoader();
  177.      var fileName:String = Config.getValue("mapLib") + _map.name +"/" + key  + ".jpg";
  178. //     trace("fileName:" + fileName);
  179.      _loadingMap.put(imageLoader,key);
  180.      imageLoader.addEventListener(Event.COMPLETE,loadScreenImageSuccess);
  181.      imageLoader.addEventListener(ProgressEvent.PROGRESS,loadingHandler);
  182.      imageLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
  183.      imageLoader.load(fileName);
  184.     }
  185.    }
  186.   }
  187.   
  188.   //成功加载某屏的图片
  189.   private function loadScreenImageSuccess(evet:Event):void{
  190.    var imageLoader:ImageLoader = ImageLoader(evet.target);
  191.    var tempStr:String = String(_loadingMap.getValue(imageLoader));
  192.    var tempStrArr:Array = tempStr.split("_");
  193.    var yy:int = tempStrArr[0];
  194.    var xx:int = tempStrArr[1];
  195.    _loadingMap.remove(imageLoader);
  196.    var image:Bitmap = new Bitmap(imageLoader._data);
  197.    image.x = _sliceWidth*xx;
  198.    image.y = _sliceHeight*yy;
  199.    this.addChild(image);
  200.    _imageMap.put(yy+"_"+xx,image);
  201.    imageLoader.removeEventListener(Event.COMPLETE,loadScreenImageSuccess);
  202.    imageLoader.removeEventListener(ProgressEvent.PROGRESS,loadingHandler);
  203.    imageLoader.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
  204.    imageLoader = null;
  205.    loadImage();
  206.   }
  207.   //卸载指定屏的地图图片
  208.   private function removeScreenImage(screenX:int,screenY:int):void{
  209.    var startX:int = (screenX - _preloadX < 0 ? 0 : screenX - _preloadX);
  210.    var startY:int = (screenY - _preloadY < 0 ? 0 : screenY - _preloadY);
  211.    
  212.    var endX:int = (screenX + _preloadX > _row ? _row : screenX + _preloadX);
  213.    var endY:int = (screenY + _preloadY > _col ? _col : screenY + _preloadY);
  214.    var keyArr:Array = _imageMap.keys();
  215.    for(var i:int = 0;i < keyArr.length;i++){
  216.     var key:String = keyArr;
  217.     var tempStrArr:Array = key.split("_");
  218.     var yy:int = tempStrArr[0];
  219.     var xx:int = tempStrArr[1];
  220.     if(xx < startX*_screenImageRow || xx > endX * _screenImageRow || yy < startY*_screenImageCol || yy > endY*_screenImageCol){
  221.      var image:Bitmap = Bitmap(_imageMap.getValue(key));
  222.      this.removeChild(image);
  223.      image = null;
  224.      _imageMap.remove(key);
  225.     }
  226.    }
  227.    HeptaFishGC.gc();
  228.   }
  229.   
  230.   //检查是否需要加载
  231.   public function checkLoad(pointoint):void{
  232.    var nowX:int = Math.floor(point.x/_sliceWidth);//现在所处的索引X
  233.    var nowY:int = Math.floor(point.y/_sliceHeight);//现在所处的索引Y
  234.    var nowScreenX:int = Math.floor(nowX/_screenImageRow);//现在所处的屏索引X
  235.    var nowScreenY:int = Math.floor(nowY/_screenImageCol);//现在所处的屏索引Y
  236.    if(nowScreenX != _nowPlayerPoint.x || nowScreenY != _nowPlayerPoint.y){
  237.     loadSliceImage(point);
  238.    }
  239.    
  240.   }
  241. }
  242. }
  243. 在家上网赚钱更容易

分享到:
评论
1 楼 hyx0914 2011-12-13  
有源代码打包下载的吗?

相关推荐

    Flex地图编辑技术

    Flex地图编辑技术主要涉及到使用Adobe Flex这一开源框架与Esri的ArcGIS Server相结合,实现对地理信息系统的交互式编辑功能。在GIS应用中,地图编辑是核心部分,它允许用户创建、修改和管理地理空间数据。下面将详细...

    flex 百度地图 实例下载

    8. **性能优化**:在大规模数据展示或复杂交互时,需要注意性能优化,如延迟加载、分块加载地图数据,以及合理设计数据结构和算法。 9. **响应式设计**:考虑不同设备和屏幕尺寸,确保应用在手机、平板和桌面等不同...

    arcgis api for flex 引用天地图地图

    7. **优化性能**:在处理大量数据或复杂操作时,合理利用缓存、分块加载和异步处理等技术可以提高应用的性能。 在实际开发过程中,可能还需要关注一些问题,比如地图的版权显示、兼容性测试、错误处理等。通过不断...

    flex 中图片做地图

    在这种场景下,"flex 中图片做地图"通常指的是利用Flex技术进行地图分块加载,以提高应用性能和用户体验。地图分块加载是一种优化策略,通过只加载用户可视区域内的地图部分,降低内存占用并加快加载速度。 首先,...

    flex地图应用开发教程及项目源代码

    此外,你还可以学习到如何优化性能,如延迟加载、分块加载大图层,以及如何利用缓存提高用户体验。 总的来说,"flex地图应用开发教程及项目源代码"提供了一个学习Flex地图开发的宝贵资源。通过实践这些示例和代码,...

    flex as3游戏寻路源码+详解

    在Flex中,可以使用Loader类加载地图图像,并通过BitmapData对象处理图像的切片和拼接,以实现地图分块加载。 2. **地图分块加载**:地图分块加载是一种优化技术,尤其适用于大型地图。它只加载当前可视区域的地图...

    flex 电子地图 实例

    这可以通过分块加载地图数据、使用瓦片地图服务、以及合理设置地图的可见范围来实现。 8. **自定义样式和皮肤**:Flex允许开发者通过CSS或MXML来定制`Map`组件的外观,包括地图控件的样式、颜色、字体等,以匹配...

    Flex实现goole地图程序

    7. **优化性能**:在处理大量数据时,考虑使用分块加载(Clustering)技术,以提高地图的性能和用户体验。这通常涉及到对地图覆盖物(Overlays)进行管理和分组。 8. **部署与测试**:最后,将你的Flex应用打包成...

    tianditu.zip_arcgis切片_flex_天地图

    天地图的切片服务是一种将地图分块存储的方式,每个小块称为一个切片,通常为JPEG或PNG格式。这种分块方式有利于提高地图加载速度和优化网络传输。在ArcGIS for Flex中,我们可以通过扩展类来定制对这些切片的读取和...

    flex4开发的模E都市地图

    4. **数据加载与异步通信**:E都市地图的图像通常是分块加载的,这需要用到HTTPService或WebService组件进行异步数据请求。开发者可能使用URLLoader类加载图片,并通过BitmapData对象将图片加载到舞台上。 5. **...

    基于flex的arcengine基础教程的实例

    我们将讨论如何合理缓存地图数据,使用分块加载技术,以及优化地图渲染策略,提高应用的响应速度和用户体验。 在学习过程中,你可能需要用到像Flex Builder这样的开发环境,以及ArcGIS Desktop和ArcGIS Server来...

    ArcGIS-Flex.rar_FLEX ARCGIS_flex

    7. **缓存和性能优化**:对于大规模数据和高并发场景,ArcGIS for Flex支持离线缓存和分块加载策略,以提高应用的性能和响应速度。 8. **地图渲染和样式控制**:通过设置Symbology,开发者可以自定义地图的颜色、...

    arcgis_flex 1.2

    8. **性能优化**:通过缓存机制和分块加载策略,提高了大范围地图和大量数据的加载速度。 9. **扩展和自定义**:ArcGIS Flex API 1.2允许开发者根据需求自定义控件和样式,扩展功能以满足特定应用的需求。 10. **...

    Flex ArcGis 点聚合 flex4版本

    6. **异步处理和性能优化**:处理大量点数据可能影响应用性能,因此需要考虑异步加载和分块加载策略。同时,通过缓存和批处理技术,可以减少网络通信和计算负载。 7. **数据可视化**:为了使聚合效果更直观,可以...

    arcgis-viewer-flex-3.7-src

    7. **性能优化**:源代码还包含了性能优化的策略,例如缓存机制、异步加载和分块加载等,这可以帮助开发者在处理大量数据或高并发访问时提升应用性能。 通过对"arcgis-viewer-flex-3.7-src"源码的深入学习,开发者...

    ARCGIS Flex API 2.4版本 离线帮助

    1. 分块加载:为了提高大地图的加载速度,API支持分块加载,只加载可视区域内的数据。 2. 图层缓存:预加载常用图层或数据,减少网络延迟。 3. 图层透明度控制:优化内存使用,通过调整图层透明度减少同时加载的图层...

    flex 图片查看器

    可以采用分块加载或懒加载策略,只加载当前可视区域的图片部分,提高应用的响应速度。 7. **用户体验**:为了提供良好的用户体验,还需要考虑图片加载的动画效果、缩放平滑性、边界检测等细节,确保用户在操作过程...

    load shape

    以GeoFlex为例,这个库提供了读取和解析Shapefile的功能,并能将其数据映射到Flex地图控件上的图形对象。 1. **集成GeoFlex库**:首先,你需要将GeoFlex库导入到你的Flex项目中,可以通过添加库的SWC文件到类路径,...

    FLEX WebGame源码

    地图通常以分块的形式存储,玩家移动到新区域时,只加载相应区块的地图数据,从而实现平滑的用户体验。 “MapDemo”作为压缩包内的一个文件,很可能是演示地图动态加载功能的示例代码。开发者可以通过分析MapDemo的...

    Arcgis Api for flex 3.6

    - **动态图层的分块加载**:减少初始加载时间,提高用户体验。 - **LOD(级别细节)管理**:根据地图缩放级别自动调整图层的细节水平。 8. **地图服务的扩展**: - **WMS与WFS兼容**:ArcGIS API还可以与其他...

Global site tag (gtag.js) - Google Analytics