Newer
Older
JumpingGame / src / main / java / Main.java
import entities.Const;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;

public class Main {

    private long variableYieldTime, lastTime;
    // ウィンドウハンドル
    private long hWnd;

    //
    private JumpGame jumpGame = new JumpGame();

    // フルスクリーン
    public boolean fullScreen;

    //---------------------------------------------------------------
    //---------------------------------------------------------------
    // エントリーポイント
    public static void main(String[] args) {
        new Main().run(false);
    }

    //---------------------------------------------------------------
    // メイン関数
    public void run(boolean fullScreen) {
        // フルスクリーンの真偽値を貰う
        this.fullScreen = fullScreen;

        // 色々初期化
        initWindow();
        initRender();
        jumpGame.init();

        // メインループ
        while (!glfwWindowShouldClose(hWnd)) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // バッファのクリア

            jumpGame.update();

            glfwSwapBuffers(hWnd); // バッファのスワップ
            glfwPollEvents(); // 入力とかイベントの取得

        }

        // 終了処理
        delete(); // デストラクタ
        glfwFreeCallbacks(hWnd); // ウィンドウコールバックの解放
        glfwDestroyWindow(hWnd); // ウィンドウの破棄
        glfwTerminate(); // GLFWの破棄
        glfwSetErrorCallback(null).free(); // エラーコールバックの解放
    }

    //---------------------------------------------------------------
    //---------------------------------------------------------------
    // ウィンドウの初期化
    private void initWindow() {
        GLFWErrorCallback.createPrint(System.err).set(); // エラーコールバックの設定


        // GLFWの初期化
        if (!glfwInit())
            throw new IllegalStateException("Unable to initialize GLFW");

        // ウィンドウの設定
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

        // ウィンドウの作成
        hWnd = glfwCreateWindow(Const.WIDTH, Const.HEIGHT, Const.TITLE_NAME, fullScreen ? glfwGetPrimaryMonitor() : NULL, NULL);
        if (hWnd == NULL)
            throw new RuntimeException("Failed to create the window.");

        // ウィンドウをタゲにするのか?
        glfwMakeContextCurrent(hWnd);
        // v-syncの適応
        glfwSwapInterval(1);

        // ウィンドウの表示
        glfwShowWindow(hWnd);


    }

    //---------------------------------------------------------------
    // 描画プロセス初期化
    private void initRender() {
        GL.createCapabilities();
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // 背景色設定

        // OpenGLの初期化
        glEnable(GL_TEXTURE_2D); // 二次元テクスチャの有効化
        glEnable(GL_BLEND); // アルファブレンディングの有効化
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // ブレンドモードの設定
    }

    //---------------------------------------------------------------
    // デストラクタ
    public void delete() {
        jumpGame.delete();
    }

    //---------------------------------------------------------------
    //
    private void sync(int fps) {
        if (fps <= 0) return;

        long sleepTime = 1000000000 / fps; // nanoseconds to sleep this frame
        // yieldTime + remainder micro & nano seconds if smaller than sleepTime
        long yieldTime = Math.min(sleepTime, variableYieldTime + sleepTime % (1000*1000));
        long overSleep = 0; // time the sync goes over by

        try {
            while (true) {
                long t = System.nanoTime() - lastTime;

                if (t < sleepTime - yieldTime) {
                    Thread.sleep(1);
                }else if (t < sleepTime) {
                    // burn the last few CPU cycles to ensure accuracy
                    Thread.yield();
                }else {
                    overSleep = t - sleepTime;
                    break; // exit while loop
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            lastTime = System.nanoTime() - Math.min(overSleep, sleepTime);

            // auto tune the time sync should yield
            if (overSleep > variableYieldTime) {
                // increase by 200 microseconds (1/5 a ms)
                variableYieldTime = Math.min(variableYieldTime + 200*1000, sleepTime);
            }
            else if (overSleep < variableYieldTime - 200*1000) {
                // decrease by 2 microseconds
                variableYieldTime = Math.max(variableYieldTime - 2*1000, 0);
            }
        }
    }
    //---------------------------------------------------------------
}