// ---------------------------------- /// <summary> /// Try player wall jump /// </summary> public bool Try_Wall_Jump() { if (!dead && !busy && airborne) { // ---------------------------------- // Wall Jumping Logic if (CollisionManager.Wall_Collision(this, Shared.Direction.LEFT) && direction == Shared.Direction.RIGHT) { Wall_Jump(7f); } else if (CollisionManager.Wall_Collision(this, Shared.Direction.RIGHT) && direction == Shared.Direction.LEFT) { Wall_Jump(-7f); } // ---------------------------------- } return(false); }
// ---------------------------------- // ---------------------------------- /// <summary> /// Smart Navigation guides the host around terrain to a specified grid destination /// </summary> /// <param name="destination">The destination our host wants to move to</param> public void Smart_Movement(Vector2 destination, string movement = "walk") { // ---------------------------------- bool horizontal_tracking = false; Vector2 source_pos = host.Grid_Position; Shared.Direction dest_direction = Shared.Direction.NONE; // ---------------------------------- // If the destination X is greater, it's too the right if (destination.X > source_pos.X) { host.Direction = Shared.Direction.RIGHT; dest_direction = Shared.Direction.RIGHT; horizontal_tracking = true; } // ---------------------------------- // Less than, it's too the left. else if (destination.X < source_pos.X) { host.Direction = Shared.Direction.LEFT; dest_direction = Shared.Direction.LEFT; horizontal_tracking = true; } // ---------------------------------- // Begin tracking toward horizontal destination if (horizontal_tracking) { if (CollisionManager.Safe_Step(host)) { if (movement == "run") { host.Try_Run(dest_direction); } else { host.Try_Walk(dest_direction); } } else if (CollisionManager.Safe_Drop(host)) { if (movement == "run") { host.Try_Run(dest_direction); } else { host.Try_Walk(dest_direction); } } // ---------------------------------- // We've hit a wall. Jump to see if that resolves our oh so // complicated dilemma if (CollisionManager.Wall_Collision(host, dest_direction)) { if (Shared.Active_World.Get_Terrain_At((int)destination.X, (int)destination.Y) == null) { if (CollisionManager.Jumpable_Terrain(host)) { host.Try_Jump(); } } } } }
public override void Draw(GameTime gameTime) { if (Enabled) { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // World Render Order // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Prepare dead character list List <Character> Dead_Characters = new List <Character>(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Update // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // World Parallax // -------------------------------- worldParallax.Update(gameTime); // Perform Combat Collision Checks // -------------------------------- CollisionManager.Projectile_Collisions(); CollisionManager.Character_Collision(); // Terrain // -------------------------------- foreach (KeyValuePair <string, Terrain> terrain in worldTerrain) { terrain.Value.Update(gameTime); if (terrain_changed) { terrain.Value.Terrain_Render(); } } if (has_background && worldBKGTerrain.Count() != 0) { foreach (KeyValuePair <string, Terrain> terrain in worldBKGTerrain) { terrain.Value.Update(gameTime); if (terrain_changed) { terrain.Value.Terrain_Render(); } } } // Reset terrain changed flag terrain_changed = false; // ---------------------- // Characters // -------------------------------- if (Shared.Active_World.loaded) { foreach (Character character in worldCharacters) { if (character.Is_dead() && !(character is Player)) { Dead_Characters.Add(character); character.Enabled = false; break; } character.Update(gameTime); } if (Dead_Characters.Count() != 0) { foreach (Character dead_character in Dead_Characters) { worldCharacters.Remove(dead_character); } } } // -------------------------------- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Draw // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BKG Terrain // -------------------------------- if (has_background && worldBKGTerrain.Count() != 0) { foreach (KeyValuePair <string, Terrain> terrain in worldBKGTerrain) { terrain.Value.Draw(gameTime); } } // Characters // -------------------------------- foreach (Character character in worldCharacters) { character.Draw(gameTime); } // Terrain // -------------------------------- foreach (KeyValuePair <string, Terrain> terrain in worldTerrain) { terrain.Value.Draw(gameTime); } if (Shared.Debug) { string key = Get_Grid_Key(Shared.Player.Grid_Position.X, Shared.Player.Grid_Position.Y + 1); if (WorldTerrain.ContainsKey(key)) { Shared.DebugWindow.Message += WorldTerrain[key].Name + "\n"; } else { Shared.DebugWindow.Message += "Air \n"; } Shared.DebugWindow.Draw(gameTime); Shared.DebugWindow.Message = ""; } // -------------------------------- // Effects // -------------------------------- Particles.Draw_Effects(gameTime); // -------------------------------- // Projectiles // -------------------------------- Particles.Draw_Projectiles(gameTime); // -------------------------------- // GUI // -------------------------------- foreach (GUI_Element element in Shared.GUI) { element.Draw(gameTime); } // -------------------------------- } }
// --------------------- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Physics & Movement // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -------------------------- #region Physics & Movement /// <summary> /// Applies physics to character entities every tick /// </summary> /// <param name="gameTime">Snapshot of gametime</param> public void Physics(GameTime gameTime) { // -------------------------- // Basic Gravity Physics // -------------------------- // -------------------------- // Horizontal Trajectory Logic & Resistance // -------------------------- // -------------------------- // Log potential airborne velocity before leaving the ground if (!airborne) { Airborne_Velocity = Velocity.X; } // -------------------------- if (!walking && !running && !airborne) { Velocity.X -= Velocity.X * (Resistance); } else { float x_speed = 0f; // -------------------------- if (walking) { x_speed = Walk_Speed; } if (running) { x_speed = Run_Speed; } // -------------------------- if (direction == Shared.Direction.LEFT) { x_speed = -x_speed; } // -------------------------- // If we're airborne, velocity works differently! Who knew! if (airborne) { // -------------------------- Airborne_Velocity = Airborne_Velocity * 0.95f; Airborne_Velocity += x_speed * 0.05f; // -------------------------- //Ensure no ridiculous acceleration. if (Math.Abs(Airborne_Velocity) > Math.Abs(x_speed) && x_speed != 0) { Airborne_Velocity = x_speed; } Velocity.X = Airborne_Velocity; // -------------------------- } else { Velocity.X = x_speed * (Resistance); } // -------------------------- // -------------------------- // Set to false to prevent 'stick' walking = false; running = false; // -------------------------- } // -------------------------- // Apply External Velocity if (External_Velocity != Vector2.Zero) { if (Math.Abs(External_Velocity.X) < 0.05f) { External_Velocity.X = 0f; } if (Math.Abs(External_Velocity.Y) < 0.05f) { External_Velocity.Y = 0f; } Velocity += External_Velocity; External_Velocity = External_Velocity * 0.9f; } // -------------------------- // If velocity becomes super tiny, just set to zero if (Math.Abs(Velocity.X) < 0.01f) { Velocity.X = 0; } // -------------------------- //Always run ground collision test incase of floor no longer ... existing. // -------------------------- On_ground = CollisionManager.Ground_Collision(this); if (On_ground) { airborne = false; if (Velocity.Y > 0f) { Velocity.Y = 0f; if (External_Velocity.Y > 0f) { External_Velocity.Y = 0f; } } } else { airborne = true; } if (On_ground && !jumping) { falling = false; has_jumped = false; } if (Velocity.Y >= 0) { jumping = false; } // Jump Velocity Logic // -------------------------- if (!On_ground) { // We're not on the ground, so we have to start // calculating our trajectory // ------------------------ if (!falling) { falling = true; } fall_time = 0; // ------------------------ if (falling) { fall_time += (float)gameTime.ElapsedGameTime.Milliseconds / 650; // ------------------------ // Special case for Player character, allowing jump hold & hover if (this is Player) { Player player = (Player)this; if (Velocity.Y > 0) { player.Holding_Jump = false; } if (player.Holding_Jump) { Velocity -= (Shared.Gravity * fall_time); } else { Velocity -= ((Shared.Gravity * fall_time) * 2f); } } // ------------------------ else { Velocity -= (Shared.Gravity * fall_time); } } } // -------------------------- // Ensures proper state animations play // Depending on vertical velocity // -------------------------- if (Velocity.Y < 0 && airborne) { Set_State(Shared.EntityState.JUMPING); } else if (Velocity.Y > 0 && airborne) { Set_State(Shared.EntityState.FALLING); } // Gravity = Maximum Falling Velocity for all entities // -------------------------- if (Velocity.Y > -Shared.Gravity.Y) { Velocity.Y = -Shared.Gravity.Y; } // -------------------------- // Wall Collisions // -------------------------- if (Velocity.X != 0 || walking || running || airborne) { if (CollisionManager.Wall_Collision(this, Shared.Direction.RIGHT)) { if (Velocity.X > 0f) { Velocity.X = 0f; } if (External_Velocity.X > 0f) { External_Velocity.X = 0f; } } if (CollisionManager.Wall_Collision(this, Shared.Direction.LEFT)) { if (Velocity.X < 0f) { Velocity.X = 0f; } if (External_Velocity.X < 0f) { External_Velocity.X = 0f; } } } // -------------------------- // Ceiling Check // -------------------------- if (Velocity.Y < 0f) { if (CollisionManager.Ceiling_Collision(this)) { Velocity.Y = 0f; if (External_Velocity.Y < 0f) { External_Velocity.Y = 0f; } } } // -------------------------- // Update Position // -------------------------- Position += Velocity; }