При использовании setinterval и settiomeout pong padd тикают

Поэтому я пытаюсь создать игру в понг, и весла понга тикают... Я использую две функции для мяча и для весла, также я использую холст. Для движения есть объект весла и слушатель событий. Помогите:)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Pong</title>
    <script type="text/javascript">

        function canvas() {
            var can = document.getElementById('theCanvas');
            can.style.backgroundColor = "black";
            var ctx = can.getContext('2d');
            var keys = [];
            
        var ball = {    
            x: (can.width-10)/2,
            y: (can.width-10)/2,
            dx: 8,
            dy: 8
            }
        
        var playerOne = {
            x: can.width-50,
            y: (can.width-50)/2,
            H: 100,
            W: 20,
            hitDir: 0
        }
        
        var playerTwo = {
            x: 50,
            y: (can.width-50)/2,
            H: 100,
            W: 20,
            hitDir: 0
        }
            ctx.fillStyle ="white";
            ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
            ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
            
            function draw()
            {
            ctx.clearRect(0,0, 800,800);
            ctx.beginPath();
            ctx.fillStyle="#0000ff";
            ctx.arc(ball.x,ball.y,10,0,Math.PI*2,true);
            ctx.closePath();
            ctx.fill();
            if( ball.x<10 || ball.x>790) 
            {
            ball.dx=-ball.dx
            }
            
            if( ball.y<10 || ball.y>790) {
                ball.dy=-ball.dy
            }
            ball.x+=ball.dx; 
            ball.y+=ball.dy;
            
            ctx.fillStyle ="white";
            ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
            ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
            
            }
            setInterval(draw,10);

            function move() {
                ctx.clearRect(0,0,800,800);
                if (keys[38]) {
                playerTwo.y-=10;
            }

                if (keys[40]) {
                playerTwo.y+=10;
            
            }
            ctx.fillStyle ="white";
            ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
            ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
            ctx.clearRect(0,0, 800,800);
            ctx.beginPath();
            ctx.fillStyle="#0000ff";
            ctx.arc(ball.x,ball.y,10,0,Math.PI*2,true);
            ctx.closePath();
            ctx.fill();
            setTimeout(move, 1000/60);
            }
            move();
            document.body.addEventListener("keydown", function (e) {
            keys[e.keyCode] = true;
            });
            document.body.addEventListener("keyup", function (e) {
            keys[e.keyCode] = false;
            });
            
             }
             
    </script>
</head>
<body onload="canvas()">
    <canvas id="theCanvas" width="800" height="800"></canvas>
</body>
</html>

1 ответ

Решение

Спасибо за интересную проблему.

То, что вы хотите сделать, это объединить два setInterval/setTimeout в одну функцию рендеринга. Затем он используется единственной функцией window.requestAnimationFrame, которая вызывается, когда браузер готов рисовать следующий кадр. Это лучше, чем setTimeout или setInterval, что может быть причиной для "галочки", так как ваш холст может пытаться нарисовать кадр, когда браузер еще не готов отрисовать этот кадр.

Я также реорганизовал вашу игру в следующий псевдокод

1) Set up the canvas and event listeners
2) Declare the render function
  2a) Change the position data of the ball & paddles
  2b) Render the ball & paddles based on its data
  2c) request another animation frame
3) request an animation frame with the render function

Вот мой jsfiddle

Другие вопросы по тегам