private static void r_rebound(PhysicActor actor, Rectangle rect, double dt) { /* * Employ a heuristic * ------------ * | 0 | * | 1 RECT 3 | * | 2 | * ------------ */ actor.set_last_obstacle_collided(rect); Vector actor_pos = actor.get_position().add(actor.get_velocity().multiply(dt)); Rectangle actor_mbr = actor.get().get_mbr(); double h[] = { actor_pos.y + actor_mbr.y1 - rect.y2, actor_pos.y + actor_mbr.y2 - rect.y1, actor_pos.x + actor_mbr.x2 - rect.x1, actor_pos.x + actor_mbr.x1 - rect.x2 }; for (int i = 0; i < 4; i++) h[i] = Math.abs(h[i]); // now the question is - which of those is the smallest? double smallest_val = Double.POSITIVE_INFINITY; int smallest_index = -1; for (int i = 0; i < 4; i++) if (smallest_val > h[i]) { smallest_val = h[i]; smallest_index = i; } assert (smallest_index != -1); // ok, smallest_index is that if (smallest_index == 0) // colliding with floor Rebound.actor_hit_floor(actor, rect.y2, dt); if (smallest_index == 1) // colliding with roof Rebound.actor_hit_roof(actor, rect.y1, dt); if (smallest_index == 2) { Rebound.actor_hit_rightside(actor, rect.x1, dt); if (actor.get_last_obstacle_collided() != rect) { actor.set_v_braked(true); actor.set_last_obstacle_collided(rect); } } if (smallest_index == 3) { Rebound.actor_hit_leftside(actor, rect.x2, dt); if (actor.get_last_obstacle_collided() != rect) { actor.set_v_braked(true); actor.set_last_obstacle_collided(rect); } } }
/** * Rebound an actor by a platform. Actor must collide with platform. * * <p>Can mutate both actor position and velocity. Will not touch anchor nor flags. * * @param actor actor (can be mutated) * @param hs platform * @param dt time delta */ public static void rebound(PhysicActor actor, HorizSegment hs, double dt) { actor.set_v_braked(true).on_vbrake(actor.get_h_moving()); double actor_x = actor.get_position().x; double actor_y = hs.y - actor.get().get_mbr().y1 + Rebound.GRAVITY_EPSILON; actor.set_position(new Vector(actor_x, actor_y)); actor.set_velocity(actor.get_velocity().force_y(0)); // Friction?? if (actor.get_h_moving()) return; // Actor wants to move, no friction Vector vel = actor.get_velocity(); if (Math.abs(vel.x) < Rebound.FRICTION * dt) vel.x = 0; else vel.x += -Math.abs(vel.x) / vel.x * Rebound.FRICTION * dt; actor.set_velocity(vel); }
/** Modify the actor, as it has hit the floor */ private static void actor_hit_floor(PhysicActor actor, double fy, double dt) { actor.on_vbrake(actor.get_h_moving()); actor.set_v_braked(true).set_velocity(actor.get_velocity().force_y(0)); actor.set_position( actor.get_position().force_y(fy - actor.get().get_mbr().y1 + Rebound.GRAVITY_EPSILON)); if (!actor.get_h_moving()) { // consider friction if (Math.abs(actor.get_velocity().x) < Rebound.FRICTION * dt) { actor.set_velocity(actor.get_velocity().force_x(0)); actor.on_hbrake(); } else { actor.set_velocity( actor .get_velocity() .add_x( -Math.abs(actor.get_velocity().x) / actor.get_velocity().x * Rebound.FRICTION * dt)); } } }