diff --git a/GameEngine/src/main/java/gameEngine/GameEditor.java b/GameEngine/src/main/java/gameEngine/GameEditor.java index 7d2f92d..8a1eeb6 100644 --- a/GameEngine/src/main/java/gameEngine/GameEditor.java +++ b/GameEngine/src/main/java/gameEngine/GameEditor.java @@ -15,25 +15,34 @@ private Button playButton; private Text playButtonText; + private Button openButton; + private Text openButtonText; + private Button createObjectButton; private Text createObjectButtonText; + private Button createTextButton; + private Text createTextButtonText; + public GameEditor(Scene scene) { this.scene = scene; initializeEditorComponents(); } private void initializeEditorComponents() { - EditorFrameSprite[0] = new Sprite(frameImagePath, 0, 0, 20, 0.5f); - EditorFrameSprite[1] = new Sprite(frameImagePath, 0, 0, 0.25f, 20); - EditorFrameSprite[2] = new Sprite(frameImagePath, Window.get().width-16, 0, 0.25f, 20); - EditorFrameSprite[3] = new Sprite(frameImagePath, 0, Window.get().height-16, 20, 0.5f); + createFrame(); playButton = new Button(Window.get().width/ 2 -16 , 3, 1, 0.4f); playButtonText = new Text(Window.get().width/ 2 - 11.25f, 1, "Play", 24); - createObjectButton = new Button(50, 3, 0.4f, 0.4f); - createObjectButtonText = new Text(50 +5.25f, 0.4f, "+", 24); + openButton = new Button(50, 3, 0.4f, 0.4f); + openButtonText = new Text(50 +5.25f, 0.4f, "+", 24); + + createObjectButton = new Button(20, 73, 3.2f, 0.5f); + createObjectButtonText = new Text(20 +5.25f, 70.4f, "Add GameObject", 24); + + createTextButton = new Button(20, 33, 3.2f, 0.5f); + createTextButtonText = new Text(20 +5.25f, 30.4f, "Add TextMesh", 24); setButtonListeners(); } @@ -44,6 +53,9 @@ createObjectButton.clearListeners(); createObjectButton.addListener(scene::addNewObject); + + createTextButton.clearListeners(); + createTextButton.addListener(scene::addNewTextMesh); } public void setScene(Scene newScene) { @@ -57,5 +69,14 @@ playButtonText.update(); createObjectButton.update(); createObjectButtonText.update(); + createTextButton.update(); + createTextButtonText.update(); + } + + private void createFrame(){ + EditorFrameSprite[0] = new Sprite(frameImagePath, 0, 0, 20, 0.5f); + EditorFrameSprite[1] = new Sprite(frameImagePath, 0, 0, 0.25f, 20); + EditorFrameSprite[2] = new Sprite(frameImagePath, Window.get().width-16, 0, 0.25f, 20); + EditorFrameSprite[3] = new Sprite(frameImagePath, 0, Window.get().height-16, 20, 0.5f); } } diff --git a/GameEngine/src/main/java/gameEngine/entites/GameObject.java b/GameEngine/src/main/java/gameEngine/entites/GameObject.java index 3325805..d06d7b0 100644 --- a/GameEngine/src/main/java/gameEngine/entites/GameObject.java +++ b/GameEngine/src/main/java/gameEngine/entites/GameObject.java @@ -10,8 +10,6 @@ import java.util.List; public class GameObject extends Entity { - - Window window = Window.get(); public final List gameComponents = new ArrayList<>(); public GameObject(String id) { @@ -26,7 +24,6 @@ } } this.gameComponents.add(component); - if(window.getScene() instanceof GameScene) component.setGameSceneComponent(true); System.out.println("Component added: " + component.getClass().getSimpleName()); } @@ -45,18 +42,9 @@ } } - public void updateComponents(boolean isEditorScene) { + public void updateComponents() { for (GameComponent component : gameComponents) { - if (isEditorScene) { //Editorシーンでも機能するコンポーネント - if (component instanceof Mesh) { - component.update(); - } - else if (component instanceof TextMesh) { - component.update(); - } - } else { - component.update(); - } + component.update(); } } diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/Draggable.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Draggable.java new file mode 100644 index 0000000..367ec19 --- /dev/null +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Draggable.java @@ -0,0 +1,45 @@ +package gameEngine.entites.gameComponents; + +import gameEngine.entites.Entity; +import gameEngine.input.Input; +import gameEngine.input.MouseInput; +import gameEngine.scenes.Scene; +import gameEngine.views.Window; + +public abstract class Draggable extends GameComponent { + protected Entity parent; + protected boolean isDraggable = true; + protected boolean isDragging = false; + + public void setDraggable(boolean draggable) { + this.isDraggable = draggable; + } + + protected void handleDragging() { + if (!isDraggable) return; + float mouseX = MouseInput.getX(); + float mouseY = MouseInput.getY(); + Scene scene = Window.get().getScene(); + + if (scene.getSelectedEntity() != null && scene.getSelectedEntity() != parent) { + return; + } + + if (Input.GetMouseButtonDown(0) && isMouseOver(mouseX, mouseY)) { + isDragging = true; + scene.setSelectedEntity(parent); + } + + if (isDragging && Input.GetMouseButton(0)) { + updatePosition(mouseX, mouseY); + } + + if (Input.GetMouseButtonUp(0)) { + isDragging = false; + scene.clearSelectedEntity(); // ドラッグ解除時に選択をクリア + } + } + + protected abstract boolean isMouseOver(float mouseX, float mouseY); + protected abstract void updatePosition(float mouseX, float mouseY); +} diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java index 792f83e..9787337 100644 --- a/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java @@ -2,15 +2,6 @@ public abstract class GameComponent { public abstract GameComponent copy(); - protected boolean isGameSceneComponent; - - public boolean isGameSceneComponent() { - return isGameSceneComponent; - } - - public void setGameSceneComponent(boolean gameSceneComponent) { - isGameSceneComponent = gameSceneComponent; - } public void init() { diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java index 1c55d6a..69ad00a 100644 --- a/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java @@ -2,13 +2,15 @@ import gameEngine.entites.Entity; import gameEngine.entites.GameObject; +import gameEngine.input.Input; +import gameEngine.input.MouseInput; import gameEngine.views.Color; import gameEngine.views.Sprite; import gameEngine.views.Texture; import gameEngine.views.Window; import static org.lwjgl.opengl.GL11.*; -public class Mesh extends GameComponent { +public class Mesh extends Draggable { public enum MeshType { SPRITE, CUBE @@ -16,7 +18,6 @@ private final MeshType type; private Sprite sprite; - private final Entity parent; // 親のオブジェクトを持つ public Mesh(Entity parent, MeshType type, String texturePath) { this.parent = parent; @@ -52,10 +53,23 @@ sprite.setPosition(parent.transform.position); sprite.setRotation(parent.transform.rotation); sprite.setScale(parent.transform.scale); + + handleDragging(); sprite.update(); } } + @Override + protected boolean isMouseOver(float mouseX, float mouseY) { + return sprite.isMouseOver(mouseX, mouseY); + } + + @Override + protected void updatePosition(float mouseX, float mouseY) { + sprite.setPosition(mouseX - sprite.getDisplayedWidth() / 2, + mouseY - sprite.getDisplayedHeight() / 2); + } + public void setSprite(String texturePath){ sprite.setTexturePath(texturePath); } diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java index cdba938..e195a42 100644 --- a/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java @@ -1,11 +1,11 @@ package gameEngine.entites.gameComponents; import gameEngine.entites.Entity; +import gameEngine.input.MouseInput; import gameEngine.views.*; -public class TextMesh extends GameComponent{ +public class TextMesh extends Draggable{ - private Entity parent; private Text textRenderer; public TextMesh(Entity parent, String text, int textSize) { @@ -38,9 +38,21 @@ textRenderer.setPosition(parent.transform.position); textRenderer.setRotation(parent.transform.rotation); textRenderer.setScale(parent.transform.scale); + + handleDragging(); textRenderer.update(); } + @Override + protected boolean isMouseOver(float mouseX, float mouseY) { + return textRenderer.isMouseOver(mouseX, mouseY); + } + + @Override + protected void updatePosition(float mouseX, float mouseY) { + textRenderer.setPosition(mouseX, mouseY); + } + public void setText(String newText){ textRenderer.setText(newText); } diff --git a/GameEngine/src/main/java/gameEngine/scenes/Scene.java b/GameEngine/src/main/java/gameEngine/scenes/Scene.java index 6dd2bb0..c621ecf 100644 --- a/GameEngine/src/main/java/gameEngine/scenes/Scene.java +++ b/GameEngine/src/main/java/gameEngine/scenes/Scene.java @@ -20,12 +20,26 @@ private Camera camera; public HashMap entities = new HashMap<>(); + private Entity selectedEntity = null; private final Queue taskQueue = new LinkedList<>(); private boolean changingScene = false; private float timeToChangeScene = 2.0f; private final Color editorBackColor = new Color(1,1,1,0); + public Entity getSelectedEntity() { + return selectedEntity; + } + + public void setSelectedEntity(Entity entity) { + selectedEntity = entity; + System.out.println("Selected Entity: " + selectedEntity); + } + + public void clearSelectedEntity() { + selectedEntity = null; + } + public Scene(){ } @@ -53,6 +67,11 @@ return null; } + public Runnable addNewTextMesh() { + enqueueTask(this::addTextMesh); + return null; + } + private GameObject createGameObject(){ int entitiesLength = entities.size(); String newId = Integer.toString(entitiesLength); @@ -67,10 +86,16 @@ 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)); - object.addComponent(new TextMesh(object, "Test", 30)); - object.addComponent(new ButtonComponent(object)); } + private void addTextMesh(){ + GameObject object = createGameObject(); + object.transform.setPosition((float) Window.get().width / 2 ,(float) Window.get().height /2, 0); + object.addComponent(new TextMesh(object, "Text", 32)); + } + + + /** * Adds a component to the specified GameObject. * This method enqueues a task to add the given GameComponent to the GameObject's component list. diff --git a/GameEngine/src/main/java/gameEngine/views/Button.java b/GameEngine/src/main/java/gameEngine/views/Button.java index 8714392..b2e9b20 100644 --- a/GameEngine/src/main/java/gameEngine/views/Button.java +++ b/GameEngine/src/main/java/gameEngine/views/Button.java @@ -33,18 +33,14 @@ float mouseX = MouseInput.getX(); float mouseY = MouseInput.getY(); - float width = buttonSprite.getDisplayedWidth(); - float height = buttonSprite.getDisplayedHeight(); - - if (Input.GetMouseButtonDown(0) && isMouseOver(mouseX, mouseY, width, height)) { - isPressed = true; // ボタン上でMouseDownした場合のみ押下状態にする + if (Input.GetMouseButtonDown(0) && buttonSprite.isMouseOver(mouseX, mouseY)) { + isPressed = true; buttonSprite.setColor(pressedColor); } if (Input.GetMouseButtonUp(0)) { buttonSprite.setColor(normalColor); - if (isPressed && isMouseOver(mouseX, mouseY, width, height)) { - System.out.println("Editor Button clicked at Mouse X: " + mouseX + ", Mouse Y: " + mouseY); + if (isPressed && buttonSprite.isMouseOver(mouseX, mouseY)) { for (Runnable listener : onClickListeners) { listener.run(); } @@ -53,11 +49,6 @@ } } - private boolean isMouseOver(float mouseX, float mouseY, float width, float height) { - return mouseX >= buttonSprite.position.x && mouseX <= buttonSprite.position.x - + width && mouseY >= buttonSprite.position.y && mouseY <= buttonSprite.position.y + height; - } - public void addListener(Runnable listener) { onClickListeners.add(listener); } diff --git a/GameEngine/src/main/java/gameEngine/views/Sprite.java b/GameEngine/src/main/java/gameEngine/views/Sprite.java index e7c2280..60b4432 100644 --- a/GameEngine/src/main/java/gameEngine/views/Sprite.java +++ b/GameEngine/src/main/java/gameEngine/views/Sprite.java @@ -60,6 +60,13 @@ } } + public boolean isMouseOver(float mouseX, float mouseY) { + float width = getDisplayedWidth(); + float height = getDisplayedHeight(); + return mouseX >= position.x && mouseX <= position.x + width && + mouseY >= position.y && mouseY <= position.y + height; + } + @Override public void render() { prepareRendering(); diff --git a/GameEngine/src/main/java/gameEngine/views/Text.java b/GameEngine/src/main/java/gameEngine/views/Text.java index 41025b3..489aa1a 100644 --- a/GameEngine/src/main/java/gameEngine/views/Text.java +++ b/GameEngine/src/main/java/gameEngine/views/Text.java @@ -58,6 +58,13 @@ render(); } + public boolean isMouseOver(float mouseX, float mouseY) { + float width = getDisplayedWidth(); + float height = getDisplayedHeight(); + return mouseX >= position.x && mouseX <= position.x + width && + mouseY >= position.y && mouseY <= position.y + height; + } + @Override public void render() { prepareRendering(); @@ -70,7 +77,7 @@ char ch = text.charAt(i); if (ch == '\n') { drawY += fontHeight; - drawX = 0; // Move back to the start of the line + drawX = 0; continue; } @@ -117,5 +124,33 @@ return height; } + public float getDisplayedWidth() { + float width = 0; + float lineWidth = 0; + for (int i = 0; i < text.length(); i++) { + char ch = text.charAt(i); + if (ch == '\n') { + width = Math.max(width, lineWidth); + lineWidth = 0; // 新しい行に移行するためにリセット + } else { + Glyph g = fontGlyphs.get(ch); + if (g != null) { + lineWidth += g.width; // 文字の幅を加算 + } + } + } + width = Math.max(width, lineWidth); // 最後の行の幅も確認 + return width * scale.x; + } + + public float getDisplayedHeight() { + int numLines = 1; // 初期行は1行 + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) == '\n') { + numLines++; + } + } + return numLines * fontHeight * scale.y; + } } diff --git a/GameEngine/src/main/java/gameEngine/views/Window.java b/GameEngine/src/main/java/gameEngine/views/Window.java index 54fa1f6..caace3c 100644 --- a/GameEngine/src/main/java/gameEngine/views/Window.java +++ b/GameEngine/src/main/java/gameEngine/views/Window.java @@ -45,14 +45,9 @@ 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(); } @@ -165,32 +160,50 @@ 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(); - if(currentScene instanceof EditorScene) gameEditor.update(); + if(currentScene instanceof EditorScene) { + gameEditor.update(); + for (Entity entity : currentScene.entities.values()) { + if (entity instanceof GameObject) { + GameObject gameObject = (GameObject) entity; + if(gameObject.getComponent(Mesh.class) != null){ + gameObject.getComponent(Mesh.class).update(); + gameObject.getComponent(Mesh.class).setDraggable(true); + } + if(gameObject.getComponent(TextMesh.class) != null){ + gameObject.getComponent(TextMesh.class).update(); + gameObject.getComponent(TextMesh.class).setDraggable(true); + } + if(gameObject.getComponent(ButtonComponent.class) != null)gameObject.getComponent(ButtonComponent.class).update(); + } + } + } + else { + for (Entity entity : currentScene.entities.values()) { + if (entity instanceof GameObject) { + GameObject gameObject = (GameObject) entity; + gameObject.updateComponents(); + if(gameObject.getComponent(Mesh.class) != null){ + gameObject.getComponent(Mesh.class).setDraggable(false); + } + if(gameObject.getComponent(TextMesh.class) != null){ + gameObject.getComponent(TextMesh.class).setDraggable(false); + } + } + } + } MouseInput.endFrame(); KeyInput.endFrame(); - } - glfwSwapBuffers(glfwWindow); Time.update(); } - } //Gameシーン開始時にタイマーをリセット、Editorシーン戻ったときにフラグをfalseにする