예제 #1
0
 private void CheckObstacles(Player player)
 {
     for (int i = game.obstacles.Count - 1; i >= 0; i--)
     {
         Obstacle obstacle    = game.obstacles[i];
         Vector2  translation = player.Intersects(obstacle);
         if (translation != Vector2.Zero)
         {
             //if (player.CurrentState == Player.State.Slamming)
             //{
             //    game.obstacles.RemoveAt(i);
             //    MakeParticles(obstacle.Position, obstacle, GameData.NUM_PART_OBSTACLE, 0, 0);
             //}
             if (player.Velocity.Y < 0)  // player going up
             {
                 player.Velocity.Y = -GameData.OBSTACLE_JUMP;
                 player.StunTime   = GameData.OBSTACLE_STUN;
                 //player.CurrentState = Player.State.Flying;
             }
             else if (translation.Y == 0) // hitting from side
             {
                 player.Velocity.X  *= GameData.OBSTACLE_SLOW;
                 player.Velocity.Y   = 0;
                 player.CurrentState = Player.State.Stunned;
                 player.StunTime     = GameData.OBSTACLE_HIT_STUN;
                 game.obstacles.RemoveAt(i);
                 MakeParticles(obstacle.Position, obstacle.texture, GameData.NUM_PART_OBSTACLE, 0, 0, obstacle.Color);
             }
             else if (translation.Y > 0) // hitting from top
             {
                 player.MoveByPosition(-translation);
                 player.Velocity.Y   = 0;
                 player.CurrentState = Player.State.Walking;
             }
         }
     }
 }
예제 #2
0
        private void CheckPlatforms(Player player)
        {
            int totalCollisions = 0;
            foreach (Platform platform in game.platforms)
            {
                Vector2 translation = player.Intersects(platform);
                if (translation != Vector2.Zero)
                {
                    totalCollisions++;

                    //if (Math.Abs(translation.X) > Math.Abs(translation.Y)/* && !player.WallAbove*/)
                    //{
                    //    player.CurrentState = Player.State.Climbing;
                    //    //player.Velocity.Y = player.ActionTime > 0 ? -GameData.CLIMB_SPEED_FAST : -GameData.CLIMB_SPEED;
                    //}
                    //else if (player.CurrentState == Player.State.Climbing)
                    //    player.CurrentState = Player.State.Walking;

                    if (translation.Y == 0)    // Horizontal collision
                    {
                        if (player.CurrentState == Player.State.Stunned)
                            player.Velocity.X *= -1;
                        else
                        {
                            player.Velocity.X = 0;
                            //if (player.InAir && player.JumpTime <= 0)
                            //{
                            //if (player.WallJump == Player.Jump.None && player.Velocity.Y > 0)
                            //    player.Velocity.Y *= GameData.WALL_STICK_SCALE;
                            if (player.Velocity.Y >= GameData.WALL_STICK_VEL)
                            {
                                if (translation.X > 0 && player.TargetVelocity == Player.Direction.Right ||
                                    translation.X < 0 && player.TargetVelocity == Player.Direction.Left)
                                    player.CurrentState = Player.State.WallStick;
                            }
                            //player.WallJumpLeway = GameData.WALL_JUMP_LEWAY;
                            //}
                        }
                    }
                    else        // Vertical or diagonal collision
                    {
                        if (player.CurrentState == Player.State.Stunned)
                            player.Velocity.Y *= -1;
                        else
                        {
                            player.Velocity.Y = 0;
                            player.JumpTime = 0f;
                            if (translation.Y > 0 && player.InAir)
                            {
                                player.CurrentState = Player.State.Walking;
                                player.GrappleTarget = Vector2.Zero;
                                player.JetpackTime = GameData.JETPACK_TIME;
                                player.JetpackEnabled = false;
                                player.JumpsLeft = GameData.TOTAL_JUMPS;
                            }
                        }
                    }
                    player.MoveByPosition(-translation);
            #if DEBUG
                    if (translation.LengthSquared() > 1)
                    {
                        Console.WriteLine("Collision translation of {0}", translation);
                        platform.Color = Color.Green;
                    }
            #endif
                }
                //else        // player is Slamming or Stunned
                //{
                //    if (platform.Rotation != 0)
                //    {
                //        MakeParticles(player.Position, platform, GameData.NUM_PART_FLOOR, 0, 1);
                //    }
                //    else
                //    {
                //        MakeParticles(player.Position, platform, GameData.NUM_PART_FLOOR, 0, 1);

                //        float newFloorX = platform.Position.X + player.Position.X;
                //        float sizeDiff = platform.Size.X / 2 + GameData.FLOOR_HOLE / 2;
                //        float halfWidth = platform.Size.X / 2 - GameData.FLOOR_HOLE / 2;
                //        float playerDist = player.Position.X - platform.Position.X;

                //        if (halfWidth + playerDist > GameData.MIN_FLOOR_WIDTH)
                //            game.platforms.Add(new Platform(platform.texture, new Vector2((newFloorX - sizeDiff) / 2, platform.Position.Y), halfWidth + playerDist));
                //        if (halfWidth - playerDist > GameData.MIN_FLOOR_WIDTH)
                //            game.platforms.Add(new Platform(platform.texture, new Vector2((newFloorX + sizeDiff) / 2, platform.Position.Y), halfWidth - playerDist));
                //    }

                //    game.platforms.Remove(platform);
                //    break;
                //}
            }

            if (player.Position.Y > BOTTOM) {  // bottom of the level
                // Kill the player
                player.Reset();
                //if (player.Score == 0) {
                //	for (int i = 0; i < game.players.Count; i++) {
                //		game.players [i].Score++;
                //	}
                //}
                //player.Score--;
            }

            if (totalCollisions == 0 && player.CurrentState != Player.State.Stunned && player.WallJump == Player.Direction.None)
                player.CurrentState = Player.State.Jumping;
        }
예제 #3
0
 private void CheckObstacles(Player player)
 {
     for (int i = game.obstacles.Count - 1; i >= 0; i--)
     {
         Obstacle obstacle = game.obstacles[i];
         Vector2 translation = player.Intersects(obstacle);
         if (translation != Vector2.Zero)
         {
             //if (player.CurrentState == Player.State.Slamming)
             //{
             //    game.obstacles.RemoveAt(i);
             //    MakeParticles(obstacle.Position, obstacle, GameData.NUM_PART_OBSTACLE, 0, 0);
             //}
             if (player.Velocity.Y < 0)  // player going up
             {
                 player.Velocity.Y = -GameData.OBSTACLE_JUMP;
                 player.StunTime = GameData.OBSTACLE_STUN;
                 //player.CurrentState = Player.State.Flying;
             }
             else if (translation.Y == 0) // hitting from side
             {
                 player.Velocity.X *= GameData.OBSTACLE_SLOW;
                 player.Velocity.Y = 0;
                 player.CurrentState = Player.State.Stunned;
                 player.StunTime = GameData.OBSTACLE_HIT_STUN;
                 game.obstacles.RemoveAt(i);
                 MakeParticles(obstacle.Position, obstacle.texture, GameData.NUM_PART_OBSTACLE, 0, 0, obstacle.Color);
             }
             else if (translation.Y > 0) // hitting from top
             {
                 player.MoveByPosition(-translation);
                 player.Velocity.Y = 0;
                 player.CurrentState = Player.State.Walking;
             }
         }
     }
 }
예제 #4
0
        private void CheckPlatforms(Player player)
        {
            int totalCollisions = 0;

            foreach (Platform platform in game.platforms)
            {
                Vector2 translation = player.Intersects(platform);
                if (translation != Vector2.Zero)
                {
                    totalCollisions++;

                    //if (Math.Abs(translation.X) > Math.Abs(translation.Y)/* && !player.WallAbove*/)
                    //{
                    //    player.CurrentState = Player.State.Climbing;
                    //    //player.Velocity.Y = player.ActionTime > 0 ? -GameData.CLIMB_SPEED_FAST : -GameData.CLIMB_SPEED;
                    //}
                    //else if (player.CurrentState == Player.State.Climbing)
                    //    player.CurrentState = Player.State.Walking;

                    if (translation.Y == 0)    // Horizontal collision
                    {
                        if (player.CurrentState == Player.State.Stunned)
                        {
                            player.Velocity.X *= -1;
                        }
                        else
                        {
                            player.Velocity.X = 0;
                            //if (player.InAir && player.JumpTime <= 0)
                            //{
                            //if (player.WallJump == Player.Jump.None && player.Velocity.Y > 0)
                            //    player.Velocity.Y *= GameData.WALL_STICK_SCALE;
                            if (player.Velocity.Y >= GameData.WALL_STICK_VEL)
                            {
                                if (translation.X > 0 && player.TargetVelocity == Player.Direction.Right ||
                                    translation.X < 0 && player.TargetVelocity == Player.Direction.Left)
                                {
                                    player.CurrentState = Player.State.WallStick;
                                }
                            }
                            //player.WallJumpLeway = GameData.WALL_JUMP_LEWAY;
                            //}
                        }
                    }
                    else        // Vertical or diagonal collision
                    {
                        if (player.CurrentState == Player.State.Stunned)
                        {
                            player.Velocity.Y *= -1;
                        }
                        else
                        {
                            player.Velocity.Y = 0;
                            player.JumpTime   = 0f;
                            if (translation.Y > 0 && player.InAir)
                            {
                                player.CurrentState   = Player.State.Walking;
                                player.GrappleTarget  = Vector2.Zero;
                                player.JetpackTime    = GameData.JETPACK_TIME;
                                player.JetpackEnabled = false;
                                player.JumpsLeft      = GameData.TOTAL_JUMPS;
                            }
                        }
                    }
                    player.MoveByPosition(-translation);
#if DEBUG
                    if (translation.LengthSquared() > 1)
                    {
                        Console.WriteLine("Collision translation of {0}", translation);
                        platform.Color = Color.Green;
                    }
#endif
                }
                //else        // player is Slamming or Stunned
                //{
                //    if (platform.Rotation != 0)
                //    {
                //        MakeParticles(player.Position, platform, GameData.NUM_PART_FLOOR, 0, 1);
                //    }
                //    else
                //    {
                //        MakeParticles(player.Position, platform, GameData.NUM_PART_FLOOR, 0, 1);

                //        float newFloorX = platform.Position.X + player.Position.X;
                //        float sizeDiff = platform.Size.X / 2 + GameData.FLOOR_HOLE / 2;
                //        float halfWidth = platform.Size.X / 2 - GameData.FLOOR_HOLE / 2;
                //        float playerDist = player.Position.X - platform.Position.X;

                //        if (halfWidth + playerDist > GameData.MIN_FLOOR_WIDTH)
                //            game.platforms.Add(new Platform(platform.texture, new Vector2((newFloorX - sizeDiff) / 2, platform.Position.Y), halfWidth + playerDist));
                //        if (halfWidth - playerDist > GameData.MIN_FLOOR_WIDTH)
                //            game.platforms.Add(new Platform(platform.texture, new Vector2((newFloorX + sizeDiff) / 2, platform.Position.Y), halfWidth - playerDist));
                //    }

                //    game.platforms.Remove(platform);
                //    break;
                //}
            }

            if (player.Position.Y > BOTTOM)                // bottom of the level
            // Kill the player
            {
                player.Reset();
                //if (player.Score == 0) {
                //	for (int i = 0; i < game.players.Count; i++) {
                //		game.players [i].Score++;
                //	}
                //}
                //player.Score--;
            }

            if (totalCollisions == 0 && player.CurrentState != Player.State.Stunned && player.WallJump == Player.Direction.None)
            {
                player.CurrentState = Player.State.Jumping;
            }
        }
예제 #5
0
        /// <summary>
        /// Handles input for a single player for given input keys
        /// </summary>
        /// <param name="player"></param>
        /// <param name="controller"></param>
        private void HandlePlayerInput(Player player, int controller, float deltaTime)
        {
            GameData.Controls controls = playerControls[controller];

            if (!simulating)
            {
                if (controls.Special1)
                {
                    simTimes.Add(totalTime);
                    keys.Add(GameData.ControlKey.Special1);
                }
                if (controls.Special2)
                {
                    simTimes.Add(totalTime);
                    keys.Add(GameData.ControlKey.Special2);
                }
                if (controls.Basic1)
                {
                    simTimes.Add(totalTime);
                    keys.Add(GameData.ControlKey.Basic1);
                }
                if (controls.Down != prevDown)
                {
                    simTimes.Add(totalTime);
                    prevDown = !prevDown;
                    keys.Add(GameData.ControlKey.Down);
                }
                if (controls.JumpHeld != prevJumpHeld)
                {
                    simTimes.Add(totalTime);
                    prevJumpHeld = !prevJumpHeld;
                    keys.Add(GameData.ControlKey.JumpHeld);
                }
                if (controls.Left != prevLeft)
                {
                    simTimes.Add(totalTime);
                    prevLeft = !prevLeft;
                    keys.Add(GameData.ControlKey.Left);
                }
                if (controls.Right != prevRight)
                {
                    simTimes.Add(totalTime);
                    prevRight = !prevRight;
                    keys.Add(GameData.ControlKey.Right);
                }
            }

            if (player.CurrentState != Player.State.Stunned)
            {
                // Wall-jump
                Vector2 dir = new Vector2(GameData.WALL_HITBOX, 0f);
                float ray = Raycast(player.Position - dir, dir);
                if (ray < 1f)
                    player.WallJump = Player.Direction.Left;
                else if (ray < 2f)
                    player.WallJump = Player.Direction.Right;
                else
                    player.WallJump = Player.Direction.None;

                if (controls.JumpHeld)
                {
                    if (!player.PrevJump)       // toggle jump
                    {
                        if (player.CanJump)    // normal jump
                        {
                            if (player.Velocity.Y > 0)
                                player.Velocity.Y = 0;
                            player.JumpSpeed = player.Velocity.Y * GameData.JUMP_HOLD_PROP - GameData.JUMP_SPEED;

                            player.Velocity.Y -= GameData.JUMP_SPEED;
                            //player.TargetVelocity = player.TargetVelocity * GameData.JUMP_SLOW;
                            player.CurrentState = Player.State.Jumping;
                            player.JumpTime = GameData.JUMP_TIME;
                        }
                        else if (player.WallJump != Player.Direction.None)    // wall jump
                        {
                            if (player.Velocity.Y > 0)
                                player.Velocity.Y = 0;
                            player.JumpSpeed = player.Velocity.Y * GameData.JUMP_HOLD_PROP - GameData.WALL_JUMP_Y;

                            player.Velocity.Y -= GameData.WALL_JUMP_Y;
                            if (player.WallJump == Player.Direction.Left)
                                player.Velocity.X = GameData.WALL_JUMP_X;
                            else
                                player.Velocity.X = -GameData.WALL_JUMP_X;
                            player.JumpTime = GameData.JUMP_TIME;
                            player.WallJump = Player.Direction.None;
                        }
                        else if (player.AbilityOneTime < 0)        // jump abilities
                        {
                            switch (player.CurrentCharacter.Ability1)
                            {
                                case Character.AbilityOne.Platform:
                                    Platform plat = new Platform(platformTexture, player.Position + new Vector2(0, GameData.PLATFORM_DIST),
                                        new Vector2(GameData.PLATFORM_WIDTH, GameData.PLATFORM_HEIGHT));
                                    platforms.Add(plat);
                                    player.AbilityOneTime = GameData.PLATFORM_COOLDOWN;
                                    player.PlatformTime = GameData.PLATFORM_LIFE;
                                    player.SpawnedPlatform = plat;
                                    break;
                                case Character.AbilityOne.Grapple:
                                    //player.GrappleTarget = player.Position + new Vector2(10f, -10f);
                                    dir = new Vector2(player.FacingRight ? 1f : -1f, GameData.GRAPPLE_ANGLE);
                                    ray = Raycast(player.Position, dir);
                                    if (ray < GameData.MAX_GRAPPLE)
                                    {
                                        player.GrappleTarget = player.Position + dir * ray;
                                        player.TargetRadius = Vector2.Distance(player.Position, player.GrappleTarget);
                                        player.GrappleRight = player.Flip == SpriteEffects.None;
                                    }
                                    break;
                                case Character.AbilityOne.Blink:
                                    player.AbilityOneTime = GameData.BLINK_COOLDOWN;
                                    player.MoveByPosition(new Vector2(player.FacingRight ? GameData.BLINK_DIST : -GameData.BLINK_DIST, 0));
                                    // TODO maybe do some validation to make sure the person isn't 'cheating'
                                    break;
                                case Character.AbilityOne.Jetpack:
                                    player.JetpackEnabled = true;   // Jetpack is handled below
                                    break;
                                case Character.AbilityOne.Jump:
                                    if (--player.JumpsLeft > 0)
                                    {
                                        if (player.Velocity.Y > 0)
                                            player.Velocity.Y *= GameData.AIR_JUMP_MOMENTUM_DOWN;
                                        else
                                            player.Velocity.Y *= GameData.AIR_JUMP_MOMENTUM;
                                        player.Velocity.Y -= GameData.AIR_JUMP_SPEED;

                                        player.JumpSpeed = player.Velocity.Y * GameData.AIR_JUMP_HOLD;
                                        player.JumpTime = GameData.AIR_JUMP_TIME;
                                    }
                                    break;
                            }
                        }
                    }
                    else if (player.JumpTime > 0)   // hold jump in air
                    {
                        if (player.Velocity.Y > player.JumpSpeed)
                            player.Velocity.Y = player.JumpSpeed;
                    }
                    else if (player.JetpackEnabled)
                    {
                        if (player.JetpackTime > 0)
                        {
                            float prevTime = player.JetpackTime;
                            player.JetpackTime -= deltaTime;
                            player.Velocity.Y -= (player.Velocity.Y > 0 ? GameData.JETPACK_ACCEL_DOWN : GameData.JETPACK_ACCEL_UP) * deltaTime;
                            //Console.WriteLine("Jetpacking: {0} at time: {1}", player.Velocity.Y, player.JetpackTime);
                        }
                    }
                }
                else        // not jumping
                {
                    player.JumpTime = 0;
                    if (player.GrappleTarget != Vector2.Zero)
                    {
                        // TODO fix when player mashes grapple to get super-speed
                        player.Velocity *= GameData.GRAPPLE_BOOST;
                        player.GrappleTarget = Vector2.Zero;
                        player.AbilityOneTime = GameData.GRAPPLE_COOLDOWN;
                    }
                    player.JetpackEnabled = false;
                }

                if (controls.Right)
                    player.TargetVelocity = Player.Direction.Right;
                else if (controls.Left)
                    player.TargetVelocity = Player.Direction.Left;
                else
                    player.TargetVelocity = Player.Direction.None;

                // activate (or toggle) special abilities
                if (player.AbilityTwoTime < 0 && controls.Special1)
                {
                    switch (player.CurrentCharacter.Ability2)
                    {
                        case Character.AbilityTwo.Clone:
                            //player.AbilityTwoTime = GameData.CLONE_COOLDOWN;
                            if (player.ClonedPlayer == null)
                            {
                                GameData.SimulatedControls simulatedControls = new GameData.SimulatedControls(this);
                                playerControls.Insert(players.Count, simulatedControls);
                                AI clone = new AI(player, simulatedControls);
                                clone.MaxVelocity = GameData.CLONE_VELOCITY;
                                players.Add(clone);
                                player.ClonedPlayer = clone;
                                player.CloneTime = GameData.CLONE_TIME;
                                clone.AbilityTwoTime = player.CloneTime;
                            }
                            else
                            {
                                AI clone = player.ClonedPlayer;
                                if (clone.Timer > 0)
                                {
                                    clone.Controls.JumpHeld = false;
                                }
                                clone.Timer = GameData.CLONE_JUMP_TIME;
                            }
                            break;
                        case Character.AbilityTwo.Timewarp:
                            player.AbilityTwoTime = GameData.TIMEWARP_COOLDOWN;
                            int i = times.Count - 1;
                            while (i >= 0 && times[i] + GameData.TIMEWARP_TIME >= totalTime)
                                i--;
                            if (i >= 0)
                            {
                                Console.WriteLine("Found time: {0}\tCurrent time: {1}", times[i], totalTime);
                                foreach (Player target in players)
                                {
                                    if (target != player && target.Alive)
                                    {
                                        Tuple<Vector2, Vector2> state = target.PrevStates[i];
                                        target.MoveToPosition(state.Item1);
                                        target.Velocity = state.Item2;
                                    }
                                }
                            }
                            break;
                        case Character.AbilityTwo.Rocket:
                            player.AbilityTwoTime = GameData.ROCKET_COOLDOWN;
                            Vector2 vel = new Vector2(player.FacingRight ? GameData.ROCKET_X : -GameData.ROCKET_X, GameData.ROCKET_Y)
                                + player.Velocity * GameData.ROCKET_SCALE;
                            player.Projectiles.Add(new Projectile(whiteRect, player.Position, Color.DarkOliveGreen, Projectile.Types.Rocket, vel));
                            break;
                        case Character.AbilityTwo.Hook:
                            if (player.HookedLocation != Vector2.Zero)
                            {
                                player.HookedLocation = Vector2.Zero;
                                player.AbilityTwoTime = GameData.HOOK_COOLDOWN;
                            }
                            else if (player.HookedPlayer != null)
                            {
                                player.HookedPlayer = null;
                                player.AbilityTwoTime = GameData.HOOK_COOLDOWN;
                            }
                            else if (player.Projectiles.Count < 1)      // player is not currently firing
                            {
                                //player.AbilityTwoTime = GameData.HOOK_COOLDOWN;
                                vel = new Vector2(player.FacingRight ? GameData.HOOK_X : -GameData.HOOK_X, GameData.HOOK_Y)
                                    + player.Velocity * GameData.HOOK_SCALE;
                                Projectile proj = new Projectile(whiteRect, player.Position, Color.DarkSlateGray, Projectile.Types.Hook, vel);
                                proj.LiveTime = GameData.HOOK_LIFE;
                                player.Projectiles.Add(proj);
                                player.HookedLocation = Vector2.Zero;
                                player.HookedPlayer = null;
                            }
                            break;
                        case Character.AbilityTwo.Boomerang:
                            player.AbilityTwoTime = GameData.BOOMERANG_COOLDOWN;
                            vel = new Vector2(player.FacingRight ? GameData.BOOMERANG_X : -GameData.BOOMERANG_X, GameData.BOOMERANG_Y)
                                + player.Velocity * GameData.BOOMERANG_SCALE;
                            player.Projectiles.Add(new Projectile(whiteRect, player.Position, Color.YellowGreen, Projectile.Types.Boomerang, vel));
                            break;
                    }
                }

                if (player.AbilityThreeTime < 0 && controls.Special2)
                {
                    switch (player.CurrentCharacter.Ability3)
                    {
                        case Character.AbilityThree.Invert:
                            player.AbilityThreeTime = GameData.INVERT_COOLDOWN;
                            InvertScreen = GameData.INVERT_TIME;
                            break;
                        case Character.AbilityThree.Trap:
                            player.AbilityThreeTime = GameData.TRAP_COOLDOWN;
                            drops.Add(new Drop(player, whiteRect, player.Position, 1f, Drop.Types.Trap, Color.Red));
                            break;
                    }
                }

                // Basic attack (with 3 modifiers in both land AND air)
                // TODO animations (or just smear) for attacks
                if (controls.Basic1 && player.AttackTime < 0f)
                {
                    if (controls.Down)                                          // holding down
                    {
                        foreach (Player target in players)
                        {
                            if (target != player && Math.Abs(player.Position.X - target.Position.X) < GameData.ATTACK_DOWN_WIDTH)
                            {
                                if (target.Position.Y > player.Position.Y - player.Size.Y / 2f && target.Position.Y < player.Position.Y + GameData.ATTACK_DOWN_HEIGHT)
                                {
                                    if (target.Velocity.Y < 0)
                                        target.Velocity.Y = 0;
                                    target.Velocity += new Vector2(player.FacingRight ? GameData.ATTACK_DOWN_X : -GameData.ATTACK_DOWN_X, GameData.ATTACK_DOWN_Y)
                                        + player.Velocity * GameData.ATTACK_DOWN_MOMENTUM;
                                    hitPause = GameData.HIT_PAUSE;
                                    player.AttackTime = GameData.ATTACK_TIME;
                                    player.ShowSmear = true;
                                }
                            }
                        }
                    }
                    else if (player.TargetVelocity == Player.Direction.None)        // no direction
                    {
                        foreach (Player target in players)
                        {
                            if (target != player && Math.Abs(player.Position.Y - target.Position.Y) < GameData.ATTACK_NORM_HEIGHT)
                            {
                                if (player.FacingRight)
                                {
                                    if (target.Position.X > player.Position.X - player.Size.X / 2f && target.Position.X < player.Position.X + GameData.ATTACK_NORM_WIDTH)
                                    {
                                        if (target.Velocity.X < 0)
                                            target.Velocity.X = 0;
                                        if (target.Velocity.Y > 0)
                                            target.Velocity.Y = 0;
                                        target.Velocity += new Vector2(GameData.ATTACK_NORM_X, GameData.ATTACK_NORM_Y) + player.Velocity * GameData.ATTACK_NORM_MOMENTUM;
                                        hitPause = GameData.HIT_PAUSE;
                                        player.AttackTime = GameData.ATTACK_TIME;
                                        player.ShowSmear = true;
                                    }
                                }
                                else
                                {
                                    if (target.Position.X < player.Position.X + player.Size.X / 2f && target.Position.X > player.Position.X - GameData.ATTACK_NORM_WIDTH)
                                    {
                                        if (target.Velocity.X > 0)
                                            target.Velocity.X = 0;
                                        if (target.Velocity.Y > 0)
                                            target.Velocity.Y = 0;
                                        target.Velocity += new Vector2(-GameData.ATTACK_NORM_X, GameData.ATTACK_NORM_Y) + player.Velocity * GameData.ATTACK_NORM_MOMENTUM;
                                        hitPause = GameData.HIT_PAUSE;
                                        player.AttackTime = GameData.ATTACK_TIME;
                                        player.ShowSmear = true;
                                    }
                                }
                            }
                        }
                    }
                    else                                                    // holding left or right
                    {
                        foreach (Player target in players)
                        {
                            if (target != player && Math.Abs(player.Position.Y - target.Position.Y) < GameData.ATTACK_SIDE_HEIGHT)
                            {
                                if (player.FacingRight)
                                {
                                    if (target.Position.X > player.Position.X - player.Size.X / 2f && target.Position.X < player.Position.X + GameData.ATTACK_SIDE_WIDTH)
                                    {
                                        if (target.Velocity.X < 0)
                                            target.Velocity.X = 0;
                                        if (target.Velocity.Y > 0)
                                            target.Velocity.Y = 0;
                                        target.Velocity += new Vector2(GameData.ATTACK_SIDE_X + player.Velocity.X * GameData.ATTACK_SIDE_MOMENTUM, GameData.ATTACK_SIDE_Y);
                                        hitPause = GameData.HIT_PAUSE;
                                        player.AttackTime = GameData.ATTACK_TIME;
                                        player.ShowSmear = true;
                                    }
                                }
                                else
                                {
                                    if (target.Position.X < player.Position.X + player.Size.X / 2f && target.Position.X > player.Position.X - GameData.ATTACK_SIDE_WIDTH)
                                    {
                                        if (target.Velocity.X > 0)
                                            target.Velocity.X = 0;
                                        if (target.Velocity.Y > 0)
                                            target.Velocity.Y = 0;
                                        target.Velocity += new Vector2(-GameData.ATTACK_SIDE_X + player.Velocity.X * GameData.ATTACK_SIDE_MOMENTUM, GameData.ATTACK_SIDE_Y);
                                        hitPause = GameData.HIT_PAUSE;
                                        player.AttackTime = GameData.ATTACK_TIME;
                                        player.ShowSmear = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            player.PrevJump = controls.JumpHeld;
        }