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