public bool HitCheck(Universe universe, Physical phys) { if (phys != parent) { Vector2 bounce; if ( phys.shield != null && phys.shield.active) { ComponentShield shield = phys.shield; Intersection sect = shield.hitbox.Intersect(pos); if ( sect != null ) { bounce = Utility.Bounce(velocity - phys.velocity, sect.surface_normal); bounce.Normalize(); explosion.Explode(universe, pos, phys.velocity, bounce); shield.BlockDamage(explosion.dmg, pos); this.Destory(); return true; } } else { Intersection sect = phys.hitbox.Intersect(pos); if (sect != null) { bounce = Utility.Bounce(velocity - phys.velocity, sect.surface_normal); bounce.Normalize(); explosion.Explode(universe, pos, phys.velocity, bounce); phys.AdsorbExplosion(explosion, pos); this.Destory(); return true; } } } return false; }
public bool HitCheck(Physical phys) { Intersection sect = hitbox.Intersect(phys.hitbox); if (sect == null) { return false; } Vector2 this_ecc = sect.position - pos; Vector2 phys_ecc = sect.position - phys.pos; // determine the velocities at the points of impact, this includes the velocity due to radial effects Vector2 v1 = velocity + Utility.RotatePos(this_ecc * angular_velocity); Vector2 v2 = phys.velocity + Utility.RotatePos(phys_ecc * phys.angular_velocity); // get the relative velocity at the impact point Vector2 relative_impact_velocity = (v1 - v2); // modify the imact velocity in the direction of the surface normal. // This is based on the overlap, and functions as a spring. relative_impact_velocity += (Utility.CosSin(sect.surface_normal) * (0.2f + (sect.overlap * 0.05f))); // calculate the 'bounce' velocity. // The velocity which must be created between the two physicals, as a result of the collision Vector2 surface_aligned = Utility.Rotate(relative_impact_velocity, -sect.surface_normal); surface_aligned.X *= -GameConst.collision_elasticity; // bouncyness surface_aligned.Y *= -GameConst.collision_friction; // friction Vector2 bounce = Utility.Rotate(surface_aligned, sect.surface_normal); float this_mass_ratio = mass / (mass + phys.mass); float phys_mass_ratio = phys.mass / (mass + phys.mass); // modify the physicals positions, to remove them from the collision. // this may cause problems if it pushes a ship into a second collsion. Whatevs. this.pos += bounce * 1.5f * phys_mass_ratio; phys.pos -= bounce * 1.5f * this_mass_ratio; /* Replaced by the below // calculate the generated foce between each ship required to produce the bounce velocity ector2 force = ((bounce) / ((1 / mass) + (1 / phys.mass))); Vector2 velocity_this = (force / mass) + Utility.RotatePos(eccentricity_this * Utility.Cross(eccentricity_this, force) / intertia); Vector2 velocity_phys = (force / phys.mass) + Utility.RotatePos(eccentricity_phys * Utility.Cross(eccentricity_phys, force) / phys.intertia) */ // Calculate some constants. float A1 = (1.0f / this.mass) + (1.0f / phys.mass) + (this_ecc.Y * this_ecc.Y / this.inertia) + (phys_ecc.Y * phys_ecc.Y / phys.inertia); float B1 = (this_ecc.Y * this_ecc.X / this.inertia) + (phys_ecc.Y * phys_ecc.X / phys.inertia); float A2 = (1.0f / this.mass) + (1.0f / phys.mass) + (this_ecc.X * this_ecc.X / this.inertia) + (phys_ecc.X * phys_ecc.X / phys.inertia); float B2 = (this_ecc.X * this_ecc.Y / this.inertia) + (phys_ecc.X * phys_ecc.Y / phys.inertia); // Solve for the force in the X and Y directions. float Fx = ((B1 * bounce.Y / (A1 * A2)) + (bounce.X / A1)) / (1.0f - (B1 * B2 / (A1 * A2))); float Fy = ((B2 * Fx) + bounce.Y) / A2; Vector2 force = new Vector2(Fx, Fy); // apply the forces. this.Push(force, this_ecc); phys.Push(-force, phys_ecc); // generate an explosion as the result of the collision. // the radius is ish 1/4 of the larger hulls's radius. Maybe look into whether that is smart. Explosion exp = AssetWeaponTemplates.collision_explosion * force.Length(); // apply the damage to the phys. this.AdsorbExplosion(exp, sect.position); phys.AdsorbExplosion(exp, sect.position); Vector2 explosion_velocity = phys_mass_ratio * phys.velocity + this_mass_ratio * this.velocity; // Inform the universe of the explosion. exp.Explode(universe, sect.position, explosion_velocity, Utility.CosSin(sect.surface_normal + MathHelper.PiOver2)); return true; // a collision was indeed serviced. }