// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #region Generic Character Entity vs Terrain Entity Collision /// <summary> /// Ground Collision Checker /// </summary> public static bool Ground_Collision(Character character_entity) { //------------------------------------- // Check block below for floor collision //------------------------------------- //------------------------------------- // Block Below Adjacent Terrain block = Shared.Active_World.Get_Terrain_At( (int)character_entity.Grid_Position.X, (int)character_entity.Grid_Position.Y + 1); if (block == null) { return(false); } //------------------------------------- // Retrieve the character entities floor collision bound box //------------------------------------- Rectangle bound_box = new Rectangle ( character_entity.Get_Bounds().X, character_entity.Get_Bounds().Y, character_entity.Get_Bounds().Width, character_entity.Get_Bounds().Height ); //------------------------------------- if (bound_box.Intersects(block.Get_Bounds())) { // We've found a collision. Let's check if it's a ground collision! //------------------------------------- // Bound Boxes //-------------------- Rectangle c_bound = bound_box; Rectangle t_bound = block.Get_Bounds(); //-------------------- // Make sure this block is actually below us //-------------------- if (c_bound.Bottom > t_bound.Top) { if (c_bound.Top < t_bound.Top) { // Ensure the player is only shifted to the ground if absolutely necessary //-------------------- if (c_bound.Top < t_bound.Top && c_bound.Bottom > t_bound.Top && c_bound.Bottom < t_bound.Bottom) { character_entity.Shift(new Vector2(0, (c_bound.Bottom - t_bound.Top) - 3)); } return(true); } } } return(false); //------------------------------------- }
// ---------------------------------- /// <summary> /// Runs, updates, and draws this effect /// </summary> /// <param name="gameTime">A snapshot of game time</param> public virtual void Play(GameTime gameTime) { // ------------------------------- // Lifespan Counter // ------------------------------- if (lifespan > 0) { float elapsed_time = (float)gameTime.ElapsedGameTime.TotalSeconds; lifespan -= elapsed_time; } if (lifespan <= 0) { complete = true; } // ------------------------------- if (animated) { // ------------------------- // Play Animation anim_delay++; if (anim_delay > Shared.FPS) { anim_delay = 0; anim_index++; if (anim_index >= anim_length) { if (animation.Loop) { anim_index = 0; } else { anim_index = anim_length - 1; lifespan = 0f; } } } // ------------------------- } // ------------------------------- // ------------------------- Rectangle frame; float scale = Shared.Pixel_Scale; Vector2 origin = new Vector2(dimensions.X / 2, dimensions.Y / 2);; // ------------------------- if (animated) { frame = animation.Frames[anim_index]; } else { frame = new Rectangle(0, 0, image.Width, image.Height); } // -------------------- // Positioning & Source Following // -------------------- // -------------------- // Offset Reflection Vector2 Offset = Source_Offset; if (direction == Shared.Direction.LEFT) { Offset.X = -Offset.X; } // -------------------- // Source Following if (follow_source) { position = Source.Position + Offset; } // -------------------- // Flipping SpriteEffects Flip = SpriteEffects.None; if (flippable) { if (direction == Shared.Direction.LEFT) { Flip = SpriteEffects.FlipHorizontally; } } // -------------------- // Velocity Rotation if (do_rotation) { float x_slope = (Velocity.X * 2) - Velocity.X; float y_slope = (Velocity.Y * 2) - Velocity.Y; rotation = (float)Math.Atan(y_slope / x_slope); Flip = SpriteEffects.None; if (x_slope < 0) { Flip = SpriteEffects.FlipHorizontally; } } // -------------------- // -------------------- // Special cases // -------------------- if (name == "Blood") { scale = Shared.Randomizer.Next(2, 5); } // Health Bars // -------------------- if (name == "HPcontainer") { if (Source is NPC) { NPC npc = (NPC)Source; npc.health_container = this; if (npc.Is_dead()) { lifespan = 0f; } } } if (name == "HP") { if (Source is NPC) { NPC npc = (NPC)Source; npc.health_bar = this; // Handle color // -------------------------- float percentage = ((float)npc.Health_Points / npc.MAX_Health_Points); if (percentage > 0.5f) { overlay_color = new Color(165, 235, 126); } else if (percentage > 0.25f) { overlay_color = new Color(235, 220, 90); } else if (percentage <= 0.25f) { overlay_color = new Color(210, 64, 49); } // -------------------------- // Handle size frame.Width = (int)(frame.Width * percentage); if (npc.Is_dead()) { lifespan = 0f; } } } // -------------------- // -------------------- // Draw // -------------------- spriteBatch.Begin ( SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Shared.Screen.Get_Camera() ); spriteBatch.Draw ( image, position, frame, overlay_color, rotation, origin, scale, Flip, 0 ); spriteBatch.End(); // -------------------- // Ensure this Effect is spawned at the proper time // -------------------- if (Source != null) { if (Source.Anim_index == spawn_frame || spawn_frame == 0) { spawned = true; } } else { spawned = true; } // -------------------- if (spawned) { if (do_gravity) { // Simple gravity for effects, particles & projectiles // ------------------------------------- fall_time += (float)gameTime.ElapsedGameTime.Milliseconds / 2000; Velocity.Y -= (Shared.Gravity.Y * fall_time) * 0.1f; Velocity.X = Velocity.X * 0.98f; if (Velocity.Y > -Shared.Gravity.Y) { Velocity.Y = -Shared.Gravity.Y; } // ------------------------------------- } if (do_collision) { // Simple collision for effects, particles & projectiles // ------------------------------------- int X = (int)Math.Round((Position.X / Shared.Pixel_Scale) / Shared.Block_Dimension); int Y = (int)Math.Round((Position.Y / Shared.Pixel_Scale) / Shared.Block_Dimension); // ------------------------------------- // Stop directional velocity Terrain right = Shared.Active_World.Get_Terrain_At(X + 1, Y); Terrain left = Shared.Active_World.Get_Terrain_At(X - 1, Y); Terrain up = Shared.Active_World.Get_Terrain_At(X, Y - 1); Terrain down = Shared.Active_World.Get_Terrain_At(X, Y + 1); // Right Side if (right is Terrain) { if (Velocity.X > 0f) { if (Get_Bounds().Intersects(right.Get_Bounds())) { Velocity.X = 0f; } } } // Left Side if (left is Terrain) { if (Velocity.X < 0f) { if (Get_Bounds().Intersects(left.Get_Bounds())) { Velocity.X = 0f; } } } // Ceiling if (up is Terrain) { if (Velocity.Y < 0f) { if (Get_Bounds().Intersects(up.Get_Bounds())) { Velocity.Y = 0f; } } } // Floor if (down is Terrain) { if (Velocity.Y >= 0f) { if (Get_Bounds().Intersects(down.Get_Bounds())) { Velocity.Y = 0f; } } } // ------------------------------------- } // Apply Velocity // -------------------- if (follow_source) { // Velocity reflection for flipping left & right if (direction == Shared.Direction.LEFT) { Source_Offset.X -= Velocity.X; } else { Source_Offset.X += Velocity.X; } // -------------------- Source_Offset.Y += Velocity.Y; // -------------------- } else { // -------------------- position += Velocity; // -------------------- } } }