/// <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 ResetGame() { AlphaParticles = new Utilities.Graphics.ParticleEffect(ArtAssets.EmptySprite, V2.Zero, new List<Utilities.Graphics.ParticleEffect.Particle>()); AdditiveParticles = new Utilities.Graphics.ParticleEffect(ArtAssets.EmptySprite, V2.Zero, new List<Utilities.Graphics.ParticleEffect.Particle>()); MoveUp = false; MoveDown = false; TimeSinceMinigameStart = 0.0f; Harmony = new Jousting.Jouster(Jousting.Jousters.Harmony, WorldData.GetStartingPos(CurrentZoom, Jousting.Jousters.Harmony), CurrentZoom); Dischord = new Jousting.Jouster(Jousting.Jousters.Dischord, WorldData.GetStartingPos(CurrentZoom, Jousting.Jousters.Dischord), CurrentZoom); Blockers.Clear(); Timers.ClearTimers(); Reset(); }
public void OnHitJouster(Jouster joust, float stabForce) { if (OnHitByJouster != null) OnHitByJouster(this, new Jouster.HurtEventArgs(joust, stabForce)); float max = joust.MaxVelocity; joust.MaxVelocity = 0.000001f; MovementPhysics.Separate(this, joust, 0.2f * WorldData.ZoomScaleAmount[KarmaWorld.World.CurrentZoom]); joust.MaxVelocity = max; if (IsMovable) { //Define "tangent" as the line perpendicular to the line from the Blocker to the Jouster. //Both entities keep the portion of momentum parallel to their tangent, //But swap the portion of momentum perpendicular to their tangent. V2 toJoust = joust.Pos - Pos; V2 tangent = V2.Normalize(Utilities.Conversions.GetPerp(toJoust)); Utilities.Conversions.ParallelPerp blockerPP = Utilities.Conversions.SplitIntoComponents(Velocity, tangent), joustPP = Utilities.Conversions.SplitIntoComponents(joust.Velocity, tangent); Velocity = blockerPP.Parallel + (BounceVelocityDamp * joustPP.Perpendicular * joust.Mass / Mass); joust.Velocity = joustPP.Parallel + (joust.PhysData.BounceEnergyScale * blockerPP.Perpendicular * Mass / joust.Mass); } else { //Push the jouster away from this Blocker. V2 away = UsefulMath.FindDirection(Pos, joust.Pos); Utilities.Conversions.ParallelPerp pp = Utilities.Conversions.SplitIntoComponents(joust.Velocity, away); joust.Velocity = pp.Perpendicular + (joust.PhysData.BounceEnergyScale * -pp.Parallel); } }
/// <summary> /// Checks for collision between the two given jousters and responds accordingly. /// Returns the collision data for this collision, or 'null' if no collision occurred. /// </summary> public static CollisionData CheckCollision(Jouster first, Jouster second) { //If the players aren't touching, exit. if (!first.ColShape.Touches(second.ColShape)) { first.touchingOtherJouster = false; second.touchingOtherJouster = false; return null; } if (first.touchingOtherJouster || second.touchingOtherJouster) return null; //If the players aren't moving fast enough relative to each other, // exit. if ((first.Velocity - second.Velocity).LengthSquared() < PhysicsData.GetMinHitSpeed(KarmaWorld.World.CurrentZoom) * PhysicsData.GetMinHitSpeed(KarmaWorld.World.CurrentZoom)) { return null; } CollisionData col = new CollisionData(); //Get the component of the jousters' velocities that is along their forward movement. //Use only this component in figuring out stab strength. V2 lookDir1 = UsefulMath.FindDirection(first.Rotation), lookDir2 = UsefulMath.FindDirection(second.Rotation), moveDir1 = first.Velocity, moveDir2 = second.Velocity; col.StabStrength1 = first.Mass * V2.Dot(lookDir1, moveDir1); col.StabStrength2 = second.Mass * V2.Dot(lookDir2, moveDir2); if (first.IsSpiky) col.StabStrength1 *= Minigames.Minigame_1.PhysicsData1.SpikePowerScale; if (second.IsSpiky) col.StabStrength2 *= Minigames.Minigame_1.PhysicsData1.SpikePowerScale; //If neither player really did damage, exit. if (col.StabStrength1 <= 0.0f && col.StabStrength2 <= 0.0f) return null; first.touchingOtherJouster = true; second.touchingOtherJouster = true; if (col.StabStrength1 > col.StabStrength2) { first.Hurt(second, col.StabStrength1); second.HurtBy(first, col.StabStrength1); } else { first.HurtBy(second, col.StabStrength2); second.Hurt(first, col.StabStrength2); } return col; }
public HurtEventArgs(Jouster enemy, float damageDealt) { Enemy = enemy; DamageDealt = damageDealt; }
public void HurtBy(Jouster other, float stabDamage) { Health -= PhysicsData.GetDamage(stabDamage, WorldData.ZoomScaleAmount[KarmaWorld.World.CurrentZoom]); Velocity += PhysData.BounceEnergyScale * PhysicsData.VelocityFromHit(stabDamage, UsefulMath.FindDirection(other.Rotation)); if (OnHurtByEnemy != null) OnHurtByEnemy(this, new HurtEventArgs(other, stabDamage)); }
public void Hurt(Jouster other, float stabDamage) { Velocity *= PhysData.BounceEnergyScale * PhysicsData.VelocityDampFromHit(stabDamage, MaxVelocity); if (OnHurtEnemy != null) OnHurtEnemy(this, new HurtEventArgs(other, stabDamage)); }
/// <summary> /// Resizes the given jouster by changing his mass by the given amount. /// </summary> private void ResizeJouster(float massChange, Jouster jouster) { jouster.Mass += massChange; float scale = jouster.Mass / PhysicsData.JousterStartingMass[ZoomLevels.One]; ArtAssets.PlayerSprites[World.CurrentZoom][jouster.ThisJouster].DrawArgs.Scale = V2.One * scale; V2 oldPos = jouster.Pos; float oldRot = jouster.Rotation; jouster.ColShape = ArtAssets.GetJousterShape(ZoomLevels.One, scale * WorldData.ZoomScaleAmount[ZoomLevels.One]); jouster.Pos = oldPos; jouster.Rotation = oldRot; }
protected override void Update(Jouster.CollisionData playerCollision) { if (Dischord.IsSpiky_Aura) { //The aura can infect bacteria at a distance. for (int i = 0; i < Blockers.Count; ++i) { if (V2.Distance(Blockers[i].Pos, Dischord.ColShape.ClosestOnEdgeToPoint(Blockers[i].Pos)) < PhysicsData1.GetAuraDist(WorldData.ZoomScaleAmount[CurrentZoom])) { ((Bacteria)Blockers[i]).Infect(WorldData.ZoomScaleAmount[CurrentZoom]); } } } ArtAssets1.Spikes.UpdateAnimation(World.CurrentTime); }