Y. Georgiev
Y. Georgiev

Reputation: 610

How can I have multiple simultaneous animations on 1 canvas in javascript

I am using sprites to animate 3 different characters. But the problem I am getting is I can see only one of the three animations (i guess the one that loads faster than the others). Is there a way to animate them at the same time so all of them can be seen?

js:

var monsterImg = new Image();
var monsterImg1 = new Image();
var monsterImg2 = new Image();

var canvas = document.getElementById("board");

monsterImg1.src = "minotaur.png";
monsterImg.src = "manyeyedball.png";
monsterImg2.src = "nomad.png";

var monster = sprite({
    context: canvas.getContext("2d"),
    width: 936,
    height: 222,
    image: monsterImg,
    x: 0,
    y: 144,
    amp: 10
});

var monster1 = sprite({
    context: canvas.getContext("2d"),
    width: 540,
    height: 144,
    image: monsterImg1,
    x: 0,
    y: 0,
    amp: 10
});

var monster2 = sprite({
    context: canvas.getContext("2d"),
    width: 828,
    height: 114,
    image: monsterImg2,
    x: 0,
    y: 366,
    amp: 15
});

function sprite (options) {

    var that = {},
        frameIndex = 0,
        tickCount = 0,
        ticksPerFrame = options.ticksPerFrame || 4,
        numberOfFrames = options.numberOfFrames || 6;

    that.context = options.context;
    that.width = options.width;
    that.height = options.height;
    that.image = options.image;
    that.x = options.x;
    that.y = options.y;

    that.loop = options.loop;

    that.update = function () {

        tickCount += 1;

        //console.log("tick count: " + tickCount);

        if (tickCount > ticksPerFrame) {

            tickCount = 0;

            //console.log("frame index: " + frameIndex + ", number of frames: " + numberOfFrames)

            // If the current frame index is in range
            if (frameIndex < numberOfFrames - 1) {  
                // Go to the next frame
                frameIndex += 1;
                that.x += options.amp;
            }
            else {
                frameIndex = 0;
            }
            //console.log("frame index: " + frameIndex);
        }
    };

    that.render = function () {

        // Clear the canvas
        that.context.clearRect(0, 0, canvas.width, canvas.height);

        // Draw the animation
        that.context.drawImage( that.image, frameIndex * that.width / numberOfFrames, 0, that.width / numberOfFrames, that.height, that.x, that.y, that.width / numberOfFrames, that.height);
    };

    return that;
}

function eyedBallLoop() {

    window.requestAnimationFrame(eyedBallLoop);

    monster.update();
    monster.render();
}

function minotaurLoop() {

    window.requestAnimationFrame(minotaurLoop);

    monster1.update();
    monster1.render();
}

function nomadLoop() {

    window.requestAnimationFrame(nomadLoop);

    monster2.update();
    monster2.render();
}

monsterImg.addEventListener("load", eyedBallLoop, false);
monsterImg1.addEventListener("load", minotaurLoop, false);
monsterImg2.addEventListener("load", nomadLoop, false);

html:

<!DOCTYPE HTML>
<html>
    <body>
        <canvas id="board" width="950" height="950"></canvas>

        <script type="text/javascript" src="test.js"></script>
    </body>

images:

1st: https://imgur.com/o9hC5d8

2nd: https://imgur.com/I4SY0c9

3rd: https://imgur.com/3nM3lmT

Upvotes: 1

Views: 1280

Answers (1)

4thex
4thex

Reputation: 1166

The problem is that you clear the canvas before each render in the sprite function.
Instead render all three images, and clear the canvas before each round of rendering.
Another thing to consider is to render all of them each time you get the animation frame. Just iterate over an array of "monsters".

Upvotes: 1

Related Questions