2016-07-20 7 views
1

Я создаю игру JS Pong, но мяч в игре понга начинает отставать через несколько секунд. Я попытался остановить рамку анимации, оптимизировать свой код для лучшей производительности и переписать код для мяча, но ничего не работает. Может кто-то мне помочь, пожалуйста?JavaScript Pong Game Lag

HTML (No CSS)

<!DOCTYPE html> 
<html lang="en"> 

<head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>Pong</title> 
</head> 

<body> 
    <canvas id="canvas" width="800" height="400" style="background: #000"></canvas> 
</body> 

</html> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> 
<script src="main.JS"></script> 

Javascript (с помощью JQuery)

/* 
Created : 7/18/2016 
*/ 

//Bottom comment is used to define JQuery 

/*jslint browser: true*/ 
/*global $, jQuery, alert*/ 

//Define variables 
var canvas, ctx; 

var ballX, ballY; //Balls x and y pos 
var ballSpeedX, ballSpeedY; //Speed of ball x and y pos 

var paddleY, paddleHeight, paddleWidth, aiY; //PaddleY = paddle's y pos and paddleHeight = Centering mouse on paddle 

//Score variables 
var aiScore, playerScore; 

//Set functions 

//Gets mouse pos 
function getMousePos(e) { 

    "use strict"; 

    //Define variables 
    var rect, root, mouseX, mouseY; 

    rect = canvas.getBoundingClientRect(); //Get canvas outline 
    root = document.documentElement; //Get html document 

    mouseX = e.clientX - rect.left - root.scrollLeft; 
    mouseY = e.clientY - rect.top - root.scrollTop; 

    //Return x and y pos to page 
    return { 

     x: mouseX, 
     y: mouseY 

    }; 

} 

//Move ai function 
function moveAI() { 

    "use strict"; 

    var aiYCenter = aiY + paddleHeight/2; 

    if (aiYCenter < ballY - 35) { 

     aiY += 6; 

    } else if (aiYCenter > ballY + 35) { 

     aiY -= 6; 

    } 

} 

//Animate objects 
function animate() { 

    "use strict"; 

    //Animate ball 
    ballX += ballSpeedX; 
    ballY += ballSpeedY; 

    //Make ai move 
    moveAI(); 

    return false; 

} 

function resetBall() { 

    "use strict"; 

    ballX = canvas.width/2; 
    ballY = canvas.height/2; 

    //Flip ball 
    ballSpeedX = -ballSpeedX; 

    return false; 

} 

//Detect collisiom 
function collision() { 

    "use strict"; 

    //Right wall 
    if (ballX > canvas.width) { 

     //If player paddle hits ball 
     if (ballY > aiY && ballY < aiY + paddleHeight) { 

      ballSpeedX = -ballSpeedX; 

     } else { 

      //If player paddle doesn't hit ball 
      resetBall(); //Reset ball function 

      playerScore += 1; //If ai scores add 1 point to ai's score 

     } 

    } 
    //Left wall 
    if (ballX < 0) { 

     //If player paddle hits ball 
     if (ballY > paddleY && ballY < paddleY + paddleHeight) { 

      ballSpeedX = -ballSpeedX; 

     } else { 

      //If player paddle doesn't hit ball 
      resetBall(); //Reset ball function 

      aiScore += 1; //If ai scores add 1 point to ai's score 

     } 

    } 

    if (ballY > canvas.height) { //If ballY does outside of 800px 

     ballSpeedY = -ballSpeedY; 

    } 
    if (ballY <= 0) { //If ballY goes outside of 0px 

     ballSpeedY = -ballSpeedY; 

    } 

    return false; 

} 

//Make paddle move 
function movePaddle(e) { 

    "use strict"; 

    var pos = getMousePos(e); 
    paddleY = pos.y - paddleHeight/2; //Set paddleY to y pos of function and center user's mouse on the paddle 

    return false; 

} 

//Draw objects 
function draw() { 

    "use strict"; 

    ctx.clearRect(0, 0, canvas.width, canvas.height); //Clear canvas after animation frame 
    ctx.fillStyle = "white"; //Set color 

    //Draw ball 
    ctx.beginPath(); 
    ctx.arc(ballX, ballY, 10, 0, Math.PI * 2, true); 
    ctx.fill(); 

    //Draw player paddle 
    ctx.fillRect(0, paddleY, paddleWidth, paddleHeight); 

    //Draw ai 
    ctx.fillRect(canvas.width - paddleWidth, aiY, paddleWidth, paddleHeight); 

    //Score boarc 
    ctx.font = "30px Roboto"; 
    //Draw score 
    ctx.fillText(playerScore, 100, 100); //Player score 
    ctx.fillText(aiScore, canvas.width - 100, 100); 

    return false; 

} 

//When document is ready 
$("document").ready(function() { 

    "use strict"; 

    //Get canvas and set its context 
    canvas = $("#canvas")[0]; 
    ctx = canvas.getContext("2d"); 

    //Set values to variables 

    //Set fps 
    var fps = 30; 

    ballX = 100; 
    ballY = 100; 
    ballSpeedX = 2; 
    ballSpeedY = 2; 

    paddleHeight = 100; //Used for centering mouse on paddle 
    paddleY = canvas.height/2 - paddleHeight/1.5; //Set paddle's y pos 
    paddleWidth = 10; //Width of paddle 

    //Score variables 
    aiScore = 0; 
    playerScore = 0; 

    aiY = canvas.height/2 - paddleHeight/1.5; //Height of ai player 

    setInterval(function() { 

     animate(); 
     collision(); 
     $(canvas).bind("mousemove", movePaddle); //Move paddle 
     draw(); 

    }, fps/1000); 

    return false; 

}); 
+0

Вы пробовали заменить ** setInterval ** на ** requestAnimationFrame **? Если нет, обратитесь к https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame и попробуйте выполнить его. –

+0

Почему бы не переместить '$ (canvas) .bind (" mousemove ", movePaddle); 'вне игрового цикла, чтобы привязка выполнялась только один раз и использовала' requestAnimationFrame' вместо 'setInterval' для игрового цикла? –

ответ

1

я сделал небольшие изменения, чтобы рассмотреть частоту кадров в коде.

Пожалуйста, попробуйте приведенный ниже.

//Set fps 

var fps = 30, frameInterval = 1000/fps, lastTime = new Date().getTime();; // I would increase fps to 60 

$(document).ready(function() { 

    "use strict"; 

    //Get canvas and set its context 
    canvas = $("#canvas")[0]; 
    ctx = canvas.getContext("2d"); 

    //Set values to variables 


    ballX = 100; 
    ballY = 100; 
    ballSpeedX = 2; 
    ballSpeedY = 2; 

    paddleHeight = 100; //Used for centering mouse on paddle 
    paddleY = canvas.height/2 - paddleHeight/1.5; //Set paddle's y pos 
    paddleWidth = 10; //Width of paddle 

    //Score variables 
    aiScore = 0; 
    playerScore = 0; 

    aiY = canvas.height/2 - paddleHeight/1.5; //Height of ai player 
    $(canvas).bind("mousemove", movePaddle); //Bind once only 
    window.requestAnimationFrame(run); 

    return false; 

}); 


function run() { 
     var now = new Date().getTime(); 
     var elapsed = now - lastTime; 
     if(elapsed > frameInterval) { 
      animate(); 
      collision(); 

      draw(); 
      lastTime = now; 
     } 
     window.requestAnimationFrame(run); 
} 

Сообщите мне, если это сработает.