├── simone-viani-2XPHSXVT_Ls-unsplash.jpg ├── shep-mcallister-J1j3cImjmgE-unsplash.jpg ├── index.html ├── style.css ├── README.md └── script.js /simone-viani-2XPHSXVT_Ls-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/essencerigby/pongGame/HEAD/simone-viani-2XPHSXVT_Ls-unsplash.jpg -------------------------------------------------------------------------------- /shep-mcallister-J1j3cImjmgE-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/essencerigby/pongGame/HEAD/shep-mcallister-J1j3cImjmgE-unsplash.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Kei's Classic | Pong Game 13 | 14 | 15 |
16 |

Press Space to Start Game!

17 |
0 : 0
18 | 19 |
20 | 21 |
22 | 23 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | font-family: 'Passion One', cursive; 3 | font-family: 'Rubik Dirt', cursive; 4 | background-image: url('./shep-mcallister-J1j3cImjmgE-unsplash.jpg'); 5 | background-size: cover; 6 | } 7 | #gameContainer{ 8 | text-align: center; 9 | } 10 | 11 | canvas { 12 | /* background-image: url("./simone-viani-2XPHSXVT_Ls-unsplash.jpg"); 13 | background-size: contain; */ 14 | border: 3px solid black; 15 | } 16 | p{ 17 | color: white; 18 | font-size: 20px; 19 | } 20 | #scoreText{ 21 | color: white; 22 | font-size: 40px; 23 | font-family: Verdana, Geneva, Tahoma, sans-serif; 24 | 25 | } 26 | #resetBtn{ 27 | font-family: Verdana, Geneva, Tahoma, sans-serif; 28 | font-size: 20px; 29 | width: 150px; 30 | height: 50px; 31 | color: #fff; 32 | background-color: #6C935C; 33 | border: none; 34 | border-radius: 15px; 35 | box-shadow: 5px 5px 2px 1px #B5E0A4; 36 | cursor: pointer; 37 | } 38 | #resetBtn:active{ 39 | box-shadow: 0 5px #95bdd6; 40 | transform: translateY(4px); 41 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kei's Classic: Pong Game 2 | 3 | Access Game here: https://codedependant74.github.io/pongGame/ 4 | 5 | ## Description 6 | 7 | This is a classic Pong Game made to resemble a tennis court. It is a multiplayer game with player 1 using the 'w' & 's' keys as up and down to move the left paddle, respectfully. Player 2 uses the up and down arrow keys to move the right paddle. 8 | 9 | ### To play game: 10 | 11 | 1. press the space bar to start the game 12 | 2. use respective player keys to move paddle up and down to hit the ball. 13 | 3. Each time the ball is hit, the speed increases. When a player misses the speed resets. 14 | 4. First player to 5 wins the game. 15 | 5. To exit or restart game, press the restart button, then click on the game and press space bar. 16 | 17 | ## Tech Stack 18 | 19 | - HTML 20 | - CSS 21 | - JavaScript 22 | 23 | ## Unsolved Problems 24 | 25 | - After Reset Game is pressed, and space bar is pressed directly after it glitches. User will have to click on game board the press space bar for it to work properly. 26 | - Add tennis court as background 27 | 28 | ## Upcoming Features 29 | 30 | - Option to play multiplayer or versus computer 31 | - Game start screen 32 | - Game over screen to display winner 33 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const gameBoard = document.querySelector("#pongGame"); 2 | gameBoard.width = 850; 3 | gameBoard.height = 500; 4 | const ctx = gameBoard.getContext("2d"); 5 | const scoreText = document.querySelector("#scoreText"); 6 | const resetBtn = document.querySelector("#resetBtn"); 7 | const popup = document.getElementById("popup"); 8 | const startBtn = document.querySelector("#startBtn"); 9 | const gameWidth = gameBoard.width; 10 | const gameHeight = gameBoard.height; 11 | const boardBackground = new Image(); 12 | boardBackground.src = "./simone-viani-2XPHSXVT_Ls-unsplash.jpg"; 13 | boardBackground.addEventListener("load", () => { 14 | ctx.drawImage(boardBackground, 0, 0, gameWidth, gameHeight); 15 | }); 16 | const paddle1Color = "#fff"; 17 | const paddle2Color = "#a0d6b4"; 18 | const paddleBorder = "black"; 19 | const ballColor = "#ccff00"; 20 | const ballBorderColor = "#fff"; 21 | const ballRadius = 12.5; 22 | const paddleSpeed = 50; 23 | let intervalID; 24 | let ballSpeed; 25 | let ballX = gameWidth / 2; 26 | let ballY = gameHeight / 2; 27 | let ballXDirection = 0; 28 | let ballYDirection = 0; 29 | let player1Score = 0; 30 | let player2Score = 0; 31 | let paddle1 = { 32 | width: 25, 33 | height: 100, 34 | x: 0, 35 | y: 0, 36 | }; 37 | let paddle2 = { 38 | width: 25, 39 | height: 100, 40 | x: gameWidth - 25, 41 | y: gameHeight - 100, 42 | }; 43 | 44 | window.addEventListener("keydown", changeDirection); 45 | resetBtn.addEventListener("click", resetGame); 46 | 47 | function gameStart() { 48 | createBall(); 49 | nextTick(); 50 | } 51 | function nextTick() { 52 | intervalID = setTimeout(() => { 53 | clearBoard(); 54 | drawPaddles(); 55 | moveBall(); 56 | drawBall(ballX, ballY); 57 | checkCollision(); 58 | nextTick(); 59 | }, 10); 60 | } 61 | function clearBoard() { 62 | // game board characteristics 63 | ctx.fillStyle = "#A2C128"; 64 | ctx.fillRect(0, 0, gameWidth, gameHeight); 65 | } 66 | function drawPaddles() { 67 | // paddles characteristics 68 | ctx.strokeStyle = paddleBorder; 69 | 70 | ctx.fillStyle = paddle1Color; 71 | ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); 72 | ctx.strokeRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); 73 | 74 | ctx.fillStyle = paddle2Color; 75 | ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); 76 | ctx.strokeRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); 77 | } 78 | function createBall() { 79 | // initial ball movement starts at a slow speed then increases as it is hit 80 | ballSpeed = 1; 81 | if (Math.round(Math.random()) == 1) { 82 | ballXDirection = 1; 83 | } else { 84 | ballXDirection = -1; 85 | } 86 | if (Math.round(Math.random()) == 1) { 87 | ballYDirection = Math.random() * 1; //more random directions 88 | } else { 89 | ballYDirection = Math.random() * -1; //more random directions 90 | } 91 | ballX = gameWidth / 2; //places the ball in center 92 | ballY = gameHeight / 2; 93 | drawBall(ballX, ballY); 94 | } 95 | function moveBall() { 96 | ballX += ballSpeed * ballXDirection; 97 | ballY += ballSpeed * ballYDirection; 98 | } 99 | function drawBall(ballX, ballY) { 100 | // creates the ball characteristics 101 | ctx.fillStyle = ballColor; 102 | ctx.strokeStyle = ballBorderColor; 103 | ctx.lineWidth = 2; 104 | ctx.beginPath(); 105 | ctx.arc(ballX, ballY, ballRadius, 0, 2 * Math.PI); // Makes the ball round 106 | ctx.stroke(); 107 | ctx.fill(); 108 | } 109 | function checkCollision() { 110 | // if ball hits wall, update score. If ball hit the paddle then the ball changes direction for the opponent to hit the ball 111 | if (ballY <= 0 + ballRadius) { 112 | ballYDirection *= -1; 113 | } 114 | if (ballY >= gameHeight - ballRadius) { 115 | ballYDirection *= -1; 116 | } 117 | if (ballX <= 0) { 118 | player2Score += 1; 119 | updateScore(); 120 | createBall(); 121 | return; 122 | } 123 | if (ballX >= gameWidth) { 124 | player1Score += 1; 125 | updateScore(); 126 | createBall(); 127 | return; 128 | } 129 | if (ballX <= paddle1.x + paddle1.width + ballRadius) { 130 | if (ballY > paddle1.y && ballY < paddle1.y + paddle1.height) { 131 | ballX = paddle1.x + paddle1.width + ballRadius; // if ball gets stuck 132 | ballXDirection *= -1; 133 | ballSpeed += 1; 134 | } 135 | } 136 | if (ballX >= paddle2.x - ballRadius) { 137 | if (ballY > paddle2.y && ballY < paddle2.y + paddle2.height) { 138 | ballX = paddle2.x - ballRadius; // if ball gets stuck 139 | ballXDirection *= -1; 140 | ballSpeed += 1; 141 | } 142 | } 143 | } 144 | function changeDirection(event) { 145 | //assign keyboard keys to paddle motion and start game 146 | const keyPressed = event.keyCode; 147 | const start = 32; 148 | const paddle1Up = 87; 149 | const paddle1Down = 83; 150 | const paddle2Up = 38; 151 | const paddle2Down = 40; 152 | 153 | switch (keyPressed) { 154 | case start: 155 | if (start == keyPressed) { 156 | gameStart(); 157 | } 158 | case paddle1Up: 159 | if (paddle1.y > 0) { 160 | paddle1.y -= paddleSpeed; 161 | } 162 | break; 163 | case paddle1Down: 164 | if (paddle1.y < gameHeight - paddle1.height) { 165 | paddle1.y += paddleSpeed; 166 | } 167 | break; 168 | case paddle2Up: 169 | if (paddle2.y > 0) { 170 | paddle2.y -= paddleSpeed; 171 | } 172 | break; 173 | case paddle2Down: 174 | if (paddle2.y < gameHeight - paddle2.height) { 175 | paddle2.y += paddleSpeed; 176 | } 177 | break; 178 | } 179 | } 180 | // function stopGame() { 181 | // clearInterval(gamestart); 182 | // } 183 | function updateScore() { 184 | scoreText.textContent = `${player1Score} : ${player2Score}`; 185 | if (player1Score === 5 || player2Score === 5) { 186 | resetGame(); 187 | } 188 | } 189 | function resetGame() { 190 | player1Score = 0; 191 | player2Score = 0; 192 | paddle1 = { 193 | width: 25, 194 | height: 100, 195 | x: 0, 196 | y: 0, 197 | }; 198 | paddle2 = { 199 | width: 25, 200 | height: 100, 201 | x: gameWidth - 25, 202 | y: gameHeight - 100, 203 | }; 204 | ballSpeed = 1; 205 | ballX = 0; 206 | ballY = 0; 207 | ballXDirection = 0; 208 | ballYDirection = 0; 209 | updateScore(); 210 | clearInterval(intervalID); 211 | clearBoard(); 212 | } 213 | --------------------------------------------------------------------------------