Kyle B.
Kyle B.

Reputation: 439

HTML Canvas create multiple rectangles that are animated

I am trying to create and HTML5 game using Canvas that needs to have multiple blocks being created (create a new block every second). Each time a new block is created, it needs to "fall" down the screen using an animation. I can get the animation to work correctly for one element, but I'm not sure how to do it with creating multiple (and creating them at a time interval different that the interval being used for the animation FPS).

//update and animate the screen
var FPS = 60;
setInterval(function() {
  //update();
  draw();
}, 1000/FPS);

var y = 30;
var dy = 5;

//5 + Math.floor(Math.random()*6)

//draw the screen
function draw() {
    //var y = 30;
    context.save();
    context.clearRect(0,0,canvas.width, canvas.height);
    rounded_rect(1*40, y, 40, 40, 5, "red", "black");
    if (this.y < 360){
        y += dy;
    }
    context.restore();

};

rounded_rect is just another function that creates a rounded rectangle. It works correctly.

Upvotes: 2

Views: 2978

Answers (1)

Loktar
Loktar

Reputation: 35319

Live Demo

This is one way to do it. Create an array to hold your blocks, and a Block object to use for the boxes. I then create two methods, update and render which update the box and draw it to the canvas.

Block Object

function Block(x,y,width,height){
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

Block.prototype.update = function(){
    if(this.y < 360){
        this.y+=dy   
    }else{
        this.y = 0;   
    }
};

Block.prototype.render = function(){
    context.fillRect(this.x, this.y, this.width, this.height);
};

Checking if time passed has met the threshold

As for creating new ones independent of the frame rate you can just do a time check to see if 1 second has passed since the last time you created a block.

if(+new Date() > lastTime + minWait){
    lastTime = +new Date();
    // add a new block
    blocks.push(new Block(Math.random()*300, 0,20,20));
}

Basically how this works is if the current time is greater than the last time + 1 second it will create a new one, and reset the lastTime to the current time.

Additional Info

I highly suggest you look at requestAnimationFrame it is the proper and defacto way to do any sort of canvas rendering.

Full source

var canvas = document.getElementById("canvas"),
    context = canvas.getContext("2d");

//update and animate the screen
var FPS = 60;
setInterval(function() {
  //update();
  draw();
}, 1000/FPS);

var dy = 5,
    blocks = [],
    minWait = 1000,
    lastTime = +new Date();

function Block(x,y,width,height){
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

Block.prototype.update = function(){
    if(this.y < 360){
        this.y+=dy   
    }else{
        this.y = 0;   
    }
};

Block.prototype.render = function(){
    context.fillRect(this.x, this.y, this.width, this.height);
};

//draw the screen
function draw() {
    if(+new Date() > lastTime + minWait){
        lastTime = +new Date();
        blocks.push(new Block(Math.random()*300, 0,20,20));
    }

    context.clearRect(0,0,canvas.width, canvas.height);

        blocks.forEach(function(e){
            e.update();
            e.render();
        });
};

Upvotes: 4

Related Questions