package gameEngine; import gameEngine.entites.Entity; import gameEngine.entites.GameObject; import gameEngine.entites.gameComponents.GameComponent; import gameEngine.entites.gameComponents.Mesh; import gameEngine.entites.gameComponents.MoveImage; 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; private Timer updateTimer; public GameEditor() { setTitle("Game Object Editor"); setSize(600, 500); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // 閉じられないようにする setLayout(null); // レイアウトを絶対座標に設定 initializeUIComponents();// 各UI要素の初期化 initializeUpdateTimer(); // 定期的にリスト更新を行うタイマーを初期化 setVisible(true); // フレームを表示 } // UI要素を初期化し、配置関数を呼び出す private void initializeUIComponents() { listModel = new DefaultListModel<>(); objectList = new JList<>(listModel); JScrollPane scrollPane = new JScrollPane(objectList); objectList.setCellRenderer(createEntityRenderer()); componentListModel = new DefaultListModel<>(); componentList = new JList<>(componentListModel); JScrollPane componentScrollPane = new JScrollPane(componentList); componentList.setCellRenderer(createComponentRenderer()); // 各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("Add 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 JTextField createTextField() { return new JTextField(5); } // タイマーによる定期的なリスト更新 private void initializeUpdateTimer() { updateTimer = new Timer(1000, e -> { updateGameObjectList(gameScene); if (objectList.getSelectedValue() != null) { Entity selectedEntity = gameScene.getEntity(objectList.getSelectedValue()); if (selectedEntity instanceof GameObject) { updateComponentList((GameObject) selectedEntity); } } }); updateTimer.start(); } private ListCellRenderer<String> createEntityRenderer() { return (list, value, index, isSelected, cellHasFocus) -> { JLabel label = new JLabel(); Entity entity = gameScene.getEntity(value); label.setText(entity.name); label.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground()); label.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground()); label.setOpaque(true); return label; }; } private ListCellRenderer<GameComponent> createComponentRenderer() { return (list, value, index, isSelected, cellHasFocus) -> { JLabel label = new JLabel(value.getClass().getSimpleName()); label.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground()); label.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground()); label.setOpaque(true); return label; }; } 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.addNewObject(); // 新しいGameObjectを作成 updateGameObjectList(gameScene); // オブジェクトリストの更新 objectList.setSelectedIndex(listModel.getSize() - 1); // 新規作成したオブジェクトを選択 applyGameObjectChanges(); // 作成直後に即座にプロパティを反映させる } private void addComponentToGameObject() { String selectedIdStr = objectList.getSelectedValue(); if (selectedIdStr != null) { Entity selectedEntity = gameScene.getEntity(selectedIdStr); if (selectedEntity instanceof GameObject) { GameObject gameObject = (GameObject) selectedEntity; System.out.println("仮でMeshコンポーネントを付与します"); gameScene.addComponentToGameObject(gameObject, new MoveImage(gameObject)); updateComponentList(gameObject); // コンポーネントリストの更新 updateGameObjectList(gameScene); // オブジェクトリストの更新 JOptionPane.showMessageDialog(this, "Component Added to " + selectedEntity.name); } } } private void removeComponentFromGameObject() { String selectedIdStr = objectList.getSelectedValue(); if (selectedIdStr != null) { Entity selectedEntity = gameScene.getEntity(selectedIdStr); if (selectedEntity instanceof GameObject) { GameObject gameObject = (GameObject) selectedEntity; GameComponent selectedComponent = componentList.getSelectedValue(); // GameComponentとして取得 if (selectedComponent != null) { gameScene.removeComponentFromGameObject(gameObject, selectedComponent); updateComponentList(gameObject); // コンポーネントリストの更新 JOptionPane.showMessageDialog(this, "Component Removed from " + selectedEntity.name); } } } } private void updateGameObjectList(Scene gameScene) { listModel.clear(); // リストの初期化 for (Map.Entry<String, Entity> entry : gameScene.entities.entrySet()) { Entity entity = entry.getValue(); listModel.addElement(entity.getId()); // そのままIDをリストに追加 } objectList.repaint(); // リストを再描画 } private void updateComponentList(GameObject gameObject) { componentListModel.clear(); // リストをクリア List<GameComponent> components = gameObject.gameComponents; for (GameComponent component : components) { componentListModel.addElement(component); // コンポーネントを追加 } componentList.repaint(); } // 選択されたGameObjectのプロパティをロードする private void loadSelectedGameObject() { String selectedIdStr = objectList.getSelectedValue(); if (selectedIdStr != null) { Entity selectedEntity = gameScene.getEntity(selectedIdStr); // IDのまま取得 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) { Entity selectedEntity = gameScene.getEntity(selectedIdStr); // IDのまま取得 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); // オブジェクトリストの再描画 } } } 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)); } }