// If any objects are moving faster than the maximum allowed speed, // sets their speed to the maximum allowed speed private void MaximumVelocityCheck(PhysicsManager world, PhysObject po) { // Not a projectile if (!(po is Projectile)) { if (LinearVelocity.X > world.MaximumHorizontalSpeed) { LinearVelocity = new Vector2(world.MaximumHorizontalSpeed, LinearVelocity.Y); } if (LinearVelocity.X < (world.MaximumHorizontalSpeed * -1)) { LinearVelocity = new Vector2(world.MaximumHorizontalSpeed * -1, LinearVelocity.Y); } if (LinearVelocity.Y > world.MaximumVerticalSpeed) { LinearVelocity = new Vector2(LinearVelocity.X, world.MaximumVerticalSpeed); } if (LinearVelocity.Y < (world.MaximumVerticalSpeed * -1)) { LinearVelocity = new Vector2(LinearVelocity.X, world.MaximumVerticalSpeed * -1); } } }
// Friction only applied if the body is not in the air private void ApplyFriction(PhysicsManager world, PhysObject po) { Vector2 friction = new Vector2(0); if (LinearVelocity.X == 0) { float staticFrictionCoefficient = 0.7f; friction = world.Gravity * staticFrictionCoefficient; } else { float kineticFrictionCoefficient = po.FrictionCoefficient; friction = -1 * kineticFrictionCoefficient * LinearVelocity; } Force += new Vector2(friction.X * 200, 0); // If the horizontal speed is very small, just set it to 0 if (Math.Abs(LinearVelocity.X) < 0.01) { LinearVelocity = new Vector2(0, LinearVelocity.Y); } }
// Create platforms & environment private void CreateEnvironment(GraphicsDevice g) { #region Create Player & Target // First objects to create are the player and the target Player = new Character(true); Player.Position = new Vector2(_nearEdge + 32, _bottomEdge - 128); Player.IsPlayer = true; RigidBody playerBody = Player.RigidBody; playerBody.Position = Player.Position; playerBody.Width = 32; playerBody.Height = 32; playerBody.CollidableObject = new BoxCollider(); Player.TexturePos = new Vector2(Player.Position.X - playerBody.Width / 2, Player.Position.Y - playerBody.Height / 2); DynamicObjects.Add(Player); AllPhysObjects.Add(Player); Target = new PhysObject(); Target.Position = new Vector2(_farEdge / 2, _bottomEdge - 256); Target.IsTarget = true; Target.Elasticity = 1; RigidBody targetBody = Target.RigidBody; targetBody.Mass = 100.0f; targetBody.Position = Target.Position; targetBody.Width = 32; targetBody.Height = 32; targetBody.CollidableObject = new BoxCollider(); targetBody.CollidableObject.IsCircle = true; targetBody.AffectedByPhysics = false; targetBody.IgnoreGravity = true; float targetYVelocity = ((float)World.RandomGen.Next(3, 7) / 10.0f); if (World.RandomGen.Next(0, 1) == 0) { targetYVelocity *= -1; } float targetXVelocity = ((float)World.RandomGen.Next(3, 7) / 10.0f); if (World.RandomGen.Next(0, 1) == 0) { targetXVelocity *= -1; } targetBody.LinearVelocity = new Vector2(targetXVelocity * _portalSpeed, targetYVelocity * _portalSpeed); Target.TexturePos = new Vector2(targetBody.Position.X - targetBody.Width / 2, targetBody.Position.X - targetBody.Height / 2); DynamicObjects.Add(Target); AllPhysObjects.Add(Target); #endregion #region Edges // EDGES - Create the far left walls PhysObject block = new PhysObject(); block.Position = new Vector2(_nearEdge - 480, _bottomEdge / 2); RigidBody body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = _farEdge / 2; body.Height = _bottomEdge; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // EDGES - Create the far right wall block = new PhysObject(); block.Position = new Vector2(_farEdge + 480, _bottomEdge / 2); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = _farEdge / 2; body.Height = _bottomEdge; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // EDGES - Create the main floor block = new PhysObject(); block.Position = new Vector2(_farEdge / 2, _bottomEdge + 480); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 4096; body.Height = 1024; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // EDGES - Create the roof block = new PhysObject(); block.Position = new Vector2(_farEdge / 2, _topEdge - 480); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 4096; body.Height = 1024; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 0 // Platform block = new PhysObject(); block.Position = new Vector2(_nearEdge + 320, _bottomEdge - 32); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 640; body.Height = 64; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge - 320, _bottomEdge - 32); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 640; body.Height = 64; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 1 // Platform block = new PhysObject(); block.Position = new Vector2(_nearEdge + 256, _bottomEdge - 240); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Moving Platform block = new MovingPlatform(new Vector2(_nearEdge + 256, _bottomEdge - 144), new Vector2(_nearEdge + 192, _bottomEdge - 144), new Vector2(_nearEdge + (_farEdge / 2) - 160, _bottomEdge - 144), new Vector2(100, 0)); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Moving Platform block = new MovingPlatform(new Vector2(_farEdge - 256, _bottomEdge - 144), new Vector2((_farEdge / 2) + 160, _bottomEdge - 144), new Vector2(_farEdge - 192, _bottomEdge - 144), new Vector2(-100, 0)); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge - 256, _bottomEdge - 240); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 2 // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 - 448, _bottomEdge - 400); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 128; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 + 448, _bottomEdge - 400); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 128; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 3 // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2, _bottomEdge - 496); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 512; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); /* * // Pendulum (spins, collisions partially broken though, uncomment if you want to see (spawns to the right of the player start)) * block = new Pendulum(new Vector2(_farEdge / 2, _bottomEdge - 496), new Vector2(0, 128)); * DynamicObjects.Add(block); * AllPhysObjects.Add(block); */ #endregion #region Platforms - Tier 4 // Platform block = new PhysObject(); block.Position = new Vector2(_nearEdge + 256, _bottomEdge - 592); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 512; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge - 256, _bottomEdge - 592); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 512; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 5 // Platform block = new PhysObject(); block.Position = new Vector2(_nearEdge + 128, _bottomEdge - 784); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 - 208, _bottomEdge - 784); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 352; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Thicker block block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 + 80, _bottomEdge - 704); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 96; body.Height = 128; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Thicker block block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 - 80, _bottomEdge - 704); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 96; body.Height = 128; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 + 208, _bottomEdge - 784); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 352; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge - 128, _bottomEdge - 784); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 6 // Platform block = new PhysObject(); block.Position = new Vector2(_nearEdge + 432, _bottomEdge - 1008); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 288; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Thicker block block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 - 80, _bottomEdge - 1040); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 96; body.Height = 160; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Thicker block block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 + 80, _bottomEdge - 1040); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 96; body.Height = 160; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge - 432, _bottomEdge - 1008); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 288; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 7 // Platform block = new PhysObject(); block.Position = new Vector2(_nearEdge + 560, _bottomEdge - 1072); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 32; body.Height = 96; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge - 560, _bottomEdge - 1072); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 32; body.Height = 96; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 8 // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 - 256, _bottomEdge - 1136); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 448; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 + 256, _bottomEdge - 1136); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 448; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 9 // Platform block = new PhysObject(); block.Position = new Vector2(_nearEdge + 128, _bottomEdge - 1424); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 - 288, _bottomEdge - 1424); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2 + 288, _bottomEdge - 1424); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge - 128, _bottomEdge - 1424); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 10 // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2, _bottomEdge - 1680); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 640; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 11 // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2, _bottomEdge - 1760); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 128; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 12 // Moving Platform block = new MovingPlatform(new Vector2(_nearEdge + 256, _bottomEdge - 2000), new Vector2(_nearEdge + 160, _bottomEdge - 2000), new Vector2(_nearEdge + (_farEdge / 2) - 160, _bottomEdge - 2000), new Vector2(100, 0)); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); // Moving Platform block = new MovingPlatform(new Vector2(_farEdge - 256, _bottomEdge - 2000), new Vector2((_farEdge / 2) + 160, _bottomEdge - 2000), new Vector2(_farEdge - 160, _bottomEdge - 2000), new Vector2(-100, 0)); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 256; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion #region Platforms - Tier 13 // Platform block = new PhysObject(); block.Position = new Vector2(_farEdge / 2, _bottomEdge - 2288); body = block.RigidBody; body.Mass = _maximumMass; body.IgnoreGravity = true; body.IsDynamic = false; body.Position = block.Position; body.Width = 512; body.Height = 32; body.CollidableObject = new BoxCollider(); StaticObjects.Add(block); AllPhysObjects.Add(block); #endregion }
public void Update(float dt, PhysicsManager physManager, PhysObject po) { // Apply friction if the body is not in the air if (!po.IsInTheAir && AffectedByPhysics) { ApplyFriction(physManager, po); } Vector2 acceleration = Force * (1 / Mass); if (IgnoreGravity || !AffectedByPhysics) { LinearVelocity += (acceleration * dt); } else { LinearVelocity += (physManager.Gravity + acceleration) * dt; } // If projectile, update it if (po is Projectile) { Projectile projectile = (Projectile)po; projectile.Update(); } // If pendulum, update it if (po is Pendulum) { Pendulum pendulum = (Pendulum)po; pendulum.Update(physManager, dt); } // If moving platform, update it if (po is MovingPlatform) { MovingPlatform movingPlatform = (MovingPlatform)po; movingPlatform.Update(); } // Update the time since last collision // Don't care when moving platform or pendulum last collided if (!(po is MovingPlatform) && !(po is Pendulum)) { po.TimeSinceLastCollisionWithFloor++; po.TimeSinceLastCollision++; // Determine if the body is in the air or not if (po.TimeSinceLastCollisionWithFloor < 50 && AffectedByPhysics) { po.IsInTheAir = false; } else { po.IsInTheAir = true; } } // Ensure things aren't moving too fast MaximumVelocityCheck(physManager, po); if ((Math.Abs(LinearVelocity.X) > 0 || Math.Abs(LinearVelocity.Y) > 0) && AffectedByPhysics) { // If there's a body on top of the current rigid body for (int i = 0; i < po.BodiesOnTop.Count; i++) { // Check if the body is still on top if (po.BodiesOnTop[i].TimeSinceLastCollision < 50) { // If this is a moving platform, move the object on top with this body if (po is MovingPlatform) { po.BodiesOnTop[i].RigidBody.Position += (LinearVelocity * dt); // If there is a stack of bodies on top of the moving platform for (int j = 0; j < po.BodiesOnTop[i].BodiesOnTop.Count; j++) { if (!po.BodiesOnTop.Contains(po.BodiesOnTop[i].BodiesOnTop[j])) { // Add each unique body to the list of bodies on the platform po.BodiesOnTop.Add(po.BodiesOnTop[i].BodiesOnTop[j]); } } } } else { po.BodiesOnTop.Remove(po.BodiesOnTop[i]); } } } // Reset the force Force = new Vector2(0); Position += (LinearVelocity * dt); }