2017-05-06 200 views
0

球似乎從槳的一側反彈,但當它從側面發出時,它會通過槳振動。我只是無法找到一個方法,它真的困擾我。我使用了一些邏輯門來定義其中需要進行invereted乒乓球比賽中球和槳之間的碰撞

function startGame() { 
 
    GameArea.start(); 
 
\t Ball1 = new CircleComp('white' , window.innerWidth - 200 , window.innerHeight - 20); 
 
\t Ball1.ySpeed = 13.5; 
 
\t Ball1.xSpeed = 6; 
 
\t Paddle1 = new PaddleComp(87, 83, 0, window.innerHeight/2.5, 10, 70); 
 
\t Paddle2 = new PaddleComp(38, 40, window.innerWidth - 10, window.innerHeight/2.5, 10 , 70); 
 
} 
 
var GameArea = { 
 
\t canvas : canvas = document.querySelector("canvas"), 
 
\t start : function(){ 
 
\t \t this.canvas.width = window.innerWidth; 
 
\t \t this.canvas.height = window.innerHeight; 
 
\t \t this.ctx = this.canvas.getContext('2d'); 
 
\t \t this.interval = setInterval(updateGameArea, 20); 
 
     window.addEventListener('keydown', function (e) { 
 
      GameArea.keys = (GameArea.keys || []); 
 
      GameArea.keys[e.keyCode] = true; 
 
     }) 
 
     window.addEventListener('keyup', function (e) { 
 
      GameArea.keys[e.keyCode] = false; 
 
     }) 
 
    }, 
 
\t clear : function() { 
 
     this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 
 
    } 
 
} 
 
function CircleComp(color, x , y){ 
 
\t this.x = x; 
 
\t this.y = y; 
 
\t this.width = 8; 
 
    this.height = 8; 
 
\t var context1 = GameArea.ctx; 
 
\t this.update = function(){ 
 
\t \t context1.beginPath(); 
 
\t \t context1.fillStyle = color; 
 
\t \t context1.fillRect(this.x, this.y, this.width, this.height); 
 
\t \t context1.fill(); 
 
\t \t context1.stroke(); 
 
\t \t this.updatePosition(); 
 
\t } 
 
\t this.updatePosition = function(){ 
 
\t \t this.y += this.ySpeed; \t 
 
\t \t this.x += this.xSpeed; 
 
\t \t if(this.x + this.width > GameArea.canvas.width){ 
 
\t \t \t this.xSpeed = -this.xSpeed; 
 
\t \t } 
 
\t \t if(this.y + this.height > GameArea.canvas.height){ 
 
\t \t \t this.ySpeed = -this.ySpeed;; \t 
 
\t \t } 
 
\t \t if(this.x - this.width < 0){ 
 
\t \t \t this.xSpeed = -this.xSpeed; 
 
\t \t } \t 
 
\t \t if(this.y - this.height < 0){ 
 
\t \t \t this.ySpeed = -this.ySpeed; 
 
\t \t } 
 
\t \t if(this.y + this.height > Paddle2.y && this.y - this.width < (Paddle2.y + 130) && this.x + this.width > Paddle2.x){ 
 
\t \t \t this.xSpeed = -this.xSpeed; 
 
\t \t } \t 
 
\t \t if(this.y + this.height > Paddle1.y && this.y - this.width < (Paddle1.y + 70) && this.x - this.height < Paddle1.x + 10){ 
 
\t \t \t this.xSpeed = -this.xSpeed; 
 
\t \t } 
 
\t } 
 
} 
 
function PaddleComp(Upkey, Downkey, x, y, width, height){ 
 
\t this.x = x; 
 
\t this.y = y; 
 
\t this.width = width; 
 
\t this.height = height; 
 
\t this.ySpeed = 0; 
 
\t var context2 = GameArea.ctx; 
 
\t this.update = function(){ 
 
\t context2.fillStyle = 'white'; 
 
\t context2.fillRect(x,this.y,this.width,this.height); \t 
 
\t this.updatePosition(); 
 
\t } 
 
\t this.updatePosition = function() { 
 
\t \t this.ySpeed = 0; \t 
 
\t \t if (GameArea.keys && GameArea.keys[Upkey]) { 
 
\t \t \t this.ySpeed = -15; //console.log('Up'); 
 
\t \t } 
 
\t \t if (GameArea.keys && GameArea.keys[Downkey]) { 
 
\t \t \t this.ySpeed = 15; //console.log('Down'); 
 
\t \t } 
 
\t \t if ((GameArea.keys && GameArea.keys[Downkey]) && this.y + 130 > window.innerHeight){ 
 
\t \t \t this.ySpeed = this.ySpeed -15 ; \t 
 
\t \t } 
 
\t \t if ((GameArea.keys && GameArea.keys[Upkey]) && this.y < 0){ 
 
\t \t \t this.ySpeed = this.ySpeed +15 ; \t 
 
\t \t } 
 
\t \t this.y += this.ySpeed; \t \t \t 
 
\t } 
 
} 
 
function updateGameArea(){ 
 
\t GameArea.clear(); 
 
\t Paddle1.update(); 
 
\t Paddle2.update(); 
 
\t Ball1.update(); 
 
}
<html> 
 
\t <head> 
 
\t \t <meta charset='urf-8'> 
 
\t \t <style> 
 
\t \t \t canvas{ 
 
\t \t \t \t border: 0px solid black; 
 
\t \t \t \t background-color: black; 
 
\t \t \t } 
 
\t \t \t body{ 
 
\t \t \t \t margin: 0; 
 
\t \t \t \t overflow: hidden; 
 
\t \t \t } 
 
\t \t </style> 
 
\t </head> 
 
\t <body onload='startGame()'> 
 
\t \t <canvas></canvas> 
 
\t \t <script src='Pong.js'></script> 
 
\t </body> 
 
</html>
球的方向

回答

0

無法直接看到的問題是你的代碼,所以我只是重寫了代碼球,蝙蝠(槳)測試功能在球對象中並從球員對象中調用。 ball.checkPad(播放器);測試球是否擊中了球員蝙蝠。爲了幫助描繪發生的事情,我放慢了腳步,讓蝙蝠真正成爲了蝙蝠。當球擊中球棒時,它會變成黃色,球棒紅色一秒鐘左右。

有大量的在你問一下,

希望它可以幫助

演示從OP的問題複製的部分意見。

const setting = { 
 
    speed : 2, // of ball 
 
    left : 0, 
 
    width : 400, 
 
    height : 200, 
 
    padWidth : 50, 
 
    padHeight : 80, 
 
    padSpeed : 4, // double balls 
 
    hitPauseCount : 30, // nuber of frames to hold when there is a collisiotn so you 
 
          // can check all is good 
 
} 
 
const keys = { 
 
    ArrowUp : false, 
 
    ArrowDown : false, 
 
    ArrowLeft : false, 
 
    ArrowRight : false, 
 
    keyEvent(e) { // dont use keyCode it has depreciated 
 
     if (keys[e.code] !== undefined) { 
 
      keys[e.code] = e.type === "keydown"; 
 
      e.preventDefault(); 
 
     } 
 
    } 
 
} 
 
var ctx; 
 
var ball1, paddle1, paddle2; 
 
var gameArea = { 
 
    start() { 
 
     canvas.width = setting.width; 
 
     canvas.height = setting.height; 
 
     ctx = canvas.getContext('2d'); 
 
     requestAnimationFrame(updateGameArea); 
 
    }, 
 
    clear() { 
 
     ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 
 
    } 
 
} 
 
gameArea.start(); 
 
ball = new CircleComp('white', window.innerWidth - 200, window.innerHeight - 20); 
 
ball.ySpeed = setting.speed; 
 
ball.xSpeed = setting.speed; 
 
paddle1 = new PaddleComp("ArrowUp", "ArrowDown", setting.left, setting.height/2, setting.padWidth, setting.padHeight); 
 
paddle2 = new PaddleComp("ArrowLeft", "ArrowRight", setting.width - setting.padWidth, setting.height/2, setting.padWidth, setting.padHeight); 
 
window.addEventListener('keydown', keys.keyEvent); 
 
window.addEventListener('keyup', keys.keyEvent); 
 

 

 
function CircleComp(color, x, y) { 
 
    this.x = x; 
 
    this.y = y; 
 
    this.width = 8; 
 
    this.height = 8; 
 
    this.xSpeed = setting.speed; 
 
    var hit = 0; 
 
    var restartCount; 
 
    var serveDirection; 
 

 
    this.reset = function(){ 
 
     this.x = ctx.canvas.width /2; 
 
     this.y = ctx.canvas.height/2; 
 
     this.xSpeed = -this.xSpeed 
 
     this.ySpeed = setting.speed * Math.sign(Math.random() - 0.5); 
 
     restartCount = 60; 
 
    } 
 
    this.draw = function() { 
 
     if(hit > 0){ 
 
      hit -= 1; 
 
      ctx.fillStyle = "yellow"; 
 
     }else{ 
 
      ctx.fillStyle = color; 
 
     } 
 
     ctx.fillRect(this.x, this.y, this.width, this.height); 
 
    } 
 
    // next funtion is called by the player objects 
 
    this.checkPad = function (player) { 
 
     if (player.x > canvas.width/2) { // is player on left or right 
 
      if (this.xSpeed > 0) { // player on right only check if ball moving rigth 
 
       if (this.x + this.width > player.x) { // ball is in paddles zone 
 
        //if not bottom of ball above top of bat or top of ball bellow bottom of bat 
 
        if (!(this.y + this.height <= player.y || this.y >= player.y + player.height)) { 
 
         // ball and bat in contact 
 
         // is ball moving down and the balls top edge above the player 
 
         // then ball has hit the top side of the bat 
 
         if(this.ySpeed > 0 && this.y <= player.y){ 
 
          this.y = player.y - this.width; 
 
          this.ySpeed = -setting.speed; 
 
         }else if(this.ySpeed < 0 && this.y + this.height >= player.y + player.height){ // do bottom check 
 
          this.y = player.y + player.height; 
 
          this.ySpeed = setting.speed; 
 
         }else{ // ball hit front of bat 
 
          this.x = player.x - this.width; 
 
          this.xSpeed = - setting.speed; 
 
         } 
 
         player.hit = setting.hitPauseCount; // counters to show FX when a hit happens 
 
         hit = setting.hitPauseCount; 
 
        } 
 
       } 
 
      } 
 

 
     } else { // player must be left 
 
      if (this.xSpeed < 0) { // ball must move left 
 
       if (this.x < player.x + player.width) { // ball is in paddles zone 
 
        if (!(this.y + this.height <= player.y || this.y >= player.y + player.height)) { 
 
         // ball and bat in contact 
 
         // ball and bat in contact 
 
         // is ball moving down and the balls top edge above the player 
 
         // then ball has hit the top side of the bat 
 
         if(this.ySpeed > 0 && this.y <= player.y){ 
 
          this.y = player.y - this.width; 
 
          this.ySpeed = -setting.speed; 
 
         }else if(this.ySpeed < 0 && this.y + this.height >= player.y + player.height){ // do bottom check 
 
          this.y = player.y + player.height; 
 
          this.ySpeed = setting.speed; 
 
         }else{ // ball hit front of bat 
 
          this.x = player.x + player.width; 
 
          this.xSpeed = setting.speed; 
 
         } 
 
         player.hit = setting.hitPauseCount; // counters to show FX when a hit happens 
 
         hit = setting.hitPauseCount; 
 
        } 
 
       } 
 
      } 
 
     } 
 
    } 
 
    this.update = function() { 
 
     if(restartCount > 0){ // wait for restart pause 
 
      restartCount -= 1; 
 
     }else{ 
 
      if(hit > 0){ // do nothing if paused 
 
       return; 
 
      } 
 
      this.y += this.ySpeed; 
 
      this.x += this.xSpeed; 
 
      if (this.x + this.width >= canvas.width) { 
 
       this.reset(); // point 
 
      } else if (this.x < 0) { 
 
       this.reset(); // point 
 
      } 
 
      if (this.y + this.height >= canvas.height) { 
 
       this.y = canvas.height - this.height; 
 
       this.ySpeed = -setting.speed; 
 
      } else if (this.y < 0) { 
 
       this.y = 0; 
 
       this.ySpeed = setting.speed; 
 
      } 
 
     } 
 
    } 
 
    this.reset(); 
 
} 
 
function PaddleComp(upKey, downKey, x, y, width, height) { 
 
    this.x = x; 
 
    this.y = y; 
 
    this.width = width; 
 
    this.height = height; 
 
    this.hit = 0; 
 
    this.draw = function() { 
 
     if(this.hit > 0){ 
 
      this.hit -= 1; 
 
      ctx.fillStyle = "red"; 
 
     }else{ 
 
      ctx.fillStyle = '#9CF'; 
 
     } 
 
     ctx.fillRect(this.x, this.y, this.width, this.height); 
 
    } 
 
    this.update = function() { 
 
     if (keys[upKey]) { 
 
      this.y -= setting.padSpeed; 
 
     }; 
 
     if (keys[downKey]) { 
 
      this.y += setting.padSpeed; 
 
     }; 
 
     if (this.y < 0) { 
 
      this.y = 0; 
 
     } 
 
     if (this.y + this.height >= canvas.height) { 
 
      this.y = canvas.height - this.height; 
 
     } 
 
     ball.checkPad(this); 
 
    } 
 
} 
 
function updateGameArea() { 
 
    gameArea.clear(); 
 
    paddle1.update(); 
 
    paddle2.update(); 
 
    ball.update(); 
 
    paddle1.draw(); 
 
    paddle2.draw(); 
 
    ball.draw(); 
 
    requestAnimationFrame(updateGameArea); 
 
}
<canvas id=canvas style='background:#69C;border:2px blue solid'></canvas>

+0

謝謝!這真的幫助我理解碰撞機制。 –