четверг, 15 марта 2012 г.

Andengine. Работа с большими спрайтами

Возникла необходимость загружать большую картинку карты мира (4740х2600) с возможностью её скроллить и зуммировать. Немного погуглив, остановился на решении, предложенным в этом топике. А именно - разбить её на несколько частей а затем загружать отдельными спрайтами:


 private ITextureRegion mWorldMapTextureRegionSW;
 private ITextureRegion mWorldMapTextureRegionSE;
 private ITextureRegion mWorldMapTextureRegionNW;
 private ITextureRegion mWorldMapTextureRegionNE;

 @Override
 public void onCreateResources() {
                //
                // Указываем путь до графики. В данном случае графика будет загружаться из папки assets/gfx/
                //
  BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
  
  // карта мира
  this.mBitmapTextureAtlasWorldMapSW = new BitmapTextureAtlas(2370, 1300, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
  this.mBitmapTextureAtlasWorldMapSE = new BitmapTextureAtlas(2370, 1300, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
  this.mBitmapTextureAtlasWorldMapNE = new BitmapTextureAtlas(2370, 1300, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
  this.mBitmapTextureAtlasWorldMapNW = new BitmapTextureAtlas(2370, 1300, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
  
  this.mWorldMapTextureRegionSW = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlasWorldMapSW, this, "world_map_sw.png", 0, 0);
  this.mWorldMapTextureRegionSE = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlasWorldMapSE, this, "world_map_se.png", 0, 0);
  this.mWorldMapTextureRegionNW = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlasWorldMapNW, this, "world_map_nw.png", 0, 0);
  this.mWorldMapTextureRegionNE = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlasWorldMapNE, this, "world_map_ne.png", 0, 0);  
  
  this.mBitmapTextureAtlasWorldMapSW.load(this.getTextureManager());
  this.mBitmapTextureAtlasWorldMapSE.load(this.getTextureManager());
  this.mBitmapTextureAtlasWorldMapNW.load(this.getTextureManager());
  this.mBitmapTextureAtlasWorldMapNE.load(this.getTextureManager());
  
  
 } // onCreateResources

 @Override
 public Scene onCreateScene() {
  
  this.mScene = new Scene();
  
  this.mEngine.registerUpdateHandler(new FPSLogger());
                
                // полные размеры картинки 
  final float worldMapWidth = this.mWorldMapTextureRegionNW.getWidth() * 2;
  final float worldMapHeight = this.mWorldMapTextureRegionNW.getHeight() * 2;

  /* Вычисляем координаты левого верхнего угла первой картинки */  
  final float centerX = (CAMERA_WIDTH - worldMapWidth ) / 2;
  final float centerY = (CAMERA_HEIGHT - worldMapHeight) / 2;

  this.worldMapNW = new Sprite(centerX, centerY, this.mWorldMapTextureRegionNW, this.getVertexBufferObjectManager());
  this.worldMapNE = new Sprite(centerX + this.mWorldMapTextureRegionNW.getWidth(), centerY, this.mWorldMapTextureRegionNE, this.getVertexBufferObjectManager());
  this.worldMapSW = new Sprite(centerX, centerY + this.mWorldMapTextureRegionNW.getHeight(), this.mWorldMapTextureRegionSW, this.getVertexBufferObjectManager());
  this.worldMapSE = new Sprite(centerX + this.mWorldMapTextureRegionNW.getWidth(), centerY + this.mWorldMapTextureRegionNW.getHeight(), this.mWorldMapTextureRegionSE, this.getVertexBufferObjectManager());
  
                // добавляем спрайты на сцену
  this.mScene.attachChild( this.worldMapSW );
  this.mScene.attachChild( this.worldMapSE );
  this.mScene.attachChild( this.worldMapNW );
  this.mScene.attachChild( this.worldMapNE );
  
  return mScene;
 } 
 
 
 
Опытным путем было выяснено, что на части устройств изображения больше 2000 пикселей по любой стороне не подгружаются или при попытке загрузить вылетают с ошибкой, на некоторых - всё нормально. Поэтому лучше бить на куски менее 2000.

Также, для сборки большого спрайта можно воспользоваться классом BitmapTextureAtlasSource отсюда. Как это делается напишу позднее, если разберусь. Пока это без необходимости, всё и так работает очень шустро и плавно. 

Комментариев нет: