In my main update loop, I would only first check global inputs, like for pause or anything that affects the game as a whole, then I would do specific checks on a per state basis.
STATE_DAZED:
Check for ANY possible input, and use it to reduce the daze timer.
STATE_IDLE or STATE_WALKING
Check for anything and respond. Like movement keys, attack, jump, whatever.
STATE_DASHING:
Check for anything and respond, but the responses are different than above.
STATE_ATTACKING:
Player is busy is attacking
STATE_HIT:
No valid input in this state, player is reacting to being hit.
etc...
I find that cleaner and straight forward than other methods. But that is a matter of opinion and organization. I find checking input and then later trying to match it up to a correct state to be backwards thinking. Why do the logic up front only do find out later down the line that you aren't even in the correct context?
Question 2:
As for the attack stuff. I kept my description very high level. I'll try to answer it better
You have a character object, and he references a sprite sheet, such as: http://soronline.net/sprites/sor3/Axel(sor3).png
So now you have a list of animations for this character. An animation is a class that has some data that describes it, plus a list of frame structures...
PSEUDO CODE
class animation
{
string Name;
ANIMATION_TYPE Type;
//with enums
ANIMATION_TYPE_WALKING
ANIMATION_TYPE_RUNNING
ANIMATION_TYPE_ATTACKING
etc...
//a list of frames
vector <Frame> Frames;
}
class Frame
{
bool isContact; //contact frame?
someType delay; //delay until the next frame, in whatever measurement form you are using
//coords of the frame on the sprite sheet
int x,y;
int height,width;
//coords of the hitbox
int hitbox_x,hitbox_y;
int hitbox_width,hitbox_height;
//coords of the contact hitbox, if applicable, on contact frame only
int contact_x,contact_y;
int contact_width,contact_height;
}
The logic in your update function will deal with the attack. The SetState function example was just code to handle state switching cleanly.