diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/Collider.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Collider.java new file mode 100644 index 0000000..e90c85b --- /dev/null +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/Collider.java @@ -0,0 +1,107 @@ +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; + } +}