Android遊戲開發:遊戲架構的搭建(4)

來源:互聯網
上載者:User

6.遊戲架構

  所有的基礎工作做完後,我們最後來探討一下遊戲架構本身。我們看下為了運行我們的遊戲,還需要什麼樣的工作要做:

  • 遊戲被分為不同的螢幕(screen),每個螢幕執行著相同的任務:判斷使用者輸入,根據輸入渲染螢幕。一些節目或許不需要任何使用者輸入,但會過段時間後切換到下一螢幕.(如Splash介面)
  • 螢幕需要以某種方法被管理(如我們需要跟蹤當前的螢幕並且能隨時切換的下一螢幕)
  • 遊戲需要允許螢幕訪問不同的模組(比像模組、音頻模組、輸入模組等),這樣螢幕才能載入資源,擷取使用者輸入,播放聲音,渲染緩衝區等。因為我們的遊戲是即時遊戲,我們需要當前的螢幕快速的更新。我們因此需要一個主迴圈來實現。主迴圈在遊戲退出時結束。每次迴圈迭代成為一幀,每秒幀的次數我們成為幀速(FPS).
  • 遊戲需要追蹤視窗的狀態(如是否暫停遊戲或者恢複等),並通知產生相應的處理事件。
  • 遊戲架構需要處理視窗的建立、UI組件的建立等

  下面看下一些代碼:

createWindowAndUIComponent();

Input input = new Input();

Graphics graphics = new Graphics();

Audio audio = new Audio();

Screen currentScreen = new MainMenu();

Float lastFrameTime = currentTime();


while( !userQuit() ) {

  float deltaTime = currentTime() – lastFrameTime;

  lastFrameTime = currentTime();

  currentScreen.updateState(input, deltaTime);

  currentScreen.present(graphics, audio, deltaTime);

}

cleanupResources();

  代碼首先建立了遊戲的視窗和UI組件(createWindowAndUIComponent()方法),接著我們執行個體化了基本的組件,這些能保證遊戲準系統的實現。我們又執行個體化了我們的起始螢幕,並把它作為當前的螢幕。然後記下當前的時間。

  接著我們進入了主迴圈,當使用者想退出時我們可以結束主迴圈。在主迴圈裡面,計算上一幀和當前幀的時間差,用來計算FPS。最後,我們更新了當前螢幕的狀態並呈現給使用者。updateState方法依賴時間差和輸入狀態,present方法包括渲染螢幕的狀態到framebuffer,播放音頻等。present方法也需要知道上次調用到現在的時間差。

  當主迴圈結束後,我們就需要清理和釋放各種資源了。

  這就是遊戲工作的流程:處理使用者的輸入、更新狀態、並呈現給使用者。

遊戲和顯示介面

  下面是遊戲運行時需要的介面:

  • 建立視窗進和UI,並建立相應的事件機制
  • 開啟遊戲的主迴圈
  • 跟蹤當前的螢幕顯示,在每次主迴圈中讓其更新
  • 把UI線程中的事件轉移到主線程中,並把這些事件傳遞給當前顯示介面,以便同步變化。
  • 確保能訪問所有的遊戲基本模組,如Input, FileIO,Graphics, 和 Audio.

下面是遊戲介面的代碼:

package com.badlogic.androidgames.framework;

public interface Game {

  public Input getInput();

  public FileIO getFileIO();

  public Graphics getGraphics();

  public Audio getAudio();

  public void setScreen(Screen screen);

  public Screen getCurrentScreen();

  public Screen getStartScreen();

}

  如上述所示,代碼中有一些getter方法,用來返回模組的執行個體。

  The Game.getCurrentScreen()方法返回當前啟用的螢幕,之後我們會用一個抽象的類AndroidGame來實現這個介面,這個方法會實現除了Game.getStartScreen()之外所有的方法。實際遊戲中如果我們建立AndroidGame的執行個體,我們需要繼承AndroidGame並且重載Game.getStartScreen()方法,返回初次顯示螢幕的一個執行個體。

  為了讓大家瞭解到通過上述方法構建一個遊戲是如何簡單,下面是一個例子(假定我們已經實現了AndroidGame類):

public class MyAwesomeGame extends AndroidGame {

  public Screen getStartScreen () {

    return new MySuperAwesomeStartScreen(this);

  }
}

  很簡單是吧?所有我們要做的就是執行我們遊戲顯示的起始螢幕。我們繼承的AndroidGame類來做其他工作。從這點來看,AndroidGame 類會要求MySuperAwesomeStartScreen在主迴圈中更新和重新渲染自己。注意我們把MyAwesomeGame的執行個體傳遞給了MySuperAwesomeStartScreen。

   

  下面是抽象類別Screen,之所是抽象類別而不是介面,是因為我們可以提前在裡面寫一些子類都用到的方法,減輕子類的實現。代碼如下:

//The Screen Class

package com.badlogic.androidgames.framework;

public abstract class Screen {

  protected final Game game;

  public Screen(Game game) {

    this.game = game;

  }

  public abstract void update(float deltaTime);

  public abstract void present(float deltaTime);

  public abstract void pause();

  public abstract void resume();

  public abstract void dispose();
}

  建構函式接收Game執行個體,並把它存到一個所有子類可以訪問的final變數中。通過這種機制我們可以完成達成兩件事情:

  我們可以通過Game類的執行個體播放音頻、繪製平面、擷取使用者輸入和讀寫檔案。

  在合適時候我們可以通過調用Game.setScreen()設定一個新的當前平面顯示。

  方法 Screen.update() 和 Screen.present():它們會更新平面並同步地顯示。Game執行個體會在主迴圈中調用它們。

  方法 Screen.pause() 和 Screen.resume()在遊戲暫停和恢複時被調用,同樣這兩個方法也是被Game的執行個體調用的,並通知給當前的平面顯示。

  方法Screen.dispose(),當Game.setScreen()方法被調用時,Screen.dispose()被Game的執行個體調用。通過這個方法Game的執行個體會銷毀當前的顯示螢幕,同時讓其釋放所有相關的系統資源,以便為新的螢幕視窗提供最大的記憶體。Screen.dispose()也是內容持久化的最後一個方法。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.