Ejemplo n.º 1
0
        public void move(ref Vector2 velocity, Vector2 maxSpeed, RectangleF boundary, float bouncines, Vector2 friction, Vector2 dragAir, Vector2 dragWater, List <IRectanglePhysics> collection = null, float buoyancy = 0f, bool gravity = true, float buoyancyInWater = 0.0f, bool walking = false, IMap map = null)
        {
            if (map == null)
            {
                _map = Game1.mapLive;
            }
            else
            {
                _map = map;
            }

            InWater = false;

            RecsOfWater = CompareF.VectorVsWater(_map.WaterTree, boundary.Origin);

            if (RecsOfWater.Count > 0)
            {
                InWater = true;
            }

            if (gravity == true)
            {
                velocity += new Vector2(0, Globals.Gravity);
                velocity -= new Vector2(0, buoyancy);

                if (InWater == true)
                {
                    velocity.Y -= buoyancyInWater;
                }
            }

            if (Math.Abs(velocity.X) > maxSpeed.X)
            {
                if (velocity.X > 0)
                {
                    velocity.X = maxSpeed.X;
                }
                else
                {
                    velocity.X = -maxSpeed.X;
                }
            }
            if (Math.Abs(velocity.Y) > maxSpeed.Y)
            {
                if (velocity.Y > 0)
                {
                    velocity.Y = maxSpeed.Y;
                }
                else
                {
                    velocity.Y = -maxSpeed.Y;
                }
            }

            TouchRight  = false;
            TouchLeft   = false;
            TouchTop    = false;
            TouchBottom = false;

            TouchBottomMovable = false;
            TouchTopMovable    = false;
            TouchLeftMovable   = false;
            TouchRightMovable  = false;

            VerticalPressure   = false;
            HorizontalPressure = false;

            TouchHorizontal = false;
            TouchVertical   = false;

            VelocityReceived = Vector2.Zero;

            if (InWater == false)
            {
                velocity.X *= (1 - dragAir.X);
                velocity.Y *= (1 - dragAir.Y);
            }
            else
            {
                velocity.X *= (1 - dragWater.X);
                velocity.Y *= (1 - dragWater.Y);
            }

            int iterations = 1;

            for (int i = 0; i < iterations; i++)
            {
                boundary.Position += new Vector2(0, velocity.Y.Clamp(-maxSpeed.Y, maxSpeed.Y) * Game1.Delta) / iterations;

                maxVelocityClamped = new Vector2(velocity.X.Clamp(-maxSpeed.X, maxSpeed.X), velocity.Y.Clamp(-maxSpeed.Y, maxSpeed.Y));

                RecsToCheckMap = CompareF.RectangleVsMap(_map.MapTree, boundary);
                ResolveWithMapYMinus(ref boundary, ref velocity, friction, bouncines);
                ResolveWithMapYPlus(ref boundary, ref velocity, friction, bouncines, walking);

                YCollideMoving(ref velocity, boundary, bouncines, friction, collection, walking);

                RecsToCheckMap = CompareF.RectangleVsMap(_map.MapTree, boundary);
                ResolveWithMapYMinus(ref boundary, ref velocity, friction, bouncines);
                ResolveWithMapYPlus(ref boundary, ref velocity, friction, bouncines, walking);

                YCollideMoving(ref velocity, boundary, bouncines, friction, collection, walking);
            }

            #region map boundary

            if (boundary.Position.Y < 0)
            {
                TouchBottom = true;

                boundary.Position = new Vector2(boundary.Position.X, 0);
                boundary.Position = new Vector2(boundary.Position.X, (int)Math.Round(boundary.Position.Y));
                velocity          = new Vector2(velocity.X, velocity.Y * -bouncines);
                velocity         *= new Vector2(1 - friction.X, 1);
            }
            if (boundary.CornerRightBottom.Y > _map.FunctionTileMap.GetLength(1) * tileSize)
            {
                TouchTop = true;

                boundary.Position = new Vector2(boundary.Position.X, _map.FunctionTileMap.GetLength(1) * tileSize - boundary.Size.Y);
                boundary.Position = new Vector2(boundary.Position.X, (int)Math.Round(boundary.Position.Y));
                velocity          = new Vector2(velocity.X, velocity.Y * -bouncines);
                velocity         *= new Vector2(1 - friction.X, 1);
            }

            #endregion map boundary

            if (TouchBottomMovable && TouchTopMovable)
            {
                VerticalPressure = true;
            }
            if (TouchTopMovable && TouchBottom)
            {
                VerticalPressure = true;
            }
            if (TouchTop && TouchBottomMovable)
            {
                VerticalPressure = true;
            }

            if (TouchBottom || TouchTopMovable || TouchTop || TouchBottomMovable)
            {
                TouchVertical = true;
            }

            for (int i = 0; i < iterations; i++)
            {
                boundary.Position += new Vector2(velocity.X.Clamp(-maxSpeed.X, maxSpeed.X) * Game1.Delta, 0) / iterations;

                maxVelocityClamped = new Vector2(velocity.X.Clamp(-maxSpeed.X, maxSpeed.X), velocity.Y.Clamp(-maxSpeed.Y, maxSpeed.Y));

                RecsToCheckMap = CompareF.RectangleVsMap(_map.MapTree, boundary);
                ResolveWithMapXMinus(ref boundary, ref velocity, friction, bouncines);
                ResolveWithMapXPlus(ref boundary, ref velocity, friction, bouncines);

                XCollideMoving(ref velocity, boundary, bouncines, Vector2.Zero, collection);

                RecsToCheckMap = CompareF.RectangleVsMap(_map.MapTree, boundary);
                ResolveWithMapXMinus(ref boundary, ref velocity, friction, bouncines);
                ResolveWithMapXPlus(ref boundary, ref velocity, friction, bouncines);

                XCollideMoving(ref velocity, boundary, bouncines, Vector2.Zero, collection);
            }

            #region map boundary

            if (boundary.Position.X < 0)
            {
                TouchRight = true;

                boundary.Position = new Vector2(0, boundary.Position.Y);
                boundary.Position = new Vector2((int)Math.Round(boundary.Position.X), boundary.Position.Y);
                velocity          = new Vector2(velocity.X * -bouncines, velocity.Y);
            }

            if (boundary.CornerRightTop.X > _map.FunctionTileMap.GetLength(0) * tileSize)
            {
                TouchLeft = true;

                boundary.Position = new Vector2(_map.FunctionTileMap.GetLength(0) * tileSize - boundary.Size.X, boundary.Position.Y);
                boundary.Position = new Vector2((int)Math.Round(boundary.Position.X), boundary.Position.Y);
                velocity          = new Vector2(velocity.X * -bouncines, velocity.Y);
            }

            #endregion map boundary

            if (TouchRightMovable && TouchLeftMovable)
            {
                HorizontalPressure = true;
            }
            if (TouchRightMovable && TouchLeft)
            {
                HorizontalPressure = true;
            }
            if (TouchRight && TouchLeftMovable)
            {
                HorizontalPressure = true;
            }

            if (TouchLeft || TouchRightMovable || TouchRight || TouchLeftMovable)
            {
                TouchHorizontal = true;
            }
        }