проблема с написанием игры пинг-понг на чистом js. И столкнулся с проблемой физики мяча. Мяч должен отбиваться от ракеток и рикошетить по стенкам

поле мяч ракетка 1 ракетка 2

#canvas {
  display: block;
  margin: 0px;
  text-align: center;
}

body {
  background-color: brown;
}
<!DOCTYPE html>
<html>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css">

<head>
  >
  <title>pong</title>
</head>

<body>
  <canvas id="canvas" width="500" height="500"></canvas>
  <script type="text/javascript" src="script.js">
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    var background = new Image();
    background.src = "files/back.jpg";

    var ball = new Image;
    ball.src = "files/ball.png";

    var player1 = new Image;
    player1.src = "files/player1.png";

    var player2 = new Image;
    player2.src = "files/player2.png";

    var balls = {
      x: 235,
      y: 235,
    }
    var players1 = {
      x: 0,
      y: 205,
    }

    var players2 = {
      x: 470,
      y: 205,
    }

    var action1, action2;

    var Score = 0;

    document.addEventListener("keydown", function(event) {
      /* Act on the event */
      if (event.keyCode == 87) {
        action1 = true;
      } else if (event.keyCode == 83) {
        action1 = false;
      }
    });

    document.addEventListener("keydown", function(event) {
      /* Act on the event */
      if (event.keyCode == 38) {
        action2 = true;
      } else if (event.keyCode == 40) {
        action2 = false;
      }
    });
    var target = 1;

    function draw() {


      if (action1 == true && players1.y > 0) {
        players1.y = players1.y - 1
      } else if (action1 == false & players1.y < 408) {
        players1.y = players1.y + 1
      }

      if (action2 == true && players2.y > 0) {
        players2.y = players2.y - 1
      } else if (action2 == false && players2.y < 408) {
        players2.y = players2.y + 1
      }

      ctx.drawImage(background, 0, 0);
      ctx.drawImage(ball, balls.x, balls.y);
      ctx.drawImage(player1, players1.x, players1.y);
      ctx.drawImage(player2, players2.x, players2.y);

    }

    setInterval(draw, 5);
  </script>
</body>
</html>


Ответы (1 шт):

Автор решения: 2ip
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var background = new Image();
background.src = "files/back.jpg";

var ball = new Image;
ball.src = "files/ball.jpg";

var player1 = new Image;
player1.src = "files/player1.png";

var player2 = new Image;
player2.src = "files/player1.png";

var balls = {
  x: 235,
  y: 235,
}
var players1 = {
  x: 0,
  y: 205,
}

var players2 = {
  x: 470,
  y: 205,
}

var action1, action2;

var Score = 0;

document.addEventListener("keydown", function(event) {
  /* Act on the event */
  if (event.keyCode == 87) {
    action1 = true;
  } else if (event.keyCode == 83) {
    action1 = false;
  }
});

document.addEventListener("keydown", function(event) {
  /* Act on the event */
  if (event.keyCode == 38) {
    action2 = true;
  } else if (event.keyCode == 40) {
    action2 = false;
  }
});
var target = 1;
var activemove = 0; // вид движения, принимает значения от 0 до 3 (всего 4 вида движения мяча описаны внизу) 
var way = 0; //путь мяча (1- лево 0- право)
function draw() {
    
  function ballMoveRight(){ //движение мяча вправо сверху вниз
    balls.x=balls.x+1;
    balls.y=balls.y+2;
  }
  function ballMoveRightReverce(){ //движение мяча вправо снизу вверх 
    balls.x=balls.x+1;
    balls.y=balls.y-2;
  }
  function ballMoveLeft(){ //движение мяча влево снизу вверх
    balls.x=balls.x-1;
    balls.y=balls.y-2;
  }
  function ballMoveLeftReverce(){//движение мяча влево сверху вниз 
    balls.x=balls.x-1;
    balls.y=balls.y+2;
  }
  //////////////////
  if(way==0){//если путь идёт вправо применяются следующие правила при проверки состояния мяча
    if(balls.y < 1){ //если координата мяча Y меньше 1 (упирается в верхнюю стену) происходит смена движения на вид номер 0 
        activemove = 0;
        
    }
    if(balls.y+30 > 500){//если координата мяча Y больше 500 (упирается в нижнюю стену) происходит смена движения на вид номер 1
        activemove = 1;
    }
  }else{//если движение влево применяем следующие движения мяча 
    if(balls.y < 1){// анологиченые комментарии как и к части сверху, только движение будет идти влево 
        activemove = 3;
        
    }
    if(balls.y+30 > 500){
        activemove = 2;
    } 
  }
  if(balls.x+30 == players2.x && (((balls.y > players2.y) && (balls.y < players2.y + 100)) || ((balls.y + 30 < players2.y + 100) && (balls.y + 30 > players2.y)))){ //проверка на столкновение с правым блоком (игрок2)
    way = 1; // путь меняется на лево 
    console.log(way)
    if(activemove == 1){activemove = 2}else{activemove = 3}// делаем зеркальное движение в зависимости от предыдущего типа движения
  }
  if(balls.x == player1.x+30 && (((balls.y > players1.y) && (balls.y < players1.y + 100)) || ((balls.y  < players1.y + 100) && (balls.y > players1.y)))){// проверка столкновения мяча с левым блоком (игрок1) 
    way = 0;//движение меняется на право 
    console.log(way)
    if(activemove == 2){activemove = 1}else{activemove = 0}//анологичное зеркальное изменение пути (как рикошет) 
  }
  ///////////////// Секция отвечающая за применение видов движения в зависимости от выбранного числа в activemove 
  
  if(activemove == 0){ 
    ballMoveRight();
  }else if(activemove == 1){
    ballMoveRightReverce();
  }else if(activemove == 2){
    ballMoveLeft();
  }else if(activemove == 3){
    ballMoveLeftReverce();
  }
  ///////


  if (action1 == true && players1.y > 0) {
    players1.y = players1.y - 1
  } else if (action1 == false & players1.y < 408) {
    players1.y = players1.y + 1
  }

  if (action2 == true && players2.y > 0) {
    players2.y = players2.y - 1
  } else if (action2 == false && players2.y < 408) {
    players2.y = players2.y + 1
  }

  ctx.drawImage(background, 0, 0);
  ctx.drawImage(ball, balls.x, balls.y);
  ctx.drawImage(player1, players1.x, players1.y);
  ctx.drawImage(player2, players2.x, players2.y);

}

setInterval(draw, 5);

У меня получилось вот так и все прекрасно работает =)

→ Ссылка