diff --git a/css/home.css b/css/home.css index f684bf8..e107700 100644 --- a/css/home.css +++ b/css/home.css @@ -2,12 +2,13 @@ body { font-family: Helvetica, Arial, sans-serif; font-size: 1rem; - color: #4c4f69; + color: #cad3f5; line-height: 1.5; width: 800px; margin-inline: auto; - background: white; - padding: 10px 10px 10px 10px; + background: #24273a; + padding: 6px; + margin: 10px auto; } /* @@ -16,22 +17,38 @@ body { } */ +#top { + margin-bottom: 6px; + border-radius: 16px; + border-top-left-radius: 0px; + margin: 4px auto; + margin-top: 0px; + height: 55px; +} + +#main { + background: #1e2030; +} + /* Title of the resume */ h1 { - color: #df8e1d; - font-size: 2.1rem; + width: 130px; text-align: center; - margin-top: 0px; - margin-bottom: 0px; + display: inline-block; + font-size: 1.8rem; + margin: 0px; + padding: 8px; + border-top-left-radius: 18px; + border-top-right-radius: 18px; } /* Titles of categories */ h2 { - color: #df8e1d; - font-size: 1.6rem; + color: #f5a97f; + font-size: 1.8rem; + text-align: center; margin-top: 0; margin-bottom: 0.5rem; - border-bottom: 1px solid black; } h3 { @@ -48,13 +65,6 @@ h4 { margin-bottom: 0.5rem; } -h6 { - font-size: 0.9rem; - text-align: center; - margin: 0; - padding-bottom: 9px; -} - /* Definitions */ dt { float: left; @@ -73,13 +83,28 @@ p { /* Links */ a { text-decoration: none; - color: #1e66f5; + padding: 8px; + color: #8aadf4; } + a:hover, a:active { - background-color: #7287fd; - color: #FFFFFF; + border-radius: 9px; text-decoration: underline; text-shadow: 1px 1px 1px #333; + animation: animate 3s linear infinite; +} + +a.button { + margin: 14px 10%; + padding: 4px 12px; + border: 1px outset #494d64; + border-radius: 9px; + color: #8aadf4; + display: inline-block; + background-color: #363a4f; + text-decoration: none; + width: 80px; + text-align: center; } /* Horizontal separators */ @@ -101,3 +126,31 @@ p, li { line-height: 1.6; } + +@keyframes animate { + 0% { box-shadow: 0 0 8px 4px #24273a; } + 15% { box-shadow: 0 0 8px 4px #494d64; } + 50% { box-shadow: 0 0 8px 4px #b7bdf8; } + 85% { box-shadow: 0 0 8px 4px #494d64; } + 100% { box-shadow: 0 0 8px 4px #24273a; } +} + +.card { + background: #363a4f; + text-align: center; + border-radius: 6px; + border-top-left-radius: 18px; + border-top-right-radius: 18px; +} + +.card-top { + background: #1e2030; + border-top-left-radius: 18px; + border-top-right-radius: 18px; +} + +#pong { + margin: 6px; + border-radius: 9px; + background: #494d64; +} diff --git a/home.html b/home.html index 038c252..c7349de 100644 --- a/home.html +++ b/home.html @@ -28,17 +28,25 @@ -

Trianta

-
- [ GitHub Profile ] - . [ Personal Projects ] -
-

Interactive Projects

-
-

Snakeplusplus

-

Pong

- - +
+

Trianta

+

GitHub

+

Projects

+
+
+
+

Pong

+
+ + + + +
+
diff --git a/js/pong.js b/js/pong.js index 1376005..251cc7e 100644 --- a/js/pong.js +++ b/js/pong.js @@ -1,22 +1,224 @@ -html, body { - height: 100%; - margin: 0; -} - -body { - background: black; - display: flex; - align-items: center; - justify-content: center; -} - -.button { - background: blue; - color: white; - padding: 15px 20px; - font-size: 32px; - font-family: Arial, Helvetica, sans-serif; - text-transform: uppercase; - cursor: pointer; - position: relative; -} +const canvas = document.getElementById('pong'); +const context = canvas.getContext('2d'); +const grid = 15; +const paddleHeight = grid * 5; // 80 +const maxPaddleY = canvas.height - grid - paddleHeight; + +var paddleSpeed = 6; +var ballSpeed = 5; + +var leftScore = 0; +var rightScore = 0; + +const leftPaddle = { + // start in the middle of the game on the left side + x: grid * 2, + y: canvas.height / 2 - paddleHeight / 2, + width: grid, + height: paddleHeight, + + // paddle velocity + dy: 0 +}; +const rightPaddle = { + // start in the middle of the game on the right side + x: canvas.width - grid * 3, + y: canvas.height / 2 - paddleHeight / 2, + width: grid, + height: paddleHeight, + + // paddle velocity + dy: 0 +}; +const ball = { + // start in the middle of the game + x: canvas.width / 2, + y: canvas.height / 2, + width: grid, + height: grid, + + // keep track of when need to reset the ball position + resetting: false, + + // ball velocity (start going to the top-right corner) + dx: ballSpeed, + dy: -ballSpeed +}; + +// check for collision between two objects using axis-aligned bounding box (AABB) +// @see https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection +function collides(obj1, obj2) { + return obj1.x < obj2.x + obj2.width && + obj1.x + obj1.width > obj2.x && + obj1.y < obj2.y + obj2.height && + obj1.y + obj1.height > obj2.y; +} + +function gameOver() { + context.clearRect(0, 0, canvas.width, canvas.height); + let restartGame = document.getElementById("restart"); + let gameOverText = document.getElementById("gameover"); + restartGame.hidden = false; + gameOverText.hidden = false; +} + +function restartGame() { + leftScore = 0; + rightScore = 0; + let restartGame = document.getElementById("restart"); + restartGame.hidden = true; + requestAnimationFrame(loop); +} + +function BotMovesPaddle(paddle) { + ballRegion = Math.floor(ball.y / 15); + paddleRegion = Math.floor(paddle.y / 15); + if (ballRegion < paddleRegion) paddle.dy = -paddleSpeed; + if (ballRegion > paddleRegion) paddle.dy = paddleSpeed; + if (ballRegion === paddleRegion) paddle.dy = 0; +} + +// game loop +function loop() { + //if (leftScore < 7 && rightScore < 7) { + requestAnimationFrame(loop); + //} else if (leftScore >= 7 || rightScore >= 7) { + // gameOver(); + //} + context.clearRect(0,0,canvas.width,canvas.height); + + if (ball.dx < 0) { + BotMovesPaddle(leftPaddle); + } + if (ball.dx > 0) { + BotMovesPaddle(rightPaddle); + } + + // move paddles by their velocity + leftPaddle.y += leftPaddle.dy; + rightPaddle.y += rightPaddle.dy; + + // prevent paddles from going through walls + if (leftPaddle.y < grid) { + leftPaddle.y = grid; + } + else if (leftPaddle.y > maxPaddleY) { + leftPaddle.y = maxPaddleY; + } + + if (rightPaddle.y < grid) { + rightPaddle.y = grid; + } + else if (rightPaddle.y > maxPaddleY) { + rightPaddle.y = maxPaddleY; + } + + // draw paddles + context.fillStyle = 'white'; + context.fillRect(leftPaddle.x, leftPaddle.y, leftPaddle.width, leftPaddle.height); + context.fillRect(rightPaddle.x, rightPaddle.y, rightPaddle.width, rightPaddle.height); + + // move ball by its velocity + ball.x += ball.dx; + ball.y += ball.dy; + + // prevent ball from going through walls by changing its velocity + if (ball.y < grid) { + ball.y = grid; + ball.dy *= -1; + } + else if (ball.y + grid > canvas.height - grid) { + ball.y = canvas.height - grid * 2; + ball.dy *= -1; + } + + // reset ball if it goes past paddle (but only if we haven't already done so) + if ( (ball.x < 0 || ball.x > canvas.width) && !ball.resetting) { + ball.resetting = true; + + if (ball.x < 0) { + rightScore++; + } + if (ball.x > canvas.width) { + leftScore++; + } + + // give some time for the player to recover before launching the ball again + setTimeout(() => { + ball.resetting = false; + ball.x = canvas.width / 2; + ball.y = canvas.height / 2; + }, 400); + } + + // check to see if ball collides with paddle. if they do change x velocity + if (collides(ball, leftPaddle)) { + ball.dx *= -1; + leftPaddle.dy = 0; + + // move ball next to the paddle otherwise the collision will happen again + // in the next frame + ball.x = leftPaddle.x + leftPaddle.width; + } + else if (collides(ball, rightPaddle)) { + ball.dx *= -1; + rightPaddle.dy = 0; + + // move ball next to the paddle otherwise the collision will happen again + // in the next frame + ball.x = rightPaddle.x - ball.width; + } + + // draw score + context.font = "30px Arial"; + context.fillText(leftScore, 200, 50); + context.fillText(rightScore, 560, 50); + + // draw ball + context.fillRect(ball.x, ball.y, ball.width, ball.height); + + // draw walls + context.fillStyle = "#f4dbd6"; + context.fillRect(0, 0, canvas.width, grid); + context.fillRect(0, canvas.height - grid, canvas.width, canvas.height); + + // draw dotted line down the middle + for (let i = grid; i < canvas.height - grid; i += grid * 2) { + context.fillRect(canvas.width / 2 - grid / 2, i, grid, grid); + } +} + +// listen to keyboard events to move the paddles +document.addEventListener('keydown', function(e) { + // up arrow key + if (e.which === 38) { + rightPaddle.dy = -paddleSpeed; + } + // down arrow key + else if (e.which === 40) { + rightPaddle.dy = paddleSpeed; + } + + // w key + if (e.which === 87) { + leftPaddle.dy = -paddleSpeed; + } + // a key + else if (e.which === 83) { + leftPaddle.dy = paddleSpeed; + } +}); + +// listen to keyboard events to stop the paddle if key is released +document.addEventListener('keyup', function(e) { + if (e.which === 38 || e.which === 40) { + rightPaddle.dy = 0; + } + if (e.which === 83 || e.which === 87) { + leftPaddle.dy = 0; + } +}); + +// start the game +requestAnimationFrame(loop); + diff --git a/pong.html b/pong.html index a7580e6..717ad1d 100644 --- a/pong.html +++ b/pong.html @@ -7,14 +7,6 @@ - - - -