Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Unable to code a sequence of different attack animations  (Read 1046 times)

0 Members and 1 Guest are viewing this topic.

delagore

  • Newbie
  • *
  • Posts: 3
    • View Profile
Unable to code a sequence of different attack animations
« on: March 10, 2021, 01:11:38 pm »
Hi all! Newbie game dev student here. I am trying to develop a game for my studies. It is a 2D action platformer, and I am having trouble with the attack animations. I believe I am just using the standard version of SFML, I'm not using thor or anything for my animations.

I have four attack animations, and I want to cycle through them in the correct order whenever the attack key is hit, so that the player's first attack will always be attack1, and then if the attack key is pressed during attack1 it will be attack2, and so on.

I am only able to code it so that the next animation interrupts the current animation, but I want it to wait until the current animation is over before it performs the next one. I guess I would be looking to create a 'window of opportunity' where if the attack button is hit during the second half of the current attack animation or, say, 0.2 seconds after the current animation, it goes to the next one.

The code I have so far is:

The code to call an animation, found in a separate Animation class:
void Animation::animate(float dt)
{
        if (isPlaying)
        {
                elapsedTime += dt;
                if (elapsedTime >= animationSpeed)
                {
                        currentFrame++;
                        if (currentFrame >= (int)frames.size())
                {
                if (isLooping)
                {
                        currentFrame = 0;
                }
                else
                {
                        currentFrame--;
                        setPlaying(false);
                }
        }
        elapsedTime = 0;
      }
}
 
The rest of the code is in the Player class:

The attack function:


//bool isAttacking, isAttacking2, isAttacking3 and isAttacking 4 are all set to false as standard


// The conditions in the if/else if statements make it so  the next attack happens if control is pressed half-way through the current animation, during the "return" animation (two quick frames that take it from attack->idle) or at the beginning of the idle animation

void Player::attacking()
{
        if (!isAttacking)
        {
                isAttacking = true;
                attackAnimation1();
        }
        else if (isAttacking && !isAttacking2 && (attack.getElapsedTime() > 0.15f || currentAnimation == &attackReturn || (idle.getElapsedTime() > 0 && idle.getElapsedTime() < 0.05f)))
        {
                isAttacking2 = true;
                attackAnimation2();
        }
        else if (isAttacking2 && !isAttacking3 && (attack2.getElapsedTime() > 0.15f || currentAnimation == &attackReturn || (idle.getElapsedTime() > 0 && idle.getElapsedTime() < 0.05f)))
        {
                isAttacking3 = true;
                attackAnimation3();
        }
        else if (isAttacking3 && !isAttacking4 && (attack3.getElapsedTime() > 0.15f || currentAnimation == &attackReturn || (idle.getElapsedTime() > 0 && idle.getElapsedTime() < 0.05f)))
        {
                isAttacking4 = true;
                attackAnimation4();
        }
}

In the handleInput() function:

if (isPressed(Lctrl))
{
        attacking();
}
 

In the update() function for the player:
if (isAnimationOver() && isAttacking)
{
        attackReturnAnimation();
        isAttacking = false;
        isAttacking2 = false;
        isAttacking3 = false;
        isAttacking4 = false;
}
The isAnimationOver() function called above looks like:

bool Player::isAnimationOver()
{
        if (currentAnimation->getFrame() >= currentAnimation->getSize() - 1)
        {
                return true;
        }
        else
        {
                return false;
        }
}

Lastly, the attack animations look like:

attackAnimation()
{
        attack.setPlaying(true);
        attack.reset(); // This just makes sure the animation is starting from the beginning
        currentAnimation = &attack;
}

Please let me know if I should include any more code, I tried to put in everything relevant.

Thanks in advance for any help, guidance, direction of advice!
« Last Edit: March 10, 2021, 01:16:37 pm by delagore »