/** * Cette méthode teste si une collision va avoir lieu entre les deux hitbox dans le temps imparti. * * <p>Attention, cette méthode déplace les deux hitbox et ne les remet pas en place, afin * d'économiser des calculs. Si une collision est détectée, il appartient aux hitbox filles de * recaler les hitbox au point de collision. * * <p>Une conséquence est que les deux hitbox auront le même {@link #timeOffset} si cette méthode * renvoie <tt>true</tt>. * * <p>Un appel à la méthode {@link #completeMove(float)} permettra de clore le mouvement, une fois * toutes les collisions calculées. */ protected boolean testCollision(Hitbox other, float time) { if (!canCollide(other)) return false; Hitbox[] both = new Hitbox[] {this, other}; // prétest visant à réduire les calculs if (this.speedX == other.speedX && this.speedY == other.speedY) { return false; } if (MathUtil.getSquaredDistance(this.x, this.y, other.x, other.y) > 4 * 4) { // TODO Changer ce critère pourri return false; } // Procédure de détection de collision float maxTime = time; for (Hitbox hb : both) { if (hb.nextCollisionPoint != null) { maxTime = hb.nextCollisionPoint.getTime(); } } for (Hitbox hb : both) { hb.setTimeOffset(maxTime); } return this.intersects(other); }
@Override public Hitbox clone() { Hitbox clone = null; try { clone = (Hitbox) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } clone.force = this.force.clone(); return clone; }
public void calculateNextCollisionPoint(Hitbox other, float time) { if (!testCollision(other, time)) { return; } CollisionPoint cp = getCurrentCollisionPoint(other, time); // détection des collisions infinies if (this.lastCollision >= cp.getTime() && this.lastHitboxes.contains(other)) { return; } Hitbox[] both = new Hitbox[] {this, other}; for (Hitbox hb : both) { if (hb.nextCollisionPoint != null) hb.nextCollisionPoint.delete(); hb.nextCollisionPoint = cp; } }
/** * Déplace les hitbox passées en paramètre en leur point de collision. On suppose que les objets * s'interpénètrent à t = <tt>time</tt>, et ne se touche pas à t = 0. Cette méthode trouve un * point de collision approximé par dichotomie. */ protected final CollisionPoint findCollisionPointDefault(Hitbox other, float time) { Hitbox both[] = new Hitbox[] {this, other}; float lower = Math.max(this.lastCollision, other.lastCollision); float higher = time; while (higher - lower > 0.0001) { float bound = (higher + lower) / 2; for (Hitbox hb : both) { hb.applyVelocity(bound - hb.timeOffset); } if (this.intersects(other)) { higher = bound; } else { lower = bound; } } return new CollisionPoint(lower, this, other); }
protected void ensureSameTimeOffset(Hitbox other) { if (Math.abs(this.timeOffset - other.timeOffset) > 0.001) { other.applyVelocity(this.timeOffset - other.timeOffset); } }