You can implement a time-step to slow things down. Right now, your computer is just blowing through your frames as quickly as it can. A time step will also make it run on the same speed if on a faster or slower computer, or even if the resources on the computer you're currently using change:
while i agree with everything you've said, i don't believe this is his problem. if he has vsync on then that will basically act as his timer, and without seeing the rest of his code, it's impossible to say if he does or does not use a timer(likely he does not though). so i think he should follow your post, but in this instance i don't believe that is his issue.
edit: however, upon re-reading your code, you should not be setting frameCounter back to 0, instead subtract switchFrame from that counter. this is because by setting it to 0, you lose any amount of time that has accumulated past switchFrame. for example, let's say on the first frame you get 15ms, just shy of 16ms to run at 60fps, the os switchs away, then switchs back, this took 18ms to do, so now frameCounter is at 33ms, this would be two complete frames, with an extra ms into the third but you only process one frame, then reset frameCounter to 0, which loses all that accumulated time.
Okay lemme explain this part
if(++linkSprite.curframe == 5) { if(++attackanimcount < attackanimdelay) { linkSprite.curframe = 5; canAttack = false; } }
Basically when the attack animation reaches the final frame, I want it to stay on that frame for the just a lil bit before it resets back to frame 4. that's what attackanimcount and attackanimdelay do. If attackanimcount is less than the delay, keep on staying on frame 5 until it surpasses the delay amount. But looks like it isn't working. Ill try some of the solutions that you and the others mentioned.
let me reiterate, that part of your code doesn't do anything, when you explicitly set the frame back to 4 on each frame:
if(linkSprite.curframe != 4 || linkSprite.curframe != 5)
linkSprite.curframe = 4;
this is basically saying: "hey, am i not 4? then set me to 4. hey, am i also not 5? then set me to 4." this logic will run on every single frame because a variable can not be 2 values at once. because this line is before that other logic, it's possible for you to achieve a single-frame on frame 5, but if you are running at 60 fps, you'll see this on screen for a mere 16ms of time.
also, a couple other things you should note:
-setting canAttack = true at the start of your function negates setting it to false at the end, and makes the if(canAttack==true) logic pointless.
-you will only animate while holding down the down or S key, so i'd recommend moving your animation code
outside of your input logic code.
i'm not going to fix your code completely, but as it is, a simple change like so should get you your desired result:
void Link::attack()
{
if(linkInput.CheckStateInput(ALLEGRO_KEY_S) && !linkInput.CheckStateInput(ALLEGRO_KEY_DOWN))
{
canAttack = true;
//Ready to attack?
if(canAttack == true)
{
//Dont let link move or jump while attacking
if(jump == JUMPIT)
{
linkSprite.x = linkSprite.oldpx;
linkSprite.y = linkSprite.oldpy;
}
if(++linkSprite.framecount > linkSprite.framedelay)
{
linkSprite.framecount = 0;
linkSprite.curframe++;
if(linkSprite.curframe==6) linkSprite.curframe = 4; //we go back to 4 once we've passed the 5th frame.
}
}
}
}