diff --git a/GameEngine/resources/ComponentView.png b/GameEngine/resources/ComponentView.png new file mode 100644 index 0000000..2a2c4f5 --- /dev/null +++ b/GameEngine/resources/ComponentView.png Binary files differ diff --git a/GameEngine/resources/EntityView.png b/GameEngine/resources/EntityView.png new file mode 100644 index 0000000..bc09cef --- /dev/null +++ b/GameEngine/resources/EntityView.png Binary files differ diff --git a/GameEngine/resources/PortA.png b/GameEngine/resources/PortA.png new file mode 100644 index 0000000..9dc7e6d --- /dev/null +++ b/GameEngine/resources/PortA.png Binary files differ diff --git a/GameEngine/resources/PortB.png b/GameEngine/resources/PortB.png new file mode 100644 index 0000000..e6c1186 --- /dev/null +++ b/GameEngine/resources/PortB.png Binary files differ diff --git a/GameEngine/src/main/java/gameEngine/GameEditor.java b/GameEngine/src/main/java/gameEngine/GameEditor.java index 8a1eeb6..15915d4 100644 --- a/GameEngine/src/main/java/gameEngine/GameEditor.java +++ b/GameEngine/src/main/java/gameEngine/GameEditor.java @@ -15,14 +15,14 @@ private Button playButton; private Text playButtonText; - private Button openButton; - private Text openButtonText; - private Button createObjectButton; private Text createObjectButtonText; - private Button createTextButton; - private Text createTextButtonText; + private Button createComponentViewButton; + private Text createComponentViewButtonText; + + private Button createEntityViewButton; + private Text createEntityViewButtonText; public GameEditor(Scene scene) { this.scene = scene; @@ -35,14 +35,14 @@ playButton = new Button(Window.get().width/ 2 -16 , 3, 1, 0.4f); playButtonText = new Text(Window.get().width/ 2 - 11.25f, 1, "Play", 24); - openButton = new Button(50, 3, 0.4f, 0.4f); - openButtonText = new Text(50 +5.25f, 0.4f, "+", 24); + createObjectButton = new Button(20, 33, 3.2f, 0.5f); + createObjectButtonText = new Text(20 +5.25f, 30.4f, "Add GameObject", 24); - createObjectButton = new Button(20, 73, 3.2f, 0.5f); - createObjectButtonText = new Text(20 +5.25f, 70.4f, "Add GameObject", 24); + createComponentViewButton = new Button(20, 73, 3.2f, 0.5f); + createComponentViewButtonText = new Text(20 +5.25f, 70.4f, "Add Component", 24); - createTextButton = new Button(20, 33, 3.2f, 0.5f); - createTextButtonText = new Text(20 +5.25f, 30.4f, "Add TextMesh", 24); + createEntityViewButton = new Button(20, 113, 3.2f, 0.5f); + createEntityViewButtonText = new Text(20 +5.25f, 110.4f, "Add Entity", 24); setButtonListeners(); } @@ -54,8 +54,11 @@ createObjectButton.clearListeners(); createObjectButton.addListener(scene::addNewObject); - createTextButton.clearListeners(); - createTextButton.addListener(scene::addNewTextMesh); + createComponentViewButton.clearListeners(); + createComponentViewButton.addListener(scene::addNewComponent); + + createEntityViewButton.clearListeners(); + createEntityViewButton.addListener(scene::addNewEntity); } public void setScene(Scene newScene) { @@ -69,8 +72,10 @@ playButtonText.update(); createObjectButton.update(); createObjectButtonText.update(); - createTextButton.update(); - createTextButtonText.update(); + createComponentViewButton.update(); + createComponentViewButtonText.update(); + createEntityViewButton.update(); + createEntityViewButtonText.update(); } private void createFrame(){ diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/ComponentView.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/ComponentView.java new file mode 100644 index 0000000..53d3e32 --- /dev/null +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/ComponentView.java @@ -0,0 +1,51 @@ +package gameEngine.entites.gameComponents; + +import gameEngine.entites.Entity; +import gameEngine.views.ConnectionLine; +import gameEngine.views.Sprite; +import org.joml.Vector3f; + +public class ComponentView extends Draggable{ + private Sprite sprite; + private PortView portviewA; + private PortView connectedEntity; + + public ComponentView(Entity entity){ + this.parent = entity; + this.sprite = new Sprite("GameEngine/resources/ComponentView.png"); + sprite.updateSpriteDimensions(); + portviewA = new PortView(true); + } + + @Override + public void init(){ + sprite.update(); + sprite.updateSpriteDimensions(); + } + + @Override + public void update() { + sprite.setPosition(parent.transform.position); + sprite.setRotation(parent.transform.rotation); + sprite.setScale(parent.transform.scale); + sprite.update(); + Vector3f pos = new Vector3f(parent.transform.position.x+82,parent.transform.position.y+12,parent.transform.position.z); + portviewA.update(pos, parent.transform.rotation, parent.transform.scale); + } + + @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); + } + + @Override + public GameComponent copy() { + return this; + } +} diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/EntityView.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/EntityView.java new file mode 100644 index 0000000..6d01c35 --- /dev/null +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/EntityView.java @@ -0,0 +1,58 @@ +package gameEngine.entites.gameComponents; + +import gameEngine.entites.Entity; +import gameEngine.views.Sprite; +import org.joml.Vector3f; + +public class EntityView extends Draggable{ + + private Sprite sprite; + private PortView portviewA; + private PortView portviewB; + + public EntityView(Entity entity){ + this.parent = entity; + this.sprite = new Sprite("GameEngine/resources/EntityView.png"); + sprite.updateSpriteDimensions(); + portviewA = new PortView(true); + portviewB = new PortView(false); + } + + @Override + public GameComponent copy() { + return this; + } + + @Override + public void init(){ + sprite.update(); + sprite.updateSpriteDimensions(); + } + + @Override + public void update() { + sprite.setPosition(parent.transform.position); + sprite.setRotation(parent.transform.rotation); + sprite.setScale(parent.transform.scale); + sprite.update(); + Vector3f pos = new Vector3f(parent.transform.position.x-15,parent.transform.position.y+10,parent.transform.position.z); + portviewA.update(pos, parent.transform.rotation, parent.transform.scale); + pos = new Vector3f(parent.transform.position.x-15,parent.transform.position.y+40,parent.transform.position.z); + portviewB.update(pos, parent.transform.rotation, parent.transform.scale); + } + + @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 PortView getPortView() { + return portviewA; + } +} diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java index 9787337..c3db312 100644 --- a/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/GameComponent.java @@ -1,6 +1,12 @@ package gameEngine.entites.gameComponents; +import org.joml.Vector3f; + public abstract class GameComponent { + + Vector3f localPosition = new Vector3f(0,0,0); + Vector3f localRotation = new Vector3f(0,0,0); + Vector3f localScale = new Vector3f(0,0,0); public abstract GameComponent copy(); public void init() { @@ -11,4 +17,14 @@ } + public void setLocalPosition(Vector3f pos){ + localPosition.set(pos); + } + public void setLocalRotation(Vector3f rot){ + localRotation.set(rot); + } + public void setLocalScale(Vector3f scale){ + localScale.set(scale); + } + } diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java index e02a376..93f1c67 100644 --- a/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Mesh.java @@ -3,6 +3,7 @@ import gameEngine.entites.Entity; import gameEngine.views.Color; import gameEngine.views.Sprite; +import org.joml.Vector3f; public class Mesh extends Draggable { @@ -44,9 +45,12 @@ @Override public void update() { if (type == MeshType.SPRITE) { - sprite.setPosition(parent.transform.position); - sprite.setRotation(parent.transform.rotation); - sprite.setScale(parent.transform.scale); + Vector3f globalPosition = new Vector3f(parent.transform.position).add(localPosition); + sprite.setPosition(globalPosition); + Vector3f globalRotation = new Vector3f(parent.transform.rotation).add(localRotation); + sprite.setRotation(globalRotation); + Vector3f globalScale = new Vector3f(parent.transform.scale).add(localScale); + sprite.setScale(globalScale); sprite.update(); } } diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/PortView.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/PortView.java new file mode 100644 index 0000000..b3e4bb6 --- /dev/null +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/PortView.java @@ -0,0 +1,26 @@ +package gameEngine.entites.gameComponents; + +import gameEngine.views.Sprite; +import org.joml.Vector3f; + +public class PortView { + private Sprite sprite; + + public PortView(boolean componentPort){ + if(componentPort){ + this.sprite = new Sprite("GameEngine/resources/PortA.png"); + sprite.updateSpriteDimensions(); + }else{ + this.sprite = new Sprite("GameEngine/resources/PortB.png"); + sprite.updateSpriteDimensions(); + } + } + + public void update(Vector3f pos, Vector3f rot, Vector3f scale){ + sprite.setPosition(pos); + sprite.setRotation(rot); + sprite.setScale(scale); + sprite.update(); + } + +} diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java index 8b4cbab..dae8dd9 100644 --- a/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java @@ -1,11 +1,18 @@ package gameEngine.entites.gameComponents; import gameEngine.entites.Entity; +import gameEngine.input.Input; +import gameEngine.input.MouseInput; import gameEngine.views.*; +import org.joml.Vector3f; + +import static org.lwjgl.glfw.GLFW.*; public class TextMesh extends Draggable{ private Text textRenderer; + private boolean isEditingText = false; + private StringBuilder inputBuffer = new StringBuilder(); public TextMesh(Entity parent, String text, int textSize) { this.parent = parent; @@ -15,10 +22,10 @@ public TextMesh(TextMesh original, Entity newParent) { this.parent = newParent; this.textRenderer = new Text( - newParent.transform.position.x, - newParent.transform.position.y, - original.textRenderer.text, - original.textRenderer.textSize + newParent.transform.position.x, + newParent.transform.position.y, + original.textRenderer.text, + original.textRenderer.textSize ); } @@ -34,10 +41,18 @@ @Override public void update() { - textRenderer.setPosition(parent.transform.position); - textRenderer.setRotation(parent.transform.rotation); - textRenderer.setScale(parent.transform.scale); - textRenderer.update(); + handleRightClickToggle(); + if (isEditingText) { + handleTextEditing(); + } else { + Vector3f globalPosition = new Vector3f(parent.transform.position).add(localPosition); + textRenderer.setPosition(globalPosition); + Vector3f globalRotation = new Vector3f(parent.transform.rotation).add(localRotation); + textRenderer.setRotation(globalRotation); + Vector3f globalScale = new Vector3f(parent.transform.scale).add(localScale); + textRenderer.setScale(globalScale); + textRenderer.update(); + } } @Override @@ -66,4 +81,48 @@ return textRenderer.textSize; } + private void handleRightClickToggle() { + if (Input.GetMouseButtonDown(GLFW_MOUSE_BUTTON_RIGHT) && isMouseOver(MouseInput.getX(), MouseInput.getY())) { + isEditingText = !isEditingText; // 右クリックで編集モードのトグル + if (isEditingText) { + inputBuffer = new StringBuilder(textRenderer.text); // 現在のテキストをバッファにコピー + textRenderer.setColor(Color.GRAY); // 編集中は灰色に変更 + } else { + textRenderer.setColor(textRenderer.color); // 編集終了時に色を戻す + setText(inputBuffer.toString()); + } + } + } + + private void handleTextEditing() { + // エンターキーで編集終了 + if (Input.GetKeyDown(GLFW_KEY_ENTER)) { + isEditingText = false; + setText(inputBuffer.toString()); + textRenderer.setColor(Color.WHITE); // 編集終了時に色を戻す + Window.get().getScene().clearSelectedEntity(); + inputBuffer.setLength(0); // バッファをクリア + return; + } + + // バックスペースキーで文字削除 + if (Input.GetKeyDown(GLFW_KEY_BACKSPACE)) { + if (inputBuffer.length() > 0) { + inputBuffer.deleteCharAt(inputBuffer.length() - 1); + } + } + + // 他のキー入力を処理 + for (int key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++) { + if (Input.GetKeyDown(key)) { + char typedChar = (char) key; // キーコードから文字を取得 + inputBuffer.append(typedChar); + } + } + + // 入力中のテキストをリアルタイムで表示 + textRenderer.setText(inputBuffer.toString()); + textRenderer.update(); + } + } diff --git a/GameEngine/src/main/java/gameEngine/scenes/Scene.java b/GameEngine/src/main/java/gameEngine/scenes/Scene.java index c1499c9..d80364f 100644 --- a/GameEngine/src/main/java/gameEngine/scenes/Scene.java +++ b/GameEngine/src/main/java/gameEngine/scenes/Scene.java @@ -8,6 +8,7 @@ import gameEngine.input.Input; import gameEngine.views.Color; import gameEngine.views.Window; +import org.joml.Vector3f; import java.awt.event.KeyEvent; import java.util.HashMap; @@ -88,8 +89,13 @@ return null; } - public Runnable addNewTextMesh() { - enqueueTask(this::addTextMesh); + public Runnable addNewComponent() { + enqueueTask(this::addComponentView); + return null; + } + + public Runnable addNewEntity() { + enqueueTask(this::addEntityView); return null; } @@ -107,12 +113,23 @@ 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)); + } - private void addTextMesh(){ + private void addEntityView(){ GameObject object = createGameObject(); object.transform.setPosition((float) Window.get().width / 2 ,(float) Window.get().height /2, 0); - object.addComponent(new TextMesh(object, "Text", 32)); + object.addComponent(new EntityView(object)); + object.addComponent(new TextMesh(object, "Entity", 16)); + object.getComponent(TextMesh.class).setLocalPosition(new Vector3f(0,-20,0)); + } + + private void addComponentView(){ + GameObject object = createGameObject(); + object.transform.setPosition((float) Window.get().width / 2 ,(float) Window.get().height /2, 0); + object.addComponent(new ComponentView(object)); + object.addComponent(new TextMesh(object, "Mesh", 24)); + object.getComponent(TextMesh.class).setLocalPosition(new Vector3f(10,5,0)); } diff --git a/GameEngine/src/main/java/gameEngine/views/Color.java b/GameEngine/src/main/java/gameEngine/views/Color.java index e3c9734..c5d3539 100644 --- a/GameEngine/src/main/java/gameEngine/views/Color.java +++ b/GameEngine/src/main/java/gameEngine/views/Color.java @@ -20,6 +20,7 @@ public static final Color BLUE = new Color(0, 0, 1); public static final Color WHITE = new Color(0, 0, 0); public static final Color BLACK = new Color(1, 1, 1); + public static final Color GRAY = new Color(0.75f,0.75f,0.75f); public static final Color YELLOW = new Color(1, 1, 0); public static final Color MAGENTA = new Color(1, 0, 1); public static final Color CYAN = new Color(0, 1, 1); diff --git a/GameEngine/src/main/java/gameEngine/views/ConnectionLine.java b/GameEngine/src/main/java/gameEngine/views/ConnectionLine.java new file mode 100644 index 0000000..3488c8d --- /dev/null +++ b/GameEngine/src/main/java/gameEngine/views/ConnectionLine.java @@ -0,0 +1,14 @@ +package gameEngine.views; + +import org.joml.Vector3f; +import static org.lwjgl.opengl.GL11.*; + +public class ConnectionLine { + public static void drawLine(Vector3f start, Vector3f end) { + glBegin(GL_LINES); + glVertex3f(start.x, start.y, start.z); + glVertex3f(end.x, end.y, end.z); + glEnd(); + } + +} diff --git a/GameEngine/src/main/java/gameEngine/views/Renderer.java b/GameEngine/src/main/java/gameEngine/views/Renderer.java index fa11129..ef3a9ab 100644 --- a/GameEngine/src/main/java/gameEngine/views/Renderer.java +++ b/GameEngine/src/main/java/gameEngine/views/Renderer.java @@ -8,7 +8,7 @@ protected Vector3f position = new Vector3f(0, 0, 0); protected Vector3f rotation = new Vector3f(0, 0, 0); protected Vector3f scale = new Vector3f(1, 1, 1); - protected Color color = new Color(1f, 1f, 1f, 1f); + public Color color = new Color(1f, 1f, 1f, 1f); public void setPosition(float x, float y){ this.position.x = x; diff --git a/GameEngine/src/main/java/gameEngine/views/Window.java b/GameEngine/src/main/java/gameEngine/views/Window.java index c8ee1a4..48b0353 100644 --- a/GameEngine/src/main/java/gameEngine/views/Window.java +++ b/GameEngine/src/main/java/gameEngine/views/Window.java @@ -167,19 +167,25 @@ currentScene.processTasks(); 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(); } + if(gameObject.getComponent(EntityView.class) != null){ + gameObject.getComponent(EntityView.class).update(); + } + if(gameObject.getComponent(ComponentView.class) != null){ + gameObject.getComponent(ComponentView.class).update(); + } if(gameObject.getComponent(TextMesh.class) != null){ gameObject.getComponent(TextMesh.class).update(); } if(gameObject.getComponent(ButtonComponent.class) != null)gameObject.getComponent(ButtonComponent.class).update(); } } + gameEditor.update(); } else { for (Entity entity : currentScene.entities.values()) {