├── 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 |
--------------------------------------------------------------------------------