AndEngine 분석 중 하나-----Loading Resources In The Background With A Loading Screen
Well, after searching for this for the last two days it seems that either no one has figured it out, or no one has shared such information.
So, here goes.
I read about people trying this with opening new threads and trying to put the loading on the update thread or the UI thread to no avail. I found the AsyncTask for android after remembering how we did it with XNA.
Making an AsyncTask is simple, here's the API from google: Here
For those who would like a little more instruction and some code, read on.
As far as how I implement my game as some background, I don't use different activities, I just use scenes. This is my first game and I only need 3 different scenes, I'll probably do activities in the future. (by no means is my way the best way I'm sure, this is for illustrative purposes)
I made my own subclass of scene:
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.scene.Scene;
public abstract class GameScene extends Scene {
protected Engine _engine;
public GameScene(int pLayerCount, Engine baseEngine) {
super(pLayerCount);
_engine = baseEngine;
}
// ===========================================================
// Inherited Methods
// ===========================================================
protected abstract void onLoadResources();
protected abstract void onLoadScene();
protected abstract void unloadScene();
protected abstract void onLoadComplete();
// ===========================================================
// Methods
// ===========================================================
public void LoadResources(boolean loadSceneAutomatically){
this.onLoadResources();
if(loadSceneAutomatically){
this.onLoadScene();
}
}
public void LoadScene(){
this.onLoadScene();
}
}
From here I've got a subclass of this for each of my three game scenes. I create the scene, tell it to load it's resources and then set the scene as the main scene. If I provide true to LoadResources it will load the scene automatically. I would use this for anything that doesn't have a lot to load. My PlayScene on the other hand, has all of my game images to load.
Here's where the AsyncLoader comes in.
You have to create your own subclass of AsyncTask as stated in the API. From here you send to it the parameters. I made life simple by creating an interface IAsyncCallback to use as a parameter:
public interface IAsyncCallback {
// ===========================================================
// Methods
// ===========================================================
public abstract void workToDo();
public abstract void onComplete();
}
Now, here's my subclass of AsyncTask: import android.os.AsyncTask;
public class AsyncTaskLoader extends AsyncTask<IAsyncCallback, Integer, Boolean> {
// ===========================================================
// Fields
// ===========================================================
IAsyncCallback[] _params;
// ===========================================================
// Inherited Methods
// ===========================================================
@Override
protected Boolean doInBackground(IAsyncCallback... params) {
this._params = params;
int count = params.length;
for(int i = 0; i < count; i++){
params[i].workToDo();
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
int count = this._params.length;
for(int i = 0; i < count; i++){
this._params[i].onComplete();
}
}
}
This simply calls the workToDo method on each of the parameters (no idea why you would want more than one in this case but that's how AsyncTask is built) and then calls onComplete when it's done. From here you have to simply create an IAsyncCallback in your onLoadResources with all of your asset loading in the workToDo method, and onLoadScene in the onComplete. Then execute the AsyncTask:
@Override
protected void onLoadResources(){
IAsyncCallback callback = new IAsyncCallback() {
@Override
public void workToDo() {
TextureRegionFactory.setAssetBasePath("gfx/game/");
FontFactory.setAssetBasePath("font/");
PlayScene.this._backgroundTexture = new Texture(512, 1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._backgroundTextureRegion = TextureRegionFactory.createFromAsset(PlayScene.this._backgroundTexture, Game.Instance, "background0.png", 0, 0);
PlayScene.this._backgroundTextureRegion2 = TextureRegionFactory.createFromAsset(PlayScene.this._backgroundTexture, Game.Instance, "background0.png", 0, 0);
PlayScene.this._backgroundTextureRegion2.setFlippedVertical(true);
PlayScene.this._faceTexture = new Texture(32,32,TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._faceTextureRegion = TextureRegionFactory.createTiledFromAsset(PlayScene.this._faceTexture,Game.Instance,"face_box.png", 0,0,1,1);
PlayScene.this._iffishTexture = new Texture(512,512,TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._iffishTextureTile = TextureRegionFactory.createTiledFromAsset(PlayScene.this._iffishTexture, Game.Instance, "Iffisch.png", 0, 0, 5, 3);
PlayScene.this._enemyTextures = new Texture(512,512,TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._blowFishEnemyTextureTile = TextureRegionFactory.createTiledFromAsset(PlayScene.this._enemyTextures, Game.Instance, "blowey.png", 0, 0, 1, 1);
PlayScene.this._faerieTexture = new Texture(64,64,TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._faerieTextureRegion = TextureRegionFactory.createFromAsset(PlayScene.this._faerieTexture,Game.Instance,"faerie.png",0,0);
PlayScene.this._inGameFontTexture = new Texture(512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._respawnFont = FontFactory.createFromAsset(PlayScene.this._inGameFontTexture, Game.Instance, "ANDYB.TTF", 32, true, Color.WHITE);
PlayScene.this._hudFontTexture = new Texture(512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._hudFont = FontFactory.createFromAsset(PlayScene.this._hudFontTexture, Game.Instance, "ANDYB.TTF", 24, true, Color.BLACK);
PlayScene.this._analogControlTexture = new Texture(512,256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
PlayScene.this._analogBGTextureRegion = TextureRegionFactory.createFromAsset(PlayScene.this._analogControlTexture, Game.Instance, "analogControls.png", 0, 0);
PlayScene.this._analogStickTextureRegion = TextureRegionFactory.createFromAsset(PlayScene.this._analogControlTexture, Game.Instance, "analogStick.png", 0, 75);
PlayScene.this._scoreHudTextureRegion = TextureRegionFactory.createFromAsset(PlayScene.this._analogControlTexture, Game.Instance, "scoreHud.png", 49, 75);
PlayScene.this._engine.getTextureManager().loadTextures(_enemyTextures, _backgroundTexture, _iffishTexture, _faceTexture, _inGameFontTexture, _faerieTexture, _analogControlTexture, _hudFontTexture);
PlayScene.this._engine.getFontManager().loadFonts(_respawnFont, _hudFont);
}
@Override
public void onComplete() {
PlayScene.this.onLoadScene();
}
};
new AsyncTaskLoader().execute(callback);
}
Then, just make sure you have setScene in your onLoadScene: @Override
protected void onLoadScene() {
// set this as the main scene after loading
this._engine.setScene(this);
.
.
. your scene load stuff here
.
.
}
Just about done! Now you create a new GameScene (or PlayScene in this case) and pass false to the LoadResources. This way it will create the scene, LoadResources will call onLoadResources which will execute the AsyncTask of loading the resources and then call onLoadScene which sets that scene as the main scene and loads up: I do this from within another scene (I'm working on unloading it after the next one is loaded, so that you'll have to sort out yourself :) ) which creates a loading animation. It will play this animation until all of the next scene's resources are loaded and the new one sets itself as the main scene.
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.handler.timer.ITimerCallback;
import org.anddev.andengine.engine.handler.timer.TimerHandler;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
public class LoadingScene extends GameScene {
public LoadingScene(int pLayerCount, Engine baseEngine) {
super(pLayerCount, baseEngine);
}
// ===========================================================
// Fields
// ===========================================================
private Texture _loadingTexture;
private TiledTextureRegion _loadingTextureRegion;
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Inherited Methods
// ===========================================================
@Override
protected void onLoadResources() {
TextureRegionFactory.setAssetBasePath("gfx/");
_loadingTexture = new Texture(512, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
_loadingTextureRegion = TextureRegionFactory.createTiledFromAsset(_loadingTexture, Game.Instance, "loading.png", 0, 0, 2, 2);
this._engine.getTextureManager().loadTexture(_loadingTexture);
}
@Override
protected void onLoadScene() {
this.setBackground(new ColorBackground(1,1,1));
AnimatedSprite loader = new AnimatedSprite(0, 0, _loadingTextureRegion);
loader.setPosition((Game.CAMERA_WIDTH / 2) - (loader.getWidthScaled() / 2), (Game.CAMERA_HEIGHT / 2) - (loader.getHeightScaled() / 2));
loader.animate(300, true);
this.getTopLayer().addEntity(loader);
final PlayScene gameScene = new PlayScene(3,this._engine);
gameScene.LoadResources(false);
}
@Override
protected void unloadScene() {}
@Override
protected void onLoadComplete() {}
// ===========================================================
// Methods
// ===========================================================
}
Whew! Extremely loooong winded and pretty specific to my game but this should give a decent idea as to how this works :) Any questions, comments or feedback is more than welcome. I'm also putting this up in the wiki.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.