html5使用多个块进行画布碰撞检测

时间:2013-12-13 02:52:47

标签: javascript html5 canvas collision-detection

我一直在努力创造一个具有下降块的游戏,这些游戏将叠加在一起。这些块将落入6列中的一列,并且当它们与该列上的顶部块碰撞时需要停止从屏幕上掉下来。我一直试图获得顶部块的y坐标,但这会导致问题,因为它仍然获得最新创建的块而不是最后一个完成的块。任何帮助将不胜感激!

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

var y = 30;

//draw the screen
function draw() {
    if(+new Date() > lastTime + minWait){
        var column = Math.floor(Math.random()*6) 
        lastTime = +new Date();
        blocks.push(new Block(5 + column*40, 30,40,40, 5, "red","black"));
    }

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

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

var blocks = [];
var lastTime = +new Date();
var minWait = 1000;
var topBlock = 310;

function columnTop(column){
    for(var i=0; i < blocks.length; i++){
        if(blocks[i].x === (5 + 40*columnTop)){
            if(blocks[i].y < topBlock){
                topBlock = blocks[i].y
            }
        }
    }
}


//block functions
Block.prototype.update = function(){
    var topCol1 = columnTop(1);
    var topCol2 = columnTop(2);
    var topCol3 = columnTop(3);
    var topCol4 = columnTop(4);
    var topCol5 = columnTop(5);
    var topCol6 = columnTop(6);

    if(this.y < 310){
        this.y+= this.dy   
    }else{
        this.dy = 0;   
    }
};

Block.prototype.render = function(){
    Block(this.x, this.y, this.w, this.h, this.r, this.fillstyle, this.strokestyle);
};

1 个答案:

答案 0 :(得分:1)

保持每列的最大Y值。

maximum-Y是最后一个堆积块的y位置。

每当一个区块超过最大-Y时,强制该区块位于最大-Y之上。

然后通过该块高度减少最大-Y。

if( block.y + block.height > maxY ){
    block.y = maxY - block.height;
    maxY = block.y;
}

这是代码和演示:http://jsfiddle.net/m1erickson/FMv2q/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
    $(function(){

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

        function Blocks(floor,colCount){
            this.blocks=[];
            this.floor=floor;
            this.cols=[];
            this.continueRAF=true;
            for(var i=0;i<colCount;i++){
                this.cols.push({maxY:floor,needsNewBlock:true});
            }
        }
        function animate(){
            if(blocks.continueRAF){ requestAnimationFrame(animate); }
            for(var i=0;i<blocks.cols.length;i++){
                if(blocks.cols[i].needsNewBlock){
                    blocks.cols[i].needsNewBlock=false;
                    blocks.blocks.push(new Block(i));
                }
            }
            ctx.clearRect(0,0,canvas.width,canvas.height);
            var fallingCount=0;
            for(var i=0;i<blocks.blocks.length;i++){
                var block=blocks.blocks[i];
                fallingCount+=block.fall();
                ctx.fillStyle=block.fill;
                ctx.fillRect(block.x,block.y,block.w,block.h);
            }
            if(fallingCount==0 && blocks.continueRAF){
                blocks.continueRAF=false;
                alert("All done after "+blocks.blocks.length+" blocks fell.");
            }
        }


        function Block(column){
            this.column=column;
            this.x=this.column*50;
            this.w=parseInt(Math.random()*20+15);
            this.h=parseInt(Math.random()*15+5);
            this.y=-this.h;
            this.vy=parseInt(Math.random()*3+4);
            this.fill=randomColor();;
            this.isFalling=true;
        }
        Block.prototype.fall=function(){
            if(!this.isFalling){return(0);}
            var col=blocks.cols[this.column];
            if(this.y+this.h+this.vy>col.maxY){
                this.isFalling=false;
                this.y=col.maxY-this.h;
                col.maxY=this.y;
                if(col.maxY>35){
                    col.needsNewBlock=true;
                }
            }else{
                this.y+=this.vy;
            }
            return(1);
        }

        var blocks=new Blocks(350,6);
        animate();

        function randomColor(){ 
            return('#'+Math.floor(Math.random()*16777215).toString(16));
        }


    }); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=350 height=350></canvas>
</body>
</html>