2013-12-13 6 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 для каждого столбца.

максимум-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

Я вижу, что это работает, но по какой-то причине я не смог воспроизвести его по моей точной проблеме. Однако я нашел другой способ добиться того, чего хотел, создав массив для подсчета блоков в каждом столбце, а затем вычитая нижнее расстояние по высоте для каждого из них. Я думаю, что это очень похоже на то, что вы пытались сказать, я просто использовал другой подход к кодированию. Большое вам спасибо! –

Смежные вопросы