1
\$\begingroup\$

I am recently creating a Game using html5 canvas .The player have multiple state it can walk jump kick and push and multiple other states my question is simple but after some deep research i couldn't find the best way to deal with those multiple states this is my jsfiddle : http://jsfiddle.net/Z7a5h/5/

i managed to do one animation but i started my code in a messy way ,can anyone show me a way to deal with multiple state animation for one sprite image or just give a useful link to follow and understand the concept of it please .I appreciate your help

 if (!this.IsWaiting) {
    this.IsWaiting = true;
    this.lastRenderTime = now;
    this.Pos = 1 + (this.Pos + 1) % 3;
 }
  else {
    if (now - this.lastRenderTime >= this.RenderRate) this.IsWaiting = false;
 }
\$\endgroup\$
  • \$\begingroup\$ That code snippet is really out of context. What exactly is this? Is it your game object? Your player-sprite object? Your graphic-engine object? \$\endgroup\$ – Philipp Mar 28 '14 at 9:10
2
\$\begingroup\$

When your animation system reaches a certain complexity, it becomes useful to pair each spritesheet with a separate animation manifest which says which animations are on that spritesheet and where the frames for each animation can be found.

The animation manifest could be a javascript object which says what animations the entity can perform, for how many different directions (between 1 and 8) it has separate animations for that action, and from which frames each of these animations are made up. These objects could look similar to this:

{  walk: [          // I have walk-animations for 4 directions, so a 4-entry array
       [ { frame: 0, delay: 100 },   // walk right
         { frame: 1, delay: 100 },
         { frame: 2, delay: 100 },
         { frame: 3, delay: 100 }
       ], 
       [ { frame: 4, delay: 100 },   // walk down
         { frame: 5, delay: 100 },
         { frame: 6, delay: 100 },
         { frame: 7, delay: 100 }
       ],  
       [ { frame: 8, delay: 100 },   // walk left
         { frame: 9, delay: 100 },
         { frame: 10, delay: 100 },
         { frame: 11, delay: 100 }
       ],  
       [ { frame: 12, delay: 100 },   // walk up
         { frame: 13, delay: 100 },
         { frame: 14, delay: 100 },
         { frame: 15, delay: 100 }
       ],        
   ],
   stand: [           // stanging is the same for all directions
       [ { frame: 4, delay: 0 } // just one frame borrowed from walk-down cycle
       ]         
   ],
   attack: //...
}

The advantage of this is that you are not bound to a rigid structure regarding spritesheet organization. Any entity can have as many or few animations with as many or few frames as you want. It is also possible to reuse duplicated frames between animations to reduce spritesheet size.

\$\endgroup\$
  • \$\begingroup\$ thank you for your answer would you show me a link that would be useful which explain how can i use these objects you just mention above ? \$\endgroup\$ – Sora Mar 28 '14 at 9:25
0
\$\begingroup\$

For your animations, i suppose you are using a sprite sheet like this one :

enter image description here

To handle animation, you have to deal with :
• Sprites : array containing the textures coordinates of the frames of the animation. It is just the (x,y) where the sprites starts, and the width/height of this sprite.
• Animation : frame indexes : array containing the indexes of the frame, in the order of replay.
• Animations : array or object containing all the animations.

fiddle is here : http://jsfiddle.net/gamealchemist/Vn2Nt/6/

// ____--------------------------------------_______
//           --- Bird animation ----

// array containig texture coords of all frames.
var textureCoords = [];

// fill the textureCoords using image img, assuming
//   frames are tiled in a 'regular way', sized tw X th, 
//   uses only cnt frames.
function fillTextureCoords(img, tw, th, cnt) {
    var w = img.width,
        h = img.height;
    var hCount = Math.floor(w / tw),
        vCount = Math.floor(h / th);
    for (var vIndex = 0; vIndex < vCount; vIndex++)
    for (var hIndex = 0; hIndex < hCount; hIndex++) {
        textureCoords.push({
            u: hIndex * tw,
            v: vIndex * th,
            w: tw,
            h: th
        });
        if (!--cnt) return;
    }
}

Now the frames index that form an animation :

// frames of the animation. 
// Contains index to the textureCoords array.
var regularAnimation = [];
for (var i = 0; i < 14; i++) regularAnimation.push(i);

var shortAnimation = [4, 5, 6];

// we store all anims in a single array
var birdAnimations = [regularAnimation, shortAnimation];
// Rq : could be stored in an object
// for instance : 
// var birdAnimations = { regular : regularAnimation, 
//                          short : shortAnimation };


var currentAnimation = regularAnimation;

// duration of a single frame.
var frameDuration = 100;

// current time of the animation (ms).
var animationStartTime = 0;

// draws the current animation frame
function drawThatFrame() {
    var animationStatus = applicationTime - animationStartTime;
    var whichFrame = Math.floor(animationStatus / frameDuration);
    whichFrame %= currentAnimation.length;
    var tCoord = textureCoords[currentAnimation[whichFrame]];
    context.drawImage(myBird,
    tCoord.u, tCoord.v, tCoord.w, tCoord.h,
    10, 10, tCoord.w, tCoord.h);
}

Changing the animation is done with :

function switchAnim() {
    // switch array
    if (currentAnimation == birdAnimations[0]) currentAnimation = birdAnimations[1];
    else currentAnimation = birdAnimations[0];
    // reset time
    animationStartTime = applicationTime;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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