5
\$\begingroup\$

I have created my first ping-pong game with JavaScript and Canvas. I will be glad if anybody can tell me how to optimize the code and functionality.

https://github.com/nikitalarionov/js-pong

First collision detection:

//Function to check collision between ball and one of
//the paddles
function collides(b, p) {

    if(b.x + ball.r >= p.x + p.w && b.x - ball.r <= p.x + p.w) {

        if (b.y + b.r >= p.y && b.y + b.r <= p.y + p.h && b.x - b.r <= p.x) {
            paddleHit = 1;
            if(b.x < W/ 2) {
                hit++;
            } else if (b.x > W / 2) {
                hit2++;
            }
            return true;
        }
        else if(b.y - b.r <= p.y && b.y - b.r >= p.y - p.h && b.x + b.r >= p.x) {
            paddleHit = 2;
            if(b.x < W/ 2) {
                hit++;
            } else if (b.x > W / 2) {
                hit2++;
            }                
            return true;
        }
        else return false;

    }
}

I experience bad performance when the ball hits an angle of one of the paddles:

// Function that updates everything, score, positions, main game logic
function update(){
    // Move the padles
    for(var i = 0; i <= padles.length; i++) {
        var p = padles[i];
        if (i === 0 && players[0].moveUp) {
            if (p.y <= 0) {
                p.y = 0;
            }
            else {
                                    // is it how i move left paddle
                                    // it is doesn't work good like a mousemove
                                    // animations is slowly, i dont know how to fix it
                p.y -=25;    
            }
        }
        if (i === 0 && players[0].moveDown) {
            if (p.y + p.h >= H) {
                p.y = H - p.h;
            }
            else {
                p.y += 25;
            }
        }
        if (mouse.y && i === 1) {
            if (p.y + p.h >= H && mouse.y > p.y) {
                p.y = H - p.h;
            }
            else {
                p.y = (mouse.y -50) - p.w / 10;    
            }
        }
    }

            // ... some code

}

There I have very lazy animation and moving of the left paddle. I use keys for it outside of the animation cycle:

    // Add Global Event to handle keyboards buttons
window.addEventListener('keydown', function(e) {
    if (e.keyCode === 87) {
        players[0].moveUp = true;
    } else
    if (e.keyCode === 83) {
        players[0].moveDown = true;
    }
}, false);

window.addEventListener('keyup', function(e) {
    if (e.keyCode === 87) {
        players[0].moveUp = false;
    } else
    if (e.keyCode === 83) {
        players[0].moveDown = false;
    }
}, false);
\$\endgroup\$
  • 1
    \$\begingroup\$ I posted some code with problems, but it works, but not good :) It seems i have two problem (Collision Detection, Lazy Moving of left paddle). \$\endgroup\$ – Larionov Nikita Mar 28 '14 at 15:08
  • \$\begingroup\$ this code in action: jsfiddle.net/9vgq6 for the lazy among us :) \$\endgroup\$ – Kvothe Mar 28 '14 at 19:43
6
\$\begingroup\$

From a once-over,

  • Short 1 letter variables are terrible ( except for x and y ), b, p and W are just terrible
  • Also please spellcheck your variables: padles -> paddles
  • You should only detect collision when the ball is going to the left and gets in the danger-zone or when it is going to the right and getting in the danger-zone. So instead of doing 8 accesses, 1 AND and 4 sums (if(b.x + ball.r >= p.x + p.w && b.x - ball.r <= p.x + p.w) {) you should rather do something like

    if( deltaX < 0 && ball.x < someLimit ){
      testCollision( ball , leftPaddle );
    } else if( ball.x > someOtherLimit  ) {
      testCollision( ball , rightPaddle );
    }
    

    Where deltaX is the amount of pixels the ball is moving over the X axis, this should make paddle collision a lot more efficient

  • Please don't use magical constants, in this case I see 25 all over the place
  • Same for the keycodes, you should use constants for those
\$\endgroup\$
  • \$\begingroup\$ Remember that there aren't any real constants in JavaScript. \$\endgroup\$ – Madara Uchiha Jun 15 '14 at 4:15
2
\$\begingroup\$
  1. The source of the slowness is due to the interaction with the collision object, I think.
  2. There is also a flaw with your collision management as the ball can noclip out of the canvas.

    In pseudocode, you handle object position and speed like this (one dimensional simplification) :

    x += v;
    if (collides) {v = -v;}
    

    With this approach, if the objects speed is great enough then the object can get past the barrier and it will noclip. Instead, you want your code to look like this:

    if (x += v leads to collision) {
        v = -v;
    }
    else {
        x += v;
    } 
    

    or some variation thereof.

  3. Paddle movement feels fine to me.

  4. Whatever this 'particles' thing is, doesn't seem to work.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.