イントロダクション
LWJGL GitBookのChapterを写経しながら理解していきます。Git(ソース)はこちら。。。
前回は、Chapter2(2)をやりました。でもまだ半分くらいしか見ていなかったので続きを記載いたします。
Introduction
LWJGL We will understand GitBook ‘s chapter while shooting. Git (source) is here. . . Last time I did Chapter 2,(2) so I will do Chapter 2 this time.
https://ahbejarano.gitbook.io/lwjglgamedev/chapter2
コードを読む(Read the Code)
- DummyGame
- Renderer
- GameEngine This time
- IGameLogic
- Timer
- Window
前回は、3, 5のクラスについて見ました。インターフェースがあるのでその部分について触れています。次は4, 6, 7のクラスについて見ていきます。
********************
********************
GameEngineクラスについて
Mainメソッドで呼ばれているクラスになります。
public static void main(String[] args) { try { boolean vSync = true; IGameLogic gameLogic = new DummyGame(); GameEngine gameEng = new GameEngine("GAME", 600, 480, vSync, gameLogic); /* ① */ gameEng.start(); } catch (Exception excp) { excp.printStackTrace(); System.exit(-1); } }
見ての通り、Dummyクラスを引数に取っています。
上のコードからみるとコンストラクタを呼び出しているので、GameEngineクラスのコンストラクタを眺めます。
public GameEngine(String windowTitle, int width, int height, boolean vSync, IGameLogic gameLogic) throws Exception {
gameLoopThread = new Thread(this, "GAME_LOOP_THREAD");
window = new Window(windowTitle, width, height, vSync);
this.gameLogic = gameLogic;
timer = new Timer();
}
ポイントとしては「Threadクラス」が挙げられます。このクラスはマルチスレッドでの実装をするときに使用します。
GameEngineクラスをMainメソッドの走るスレッド(Thread)とは別のスレッドで起動します。そして、Windowクラスを生成(インスタンス生成)してフィールド変数に設定します。引数にあるIGameLogic(DummyGame)クラスも同様です。
そして、Timerクラスもフィールド変数に設定します。
ここで言う「設定する」と言うのはフィールドで保持すると言う意味です。GameEngineクラスが破棄されるとき→GameEngineの処理が終了するときに上記のフィールドに設定されたクラスも解放されます(Javaの場合は、これをガベージコレクション(フレームワーク)でやってくれます。)
ここまでの整理
- GameEngineはメインメソッドから呼ばれる
- GameEngineコンストラクタで
-
- スレッドを立ち上げる
-
- Windowクラスを生成する
- 上記のクラスを全てフィールド変数で保持する
-
- GameEngine(Thred)
-
- Window
-
- DummyGame(IGameLogic)
-
- Timerクラス
<ポイント>
GameEngineクラスが別スレッドで動く
GameEngineクラスの動き
コンストラクタでクラスのインスタンスが作られた後にはstart(ソースの①)が動きます。
GameEngineクラスのstartメソッド
public void start() { String osName = System.getProperty("os.name"); if ( osName.contains("Mac") ) { gameLoopThread.run(); } else { gameLoopThread.start(); } }
システムプロパティよりOSの名前を取得してMacとそのほかで起動する方法を変更しています。(MacはThread#start()が起動、その他はThread#runが起動)。どちらもrunメソッドが起動します。
GameEngineクラスのrunメソッド(GameEngine#run())
@Override public void run() { try { init(); gameLoop(); } catch (Exception excp) { excp.printStackTrace(); } }
このクラスのinit(), gameLoop()を呼び出しています。エラーがあった場合はcatchしてエラーログを出力します。(printStackTrace())
GameEngine#init()
protected void init() throws Exception { window.init(); timer.init(); gameLogic.init(); }
Window#init()とTimer#init(), DummyGame#init()を呼び出します。
GameEngine#gameLoop()
protected void gameLoop() { float elapsedTime; float accumulator = 0f; float interval = 1f / TARGET_UPS; boolean running = true; /* ゲームループの開始 */ while (running && !window.windowShouldClose()) { elapsedTime = timer.getElapsedTime(); accumulator += elapsedTime; input(); while (accumulator != interval) { update(interval); accumulator -= interval; } render(); if (!window.isvSync()) { sync(); } }