Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <html>

<head>
  <title>Pong game made with SVG.js</title>
</head>

<body>
  <h1>Pong game made with SVG.js</h1>
  <h3>CONTROLS:<br> Left paddle:  W/S<br>Right paddle: up/down<br>Press mouse/mouse pad to start game/serve ball<br>NOTE: work in progress ;-)</h3>
  <div id="pong"></div>
  
</body>

</html>
              
            
!

CSS

              
                
              
            
!

JS

              
                /*

Todo list:
- make paddles smaller with each hit
- change colors 
- add function that stops paddles when keys are not pressed
- make reset btn
- make legend
- ball start at certain angle to avoid up/down bounce

Help src: https://css-tricks.com/pong-svg-js/

*/


// define height and width

var height = 450, width = 400;

// create SVG document and set it's size

var draw = SVG('pong').size(width, height);
draw.viewbox(0,0,450,400);

// draw background 

var background = draw.rect(width, height).fill('#E3E8E6');

// draw dashed vertical line

var line = draw.line(width/2, 0, width/2, height);
line.stroke({ width: 5, color: '#fff', dasharray: '5,6' });

// defining paddle size

var paddleWidth = 15, paddleHeight = 80;

// create and position left paddle

var paddleLeft = draw.rect(paddleWidth, paddleHeight);
paddleLeft.x(0).cy(height/2).fill('#00ff99');

// create and position right paddle

var paddleRight = paddleLeft.clone();
paddleRight.x(width-paddleWidth).fill('#ff0055');

// define ball size

var ballSize = 10;

// create ball

var ball = draw.circle(ballSize);
ball.center(width/2, height/2).fill('#73A8CC');

// scoreboard 

// initial player score

var playerLeft = 0, playerRight = 0;

// text for scores and set font properties
// The var playerLeft is assigned an integer while the text() method accepts a string. To convert an integer to a string you can append it with an empty string.

var scoreLeft = draw.text(String(playerLeft)).font({
  size: 32,
  family: 'Menlo, sans-serif',
  anchor: 'end',
  fill: '#fff'
}).move(width/2-10, 10);

// cloning playerLeft to create text for playerRight

var scoreRight = scoreLeft.clone()
 .text(String(playerRight))
  .font('anchor', 'start')
  .x(width/2+10);

// Game logic //

// random speed(velocity) for ball at start

var vx = Math.random()*500-50,
    vy = Math.random()*500-150;

// update called on every animation step. This is basically what make objects move. 

function update(dt) {
  
  // move ball by its velocity 
  ball.dmove(vx*dt, vy*dt);
  
  
  // get position of ball
  var cx = ball.cx(),
      cy = ball.cy();
 
  
  // checking if ball hits top/bottom
  if((cy < 0) || (cy > height)) {
    vy = -vy;
  }
  
  // checking if ball hits left/right
  if ((cx < 0) || (cx > width)) {
    
    // Update scoreboard
    if(vx > 0){playerRight++;} else {playerLeft++;}
    
    
    // scores are being updated
    scoreLeft.text(String(playerLeft));
    scoreRight.text(String(playerRight));
    
    // Call reset function. Resets ball and paddle position once ball hits left/right wall. 
    reset();
    
    
  }
  
  
   // getting y-pos for paddles
  
  var paddleLeftY = paddleLeft.y(),
      paddleRightY = paddleRight.y();
  
  // checking if ball hits paddles
  // vx condition added to stop ball from going behind paddles
  
  if ((cx < paddleWidth && cy > paddleLeftY && cy < paddleLeftY+paddleHeight && vx < 0) || (cx > width-paddleWidth && cy > paddleRightY && cy < paddleRightY+paddleHeight && vx > 0)){
    vx = -vx*1.05;
  } 

  // Move player paddles
  // Get y.pos
  
  var playerRightPaddleY = paddleRight.y(); 
  var playerLeftPaddleY = paddleLeft.y();
  
  // restraining paddle movement for playerRight
  if (playerRightPaddleY <= 0 && paddleDirectionRight == -1) {
  paddleRight.cy(paddleHeight / 2) 
} else if (playerRightPaddleY >= height-paddleHeight && paddleDirectionRight == 1) {
  paddleRight.y(height - paddleHeight)
} else {
  paddleRight.dy(paddleDirectionRight * paddleSpeed)
}

   // restraining paddle movement for playerLight 
 
 if (playerLeftPaddleY <= 0 && paddleDirectionLeft == -1) {
  paddleLeft.cy(paddleHeight / 2) 
} else if (playerLeftPaddleY >= height-paddleHeight && paddleDirectionLeft == 1) {
  paddleLeft.y(height - paddleHeight)
} else {
  paddleLeft.dy(paddleDirectionLeft * paddleSpeed)}
 
}

// code to call update function

var lastTime, animFrame;

function callback(ms) {
  // we get passed a timestamp in milliseconds
  // we use it to determine how much time has passed since the last call
  if (lastTime) {
    update((ms-lastTime)/1000); // call update and pass delta time in seconds
  }

  lastTime = ms;
  animFrame = requestAnimationFrame(callback);
}


callback();



// Define paddle direction and speed

var paddleDirectionRight = 0; // -1 is up, 1 is down, 0 is still
var paddleDirectionLeft = 0; // -1 is up, 1 is down, 0 is still
var paddleSpeed = 5; // pixels per frame
var keys = []; // to track multiple keys. Not in use atm.

//Add keyboard controls


// detect if up and down arrows are pressed to change direction
// SVG.on(); add an eventlistener. That listens to the event "keydown" and executes function(e).
// 38 is up-arrow, 40 is down-arrow, 87 is 'W', 83 is 'S'
// You can use myVar = condition ? value-if-true : value-if-false or you can use switch statement.

SVG.on(document, "keydown", function(e) {
  switch(e.keyCode) {
    case 40:
      paddleDirectionRight = 1
      break;
    case 38:
      paddleDirectionRight = -1
      break;
    case 87:
      paddleDirectionLeft = -1
      break;
    case 83:
      paddleDirectionLeft = 1
      break; 
    }
});


/*
//Direction is reset once the key is not pressed ('keyup')
SVG.on(document, "keyup", function(e) {
 paddleDirectionLeft = 0;
 paddleDirectionRight = 0;
 e.preventDefault();
});

//ISSUE: I'm currently not able to make the paddles stop, when keys are not pressed. This due to movement cancellation of opposite paddle, when executed.

*/
function reset(){
  
  // Reset velocity
  vx = 0;
  vy = 0;
  
  // Reset position of ball
  ball.animate(100).center(width/2, height/2);
  
  // Reset position of paddle
  paddleLeft.animate(100).cy(height/2);
  paddleRight.animate(100).cy(height/2);
 
}

  // Start game. Add click listener 

draw.on('click', function() {
  if(vx === 0 && vy === 0) {
    vx = Math.random() * 500 - 150
    vy = Math.random() * 500 - 150
  }
})
 























              
            
!
999px

Console