Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Lets say you have an animation that you want to happen when firing a bullet. How would you get the bullet to show up at the end of the animation. The only thing I can figure out is to know the time length of the animation, and delay setting the bullets position and setting it active until that amount of time has passed. I was just wondering if this is the best approach, how does everyone else handle this?

EDIT: I think i'm having trouble wording the question properly.

My Question

share|improve this question
    
Thanks! Many good ideas from all of you, I like the idea of using a callback. I think I'll try and implement that, I really didn't want to rely on time tracking. –  tp0w3rn Oct 4 '11 at 20:19

5 Answers 5

up vote 7 down vote accepted

Fundamentally you're on the right track - you need to know how long an animation lasts to do this sort of thing. Animations are more than just a collection of frames, there is all sorts of other information around them that you need. E.g. how many frames are there, does the animation loop, how quickly does it play back (e.g. 10 animation frames per second or 25, or 60?). Every animation can be defined in terms of a few pieces of data, which some generalised animation code can look at and play back. You should be encapsulating the animation part in its own bit of code, which is aware of nothing except these animation definitions and how to display the individual image frames. That is, have an animation object which you can load, start playing, stop playing, and tell to render at a particular location on screen.

A flexible approach is to use a sort of animation definition to encapsulate this sort of information. So rather than just saying "animation X is all of these frames, just play through them", you get something a bit more complex.

E.g. with some sort of mocked up data format

animations =
{
  { name="walk", files="walk*.png", frameCount="12", loop="true" },
  { name="fire" files="fire*.png" frameCount="6",
       events = {
           { name="bulletLeavesGun", frame="4", param1="43", param2="30" }
       }
  }
}

So your code says something like:

currentAnimation = animations.Get("fire");
currentAnimation.Play();

How you detect events can either be with the animation code calling you back (i.e. when it detects a new event because the animation has played to a certain frame, it calls your game code to tell it about the new event), or by polling the animation like so:

List<Event> events = currentAnimation.EventsSinceLastCheck();
foreach (AnimationEvent event in events)
{
    if (event.name == "bulletLeavesGun")
    {
        Vector2 bulletPosition = new Vector2(event.param1, event.param2);
        Vector2 actualBulletPosition = new Vector2(
                 character.x + bulletPosition.x, 
                 character.y + bulletPosition.y);
        CreateBulletAt(actualBulletPosition);
    }
}

Points to note:

  • Animation code should exist separately from game code. You really don't want your gameplay code too tightly tied to the nuts and bolts of animation playback.
  • The animation code knows whether or not to loop based on the animation definition
  • The animation code knows when the animation is done, and can call back to some other code to say 'hey, the animation called "fire" just finished, what do you want to do now?'
  • The animation code doesn't know anything about events other than that they have a name and some arbitrary data associated with them (param1 and param2)
  • The animation code knows what frame it's currently on, and when it changes to a new frame, it can check and say 'oh, I'm on frame 4 now, that means this event called "fire" has just happened, add that to my list of recent events so I can tell anyone who asks about it'.

If you don't need the bullet firing to happen within the animation, but only once it has finished, you can get away with a much less complex system without the notion of events. But you'll still want a system where animations play back on their own, know how long they are, and can call back to the game code when an animation completes.

share|improve this answer
    
I don't agree with keeping logic aware animations (on frame 4 now, that means this event called "fire" has just happened). Animations should be blind and dumb. I had to do some server side logics and tearing animations and UI out of a game is something I don't want to do again. I would really recommend using very short and segmented animations, play them in parallel to logics let the logics trigger animation sequences at the speed defined by the logics. Never have logics test for an animation's status. –  Coyote Oct 4 '11 at 19:13
    
Splitting the animation up into pieces seems pretty unnecessary. I would agree with not polling for the animation's status, but that still leaves his first recommendation. I don't know if he meant a separate event system to decouple the animation code from the rest of the game (observer pattern?) but that's how I'd do it. Neither the "logics" as you put it should know about the animation code, or vice versa. –  jhocking Oct 4 '11 at 19:57
    
@Coyote I'd say there you're mixing two separate things. Yes, server side logic should always be independent of visuals (because you don't want to have to run the animation system just to figure out when a bullet is fired), but that's not going to help you build an animation system on the client. On the client, you absolutely don't want the visuals to be mindlessly slaved to the server, because that would look awful - bullets appearing at odd times and out of sync with the character because there was a lag spike between the game and the server. There's no reason you can't have both (cont...) –  MrCranky Oct 6 '11 at 14:43
    
@Coyote (cont...), the gameplay can be driven by the server decoupled from the visuals. So the bullet is fired at time X on the server, and the client mirrors that action by starting to play the fire animation immediately, with the bullet firing visual lagging a few frames behind the bullet gameplay simulation. All sorts of compromises need to be made between visual fidelity and gameplay simulation, so to say that "animations should be blind and dumb" is simply naive. Sometimes events absolutely need to be tied to animation frames, because no other method will make them look or sound right. –  MrCranky Oct 6 '11 at 14:47
    
@Coyote Actually now I think about it, the bullet firing is a terrible example for this, mostly because of the answer from thedaian below. Firing should happen straight away. A better example would be a dust VFX firing when a character lands - the server and client would sync as to when the character starts to jump, but the visual display is left up to the client. And when the animation hits the right frame where the foot hits the ground, the VFX event should fire. Similarly, events are needed if a decision needs to be made on a certain animation frame whether to branch to another animation. –  MrCranky Oct 6 '11 at 14:55

In some way, you'll have to wait until the animation is done and create the bullet at that point.

Just setting a timer will work, if you're sure that your animation rate is fixed. As a minor variation, you could have code internal to the bullet that makes it wait invisibly for a moment before appearing and moving.

Depending on your development platform, you may have some sort of animation update function or callback that will let you respond the exact moment the animation reaches the desired point. This is how I'd do it with Flixel, for example.

share|improve this answer
1  
Flixel's addAnimationCallback method can be used on the firing entity. In the callback function, you can see if the current frame of the firing animation is the frame that should create a bullet entity. If it is then you can add a bullet on the screen. –  Snow Blind Aug 5 '12 at 8:44

Straight forward answer: Assuming you have an animation that you want to play when the player hits the 'fire' button, and then have a bullet come out after it's done playing. Ideally, you should avoid hard-coding the animation time, and fire the bullet when the animation completes (using a callback function or something, depending on your platform). I can't think of any other method to do this that isn't overly complex.

Alternate Game Design answer: Unless there's a really, really good reason to do so, I would avoid having a delay from pressing the 'fire' button and having the bullet appear. Unless the animation is really, really short (one or two frames, max, basically a muzzle flash), it's going to make the fire button response feel slow, and it will just get annoying to a typical player. Even if you do decide to go with using an animation before the bullets come out (turn based RPGs and tactical games would be acceptable reasons to do this), I'd think about including a "turn off animations" option somewhere, to allow the game to move faster if the player wants.

share|improve this answer
    
Yeah don't make the fire react slowly. This is just like the common issue with jumping; animators make a big windup, but players expect to be airborne as soon as they tap the button. –  jhocking Oct 4 '11 at 21:30

As MrCranky says ; keep animation and logics separated.

But most importantly, logics must remain the master part.

  • When the fire button is pressed you should trigger the draw "action" in your character's state (logics).
  • This action should trigger the drawing animation with all the parameters (time to live etc).
  • Once the draw action is finished you can trigger the fire action (could fire once or more depending on the weapon)
  • This action can generate bullets and trigger the fire animation.

Keep in mind that controlling the UI from the logics is the only way to ensure you will be able to keep, reuse and share your logics later (new renderer, new game, server version without a renderer...)

share|improve this answer

First off, I'd use an event system (observer pattern?) to decouple pieces of the code. This isn't just for the animation, but certainly applies there. Then the animation code can simply say dispatchEvent(event) and some other part of the code listens for that event, without either part of the code needing to know about each other.

Now the animation code needs to actually have a reference to the event dispatcher (easily done with dependency injection) and you need to have some XML or JSON that actually defines your animations. Something like:

{
  animation: {
    name: shoot,
    length: 12,
    spritesheet: shoot.png
    event: {
      frame: 4,
      name: bulletLeavesGun,
    },
  },
}

Read in the data when loading the animation, and have the animation code dispatch the event when it's on that frame during playback.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.