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

}