andengine 基本用法



l HelloWorld

本文講述如何使用AE創建Helloworld。相當簡單,不需要有什麼經驗。使用的引擎爲:

GLES2

確認android開發環境和AE的代碼都準備好了。

1. 在Eclipse中創建一個Android Project。

2.將導入的AE 工程連接成庫

右鍵點擊AndEngine-屬性-Android-Library Field

3.在創建的Helloworld工程中,刪除自動生成的Java 類.建一個新的類,基類爲:SimpleBaseGameActivity

IDE會強制你添加未實現的方法.

package test.matim;

import org.andengine.engine.options.EngineOptions;

import org.andengine.entity.scene.Scene;

import org.andengine.ui.activity.SimpleBaseGameActivity;

public class TestActivity extends SimpleBaseGameActivity

{

    @Override

    public EngineOptions onCreateEngineOptions()

    {

        return null;

    }

    @Override

    protected void onCreateResources()

    {

  

    }

    @Override

    protected Scene onCreateScene()

    {

        return null;

    }

}

4.創建新的EngineOptions 和Camera.

· 聲明Camera

· 聲明兩個final變量, 作爲Camera的寬和高.

private Camera camera;

      private static final int CAMERA_WIDTH = 800;

      private static final int CAMERA_HEIGHT = 480;

記住,攝相機大小總是由你自己控制.

· 在 onCreateEngineOptions() 中,實例化一個Camera對象.然後生成一個新的EngineOptions

@Override

public EngineOptions onCreateEngineOptions()

{

    camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

    EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, 

    new FillResolutionPolicy(), camera);

    return engineOptions;

}

EngineOptions 第一個參數指是否全屏,第二個是屏幕方法,第三個分辨率大小策略. 見CLICK HERE

5.創建新的主場景

· 在onCreateScene() 中創建新的Scene對象

· 場景是個實體(Entity)所以可以增加新的實體,如精靈

· 把場景的背景設爲藍色

@Override

protected Scene onCreateScene()

{

     Scene scene = new Scene();

     scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

     return scene;

}

現在這個工程就可以運行了,只有一個藍色的背景.

l 加載遊戲資源

這篇會說明如何加載大多數常用的資源:

u Graphics

u Fonts

u Sounds

1.注意事項

· 在GLES2中不再強制要求紋理使用2,4,8,16,32...的大小了.可以自由設置大小.

· 強烈不建議使用大於1024X1024像素的紋理,因爲在有些低端設備上不支持.

· 如果在遊戲中需要音樂,考慮.ogg格式.APK會更小.

2.加載資源

要加載資源,所有你要做的是把加載資源的代碼放在 onCreateResources() 中. 從易讀修改方面考慮, 我們可能需要將其分成三個小方法.

@Override

public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws IOException

{

    loadGraphics();

    loadFonts();

    loadSounds();

    pOnCreateResourcesCallback.onCreateResourcesFinished();

}

private void loadGraphics()

{

    

}

private void loadFonts()

{

    

}

private void loadSounds()

{

    

}

3. 加載圖片

這裏詳細實現loadGraphics

聲明一個新的紋理, 紋理區域,然後 從asset/gfx 中加載image.png圖片.

private BitmapTextureAtlas yourTexture;

private ITextureRegion yourTextureRegion;

private void loadGraphics()

{

    BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

    yourTexture = new BitmapTextureAtlas(getTextureManager(), 256, 256, TextureOptions.DEFAULT);

    yourTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(yourTexture, this, "image.png", 0, 0);

    yourTexture.load();    

}

紋理大小是256x256, 你可以在任何時候加載和缷載圖片.

· yourTexture.load();

· yourTexture.unload();

考慮這種情況, 有兩個場景,每個場景使用自己的圖片資源. 在場景切換的時候, 先缷載一個紋理,加載另一個來達到減少內存的使用.

4.加載字體

加載字體類似,選擇合適紋理大小:

private Font yourFont;

public void loadFonts()

{

    FontFactory.setAssetBasePath("font/");

    final ITexture fontTexture = new BitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

    yourFont = FontFactory.createFromAsset(getFontManager(), fontTexture, getAssets(), "font.ttf", 40, true, Color.BLACK);

    yourFont.load();

}

5. 加載聲音

這裏我們從assets/mfx/ 中加載

private Sound yourSound;

public void loadSounds()

{

    try 

    {

        yourSound = SoundFactory.createSoundFromAsset(getEngine().getSoundManager(), this, "mfx/sound.ogg");

    } 

    catch (IOException e) 

    {

        e.printStackTrace();

    }

}

l 聲音和音樂

在AE從加載使用聲音很容易, 還有一些其他功能如音量控制, 也可以加載不同格式的聲音文件.

1.加載資源

private Music music;

try

{

    music = MusicFactory.createMusicFromAsset(mEngine.getMusicManager(), this,"mfx/music.ogg");

}

catch (IOException e)

{

    e.printStackTrace();

}

2.調節音量大小

如此簡單:

yourSound.setVolume(0.5f);

3.播放,停止,暫停

yourSound.play();

yourSound.stop();

yourSound.pause();

4.循環播放

比如背景音樂:

yourSound.setLooping(true);

也可以指定循環循環次數:

yourSound.setLoopCount(yourCount);

即音樂停止前會循環 yourCount次.

4.如何設計你的遊戲----一個有用的模式

本文論述我用AE進行遊戲設計的觀點, 可能對初學者有幫助. 在動手前有個計劃會讓你在開發過程中減少很多痛苦. 開發遊戲是個耗時的工作,爲什麼不讓它變得容易點呢?

假設有一個遊戲,然後呢, 在開始編碼前思考以下幾點:

· 思考下整個程序的結構.

· 試着畫出類圖, 在以後細節往往更容易. 

· 看下引擎,確認許多東西已經實現了.

· 把你的想法轉化爲代碼!

1. 多個活動(Activities) 和 多場景(Scenes)的比較

顯然不需要多少活動, 大多數只需要:

· 菜單活動(注:指遊戲主封面)Menu Activity

· 設置活動Options Activity

· 遊戲活動Game Activity

創建很多的活動(每個界面一個活動)是好的嗎? 我個人認爲,不好. 首先, 會增加加載時間(活動的切換會重新加載資源). 而且很麻煩, 多活動會讓你在訪問其他對象時變得 麻煩, 所以爲什麼只使用單一活動是個很優雅的方式.

看下面的圖:

4個場景一個活動,只需要在Splash Scene加載資源後成功後跳到MenuScene:

engine.setScene(yourScene);

l 創建加載場景

在上節提到的應當使用多場景代替多活動.本節講述如何創建一個加載場景.這是thepi 分享的代碼改版,使用GLES2並額外增加了一些東西.末尾提供了下載 .

1.如何工作的?

· 加載Splash Scene 的紋理

· 顯示Splash Scene 並加載餘下的資源.

· 加載資源完成後,顯示主場景(menu 或者其他)

2.手把手教你

· 新建一個活動, 繼承BaseGameActivity

· 在onCreateEngine中創建EngineOptions, Camera

· 聲明兩個場景, splashScene 和 mainScene

private BitmapTextureAtlas splashTextureAtlas;

private ITextureRegion splashTextureRegion;

private Sprite splash;

在 onCreateResources() 中加載splash所需的資源,

BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

splashTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 256, 256, TextureOptions.DEFAULT);

splashTextureRegion =BitmapTextureAtlasTextureRegionFactory.createFromAsset(splashTextureAtlas,

this,"splash.png", 0, 0);

splashTextureAtlas.load();

pOnCreateResourcesCallback.onCreateResourcesFinished();

初始化splash scene:

private void initSplashScene()

{

    splashScene = new Scene();

    splash = new Sprite(0, 0, splashTextureRegion, mEngine.getVertexBufferObjectManager())

    {

        @Override

        protected void preDraw(GLState pGLState, Camera pCamera)

        {

            super.preDraw(pGLState, pCamera);

            pGLState.enableDither();

        }

    };

    splash.setScale(1.5f);

    splash.setPosition((CAMERA_WIDTH - splash.getWidth()) * 0.5f, (CAMERA_HEIGHT - splash.getHeight()) * 0.5f);

    splashScene.attachChild(splash);

}

· 把這些放到onCreateScene()中:

initSplashScene();

pOnCreateSceneCallback.onCreateSceneFinished(this.splashScene);

把以下這些也放到onCreateScene中:

mEngine.registerUpdateHandler(new TimerHandler(3f, new ITimerCallback() 

{

    public void onTimePassed(final TimerHandler pTimerHandler) 

    {

        mEngine.unregisterUpdateHandler(pTimerHandler);

        loadResources();

        loadScenes();         

        splash.detachSelf();

        mEngine.setScene(mainScene);

    }

}));

 

pOnPopulateSceneCallback.onPopulateSceneFinished();

資源加載完成後,跳轉到mainScene中

public void loadResources() 

{

    // Load your game resources here!

}

private void loadScenes()

{

    // load your game here, you scenes

    mainScene = new Scene();

    mainScene.setBackground(new Background(50, 50, 50));

}

好了!

下面的代碼有些更多功能,比如在splash顯示期間不能退出.

splashscreentemplate.rar

Download File

l 跟隨相機

在許多遊戲中, 我們很可能需要相機追蹤 主角, 雖然實現簡單,但AE也已經內置了這個功能了.

所以你只需要設置要追蹤的實體:

camera.setChaseEntity(entity);

l 設置相機的邊界

這個功能很有用, 需要使用BoundCamera類或者其擴展類.使用以下兩個方法:

camera.setBounds(0, 0, 2000, 780);

camera.setBoundsEnabled(true);

頭兩個參數是最小邊界,後兩個參數是最大邊界,也就是說,相機不會超過2000, 780

l 平滑地移動相機(由A點到B點)

AE沒有內置由A到B移動相機的默認方法,但是實現這個有幾個比較簡單辦法

顯然你可以設置相機的中心,但是重點是要平滑地移動,而不是簡單地跳轉.

camera.setCenter(pCenterX, pCenterY);

如果你想看起來專業一點,可以使用個小技巧. 聲明一個Entity,然後爲它註冊MoveModifier,然後使用相機跟隨:

Entity e = new Entity();

e.setPosition(pX, pY);

camera.setChaseEntity(e);

e.registerEntityModifier(new MoveModifier(duration, e.getX(), pToX, e.getY(), pToY));

Entity (x, y) 是起始位置, (pToX, pToY)是終點.到達B點後,應當停止相機跟隨,那麼應當爲MoveModifier增加監聽,重寫onModifierFinished

Entity e = new Entity();

e.setPosition(pX, pY);

camera.setChaseEntity(e);

       

final MoveModifier modifier = new MoveModifier(duration, e.getX(), pToX, e.getY(), pToY)

{

    @Override

    protected void onModifierFinished(IEntity pItem)

    {

        super.onModifierFinished(pItem);

        camera.setChaseEntity(null);

    }

};

               

e.registerEntityModifier(modifier);

更簡單的方法:

你可以使用SmoothCamera來平滑移動相機,通過調用setCenter(x, y) 方法.在創建這類相機時,要在構造函數中增加額外的參數,比如在x, y軸上的速度.如果想直接移動則調用:setCenterDirect(x, y)方法.

l FPS 計數

AE中獲取FPS使用很簡單.

1.FPS Logger

mEngine.registerUpdateHandler(new FPSLogger());

這樣就可以在Logcat中看到fps估值了.

2.Text Fps Counter

如果你想把FPS顯示在遊戲中 那就需要聲明一個Text 對象了

final FPSCounter fpsCounter = new FPSCounter();

this.mEngine.registerUpdateHandler(fpsCounter);

 

final Text fpsText = new Text(250, 240, this.mFont, "FPS:", "FPS: XXXXX".length(),vbo);

 

scene.attachChild(fpsText);

 

scene.registerUpdateHandler(new TimerHandler(1 / 20.0f, true, new ITimerCallback()

{

    @Override

    public void onTimePassed(final TimerHandler pTimerHandler)

    {

        fpsText.setText("FPS: " + fpsCounter.getFPS());

    }

}));

使用一個定時器不停地刷新顯示 FPSCounter中獲取的FPS值. 簡單吧..

處理onResume, onPause and onDestroy

如果你對Android生命週期(Android Life Cycle)熟悉的話, 這些方法就不會陌生. 爲什麼重要呢,請看下文分解:

1. 正確地暫停和恢復音樂的播放:

在點擊小房子那個按鈕後顯然我們要暫停音樂的播放, 在回到遊戲後應該繼續音樂的播放.

@Override

protected void onPause()

{

    super.onPause();

    if (this.isGameLoaded())

        music.pause();

}

@Override

protected synchronized void onResume()

{

    super.onResume();

    System.gc();

    if (this.isGameLoaded())

        music.play(); 

}

你應當檢查isGameLoaded() 或者Music 對象是否爲空,不然會有NullPointerException異常

2.銷燬活動.

從遊戲中退出,不應簡單地finish() , 應當在onDestroy中調用 System.exit(0);

@Override

protected void onDestroy()

{

    super.onDestroy();

        

    if (this.isGameLoaded())

    {

        System.exit(0);    

    }

}

檢查遊戲是否已經加載了很重要.否則在有些機器上, 遊戲在打開後會馬上被關閉.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章