// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        #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);
            //-------------------------------------
        }
Exemplo n.º 2
0
        // ----------------------------------
        /// <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;
                    // --------------------
                }
            }
        }