2017-10-23 17 views
0

ボールがブロックと衝突してブロックを削除する部分を得ましたが、ボールがブロックの上部または下部または左または右に当たってそれに応じて跳ね返るかどうかを知る。私はそれを試みましたが、それはかなり正しく動作していません。それはちょうど周りに飛び跳ねるフリークアウト。私はそれが動作しないので、下のコードからその部分を削除しました。誰もこの問題で私を助けることができますか?たぶん、例を挙げたり、それがどういう仕組みか教えてください。私はアタリブレイクアウトクローンを作っています。ボールがブロックの特定の面に当たったかどうかを知りたいと思っています

<canvas id="can" height="500" width="1000"></canvas> 


     var c = document.getElementById("can"); 
     var ctx = c.getContext("2d"); 
     var blocks= []; 
     var paddle = {x:450,y:480,h:10,w:100}; 
     var ball = {r:7,x:500,y:469}; 
     var rows=[0,1,2,3,4]; 
     var px = paddle.x, py = paddle.y; 
     var pxv=0; 
     var by = ball.y, bx = ball.x; 
     var bxv = -1.5, byv = -1.5; 


     function Block(h,w,x,y,c) { 
      this.h = h; 
      this.w = w; 
      this.x = x; 
      this.y = y; 
      this.c = c; 
     } 
     for(var i =0, len=rows.length;i<len;i++){ 
      for(var j=0; j<20;j++) { 
      blocks.push(new Block(20,50,j*50,i*20,rows[i])) 
     } 
     } 
     document.addEventListener("keydown",keyPush); 
     document.addEventListener("keyup",keyRelease); 
     function keyRelease(evt) { 
      switch(evt.keyCode) { 
       case 37: 
        pxv=0; 
        break; 
       case 39: 
        pxv=0; 
        break; 
      } 
     } 
     function keyPush(evt) { 
      switch(evt.keyCode) { 
       case 37: 
        pxv=-5; 
        break; 
       case 39: 
        pxv=5 
        break; 
      } 
     } 
     function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) { 
      return ax < bx+bw && bx < ax+aw && ay < by+bh && by < ay+ah; 
     }; 
     function draw(){ 
     ctx.clearRect(0,0,1000,500) 
     bx+=bxv; 
     by+=byv; 
     px+=pxv; 

     if(px > 900) { 
      px = 900; 
     } 
     else if(px < 0) { 
      px = 0; 
     } 
     for(var i = 0, len=blocks.length;i<len;i++) { 
      var bl = blocks[i]; 
      if(AABBIntersect(bx,by,ball.r,ball.r,bl.x,bl.y,bl.w,bl.h)) { 
       blocks.splice(i,1); 
       i--; 
       len--; 
      } 
     } 
     if(bx < 0) { 
      bxv = bxv*-1; 
     } 
     if(bx > 1000) { 
      bxv = bxv*-1; 
     } 
     ctx.fillStyle = "#ff4b38" 
     ctx.fillRect(px,py,paddle.w,paddle.h); 
     for(var i = 0, len=blocks.length; i<len; i++){ 

       if(blocks[i].c === 0) { 
        ctx.fillStyle = "#ff4b38" 
       } 
       else if(blocks[i].c === 1) { 
        ctx.fillStyle = "#ffba19" 
       } 
       else if(blocks[i].c === 2) { 
        ctx.fillStyle = "#fcee25" 
       } 
       else if(blocks[i].c === 3) { 
        ctx.fillStyle = "#26db02" 
       } 
       else if(blocks[i].c === 4) { 
        ctx.fillStyle = "#2d69ff" 
       } 
        ctx.fillRect(blocks[i].x,blocks[i].y,blocks[i].w,blocks[i].h); 
        ctx.beginPath(); 
        ctx.arc(bx,by,ball.r,0,2*Math.PI,false); 
        ctx.fillStyle = "gray"; 
        ctx.fill(); 

     } 
     } 
     setInterval(draw,10); 
+0

あなたの衝突検出はどこですか? 'AABBIntersect()'? – Matt

+0

はい。それはdraw()関数の外の関数です。 – Bestlogo56

答えて

1

私はそれを行う方法がもっとあると確信していますが、これは私がやる方法です。

衝突検出機能の内側には、xまたはy側からのifを検出するif文が必要です。それは、後にエラーになる場合は、わからないようにそれを微調整する必要が行われますが、それすべての矛先はこのようなものです:

function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) { 
    var bool = ax < bx + bw && bx < ax + aw && ay < by + bh && by < ay + ah; 
    if(bool){ 
     if(ax == bx || ax == bx + bw){ 
      bxv *= -1; 
      cl("x"); 
     }else{ 
      byv *= -1; 
      cl("y"); 
     } 
    } 

    return bool; 
}; 

あなたの次の問題は、それが立ち直るますので、あなたは、何のパドル衝突検出を持っていないが、それは意志でありますあなたのパドルを通過してください。したがって、あなたのdraw()機能では次のことができます。私はあなたのif(bx > 1000)後にそれを置く:

if(bx >= px && bx <= px + paddle.w && by >= py && by <= py + paddle.h){ 
    byv *= -1; 
} 

をすべてのブロックのいずれかがなくなっているか、あなたのボールがパドルを下回ると、あなたがそれをクリアすることができますので、私はまた、VARにごsetIntervalを置きます。そうでなければ、無限にどこへでも行くつもりです。

関連する問題