使用一个动画循环动画独立矩形(requestanimationframe)

时间:2014-05-30 15:10:38

标签: javascript html5 animation html5-canvas requestanimationframe

我试图水平地表示移动矩形的行。为此,我创建了矩形的实例" class"然后移动它们来增加它们的X属性。 根据这个论坛的建议,我使用requestAnimationFrame来完成这项任务。

逻辑问题

我试图表示从客户端发送到服务器的包。 (从左到右)。

这是一个打印屏幕:

https://s27.postimg.org/fw20wxyz7/Captura_de_pantalla_2014_05_30_a_la_s_17_00_16.png

我面临的问题是,当一个矩形"相交时,"与任何其他矩形(意思是相交一个或多个矩形同时具有相同的x值)我需要等待一段随机时间才能在同一行中绘制一个新矩形。

现在,我在单个requestAnimationFrame循环中执行所有动画。我怎么能等待并分别绘制每个矩形。

我搜索了很多关于这个主题的内容,看起来你应该只使用一个循环,但在这种情况下,如何在不使用Java之类的线程的情况下执行此操作?

如何在不停止整个动画循环的情况下等待一段随机时间? 我应该为每个矩形使用独立的requestAnimationFrame循环吗?

Rectangle.prototype.move=function(){

    var maxRight=canvas.width-this.width;

    for(var i=0; i< rectangles.length; i++){
        if(rectangles[i].y!=this.y){

            if(intersects(this.x,this.width,rectangles[i].x,this.width) && this.colided==false){
                console.log("choque");
                this.colided=true;
                this.color="#DC143C";
                rectangles[i].color="#DC143C";
                rectangles[i].colided=true;
                numColisions+=2;
            }
        }

    }

    this.x+=this.velocityX;


    if(this.x>maxRight){
        this.end=true;

    }
    return(this);
};

// draw this rect on the canvas
Rectangle.prototype.render=function(){
    ctx.fillStyle=this.color;
    ctx.fillRect(this.x,this.y,this.width,this.height);
    return(this);
}

2 个答案:

答案 0 :(得分:0)

你可以通过以下方式暂停一个随机动画循环的矩形运动:

  • this.suspend属性添加到R​​ectangle类

  • 当一个矩形碰撞然后将其暂停倒计时设置为随机延迟

  • 如果一个矩阵被&#34;暂停&#34;而不是移动它只是减少它的.suspend倒计时

  • 如果矩形处于活动状态,只需将其移动

  • 即可

示例代码(未经测试):

// add a this.suspend property to the Rectangle class

this.suspend=0;
...

// only move the rect if the rect is not suspended

Rectangle.prototype.move=function(){

    var maxRight=canvas.width-this.width;

    for(var i=0; i< rectangles.length; i++){
        if(rectangles[i].y!=this.y){

            if(intersects(this.x,this.width,rectangles[i].x,this.width) && this.colided==false){
                console.log("choque");
                this.colided=true;
                this.color="#DC143C";
                rectangles[i].color="#DC143C";
                rectangles[i].colided=true;
                numColisions+=2;

                // suspend moving this rect for random time (0-5 loops)
                this.suspend=parseInt(Math.random()*5);
            }
        }

    }

    // decide whether or not to move this rectangle
    if(this.suspend>0){
        // this rect is suspended, reduce the suspension countdown
        this.suspend--;
    }else{
        // this rect is active, move it
        this.x+=this.velocityX;
    }

    if(this.x>maxRight){
        this.end=true;

    }
    return(this);
};

答案 1 :(得分:0)

我认为你等待一段随机时间并不能正确理解我的意思。这不是我想延迟整理的矩形,而是从左边距创建一个新的(就像它是从同一个客户端再次发送的)。 但是你的两种方法都非常有用,只是我需要将suspend属性添加到一个新的矩形实例中(或者将负x添加到新的矩形中)。

无论如何,我的新函数看起来像那样,但是当我在if语句中创建新实例时,我不知道为什么整个代码没有运行。

Rectangle.prototype.move =函数(){

var maxRight=canvas.width-this.width;

for(var i=0; i<rectangles.length; i++){
    if(rectangles[i].y!=this.y){

        if(intersects(this.x,this.width,rectangles[i].x,this.width) && this.colided==false){
            console.log("choque");
            this.colided=true;
            this.color="#DC143C";
            rectangles[i].color="#DC143C";
            rectangles[i].colided=true;
            numColisions+=2;

            //Create 2 new rectangles 

            var rect1=newRect(0,this.y,40,30);
            rect1.velocityX=speed;
            rectangles.push(rect1);
            rect1.suspend=parseInt(Math.random()*5);


            var rect2=newRect(0,rectangles[i].y,40,30);
            rect2.velocityX=speed;
            rect2.suspend=parseInt(Math.random()*5);
            rectangles.push(rect2); 

        }


    }
}


// decide whether or not to move this rectangle
if(this.suspend>=0){
    // this rect is suspended, reduce the suspension countdown
    this.suspend--;
}else{
    // this rect is active, move it
    this.x+=this.velocityX;
} 

this.x+=this.velocityX;
if(this.x>maxRight){
    this.end=true;

}
return(this);

};