前回作成したコードでは、画面を表示するだけでした。
今度は、入力を受け付ける処理を追加します。
参考にするチュートリアルは動画ですが、こちらになります。
入力を受け付ける
入力、つまりボタンを押下した時のハンドリング部分の実装になります。
くだけた言い方をすると、ボタンを押した時の動きを実装する部分(メソッド)を作る準備をするということです。
早速、コードを写経したので、それを見て見ましょう。
<メインクラス>
public class GameMain { public static void main(String[] args) { Window win = new Window(800, 500, "LWJGL Tutorial"); win.create(); //// ゲームループ //// while (!win.closed()) { win.update(); if (win.isKeyPressed(GLFW.GLFW_KEY_A)) { System.out.println("Pressed Key A"); } if (win.isKeyReleased(GLFW.GLFW_KEY_A)) { System.out.println("Released Key A"); } win.swapBuffers(); } } }
<ウィンドウクラス>
public class Window { /** 画面の幅 */ private int width; /** 画面の高さ */ private int height; /** 画面のタイトル */ private String title; /** 画面の(プログラムレベルの)番号 */ private long window; /** キーボート配列の数だけ配列を用意 */ private boolean[] keys = new boolean[GLFW.GLFW_KEY_LAST]; /** マウスのボタン数だけ配列を用意 */ private boolean[] mouseButtons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST]; /** * 画面を作成する、コンストラクター。 * * @param width 画面の幅 * @param height 画面の高さ * @param title 画面のタイトル */ public Window(int width, int height, String title) { this.width = width; this.height = height; this.title = title; } /** * 画面を作成する処理。 */ public void create() { if (!GLFW.glfwInit()) { System.err.println("Error: Coudn not GLFW"); System.exit(-1); } window = GLFW.glfwCreateWindow(width, height, title, 0, 0); if (window == 0) { System.err.println("Error: window coud not be created"); System.exit(-1); } GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor()); GLFW.glfwSetWindowPos(window, (videoMode.width() - width) / 2, (videoMode.height() - height) / 2); } /** 画面を閉じる */ public boolean closed() { return GLFW.glfwWindowShouldClose(window); } /** 画面を更新する */ public void update() { for (int i = 0; i < GLFW.GLFW_KEY_LAST; i++) keys[i] = isKeyDown(i); for (int i = 0; i < GLFW.GLFW_MOUSE_BUTTON_LAST; i++) keys[i] = isMouseDown(i); GLFW.glfwPollEvents(); } public void swapBuffers() { GLFW.glfwSwapBuffers(window); } /** * キーボートの入力を受付 * @param keyCode this{@link #keys}の配列番号 * @return キーボードが押下されているか判定した結果 */ public boolean isKeyDown(int keyCode) { return GLFW.glfwGetKey(window, keyCode) == 1; } /** * マウスの入力を受付 * @param mouseButton this{@link #mouseButtons}の配列番号 * @return マウスのボタンが押されているか判定した結果 */ public boolean isMouseDown(int mouseButton) { return GLFW.glfwGetMouseButton(window, mouseButton) == 1; } /** キーボードのボタンが押下されているか判定 */ public boolean isKeyPressed(int keyCode) { return isKeyDown(keyCode) && !keys[keyCode]; } /** キーボードのボタンが離されているか判定 */ public boolean isKeyReleased(int keyCode) { return isKeyDown(keyCode) && keys[keyCode]; } /** マウスのボタンが押下されているか判定 */ public boolean isMouseButtonPressed(int mouseButton) { return isKeyDown(mouseButton) && !mouseButtons[mouseButton]; } /** マウスのボタンが離されているか判定 */ public boolean isMouseButtonReleased(int mouseButton) { return isKeyDown(mouseButton) && mouseButtons[mouseButton]; } /** マウスのX軸座標取得 */ @Deprecated public double getMouseX() { DoubleBuffer buf = BufferUtils.createDoubleBuffer(1); GLFW.glfwGetCursorPos(window, buf, null); return buf.get(0); } /** マウスのY軸座標取得 */ @Deprecated public double getMouseY() { DoubleBuffer buf = BufferUtils.createDoubleBuffer(1); GLFW.glfwGetCursorPos(window, null, buf); return buf.get(0); } }
とりあえず写経して動かして見ました。
しかし、マウスのイベントが取れない事象に遭遇したので、それをなんとかしてどうにかしました。
原因は、イベントが取得できるであろうと思った下のコードでイベントが取得できなかったところです。
/** * マウスの入力を受付 * @param mouseButton this{@link #mouseButtons}の配列番号 * @return マウスのボタンが押されているか判定した結果 */ public boolean isMouseDown(int mouseButton) { return GLFW.glfwGetMouseButton(window, mouseButton) == 1; }
こちらのサイトで見てみると、イベントハンドラが実装されているようなので、そちらを使用します。
コードは下の2種類あるようです。
PatternA: コールバッククラスを設定する
= new GLFWCursorPosCallback() { @Override public void invoke(long window, double xpos, double ypos) { } });
PatternB: ラムダ式でコールバック処理を設定する
// Java 8 glfwSetCursorPosCallback(window, posCallback = GLFWCursorPosCallback.create((window, xpos, ypos) -> { // ここにマウスが押下された時の処理を実装する }));
背景の実装
下の2つの動画で、出てきた。変数FPSについて自分が理解したことを記載します。
この動画のはじめの部分
最終的に、追加実装したコードは下のようなものです。GetterとSetterを覗きます。(フィールド変数のGetterを作成しました。)
Githubにソースをコミットしました。
一部抜粋してきます。
FPSをWindowクラスに追加してやりました。これは、ボタン押下時の反応速度?(フレーム数)がなんとかとチュートリアルで言っていたのを聞いた程度しか理解していません。
public boolean isUpdating() { double nextTime = getTime(); double passedTime = nextTime - time; processedTime += passedTime; time = nextTime; while(processedTime > 1.0/fps_cap) { processedTime -= 1.0/fps_cap; return true; } return false; }
この処理で、どうやらフレーム数がなんとか。。。課題として今後理解する必要がありそうだ。
実行した結果は下のような形で、背景も赤くなりました。
関連ページ一覧
<開発準備>
http://zenryokuservice.com/wp/2018/05/02/set-up-1-eclipse-java/
<LWJGLのGitBokに関して>
- Chapter1[外枠の表示のみ]
- Chapter2-1〜クラスの構成〜
- Chapter2-2〜インターフェースの使い方と詳細〜
- Chapter2-3〜GameEngineクラス(サンプルクラス)〜/li>
- Chapter2-4〜Windowクラス(サンプルクラス)〜
- Chapter3〜描画処理を読む〜
- Chapter4〜シェーダについて〜
- Chapter5-1〜レンダリングについて〜
<Java Basic>
- Java Basic Level 1 〜Hello Java〜
- Java Basic Level2 〜Arithmetic Calculate〜
- Java Basic Level3 〜About String class〜
- Java Basic Level 4〜Boolean〜
- Java Basic Level 5〜If Statement〜
- Java Basic Summary from Level1 to 5
- Java Basic Level 6 〜Traning of If statement〜
- Java Basic Level8 〜How to use for statement〜
- Java Basic Level 8.5 〜Array〜
- Java Basic Level 8.5 〜Array〜
- Java Basic Level 10 〜While statement 〜
- Java Basic Swing〜オブジェクト指向〜
- Java Basic Swing Level 2〜オブジェクト指向2〜