【问题标题】:HTML Canvas create multiple rectangles that are animatedHTML Canvas 创建多个动画矩形
【发布时间】:2013-12-29 21:44:35
【问题描述】:

我正在尝试使用需要创建多个块的 Canvas 创建 HTML5 游戏(每秒创建一个新块)。每次创建一个新块时,它都需要使用动画“落”下屏幕。我可以让动画为一个元素正常工作,但我不确定如何创建多个元素(并以与动画 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 只是另一个创建圆角矩形的函数。它工作正常。

【问题讨论】:

    标签: javascript html animation canvas


    【解决方案1】:

    Live Demo

    这是一种方法。创建一个数组来保存你的块,以及一个用于盒子的 Block 对象。然后我创建两个方法,update 和 render,它们更新框并将其绘制到画布上。

    块对象

    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);
    };
    

    检查时间是否达到阈值

    至于创建独立于帧速率的新块,您只需进行时间检查,看看自上次创建块以来是否经过了 1 秒。

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

    基本上这是如何工作的,如果当前时间大于上次时间 + 1 秒,它将创建一个新时间,并将 lastTime 重置为当前时间。

    附加信息

    我强烈建议您查看requestAnimationFrame,这是进行任何类型画布渲染的正确且事实上的方式。

    完整来源

    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();
            });
    };
    

    【讨论】:

    • +1 但是你的 +new Date() 懒人!! ;-D 如果检查发生在 0:01.9999.. 并且您存储的时间是 0:02:0000 那么您将在下一次检查中错过一整分钟:) (可能性很小,但这些事情仍然经常发生)
    • @KenFyrstenberg 我从来没想过,但你是对的!
    • 这完全符合我的要求。太感谢了!我以为我可以得到下一部分(确定块之间的碰撞),但我无法弄清楚如何确定这些块是否发生碰撞,因为它们是同一种元素?有没有办法做一个 (this.y + this.height)
    猜你喜欢
    • 2016-01-30
    • 2014-01-22
    • 2015-10-06
    • 2014-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    相关资源
    最近更新 更多