/// <summary> /// 加载列表排序函数 /// </summary> /// <param name="loaderItemA"></param> /// <param name="loaderItemB"></param> /// <returns></returns> private int LoadListSortFunc(MapLoaderItem loaderItemA, MapLoaderItem loaderItemB) { float distAX = Math.Abs(loaderItemA.mapX - _center.x); float distAY = Math.Abs(loaderItemA.mapY - _center.y); float distBX = Math.Abs(loaderItemB.mapX - _center.x); float distBY = Math.Abs(loaderItemB.mapY - _center.y); float distA = distAX > distAY ? distAX : distAY; float distB = distBX > distBY ? distBX : distBY; if (distA > distB) { return(-1); } else if (distA < distB) { return(1); } else if (distAY > distBY) { return(-1); } else if (distAY < distBY) { return(1); } else { return(0); } }
/// <summary> /// 加载地图切片 /// </summary> private void LoadNext() { while (_loadCount < MapSetting.maxLoadCount) { if (_loadList.Count <= 0) { return; } int index = _loadList.Count - 1; MapLoaderItem loaderItem = _loadList[index]; _loadList.RemoveAt(index); _loadDict.Remove(loaderItem.tile); string url = _mapVo.GetTileRelativePath(loaderItem.tile.x, loaderItem.tile.y); if (!_loadingDict.ContainsKey(url)) { MapLoader loader = _loaderPool.Get(); _loadingDict.Add(url, loader); loader.loaderItem = loaderItem; loader.completeCallback = OnTileComplete; loader.errorCallback = OnTileError; loader.StartLoad(url); _loadCount++; } } }
/// <summary> /// 地图切片加载完成 /// </summary> /// <param name="loader"></param> private void OnTileComplete(MapLoader loader) { TextureAsset asset = loader.loader.asset as TextureAsset; if (asset != null) { MapLoaderItem loadItem = loader.loaderItem; if (loadItem.mapId == _mapVo.id) { MapTile tile = loadItem.tile; asset.texture.wrapMode = TextureWrapMode.Clamp; // 资源存入缓存 _textureDict[tile] = asset; // 资源保存本地 //App.fileManager.WriteFilePersistentAsync(loader.loader.urlRelative, loader.loader.bytes, false); // 渲染图片 if (_renderTiles.ContainsKey(tile)) { MapBlock block = GetBlock(tile.x - _currentTileX, tile.y - _currentTileY); block.SetTexture(asset.texture); _renderTiles.Remove(tile); if (_loadDict.Contains(tile)) { _loadList.Remove(loadItem); _loadDict.Remove(tile); } } } else { asset.Dispose(); } } // 移除加载字典 if (_loadingDict.ContainsKey(loader.loader.urlRelative)) { _loadingDict.Remove(loader.loader.urlRelative); } _loaderPool.Release(loader); // 继续加载 _loadCount--; LoadNext(); }
/// <summary> /// 渲染 /// </summary> /// <param name="forced"></param> public void Render(bool forced = false) { int startX = (int)(_leftTop.x / _mapVo.tileWidth); int startY = (int)(_leftTop.y / _mapVo.tileHeight); _control.SetBlockPosition(new Vector3(_leftTop.x - _leftTop.x % _mapVo.tileWidth, leftTop.y - _leftTop.y % _mapVo.tileHeight)); // 判断是否需要重绘 if (_currentTileX == startX && _currentTileY == startY && forced == false) { return; } _currentTileX = startX; _currentTileY = startY; // 清理渲染列表 _renderTiles.Clear(); // 计算渲染列表 int maxTileX = startX + _tileX; int maxTileY = startY + _tileY; //int fixedStartX = startX > 0 ? startX : 0; //int fixedStartY = startY > 0 ? startY : 0; for (int y = startY; y < maxTileY; y++) { for (int x = startX; x < maxTileX; x++) { int blockX = x - _currentTileX; int blockY = y - _currentTileY; // block不存在 MapBlock block = GetBlock(blockX, blockY); if (block == null) { continue; } // 坐标超过范围则清空纹理 if (x < 0 || x > _mapVo.maxTileX || y < 0 || y > _mapVo.maxTileY) { block.SetTexture(null); continue; } // 从内存中获取纹理 TextureAsset asset; if (_textureDict.TryGetValue(new MapTile(x, y), out asset)) { // 内存中存在纹理 block.SetTexture(asset.texture); continue; } else { // 内存中不存在纹理 block.SetTexture(null); // 放入加载队列 MapLoaderItem loaderItem = new MapLoaderItem(); loaderItem.mapId = _mapVo.id; loaderItem.tile = new MapTile(x, y); loaderItem.mapX = x * _mapVo.tileWidth; loaderItem.mapY = y * _mapVo.tileHeight; _renderTiles[loaderItem.tile] = loaderItem; } } } if (MapSetting.autoClearTexture) { // 移除缓存 _globalMapTileList.Clear(); foreach (var v in _textureDict) { MapTile tile = v.Key; if (tile.x < startX || tile.x >= maxTileX || tile.y < startY || tile.y >= maxTileY) { _globalMapTileList.Add(tile); } } foreach (MapTile tile in _globalMapTileList) { TextureAsset asset = _textureDict[tile]; _textureDict.Remove(tile); asset.Dispose(); } } // 移除加载队列 for (int i = _loadList.Count - 1; i >= 0; i--) { MapLoaderItem loaderItem = _loadList[i]; if (_renderTiles.ContainsKey(loaderItem.tile) == false) { _loadList.RemoveAt(i); _loadDict.Remove(loaderItem.tile); } } // 显示切片 foreach (var v in _renderTiles) { // 判断是否需要加载 if (_loadDict.Contains(v.Key) == false) { _loadList.Add(v.Value); _loadDict.Add(v.Key); } } // 加载 if (_loadList.Count > 0) { _loadList.Sort(LoadListSortFunc); LoadNext(); } }