/// <summary> /// Processes a potential collision between two blockers. /// Returns either the data for the blockers' collision, or "null" if there was no collision. /// </summary> public static BlockerCollisionData CheckCollision(Blocker first, Blocker second) { if (!first.ColShape.Touches(second.ColShape)) return null; BlockerCollisionData dat = new BlockerCollisionData(first, second, first.Mass * first.Velocity, second.Mass * second.Velocity); first.OnHitBlocker(second); return dat; }
/// <summary> /// Processes a potential collision between a blocker and a jouster. /// Returns either the force of the jouster's thrust at the blocker, or Single.NaN if there was no collision. /// </summary> public static float CheckCollision(Blocker block, Jouster joust) { if (!block.ColShape.Touches(joust.ColShape)) return Single.NaN; V2 lookDir = UsefulMath.FindDirection(joust.Rotation), moveDir = joust.Velocity; float stabStrength = joust.Mass * V2.Dot(lookDir, moveDir); block.OnHitJouster(joust, stabStrength); return stabStrength; }
public void LaunchRing(V2 pos, V2 dir) { Jousting.Blocker ring = new Jousting.Blocker(new Utilities.Graphics.AnimatedSprite(ArtAssets5.Ring), ArtAssets5.GetRingShape(pos, WorldData.ZoomScaleAmount[CurrentZoom]), true, PhysicsData5.GetRingSpeed(WorldData.ZoomScaleAmount[CurrentZoom])); ring.Rotation = UsefulMath.FindRotation(dir); ring.Velocity = ring.MaxVelocity * dir; //ring ring.OnHitByJouster += (s, e) => { if (e.Enemy.ThisJouster == Jousting.Jousters.Dischord) return; e.Enemy.Health -= PhysicsData5.RingDamage; KillBlocker((Jousting.Blocker)s); }; Blockers.Add(ring); }
/// <summary> /// Queues the given blocker to be destroyed next Update() call. /// </summary> public void KillBlocker(Blocker b) { ToRemove.Add(b); }
public void OnHitBlocker(Blocker other) { //No hitting if both blockers don't move. if (!IsMovable && !other.IsMovable) return; MovementPhysics.Separate(this, other, 0.2f * WorldData.ZoomScaleAmount[KarmaWorld.World.CurrentZoom]); //Raise collision events. if (OnHitByBlocker != null) OnHitByBlocker(this, new HitBlockerEventArgs(other)); if (other.OnHitByBlocker != null) other.OnHitByBlocker(this, new HitBlockerEventArgs(this)); //If both blockers are movable, react accordingly. if (IsMovable && other.IsMovable) { //Define "tangent" as the line perpendicular to the line from one Blocker to the other. //Both entities keep the portion of momentum parallel to their tangent, //But swap the portion of momentum perpendicular to their tangent. V2 toOther = other.Pos - Pos; V2 tangent = V2.Normalize(Utilities.Conversions.GetPerp(toOther)); Utilities.Conversions.ParallelPerp thisPP = Utilities.Conversions.SplitIntoComponents(Velocity, tangent), otherPP = Utilities.Conversions.SplitIntoComponents(other.Velocity, tangent); Velocity = thisPP.Parallel + (BounceVelocityDamp * otherPP.Perpendicular * other.Mass / Mass); other.Velocity = otherPP.Parallel + (other.BounceVelocityDamp * thisPP.Perpendicular * Mass / other.Mass); } //Otherwise, one will bounce off. else { Blocker movable = (IsMovable ? this : other); Blocker nonMovable = (movable == this ? other : this); V2 away = UsefulMath.FindDirection(nonMovable.Pos, movable.Pos); Utilities.Conversions.ParallelPerp pp = Utilities.Conversions.SplitIntoComponents(movable.Velocity, away); movable.Velocity = pp.Perpendicular + (movable.BounceVelocityDamp * -pp.Parallel); } }
public HitBlockerEventArgs(Blocker other) { Other = other; }
public BlockerCollisionData(Blocker first, Blocker second, V2 firstM, V2 secondM) { First = first; Second = second; FirstMomentum = firstM; SecondMomentum = secondM; }
protected override void Reset() { Blockers.Add(new Jousting.Blocker(ArtAssets5.BlackHole, PhysicsData5.GetBlackHole(), true, 0.0f, 1.0f)); Blockers[0].OnHitByJouster += (s, e) => { e.Enemy.Velocity = WorldData.ZoomScaleAmount[World.CurrentZoom] * PhysicsData5.BlackHolePushBack * V2.Normalize(UsefulMath.FindDirection(e.Enemy.Pos, BlackHole.Pos, false)); e.Enemy.Health -= PhysicsData5.BlackHoleDamage; }; BlackHole = Blockers[0]; }
protected override void Reset() { Blockers.Add(new Jousting.Blocker(ArtAssets5.BlackHole, PhysicsData5.GetBlackHole(), true, 0.0f, 1.0f)); Blockers[0].OnHitByJouster += (s, e) => { e.Enemy.Velocity = WorldData.ZoomScaleAmount[World.CurrentZoom] * PhysicsData5.BlackHolePushBack * V2.Normalize(UsefulMath.FindDirection(e.Enemy.Pos, BlackHole.Pos, false)); e.Enemy.Health -= PhysicsData5.BlackHoleDamage; SoundAssets5.SunExplode.Play(); V2 fromSun = UsefulMath.FindDirection(BlackHole.Pos, e.Enemy.Pos); AdditiveParticles.Merge(ParticleAssets5.GetSunHitParticles(fromSun, BlackHole.Pos + (fromSun * BlackHoleCol.Radius), World.CurrentTime)); }; BlackHole = Blockers[0]; Harmony.OnHurtEnemy += (s, e) => { SoundAssets5.PlayRandomCollision(); AdditiveParticles.Merge(ParticleAssets5.GetPlanetHitParticles((e.Enemy.Pos + Harmony.Pos) * 0.5f, Utilities.Conversions.GetPerp(UsefulMath.FindDirection(e.Enemy.Pos, Harmony.Pos)), World.CurrentTime)); }; Harmony.OnHurtByEnemy += (s, e) => { SoundAssets5.PlayRandomCollision(); AdditiveParticles.Merge(ParticleAssets5.GetPlanetHitParticles((e.Enemy.Pos + Harmony.Pos) * 0.5f, Utilities.Conversions.GetPerp(UsefulMath.FindDirection(e.Enemy.Pos, Harmony.Pos)), World.CurrentTime)); }; Harmony.WrapAround = true; Dischord.WrapAround = true; }