package gameEngine.scenes; import gameEngine.entites.Camera; import gameEngine.entites.Entity; import gameEngine.entites.GameObject; import gameEngine.entites.gameComponents.*; import gameEngine.geometry.Transform; import gameEngine.input.Input; import gameEngine.views.Color; import gameEngine.views.Window; import java.awt.event.KeyEvent; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; import static org.lwjgl.opengl.GL11.glClearColor; public abstract class Scene { private Camera camera; public HashMap<String, Entity> entities = new HashMap<>(); private final Queue<Runnable> taskQueue = new LinkedList<>(); private boolean changingScene = false; private float timeToChangeScene = 2.0f; private final Color editorBackColor = new Color(1,1,1,0); public Scene(){ } public abstract void update(float dt); public Camera getCamera() { return camera; } public void setCamera(Camera camera) { this.camera = camera; } public Entity getEntity(String eid) { return entities.get(eid); } public void addEntity(String eid, Entity entity) { entities.put(eid, entity); } public void removeEntity(String eid) { entities.remove(eid); } public void addNewObject() { enqueueTask(() -> { addNewGameObject(); }); } public void addEditor(){ enqueueTask(() -> { addEditorFrameObject(); addNewButtonObject(); addNewTextObject(); }); } private GameObject createGameObject(){ int entitiesLength = entities.size(); String newId = Integer.toString(entitiesLength); GameObject gameObject = new GameObject(newId); addEntity(newId, gameObject); return gameObject; } private void addEditorFrameObject(){ GameObject editorFrame = createGameObject(); editorFrame.addComponent(new Mesh(editorFrame, Mesh.MeshType.SPRITE, "GameEngine/resources/EditorFrame.png")); editorFrame.transform.setPosition(0, 0, 0); editorFrame.transform.setScale(Window.get().width,0.8f,1); editorFrame.setName("EditorFrame"); } private void addNewButtonObject(){ GameObject button = createGameObject(); button.addComponent(new Mesh(button, Mesh.MeshType.SPRITE, "GameEngine/resources/button.png")); button.addComponent(new EditorButton(button, button.getComponent(Mesh.class))); button.transform.setPosition((float) Window.get().width / 2 - button.getComponent(Mesh.class).getDisplayedWidth()/2 , 5f, 0); button.transform.setScale(1.4f,0.6f,1); button.setName("NewEntity" + button.getId()); button.getComponent(Button.class).addListener(this::changeSceneStart); } private void addNewTextObject(){ GameObject text = createGameObject(); text.addComponent(new TextMesh(text, "Play",32)); text.transform.setPosition(580, 3f, 0); text.setName("NewEntity" + text.getId()); } private void addNewGameObject(){ GameObject object = createGameObject(); object.addComponent(new Mesh(object, Mesh.MeshType.SPRITE, "GameEngine/resources/0.png")); object.transform.setPosition((float) Window.get().width / 2 - object.getComponent(Mesh.class).getDisplayedWidth()/2 , (float) Window.get().height / 2 - object.getComponent(Mesh.class).getDisplayedHeight()/2, 0); object.addComponent(new MoveImage(object)); } /** * Adds a component to the specified GameObject. * This method enqueues a task to add the given GameComponent to the GameObject's component list. * * @param gameObject The GameObject to which the component will be added. * @param component The GameComponent to be added to the GameObject. */ public void addComponentToGameObject(GameObject gameObject, GameComponent component) { enqueueTask(() -> gameObject.addComponent(component)); } /** * Removes a component from the specified GameObject. * This method enqueues a task to remove the given GameComponent from the GameObject's component list. * * @param gameObject The GameObject from which the component will be removed. * @param component The GameComponent to be removed from the GameObject. */ public void removeComponentFromGameObject(GameObject gameObject, GameComponent component) { enqueueTask(() -> gameObject.removeComponent(component)); } // タスクを登録 private synchronized void enqueueTask(Runnable task) { taskQueue.add(task); } // タスクの実行 public synchronized void processTasks() { while (!taskQueue.isEmpty()) { taskQueue.poll().run(); } } //現状一つのEntityからしか呼び出せない public void Instantiate(GameObject original) { enqueueTask(() -> { String newId = Integer.toString(entities.size()); GameObject newGameObject = new GameObject(newId); newGameObject.setName(original.getName() + "_copy"); newGameObject.transform = new Transform(original.transform); if (original.getComponent(Mesh.class) != null) { newGameObject.addComponent(new Mesh((Mesh)original.getComponent(Mesh.class).copy(), newGameObject)); } if (original.getComponent(TextMesh.class) != null) { newGameObject.addComponent(new TextMesh((TextMesh)original.getComponent(TextMesh.class).copy(), newGameObject)); } if (original.getComponent(ColorController.class) != null) { newGameObject.addComponent(new ColorController()); } if (original.getComponent(CopyEntity.class) != null) { newGameObject.addComponent(new CopyEntity(newGameObject)); } if (original.getComponent(MoveImage.class) != null) { newGameObject.addComponent(new MoveImage(newGameObject)); } if (original.getComponent(Physics.class) != null) { newGameObject.addComponent(new Physics(newGameObject)); } addEntity(newId, newGameObject); }); } private void changeSceneStart(){ if(!changingScene) changingScene = true; } //シーン切り替え時の演出 void changeScene(int scene, float dt){ if(!changingScene && Input.GetKeyDown(KeyEvent.VK_SPACE)){ changingScene = true; } if(changingScene && timeToChangeScene > 0){ timeToChangeScene -= dt * 1.5f; editorBackColor.r -= dt * 5.0f; editorBackColor.g -= dt * 5.0f; editorBackColor.b -= dt * 5.0f; glClearColor(editorBackColor.r, editorBackColor.g, editorBackColor.b, editorBackColor.a); } else if(changingScene){ Window.changeScene(scene); } } }