2013-12-13 62 views
0

我一直在嘗試使用下降塊創建一個遊戲,這些塊將堆疊在彼此之上。塊將落入6列中的一列,當它們與該列上的頂部塊相撞時,需要停止落下屏幕。我一直在嘗試獲取頂部塊的y座標,但這會導致問題,因爲它仍然會獲取最新創建的塊而不是最後完成的塊。任何幫助將不勝感激!具有多個塊的html5畫布碰撞檢測

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

一個方面說明,而不是使用'setInterval' /'setTimeout',用['requestAnimationFrame'](HTTPS://developer.mozilla。 org/en-US/docs/Web/API/window.requestAnimationFrame)以更好地適應瀏覽器的重繪週期。 – Passerby

+0

對我而言,我本能地使用網格系統。否則,保持跟蹤每個塊的下降(特別是當它們隨着時間的推移而被刪除時)將是一種痛苦 –

+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> 
+0

我看到這可以工作,但由於某些原因,我無法複製它,因爲我確切的問題。然而,我找到了另一種方法來實現我想要的功能,爲每列中的塊數創建一個數組,然後將每個塊的底部距離減去高度。我認爲它與你想說的非常相似,我只是使用了不同的編碼方法。儘管非常感謝! –