package gameEngine.views; import gameEngine.GameEditor; import gameEngine.Time; import gameEngine.entites.Entity; import gameEngine.entites.GameObject; import gameEngine.entites.gameComponents.*; import gameEngine.input.*; import gameEngine.scenes.*; import org.lwjgl.*; import org.lwjgl.glfw.*; import org.lwjgl.opengl.*; import org.lwjgl.system.*; import java.nio.*; import java.util.HashMap; import static org.lwjgl.glfw.Callbacks.*; import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.system.MemoryStack.*; import static org.lwjgl.system.MemoryUtil.*; public class Window { private static Window window; private static Scene currentScene; public int width; public int height; private String title; private long glfwWindow; private static GameEditor gameEditor; private static HashMap<String , Entity> sceneEntities; private Window() { this.width = 1200; this.height = 900; this.title = "HelloWorld"; init(); } public static void changeScene(int newScene) { switch (newScene) { case 0: // EditorScene if (sceneEntities == null) { currentScene = new EditorScene(); System.out.println("new"); } else { currentScene = new EditorScene(sceneEntities); System.out.println(sceneEntities); // オリジナルのTransformを復元 for (Entity entity : currentScene.entities.values()) { entity.restoreOriginalTransform(); } // ゲームシーンのコンポーネントを削除 for (Entity entity : currentScene.entities.values()) { if (entity instanceof GameObject) { GameObject gameObject = (GameObject) entity; gameObject.gameComponents.removeIf(GameComponent::isGameSceneComponent); } } } initializeSceneEntities(); break; case 1: // GameScene // Transform保存 for (Entity entity : currentScene.entities.values()) { entity.saveOriginalTransform(); } sceneEntities = currentScene.entities; HashMap<String, Entity> gameSceneEntities = new HashMap<>(sceneEntities); // コピーした entities を使って GameScene を作成 currentScene = new GameScene(gameSceneEntities); initializeSceneEntities(); break; default: assert false : "Unknown Scene [" + newScene + "]"; break; } } private static void initializeSceneEntities() { for (Entity entity : currentScene.entities.values()) { if (entity instanceof GameObject) { GameObject gameObject = (GameObject) entity; gameObject.initComponents(); // コンポーネントの初期化 } } if(gameEditor != null) gameEditor.updateListByScene(currentScene); // ゲームエディタ側にシーン情報を渡す } public static Window get() { if (window == null) { window = new Window(); } return window; } public void runWithEditor() { gameEditor = new GameEditor(); run(); } public void run() { System.out.println("Hello LWJGL " + Version.getVersion() + "!"); Window.changeScene(0); loop(); glfwFreeCallbacks(glfwWindow); glfwDestroyWindow(glfwWindow); glfwTerminate(); glfwSetErrorCallback(null).free(); } private void init() { GLFWErrorCallback.createPrint(System.err).set(); if ( !glfwInit() ) { throw new IllegalStateException("Unable to initialize GLFW"); } //Configure GLFW glfwDefaultWindowHints(); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE); glfwWindow = glfwCreateWindow(this.width, this.height, this.title, NULL, NULL); if ( glfwWindow == NULL ) { throw new RuntimeException("Failed to create the GLFW window"); } glfwSetCursorPosCallback(glfwWindow, MouseInput::mousePosCallback); glfwSetMouseButtonCallback(glfwWindow, MouseInput::mouseButtonCallback); glfwSetScrollCallback(glfwWindow, MouseInput::mouseScrollCallBack); glfwSetKeyCallback(glfwWindow, KeyInput::keyCallback); // Get the thread stack and push a new frame try ( MemoryStack stack = stackPush() ) { IntBuffer pWidth = stack.mallocInt(1); // int* IntBuffer pHeight = stack.mallocInt(1); // int* // Get the window size passed to glfwCreateWindow glfwGetWindowSize(glfwWindow, pWidth, pHeight); // Get the resolution of the primary monitor GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); // Center the window glfwSetWindowPos( glfwWindow, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2 ); } glfwMakeContextCurrent(glfwWindow); glfwSwapInterval(1); glfwShowWindow(glfwWindow); GL.createCapabilities(); } private void loop() { Time.update(); while (!glfwWindowShouldClose(glfwWindow)) { glfwPollEvents(); // ウィンドウイベントをポーリング glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // フレームバッファをクリア float dt = Time.deltaTime; if (dt >= 0) { resetScene(); boolean isEditorScene = currentScene instanceof EditorScene; for (Entity entity : currentScene.entities.values()) { if (entity instanceof GameObject) { GameObject gameObject = (GameObject) entity; gameObject.updateComponents(isEditorScene); } } // シーン全体の update を呼び出す currentScene.update(dt); currentScene.processTasks(); } glfwSwapBuffers(glfwWindow); // カラーバッファを交換 Time.update(); } } //Gameシーン開始時にタイマーをリセット、Editorシーン戻ったときにフラグをfalseにする private boolean startGameScene = false; private void resetScene() { boolean isGameScene = currentScene instanceof GameScene; if (isGameScene && !startGameScene) { Time.reset(); startGameScene = true; } if (!isGameScene) startGameScene = false; } public Scene getScene(){ return currentScene; } }