2016-12-02 8 views
0

私はピンポンのようなビデオゲームを作ろうとしています。ボールがパドルの中に閉じ込められます

私は、それぞれrect()arc()機能を使ってパドルとボールを描いています。これらはHTML <canvas>要素に描かれています。イベントハンドラは、上下の矢印キーのためにドキュメントに添付されています。これらはパドルを動かすことを可能にする。ボールのx座標とy座標は、setInterval()関数を使用して10ミリ秒後に変更されます。

問題は、ボールがパドルに閉じ込められ、その中でジグザグに動くことがあることです。

どうすればこの問題を解決できますか?私はパドルの前面に当たったら直ちにボールのx速度を変え、その側面に当たったらy速度を変えたい。ここで

は私のコードです:たぶん

<!-- index.html --> 
<html> 
    <head> 
     <link type="text/css" rel="stylesheet" href="stylesheet.css"/> 
    </head> 
    <body> 
     <canvas id="my-canvas" height="300px" width="400px"></canvas> 

     <script src="jquery-3.1.1.min.js"></script> 
     <script src="script.js"></script> 
    </body> 
</html> 

/* stylesheet.css */ 
body { 
    background-color: #f00; 
} 

canvas { 
    background-color: #fff; 
} 

/* script.js */ 
$(document).ready(function() { 
    var canvas = $("#my-canvas")[0]; 
    var ctx = canvas.getContext("2d"); 
    var paddleHeight = 8; 
    var paddleWidth = 70; 
    var paddleY = (canvas.height - paddleWidth)/2; 
    var ballRadius = 8; 
    var ballX = canvas.width/2; 
    var ballY = canvas.height/2; 
    var xDir = 2; 
    var yDir = -2; 
    var upPressed = false; 
    var downPressed = false; 

    $(document).keydown(function (e) { 
     switch (e.which) { 
      case 38: 
       upPressed = true; 
       break; 
      case 40: 
       downPressed = true; 
     } 
    }); 

    $(document).keyup(function (e) { 
     switch (e.which) { 
      case 38: 
       upPressed = false; 
       break; 
      case 40: 
       downPressed = false; 
     } 
    }); 

    function drawPaddle() { 
     ctx.beginPath(); 
     ctx.rect(0, paddleY, paddleHeight, paddleWidth); 
     ctx.fillStyle = "#0f0"; 
     ctx.fill(); 
     ctx.closePath(); 
    } 

    function drawBall() { 
     ctx.beginPath(); 
     ctx.arc(ballX, ballY, ballRadius, 0, Math.PI*2); 
     ctx.fillStyle = "#00f"; 
     ctx.fill(); 
     ctx.closePath(); 
    } 

    function draw() { 
     ctx.clearRect(0, 0, canvas.width, canvas.height); 
     drawPaddle(); 

     ballX += xDir; 
     ballY += yDir; 

     // Collision detection with the sides of the canvas 
     if (ballY == canvas.height - ballRadius || ballY == ballRadius) { 
      yDir = -yDir; 
     } else if (ballX == ballRadius || ballX == canvas.width - ballRadius) { 
      xDir = -xDir; 
     } 

     // Collision detection with the front of the paddle 
     if (ballX == paddleHeight + ballRadius && ballY >= paddleY && ballY <= paddleY + paddleWidth) { 
      xDir = -xDir; 
     } 
     // Collision detection with the top side of the paddle 
     if (ballX < paddleHeight + ballRadius && ballY < paddleY && ballY >= paddleY - ballRadius) { 
      yDir = -yDir; 
     } 
     // Collision detection with the bottom side of the paddle 
     if (ballX < paddleHeight + ballRadius && ballY > paddleY + paddleWidth && ballY <= paddleY + paddleWidth + ballRadius) { 
      yDir = -yDir; 
     } 

     drawBall(); 

     // Paddle moving logic 
     if (downPressed && paddleY < canvas.height - paddleWidth) { 
      paddleY += 7; 
     } else if (upPressed && paddleY > 0) { 
      paddleY -= 7; 
     } 
    } 

    setInterval(draw, 10); 
}); 
+0

「ボールを動かした後、何かに衝突するのだろうか? - それは_potential_新しい位置を計算し、それから衝突をテストします。コリジョンが発生しても(まだ発生していない場合)、それに応じて反応してください。これにより、現在直面している状況が防止されます。私のgoogle-fooは現時点でサービスが必要ですが、私はこれまでのアプローチをディスカッションする素晴らしい論文を見てきました。動きが速くて、このフレームと次のフレームにほとんど衝突すると、オブジェクトを何度も通過していると、特に効果的です。 – enhzflep

答えて

0

<!-- index.html --> 
<html> 
    <head> 
     <link type="text/css" rel="stylesheet" href="stylesheet.css"/> 
    </head> 
    <body> 
     <canvas id="my-canvas" height="300px" width="400px"></canvas> 

     <script src="jquery-3.1.1.min.js"></script> 
     <script src="script.js"></script> 
    </body> 
</html> 

/* stylesheet.css */ 
body { 
    background-color: #f00; 
} 

canvas { 
    background-color: #fff; 
} 

/* script.js */ 
$(document).ready(function() { 
    var canvas = $("#my-canvas")[0]; 
    var ctx = canvas.getContext("2d"); 
    var paddleHeight = 8; 
    var paddleWidth = 70; 
    var paddleY = (canvas.height - paddleWidth)/2; 
    var ballRadius = 8; 
    var ballX = canvas.width/2; 
    var ballY = canvas.height/2; 
    var xDir = 2; 
    var yDir = -2; 
    var upPressed = false; 
    var downPressed = false; 

    $(document).keydown(function (e) { 
     switch (e.which) { 
      case 38: 
       upPressed = true; 
       break; 
      case 40: 
       downPressed = true; 
     } 
    }); 

    $(document).keyup(function (e) { 
     switch (e.which) { 
      case 38: 
       upPressed = false; 
       break; 
      case 40: 
       downPressed = false; 
     } 
    }); 

    function escapePaddle() { 
     // I copy and pasted your collision logic and composed a super long condition. Brace yourself... 
     while ((ballX == paddleHeight + ballRadius && ballY >= paddleY && ballY <= paddleY + paddleWidth) || (ballX < paddleHeight + ballRadius && ballY < paddleY && ballY >= paddleY - ballRadius) || (ballX < paddleHeight + ballRadius && ballY > paddleY + paddleWidth && ballY <= paddleY + paddleWidth + ballRadius)) { 
     ballX+= xDir; 
     ballY += yDir; 
     } 
    } 

    function drawPaddle() { 
     ctx.beginPath(); 
     ctx.rect(0, paddleY, paddleHeight, paddleWidth); 
     ctx.fillStyle = "#0f0"; 
     ctx.fill(); 
     ctx.closePath(); 
    } 

    function drawBall() { 
     ctx.beginPath(); 
     ctx.arc(ballX, ballY, ballRadius, 0, Math.PI*2); 
     ctx.fillStyle = "#00f"; 
     ctx.fill(); 
     ctx.closePath(); 
    } 

    function draw() { 
     ctx.clearRect(0, 0, canvas.width, canvas.height); 
     drawPaddle(); 

     ballX += xDir; 
     ballY += yDir; 

     // Collision detection with the sides of the canvas 
     if (ballY == canvas.height - ballRadius || ballY == ballRadius) { 
      yDir = -yDir; 
     } else if (ballX == ballRadius || ballX == canvas.width - ballRadius) { 
      xDir = -xDir; 
     } 

     // Collision detection with the front of the paddle 
     if (ballX == paddleHeight + ballRadius && ballY >= paddleY && ballY <= paddleY + paddleWidth) { 
      xDir = -xDir; 
      escapePaddle(); 
     } 
     // Collision detection with the top side of the paddle 
     if (ballX < paddleHeight + ballRadius && ballY < paddleY && ballY >= paddleY - ballRadius) { 
      yDir = -yDir; 
      escapePaddle(); 
     } 
     // Collision detection with the bottom side of the paddle 
     if (ballX < paddleHeight + ballRadius && ballY > paddleY + paddleWidth && ballY <= paddleY + paddleWidth + ballRadius) { 
      yDir = -yDir; 
      escapePaddle(); 
     } 

     drawBall(); 

     // Paddle moving logic 
     if (downPressed && paddleY < canvas.height - paddleWidth) { 
      paddleY += 7; 
     } else if (upPressed && paddleY > 0) { 
      paddleY -= 7; 
     } 
    } 

    setInterval(draw, 10); 
}); 

私はそれがパドルに衝突しなくなるまで基本的にボールを動かすescapePaddle()機能を追加しました。それから、すべてのパドル衝突試験条件に加えました。

関連する問題