Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / gameEngine / scenes / Scene.java
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);
        }
    }
}