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