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.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));
    }

}