package gameEngine; import gameEngine.entites.Entity; import gameEngine.entites.GameObject; import gameEngine.entites.gameComponents.GameComponent; import gameEngine.scenes.*; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import java.util.Map; public class GameEditor extends JFrame { private JList<String> objectList; private DefaultListModel<String> listModel; private DefaultListModel<GameComponent> componentListModel; private JList<GameComponent> componentList; private JLabel nameLabel, posLabel, rotLabel, scaLabel; private JTextField posXField, posYField, posZField; private JTextField rotXField, rotYField, rotZField; private JTextField scaleXField, scaleYField, scaleZField; private JTextField nameField; private Scene gameScene; public GameEditor() { setTitle("Game Object Editor"); setSize(600, 500); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // 閉じられないようにする setLayout(null); // レイアウトを絶対座標に設定 initializeUIComponents();// 各UI要素の初期化 setVisible(true); // フレームを表示 } // UI要素を初期化し、配置関数を呼び出す private void initializeUIComponents() { listModel = new DefaultListModel<>(); objectList = new JList<>(listModel); JScrollPane scrollPane = new JScrollPane(objectList); objectList.setCellRenderer(new ListCellRenderer<String>() { @Override public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = new JLabel(); int id = Integer.parseInt(value); // 内部でIDを使用 Entity entity = gameScene.entities.get(id); label.setText(entity.name); // リストには名前を表示する if (isSelected) { label.setBackground(list.getSelectionBackground()); label.setForeground(list.getSelectionForeground()); } else { label.setBackground(list.getBackground()); label.setForeground(list.getForeground()); } label.setOpaque(true); // 背景色が表示されるようにする return label; } }); componentListModel = new DefaultListModel<GameComponent>(); componentList = new JList<GameComponent>(componentListModel); JScrollPane componentScrollPane = new JScrollPane(componentList); componentList.setCellRenderer(new ListCellRenderer<GameComponent>() { @Override public Component getListCellRendererComponent(JList<? extends GameComponent> list, GameComponent value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = new JLabel(); label.setText(value.getClass().getSimpleName()); // クラス名を表示 if (isSelected) { label.setBackground(list.getSelectionBackground()); label.setForeground(list.getSelectionForeground()); } else { label.setBackground(list.getBackground()); label.setForeground(list.getForeground()); } label.setOpaque(true); // 背景色が表示されるようにする return label; } }); // 各UIコンポーネントの作成と配置 nameField = new JTextField(20); nameLabel = new JLabel("Name:"); posLabel = new JLabel("Position:"); rotLabel = new JLabel("Rotation:"); scaLabel = new JLabel("Scale:"); posXField = new JTextField(5); posYField = new JTextField(5); posZField = new JTextField(5); rotXField = new JTextField(5); rotYField = new JTextField(5); rotZField = new JTextField(5); scaleXField = new JTextField(5); scaleYField = new JTextField(5); scaleZField = new JTextField(5); JButton newGameObjectButton = new JButton("New Entity"); newGameObjectButton.addActionListener(e -> createNewGameObject()); JButton addComponentButton = new JButton("Add Component"); addComponentButton.addActionListener(e -> addComponentToGameObject()); JButton removeComponentButton = new JButton("Remove Component"); removeComponentButton.addActionListener(e -> removeComponentFromGameObject()); JButton applyButton = new JButton("Apply"); applyButton.addActionListener(new ApplyButtonListener()); // 各要素の位置とサイズを設定 setComponentBounds(scrollPane, 10, 10, 150, 400); setComponentBounds(componentScrollPane, 400, 200, 130, 200); setComponentBounds(nameLabel, 200, 10, 100, 30); setComponentBounds(nameField, 250, 10, 200, 30); setComponentBounds(posLabel, 180, 50, 100, 30); setComponentBounds(posXField, 250, 50, 50, 30); setComponentBounds(posYField, 310, 50, 50, 30); setComponentBounds(posZField, 370, 50, 50, 30); setComponentBounds(rotLabel, 180, 90, 100, 30); setComponentBounds(rotXField, 250, 90, 50, 30); setComponentBounds(rotYField, 310, 90, 50, 30); setComponentBounds(rotZField, 370, 90, 50, 30); setComponentBounds(scaLabel, 180, 130, 100, 30); setComponentBounds(scaleXField, 250, 130, 50, 30); setComponentBounds(scaleYField, 310, 130, 50, 30); setComponentBounds(scaleZField, 370, 130, 50, 30); setComponentBounds(newGameObjectButton, 200, 170, 150, 30); setComponentBounds(addComponentButton, 200, 250, 150, 30); setComponentBounds(removeComponentButton, 200, 290, 150, 30); setComponentBounds(applyButton, 200, 400, 100, 25); objectList.addListSelectionListener(e -> { if (!e.getValueIsAdjusting()) { // ユーザーが調整中でない場合のみ loadSelectedGameObject(); // オブジェクトをロード } }); } private void setComponentBounds(Component component, int x, int y, int width, int height) { component.setBounds(x, y, width, height); add(component); //フレームに追加 } private void createNewGameObject() { gameScene.createNewObject(); // 新しいGameObjectを作成 updateGameObjectList(gameScene); // オブジェクトリストの更新 objectList.repaint(); // リストを再描画 objectList.revalidate(); // リストを再構築 objectList.setSelectedIndex(listModel.getSize() - 1); // 新規作成したオブジェクトを選択 applyGameObjectChanges(); // 作成直後に即座にプロパティを反映させる } private void addComponentToGameObject() { String selectedIdStr = objectList.getSelectedValue(); if (selectedIdStr != null) { int selectedId = Integer.parseInt(selectedIdStr); Entity selectedEntity = gameScene.entities.get(selectedId); if (selectedEntity instanceof GameObject) { GameObject gameObject = (GameObject) selectedEntity; gameScene.addComponent(gameObject); // コンポーネントの追加処理 updateComponentList(gameObject); // コンポーネントリストの更新 updateGameObjectList(gameScene); // オブジェクトリストの更新 JOptionPane.showMessageDialog(this, "Component Added to " + selectedEntity.name); } } } private void removeComponentFromGameObject() { String selectedIdStr = objectList.getSelectedValue(); if (selectedIdStr != null) { int selectedId = Integer.parseInt(selectedIdStr); Entity selectedEntity = gameScene.entities.get(selectedId); if (selectedEntity instanceof GameObject) { GameObject gameObject = (GameObject) selectedEntity; GameComponent selectedComponent = componentList.getSelectedValue(); // GameComponentとして取得 if (selectedComponent != null) { gameScene.removeComponent(gameObject, selectedComponent); // GameComponentオブジェクトを渡す updateComponentList(gameObject); // コンポーネントリストの更新 updateGameObjectList(gameScene); // オブジェクトリストの更新 JOptionPane.showMessageDialog(this, "Component Removed from " + selectedEntity.name); } } } } private void updateGameObjectList(Scene gameScene) { listModel.clear(); // リストの初期化 for (Map.Entry<Integer, Entity> entry : gameScene.entities.entrySet()) { Entity entity = entry.getValue(); listModel.addElement(String.valueOf(entity.getId())); // IDをリストに追加 } objectList.repaint(); // リストを再描画 objectList.revalidate(); // リストを再構築 if (!listModel.isEmpty()) { objectList.setSelectedIndex(0); // 最初の項目を自動選択 } } private void updateComponentList(GameObject gameObject) { componentListModel.clear(); // リストをクリア List<GameComponent> components = gameObject.gameComponents; for (GameComponent component : components) { componentListModel.addElement(component); // コンポーネントを追加 } if (components.isEmpty()) { // 選択解除して、空の状態を扱う componentList.clearSelection(); componentList.repaint(); } } // 選択されたGameObjectのプロパティをロードする private void loadSelectedGameObject() { String selectedIdStr = objectList.getSelectedValue(); if (selectedIdStr != null) { int selectedId = Integer.parseInt(selectedIdStr); Entity selectedEntity = gameScene.entities.get(selectedId); if (selectedEntity != null) { loadObjectProperties(selectedEntity); // コンポーネントリストの更新 if (selectedEntity instanceof GameObject) { updateComponentList((GameObject) selectedEntity); } } } } // 選択されたGameObjectのプロパティを更新 private class ApplyButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { applyGameObjectChanges(); } } private void applyGameObjectChanges() { String selectedIdStr = objectList.getSelectedValue(); if (selectedIdStr != null) { int selectedId = Integer.parseInt(selectedIdStr); Entity selectedEntity = gameScene.entities.get(selectedId); if (selectedEntity != null) { selectedEntity.name = nameField.getText(); selectedEntity.transform.setPosition( Float.parseFloat(posXField.getText()), Float.parseFloat(posYField.getText()), Float.parseFloat(posZField.getText()) ); selectedEntity.transform.setRotation( Float.parseFloat(rotXField.getText()), Float.parseFloat(rotYField.getText()), Float.parseFloat(rotZField.getText()) ); selectedEntity.transform.setScale( Float.parseFloat(scaleXField.getText()), Float.parseFloat(scaleYField.getText()), Float.parseFloat(scaleZField.getText()) ); updateGameObjectList(gameScene); // オブジェクトリストの再描画 objectList.repaint(); // リストの再描画を強制 } } } public void updateListByScene(Scene gameScene) { this.gameScene = gameScene; updateGameObjectList(gameScene); } private void loadObjectProperties(Entity entity) { nameField.setText(entity.name); posXField.setText(String.valueOf(entity.transform.position.x)); posYField.setText(String.valueOf(entity.transform.position.y)); posZField.setText(String.valueOf(entity.transform.position.z)); rotXField.setText(String.valueOf(entity.transform.rotation.x)); rotYField.setText(String.valueOf(entity.transform.rotation.y)); rotZField.setText(String.valueOf(entity.transform.rotation.z)); scaleXField.setText(String.valueOf(entity.transform.scale.x)); scaleYField.setText(String.valueOf(entity.transform.scale.y)); scaleZField.setText(String.valueOf(entity.transform.scale.z)); } }