attack animation woes
red-dragon

Ok, I'm here once again.

This project is due Tuesday-Thursday (depends on the instructor). I REALLY want to finish implementing a very simple battle system. So, let me explain how I want this to go.

When user hits SPACEBAR, Link should be displayed with his sword out and attacking. So if you're facing Southwards, I want Link to use the proper sprites/frames, face downwards and attack.

So, to avoid complication (and the horrible errors I was getting last night), I made another update attack function as follows:

1/* displays proper sword attack sprite depending on direction */
2void updateattacksprite(SPRITE *spr)
3{
4 a--;
5 //update frame based on dir
6 if (++spr->framecount > spr->framedelay)
7 {
8 spr->framecount = 0;
9
10 
11 if(prev_dir == 4)
12 {
13 textout(buffer, font, "USER PRESSED SPACEBAR,
14 SHOULD USE SWORD ANIMATION", 20, 20, WHITE);
15
16 //for(a=0; a<3; a++)
17 //{
18 if(spr->curframe != 14)
19 spr->curframe++;
20 
21 
22 if(spr->curframe == 14)
23 spr->curframe = 12;
24 
25 else if(spr->curframe < 12)
26 spr->curframe = 14;
27
28 draw_link();
29 
30 }
31 }
32
33
34}

Now, within main(), within the while loop, I have this:

        if (keypressed())
           key = getinput();  

        /* key will only be 1 if SPACEBAR was pressed */
        if(key == 0)
        {
               updatesprite(link);
               move_character();
               draw_link();
        }
               
        else if((key == 1) && (a != 0))
               updateattacksprite(link);

NOTE: Keep in mind, a is set to 3 (a=3;) is done when the spacebar is pressed.

Okay, so when user is facing south and hits spacebar, frames 12-14 should consecutively be displayed. I don't want to do this using a for loop (as I've commented out) because it looks really choppy and b) even using rest(100) within the for loop, the frames happen really quickly; it seemed rest had no effect on slowing down the animation.

Now what's happening is that the results are weird. Sometimes the animation frames 12 and 13 appear. Sometimes only 12 appears or only 13. Also, sometimes Little Link disappears from screen for just the slightest fraction of a second. Is this because of the keypressed()?

Can someone point out the mistakes I'm making? Appreciate the help, TIA.

Steve Terry

Link should never flash if you are doing proper double buffering. As for the animation are you using timers to limit your fps? Perhaps he's just moving too fast. Lastly it's much much easier to lay out your sprite map such that when you press spacebar you simply do a shift/multiply/add to figure out what frame you should display.

red-dragon

Steve,
I realized why it was blinking; because I called updateattacksprite() and called draw_link() within it. Now, when spacebar is pressed, I make a=6 instead of 3. And now, I made this change:

else if((key == 1) && (a != 0))
{
   a--;
   updateattacksprite(link);
   draw_link();
}

I made a=6 because each game loop will updateattacksprite three times, and we need draw_link() to run three times as well. So, blinking problem is gone.

Still though, when I face down and spacebar, all 3 animations do come into play. But sometimes it will only display frame 12 or stay stuck on 13. Does this have to do with how long the spacebar is held? ???

EDIT: No, I'm not using any timers. I was going to implement that after I have my battle system together. But I will implement it right after I figure out this spacebar 'problem'.

Steve Terry

I think you need to think of things in states here. When you press the space bar you can't just display a frame, wait 1 second, then display the next without the possibility that you will end up mid frame. This is because once you let off the space bar there is nothing to put it back to the original state.

if(key[KEY_SPACE])
  link->state = attack;
else
  link->state = normal;

red-dragon

Steve,
I'm not sure I completely understand what you're saying, but I think I have something similar to what you're saying. For instance, within int getinput(), if keybar is pressed, it'll make key = 1; if any other key is pressed, then key = 0;

Then within main(), I have:

1 if(key == 0)
2 {
3 updatesprite(link);
4 move_character();
5 draw_link();
6 }
7 
8 /* if spacebar was pressed AND
9 all the animations are done (a=6) */
10 else if((key == 1) && (a != 0))
11 {
12 a--;
13 updateattacksprite(link);
14 draw_link();
15
16 }

So as far as I know, if any of the directional keys are pressed, it uses regular animation of walking, then moves the character, then draws it. Else if spacebar was pressed, then, go to frames 12-14.

I just don't understand why sometimes it just displays frame 12 and gets stuck there, unless I start walking again and hit spacebar again, then it kinda rectifies itself. I want to understand my error. Keep suggestions comin' :P

Matthew Dalrymple

What Steve is trying to get at is you should always be drawing and updating link, but when you press space that should be changing the state at which link is being drawn at.

Here is some c influenced pseudo-code:

1...
2LinkState(NORMAL);
3...
4while(true)
5{
6 draw_link();
7 if(key[KEY_SPACE])
8 {
9 LinkState(ATTACKING);
10 }
11 else
12 {
13 LinkState(NORMAL);
14 }
15}

Now draw_link() should incorporate the LinkState()

LinkState(variable state)
{
  if(Link's state is NORMAL)
  {
    draw him normal
  }
  if(Link's state is ATTACKING)
  {
    draw him attacking
  }
  etc...
}

Wrapping link as some sort of sprite class would make things easier and less global variables for LinkState and DrawLink are needed to be able to talk to each other.

Thread #589018. Printed from Allegro.cc