Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / gameEngine / entites / gameComponents / Collider.java
NoranekoFelician 3 days ago 3 KB ・Colliderコンポーネントの追加
package gameEngine.entites.gameComponents;

import gameEngine.entites.Entity;
import gameEngine.entites.GameObject;
import gameEngine.views.Window;

public class Collider extends GameComponent {
    private GameObject parent;
    private boolean isPassable; // すり抜け可能かどうか

    public Collider(GameObject parent, boolean isPassable) {
        this.parent = parent;
        this.isPassable = isPassable;
    }

    @Override
    public GameComponent copy() {
        return new Collider(parent, isPassable);
    }

    @Override
    public void init() {
    }

    @Override
    public void update() {
        for (Entity other : Window.get().getScene().entities.values()) {
            GameObject otherObject = (GameObject) other;
            if (otherObject == parent) continue; // 自分自身は無視

            Collider otherCollider = otherObject.getComponent(Collider.class);
            if (otherCollider != null && isCollidingWith(otherObject)) {
                System.out.println("Collision detected between "
                        + parent.getName() + " and " + otherObject.getName());

                if (!isPassable && !otherCollider.isPassable) {
                    resolveCollision(otherObject);
                }
            }
        }
    }

    private boolean isCollidingWith(GameObject other) {
        Mesh thisMesh = parent.getComponent(Mesh.class);
        Mesh otherMesh = other.getComponent(Mesh.class);

        if (thisMesh == null || otherMesh == null) {
            return false; // Meshがない場合は判定できない
        }

        float thisLeft = parent.transform.position.x;
        float thisRight = thisLeft + thisMesh.getDisplayedWidth();
        float thisTop = parent.transform.position.y;
        float thisBottom = thisTop + thisMesh.getDisplayedHeight();

        float otherLeft = other.transform.position.x;
        float otherRight = otherLeft + otherMesh.getDisplayedWidth();
        float otherTop = other.transform.position.y;
        float otherBottom = otherTop + otherMesh.getDisplayedHeight();

        return thisRight > otherLeft && thisLeft < otherRight &&
                thisBottom > otherTop && thisTop < otherBottom;
    }

    private void resolveCollision(GameObject other) {
        // 衝突を解消する処理
        Mesh thisMesh = parent.getComponent(Mesh.class);
        Mesh otherMesh = other.getComponent(Mesh.class);

        if (thisMesh == null || otherMesh == null) {
            return;
        }

        float thisLeft = parent.transform.position.x;
        float thisRight = thisLeft + thisMesh.getDisplayedWidth();
        float thisTop = parent.transform.position.y;
        float thisBottom = thisTop + thisMesh.getDisplayedHeight();

        float otherLeft = other.transform.position.x;
        float otherRight = otherLeft + otherMesh.getDisplayedWidth();
        float otherTop = other.transform.position.y;
        float otherBottom = otherTop + otherMesh.getDisplayedHeight();

        float overlapX = Math.min(thisRight, otherRight) - Math.max(thisLeft, otherLeft);
        float overlapY = Math.min(thisBottom, otherBottom) - Math.max(thisTop, otherTop);

        if (overlapX < overlapY) {
            // 横方向の重なりを解消
            if (thisLeft < otherLeft) {
                parent.transform.position.x -= overlapX;
            } else {
                parent.transform.position.x += overlapX;
            }
        } else {
            // 縦方向の重なりを解消
            if (thisTop < otherTop) {
                parent.transform.position.y -= overlapY;
            } else {
                parent.transform.position.y += overlapY;
            }
        }
    }

    public boolean isPassable() {
        return isPassable;
    }
}