Before we start, here are some more apps using javascript you might like to create:
1.Ā Snake Game using JavaScript
2.Ā 2D Bouncing Ball Game using JavaScript
3.Ā Rock Paper Scissor Game using JavaScript
4.Ā Tic Tac Toe Game using JavaScript
5. Whack a Mole Game using JavaScript
I would recommend you don’t just copy and paste the code, just look at the code and type by understanding it.
HTML CodeĀ
Starter Template
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSS --> <link rel="stylesheet" href="style.css"> <!-- FONT AWESOME CDN --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" /> <title>Pong Game using JavaScript - @code.scientist x @codingtorque</title> </head> <body> <!-- Further code here --> <script src="https://code.jquery.com/jquery-3.6.3.js" integrity="sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM=" crossorigin="anonymous"></script> <script src="script.js"></script> </body> </html>
Paste the below code in your <body>
tag.
<canvas></canvas>
CSS Code
Create a fileĀ style.css and paste the code below.
body { text-align: center; padding-top: 5rem; }
Output Till Now
JavaScript CodeĀ
Create a fileĀ script.jsĀ and paste the code below.
// Global Variables var DIRECTION = { IDLE: 0, UP: 1, DOWN: 2, LEFT: 3, RIGHT: 4 }; var rounds = [5, 5, 3, 3, 2]; var colors = ['#1abc9c', '#2ecc71', '#3498db', '#e74c3c', '#9b59b6']; var beep1 = new Audio("http://commondatastorage.googleapis.com/codeskulptor-assets/Collision8-Bit.ogg") var beep2 = new Audio("http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/pause.wav") var beep3 = new Audio("http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/theygotcha.ogg") // The ball object (The cube that bounces back and forth) var Ball = { new: function (incrementedSpeed) { return { width: 18, height: 18, x: (this.canvas.width / 2) - 9, y: (this.canvas.height / 2) - 9, moveX: DIRECTION.IDLE, moveY: DIRECTION.IDLE, speed: incrementedSpeed || 9 }; } }; // The paddle object (The two lines that move up and down) var Paddle = { new: function (side) { return { width: 18, height: 70, x: side === 'left' ? 150 : this.canvas.width - 150, y: (this.canvas.height / 2) - 35, score: 0, move: DIRECTION.IDLE, speed: 10 }; } }; var Game = { initialize: function () { this.canvas = document.querySelector('canvas'); this.context = this.canvas.getContext('2d'); this.canvas.width = 1400; this.canvas.height = 1000; this.canvas.style.width = (this.canvas.width / 2) + 'px'; this.canvas.style.height = (this.canvas.height / 2) + 'px'; this.player = Paddle.new.call(this, 'left'); this.paddle = Paddle.new.call(this, 'right'); this.ball = Ball.new.call(this); this.paddle.speed = 8; this.running = this.over = false; this.turn = this.paddle; this.timer = this.round = 0; this.color = 'black'; Pong.menu(); Pong.listen(); }, endGameMenu: function (text) { // Change the canvas font size and color Pong.context.font = '50px Courier New'; Pong.context.fillStyle = this.color; // Draw the rectangle behind the 'Press any key to begin' text. Pong.context.fillRect( Pong.canvas.width / 2 - 350, Pong.canvas.height / 2 - 48, 700, 100 ); // Change the canvas color; Pong.context.fillStyle = '#ffffff'; // Draw the end game menu text ('Game Over' and 'Winner') Pong.context.fillText(text, Pong.canvas.width / 2, Pong.canvas.height / 2 + 15 ); setTimeout(function () { Pong = Object.assign({}, Game); Pong.initialize(); }, 3000); }, menu: function () { // Draw all the Pong objects in their current state Pong.draw(); // Change the canvas font size and color this.context.font = '50px Courier New'; this.context.fillStyle = this.color; // Draw the rectangle behind the 'Press any key to begin' text. this.context.fillRect( this.canvas.width / 2 - 350, this.canvas.height / 2 - 48, 700, 100 ); // Change the canvas color; this.context.fillStyle = '#ffffff'; // Draw the 'press any key to begin' text this.context.fillText('Press any key to begin', this.canvas.width / 2, this.canvas.height / 2 + 15 ); }, // Update all objects (move the player, paddle, ball, increment the score, etc.) update: function () { if (!this.over) { // If the ball collides with the bound limits - correct the x and y coords. if (this.ball.x <= 0) Pong._resetTurn.call(this, this.paddle, this.player); if (this.ball.x >= this.canvas.width - this.ball.width) Pong._resetTurn.call(this, this.player, this.paddle); if (this.ball.y <= 0) this.ball.moveY = DIRECTION.DOWN; if (this.ball.y >= this.canvas.height - this.ball.height) this.ball.moveY = DIRECTION.UP; // Move player if they player.move value was updated by a keyboard event if (this.player.move === DIRECTION.UP) this.player.y -= this.player.speed; else if (this.player.move === DIRECTION.DOWN) this.player.y += this.player.speed; // On new serve (start of each turn) move the ball to the correct side // and randomize the direction to add some challenge. if (Pong._turnDelayIsOver.call(this) && this.turn) { this.ball.moveX = this.turn === this.player ? DIRECTION.LEFT : DIRECTION.RIGHT; this.ball.moveY = [DIRECTION.UP, DIRECTION.DOWN][Math.round(Math.random())]; this.ball.y = Math.floor(Math.random() * this.canvas.height - 200) + 200; this.turn = null; } // If the player collides with the bound limits, update the x and y coords. if (this.player.y <= 0) this.player.y = 0; else if (this.player.y >= (this.canvas.height - this.player.height)) this.player.y = (this.canvas.height - this.player.height); // Move ball in intended direction based on moveY and moveX values if (this.ball.moveY === DIRECTION.UP) this.ball.y -= (this.ball.speed / 1.5); else if (this.ball.moveY === DIRECTION.DOWN) this.ball.y += (this.ball.speed / 1.5); if (this.ball.moveX === DIRECTION.LEFT) this.ball.x -= this.ball.speed; else if (this.ball.moveX === DIRECTION.RIGHT) this.ball.x += this.ball.speed; // Handle paddle (AI) UP and DOWN movement if (this.paddle.y > this.ball.y - (this.paddle.height / 2)) { if (this.ball.moveX === DIRECTION.RIGHT) this.paddle.y -= this.paddle.speed / 1.5; else this.paddle.y -= this.paddle.speed / 4; } if (this.paddle.y < this.ball.y - (this.paddle.height / 2)) { if (this.ball.moveX === DIRECTION.RIGHT) this.paddle.y += this.paddle.speed / 1.5; else this.paddle.y += this.paddle.speed / 4; } // Handle paddle (AI) wall collision if (this.paddle.y >= this.canvas.height - this.paddle.height) this.paddle.y = this.canvas.height - this.paddle.height; else if (this.paddle.y <= 0) this.paddle.y = 0; // Handle Player-Ball collisions if (this.ball.x - this.ball.width <= this.player.x && this.ball.x >= this.player.x - this.player.width) { if (this.ball.y <= this.player.y + this.player.height && this.ball.y + this.ball.height >= this.player.y) { this.ball.x = (this.player.x + this.ball.width); this.ball.moveX = DIRECTION.RIGHT; beep1.play(); } } // Handle paddle-ball collision if (this.ball.x - this.ball.width <= this.paddle.x && this.ball.x >= this.paddle.x - this.paddle.width) { if (this.ball.y <= this.paddle.y + this.paddle.height && this.ball.y + this.ball.height >= this.paddle.y) { this.ball.x = (this.paddle.x - this.ball.width); this.ball.moveX = DIRECTION.LEFT; beep1.play(); } } } // Handle the end of round transition // Check to see if the player won the round. if (this.player.score === rounds[this.round]) { // Check to see if there are any more rounds/levels left and display the victory screen if // there are not. if (!rounds[this.round + 1]) { this.over = true; setTimeout(function () { Pong.endGameMenu('Winner!'); }, 1000); } else { // If there is another round, reset all the values and increment the round number. this.color = this._generateRoundColor(); this.player.score = this.paddle.score = 0; this.player.speed += 0.5; this.paddle.speed += 1; this.ball.speed += 1; this.round += 1; beep3.play(); } } // Check to see if the paddle/AI has won the round. else if (this.paddle.score === rounds[this.round]) { this.over = true; setTimeout(function () { Pong.endGameMenu('Game Over!'); }, 1000); } }, // Draw the objects to the canvas element draw: function () { // Clear the Canvas this.context.clearRect( 0, 0, this.canvas.width, this.canvas.height ); // Set the fill style to black this.context.fillStyle = this.color; // Draw the background this.context.fillRect( 0, 0, this.canvas.width, this.canvas.height ); // Set the fill style to white (For the paddles and the ball) this.context.fillStyle = '#ffffff'; // Draw the Player this.context.fillRect( this.player.x, this.player.y, this.player.width, this.player.height ); // Draw the Paddle this.context.fillRect( this.paddle.x, this.paddle.y, this.paddle.width, this.paddle.height ); // Draw the Ball if (Pong._turnDelayIsOver.call(this)) { this.context.fillRect( this.ball.x, this.ball.y, this.ball.width, this.ball.height ); } // Draw the net (Line in the middle) this.context.beginPath(); this.context.setLineDash([7, 15]); this.context.moveTo((this.canvas.width / 2), this.canvas.height - 140); this.context.lineTo((this.canvas.width / 2), 140); this.context.lineWidth = 10; this.context.strokeStyle = '#ffffff'; this.context.stroke(); // Set the default canvas font and align it to the center this.context.font = '100px Courier New'; this.context.textAlign = 'center'; // Draw the players score (left) this.context.fillText( this.player.score.toString(), (this.canvas.width / 2) - 300, 200 ); // Draw the paddles score (right) this.context.fillText( this.paddle.score.toString(), (this.canvas.width / 2) + 300, 200 ); // Change the font size for the center score text this.context.font = '30px Courier New'; // Draw the winning score (center) this.context.fillText( 'Round ' + (Pong.round + 1), (this.canvas.width / 2), 35 ); // Change the font size for the center score value this.context.font = '40px Courier'; // Draw the current round number this.context.fillText( rounds[Pong.round] ? rounds[Pong.round] : rounds[Pong.round - 1], (this.canvas.width / 2), 100 ); }, loop: function () { Pong.update(); Pong.draw(); // If the game is not over, draw the next frame. if (!Pong.over) requestAnimationFrame(Pong.loop); }, listen: function () { document.addEventListener('keydown', function (key) { // Handle the 'Press any key to begin' function and start the game. if (Pong.running === false) { Pong.running = true; window.requestAnimationFrame(Pong.loop); } // Handle up arrow and w key events if (key.keyCode === 38 || key.keyCode === 87) Pong.player.move = DIRECTION.UP; // Handle down arrow and s key events if (key.keyCode === 40 || key.keyCode === 83) Pong.player.move = DIRECTION.DOWN; }); // Stop the player from moving when there are no keys being pressed. document.addEventListener('keyup', function (key) { Pong.player.move = DIRECTION.IDLE; }); }, // Reset the ball location, the player turns and set a delay before the next round begins. _resetTurn: function (victor, loser) { this.ball = Ball.new.call(this, this.ball.speed); this.turn = loser; this.timer = (new Date()).getTime(); victor.score++; beep2.play(); }, // Wait for a delay to have passed after each turn. _turnDelayIsOver: function () { return ((new Date()).getTime() - this.timer >= 1000); }, // Select a random color as the background of each level/round. _generateRoundColor: function () { var newColor = colors[Math.floor(Math.random() * colors.length)]; if (newColor === this.color) return Pong._generateRoundColor(); return newColor; } }; var Pong = Object.assign({}, Game); Pong.initialize();
Written by: Piyush Patil
Code Credits: @gdube
If you have any doubts or any project ideas feel free to Contact Us
Hope you find this post helpfulš