1
\$\begingroup\$

I've been making this game where one of the characters, The Bandit, runs away from you mistaking you for a zombie. However, I can't seem to be able to animate the bandit. Is there a way I could use this w3schools example and make it fit with this canvas function?

The code for bandit is here or the second site:

   function drawBanditFacingDown(){
        //His face
    ctx.fillStyle = "#FFDE7A";
    ctx.fillRect(banditX, banditY, 25, 25);
    //His left eye (your left not his)
    ctx.fillStyle = "black";
    ctx.fillRect(banditX + 5, banditY + 5, 5, 8);
    //His right eye (again your right)
    ctx.fillRect(banditX + 15, banditY + 5, 5, 8);
    //His bandit thing on his mouth? I don't know what it's called
    ctx.fillStyle = "red";
    ctx.fillRect(banditX, banditY + 15, 25, 10);

    //His shirt
    ctx.fillStyle = "black";
    ctx.fillRect(banditX + 5, banditY + 25, 16, 25);

    //His arms
    //His right arm (YOUR RIGHT!!!!)
    ctx.fillStyle = "#FFDE7A";
    ctx.fillRect(banditX + 21, banditY + 25, 8, 20);
    //His left arm (On your left side)
    ctx.fillRect(banditX - 3, banditY + 25, 8, 20);

    //His pants
    //His right pant leg (ur right)
    ctx.fillStyle = "#11226B";
    ctx.fillRect(banditX + 12, banditY + 49, 8, 20);
    //his left pant leg
    ctx.fillRect(banditX + 5, banditY + 49, 8, 20);
    ctx.fillStyle = "black";
    ctx.fillRect(banditX + 11, banditY + 53, 3, 15);
    //his shoes
    //200 LINES!!!!!!
    ctx.fillStyle = "black";
    ctx.fillRect(banditX + 5, banditY + 68, 15, 5);
    }
\$\endgroup\$
  • \$\begingroup\$ Please integrate the code into the question. We're lazy and tend to not want to visit two external sites... \$\endgroup\$ – Vaillancourt Feb 1 '17 at 18:38
  • \$\begingroup\$ @AlexandreVaillancourt Ok, it's just it's a TON of code, but sure \$\endgroup\$ – The Gamer King Feb 1 '17 at 18:48
  • \$\begingroup\$ @AlexandreVaillancourt Edited it \$\endgroup\$ – The Gamer King Feb 1 '17 at 18:53
  • \$\begingroup\$ Well if you can't fit the code in the question, there may be an issue with the scope of the question. \$\endgroup\$ – Vaillancourt Feb 1 '17 at 18:54
  • \$\begingroup\$ @AlexandreVaillancourt It has to do with the question, it's just the function to draw the character needed for this question is a bit big. \$\endgroup\$ – The Gamer King Feb 1 '17 at 18:55
2
\$\begingroup\$

If I understand correctly you're asking how to get your function called multiple times in such a way to create an animation.

Its better to think of this problem in a different way however. Instead of thinking how can you get a moving animation, think of it as a repeating game loop that has two stages to it.

The first that updates your game's logic and the second that re-renders your entire scene.

Thankfully with the JavaScript environment in modern browsers, creating a gameloop is quite easy. You actually have a few options.

Set Interval

The setInterval(); function takes two values, the first is the name of the function you want to repeat and the second is the time in milliseconds in which you want to delay when the function is called again.

So for example

function update() {

}

function render() {

}

function loop() {
    update();
    render();
}

// Sets loop to run at ~60FPS
// 1000ms = 1s, 1000 / 60 = 16ms
setInterval(loop,1000 / 60);

This will get your game running in a loop, but calling setInterval(); again will cause problems by effectively creating two loops.

If you want to stop a loop you have created this way, you can use the value returned from setInterval(); in the clearInterval(); function.

let loopID = setInterval(loop,1000 / 60);

// stop the gameloop
clearInterval(loopID);

Set Timeout

The setTimeout(); function is the exact same as setInterval apart from one important detail, It waits for the delay you give and executes your function only once.

This is slightly more preferable since control on weather the loop needs to continue can be given over to the programmer.

but to use this to cause a function to loop like before.

function update() {

}

function render() {

}

function loop() {
    update();
    render();

    setTimeout(loop,1000 / 60);
}

setTimeout(loop,1000 / 60);

Similarly setTimeout(); has a cancel function as well clearTimeout(); that you can use in the same was as setInterval();.

Request Animation Frame

Probably the most well suited looping function for game programming in browsers. requestAnimationFrame(); will take a function and call it at the next vSync (This depends on the browser). In essense what this means is that it will automatically put a loop at 60FPS and take lag into account.

function update() {

}

function render() {

}

function loop() {
    update();
    render();

    requestAnimationFrame(loop);
}

// No additional values required
requestAnimationFrame(loop);

Like the two other functions, requestAnimationFrame(); can be stopped with cancelAnimationFrame();.

A clear advantage that this function has over the other two is what happens when a user switches tabs. A game loop using this function will effectively become paused when a user switches tabs and resume when they come back, whereas the other two loops would still be running.

Using A Loop For Animation

Using the approach I provided for animation shouldn't be too difficult.

assuming I have a square as follows.

let square = {
    x: 0,
    y: 0,
    dx: 1,
    dy: 1,
    width: 10,
    height: 10
}

I can use the update(); function to move it forward little by little each loop and then re-draw it at it's new position using render();

So the complete animation would look like this

function update() {
    // dx & dy refer to delta x & y (velocity)
    square.x = square.x + square.dx;
    square.y = square.y + square.dy;
}

function render() {
    // clear the canvas
    ctx.fillStyle = "gray";
    ctx.fillRect(0,0,canvas.width,canvas.height);

    ctx.fillStyle = "darkred";
    ctx.fillRect(square.x,square.y,square.width,square.height);
}

function loop() {
    update();
    render();

    requestAnimationFrame(loop);
}

// No additional values required
requestAnimationFrame(loop);
\$\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.