Ga naar inhoud

Dash

Doelstelling

Ik moest ervoor zorgen dat de player kan dashen, zonder te teleporteren.

Toegepaste oplossing

Mijn oplossing was dus om in plaats van teleporteren de player een stuk sneller te maken voor een duratie. In de Player class heb ik dus een manier om te dashen toe gevoegen. Eerst heb ik dus een dash class en de variabelen ervoor aangemaakt, en vervolgend de bestaande functies er op aangepast. Het was hierdoor wel nodig om GetMovementDirection aan te maken zodat we niet dubbel coderen. Om ervoor te zorgen dat in de toekosmt andere classen ook kiunnen dashen hebben we een interface gebruikt

public interface IDashable
{
    public TimeSpan dashDuration { get; set; }
    public int dashSpeed{ get; set; }

    void Dash(GameTime gameTime, InputHelper input);
}
public class Player : BaseEntity, IDashable
{
    public TimeSpan lastAttackTime = TimeSpan.FromSeconds(-1);
    private TimeSpan attackDuration = TimeSpan.FromSeconds(1);
    private TimeSpan dashCooldown = TimeSpan.FromSeconds(5);
    private TimeSpan lastDashTime = TimeSpan.FromSeconds(-1);
    public bool IsAttacking { get; set; } = false;
    public bool IsDashing { get; set; } = false;
    public bool IsInvincible { get; set; } = false;
    public Rectangle AttackBounds { get; set; }
    public TimeSpan dashDuration { get; set; } = TimeSpan.FromSeconds(0.5);
    public int dashSpeed { get; set; } = 5;

    public Player(Vector2 position = default, int layer = 1, string id = "")
        : base(position, layer, id)
    {
        Texture = App.AssetManager.GetSprite("Images/Entity/Player");
        MaxHealth = 100;
        Speed = 100;
        Size = new(50f, 100f);
    }

    public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        spriteBatch.BetterDraw(Texture, Position, Size);
    }

    public override void Update(GameTime gameTime)
    {
        var input = App.Systems.GetSystem<InputHelper>();

        if (!IsDashing)
        {
            UpdateMove(input, gameTime);
        }

        if (input.MouseLeftButtonPressed)
        {
            Melee(gameTime);
        }

        if (gameTime.TotalGameTime - lastAttackTime >= attackDuration)
        {
            IsAttacking = false;
        }

        if (input.IsKeyDown(Keys.Space) && gameTime.TotalGameTime - lastDashTime >= dashCooldown && !IsDashing)
        {
            Dash(gameTime, input);
        }

        if (IsDashing && gameTime.TotalGameTime - lastDashTime >= dashDuration)
        {
            IsDashing = false;
            ...
        }

        base.Update(gameTime);
    }

    private Vector2 GetMovementDirection(InputHelper input)
    {
        var direction = Vector2.Zero;

        if (input.IsKeyDown(Keys.W) || input.IsKeyDown(Keys.Up))
        {
            direction.Y -= 1;
        }
        if (input.IsKeyDown(Keys.S) || input.IsKeyDown(Keys.Down))
        {
            direction.Y += 1;
        }
        if (input.IsKeyDown(Keys.A) || input.IsKeyDown(Keys.Left))
        {
            direction.X -= 1;
        }
        if (input.IsKeyDown(Keys.D) || input.IsKeyDown(Keys.Right))
        {
            direction.X += 1;
        }

        if (direction != Vector2.Zero)
        {
            direction.Normalize();
        }

        return direction;
    }

    public void Dash(GameTime gameTime, InputHelper input)
    {
        ...
        var direction = GetMovementDirection(input);
        Velocity = direction * (Speed * dashSpeed);
        lastDashTime = gameTime.TotalGameTime;
        IsDashing = true;
    }

Hierna heb ik toegevoegd dat je niet kan worden gedamaged terwijl je dashed. Dit doen we door te zeggen dat je geen attacks krijgt terwijl je aan het dashen bent. Hierna zetten we in Dash Invincible dan ook als eerste meteen op true, zodat je niet per ongeluk al dashed en daardoor damage krijgt.

    public override void Update(GameTime gameTime)
        {
            if (IsDashing && gameTime.TotalGameTime - lastDashTime >= dashDuration)
            {
                IsInvincible = false;
            }
            ...
        }

    public async void Dash(GameTime gameTime)
        {
            IsInvincible = true;
            ...
        }
}

Niet alle code staat in player, want om geen damage te krijgen moeten we aan de collisions een kleine veranderingen toe brengen. Het enige wat we hier doen is voordat je damage krijgt checken of je Invincible bent.

public void CheckCollision(GameTime gameTime)
    {
        ...
        if (!Player.IsInvincible)
        {
            var died = Player.Damage(20);
            playerLastDamagedAt = gameTime.TotalGameTime;
        }
        ...
    }

Om er voor te zorgen dat de player en boss een dashanimatie laten zien zorg ik ervoor dat er een windeffect geplaatst word achter het character. De positie van de dash wordt berekend vanaf de center van de entity en die positie wordt gebruikt bij het initialiseren van de animatie.

if (isDashing)
{
    var dashPosition = new Vector2(Position.X + (Velocity.X > 0 ? -Size.X/2 : Size.X/2), Position.Y);
    PlayAnimation(
        spriteBatch,
        gameTime,
        App.AssetManager.GetSprite("Images/Entity/Dash"),
        dashPosition,
        new Vector2(80),
        Velocity,
        new (2, 1),
        animationDuration: TimeSpan.FromMilliseconds(260)
    );
}

Bronnen


Laatst geüpdatet: June 6, 2024
Gecreëerd: May 13, 2024