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\$
0

1 Answer 1

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\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .