-
-
Save shricodev/0f4558cc59192a71b0e834a80e5d5fe0 to your computer and use it in GitHub Desktop.
Gemini CLI Pong Game - Gemini 2.5 Pro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Ping Pong</title> | |
| <style> | |
| :root { | |
| --table-bg: #0d47a1; | |
| --table-border: #ffffff; | |
| --paddle-color: #ffffff; | |
| --ball-color: #ffd700; | |
| --shadow-color: rgba(0, 0, 0, 0.5); | |
| } | |
| body { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100vh; | |
| margin: 0; | |
| background-color: #1a1a1a; | |
| font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| #game-container { | |
| position: relative; | |
| width: 800px; | |
| height: 500px; | |
| background-color: var(--table-bg); | |
| border: 10px solid var(--table-border); | |
| border-radius: 10px; | |
| box-shadow: 0 0 30px var(--shadow-color); | |
| overflow: hidden; | |
| } | |
| #center-line { | |
| position: absolute; | |
| top: 0; | |
| left: 50%; | |
| width: 4px; | |
| height: 100%; | |
| background-color: var(--table-border); | |
| transform: translateX(-50%); | |
| } | |
| .paddle { | |
| position: absolute; | |
| width: 15px; | |
| height: 100px; | |
| background-color: var(--paddle-color); | |
| border-radius: 5px; | |
| box-shadow: 5px 5px 15px var(--shadow-color); | |
| } | |
| #player-paddle { | |
| left: 20px; | |
| } | |
| #opponent-paddle { | |
| right: 20px; | |
| } | |
| #ball { | |
| position: absolute; | |
| width: 20px; | |
| height: 20px; | |
| background: radial-gradient( | |
| circle at 30% 30%, | |
| var(--ball-color), | |
| #b8860b | |
| ); | |
| border-radius: 50%; | |
| box-shadow: 5px 5px 15px var(--shadow-color); | |
| } | |
| #score { | |
| position: absolute; | |
| top: 20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| font-size: 48px; | |
| color: var(--table-border); | |
| text-shadow: 2px 2px 5px var(--shadow-color); | |
| } | |
| #author { | |
| position: absolute; | |
| top: 10px; | |
| left: 10px; | |
| font-size: 16px; | |
| color: var(--table-border); | |
| text-shadow: 1px 1px 2px var(--shadow-color); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="game-container"> | |
| <div id="author">Shrijal Acharya @shricodev</div> | |
| <div id="center-line"></div> | |
| <div id="score">0 - 0</div> | |
| <div class="paddle" id="player-paddle"></div> | |
| <div class="paddle" id="opponent-paddle"></div> | |
| <div id="ball"></div> | |
| </div> | |
| <script> | |
| const gameContainer = document.getElementById("game-container"); | |
| const playerPaddle = document.getElementById("player-paddle"); | |
| const opponentPaddle = document.getElementById("opponent-paddle"); | |
| const ball = document.getElementById("ball"); | |
| const scoreDisplay = document.getElementById("score"); | |
| const gameWidth = gameContainer.clientWidth; | |
| const gameHeight = gameContainer.clientHeight; | |
| let playerScore = 0; | |
| let opponentScore = 0; | |
| let ballX = gameWidth / 2; | |
| let ballY = gameHeight / 2; | |
| let ballSpeedX = 5; | |
| let ballSpeedY = 5; | |
| function updateScore() { | |
| scoreDisplay.textContent = `${playerScore} - ${opponentScore}`; | |
| } | |
| function resetBall() { | |
| ballX = gameWidth / 2; | |
| ballY = gameHeight / 2; | |
| ballSpeedX = -ballSpeedX; | |
| } | |
| function gameLoop() { | |
| // Ball movement | |
| ballX += ballSpeedX; | |
| ballY += ballSpeedY; | |
| // Ball collision with top/bottom walls | |
| if (ballY <= 0 || ballY >= gameHeight - ball.clientHeight) { | |
| ballSpeedY = -ballSpeedY; | |
| } | |
| // Ball collision with paddles | |
| const playerRect = playerPaddle.getBoundingClientRect(); | |
| const opponentRect = opponentPaddle.getBoundingClientRect(); | |
| const ballRect = ball.getBoundingClientRect(); | |
| const gameRect = gameContainer.getBoundingClientRect(); | |
| if ( | |
| (ballSpeedX < 0 && | |
| ballX < playerRect.right - gameRect.left && | |
| ballY > playerRect.top - gameRect.top && | |
| ballY < playerRect.bottom - gameRect.top) || | |
| (ballSpeedX > 0 && | |
| ballX > opponentRect.left - gameRect.left - ball.clientWidth && | |
| ballY > opponentRect.top - gameRect.top && | |
| ballY < opponentRect.bottom - gameRect.top) | |
| ) { | |
| ballSpeedX = -ballSpeedX; | |
| } | |
| // Scoring | |
| if (ballX <= 0) { | |
| opponentScore++; | |
| updateScore(); | |
| resetBall(); | |
| } else if (ballX >= gameWidth - ball.clientWidth) { | |
| playerScore++; | |
| updateScore(); | |
| resetBall(); | |
| } | |
| // Opponent AI | |
| const opponentCenter = | |
| opponentPaddle.offsetTop + opponentPaddle.clientHeight / 2; | |
| if (opponentCenter < ballY) { | |
| opponentPaddle.style.top = opponentPaddle.offsetTop + 4 + "px"; | |
| } else { | |
| opponentPaddle.style.top = opponentPaddle.offsetTop - 4 + "px"; | |
| } | |
| // Update positions | |
| ball.style.left = ballX + "px"; | |
| ball.style.top = ballY + "px"; | |
| requestAnimationFrame(gameLoop); | |
| } | |
| // Player paddle movement | |
| gameContainer.addEventListener("mousemove", (e) => { | |
| const rect = gameContainer.getBoundingClientRect(); | |
| let newY = e.clientY - rect.top - playerPaddle.clientHeight / 2; | |
| if (newY < 0) newY = 0; | |
| if (newY > gameHeight - playerPaddle.clientHeight) | |
| newY = gameHeight - playerPaddle.clientHeight; | |
| playerPaddle.style.top = newY + "px"; | |
| }); | |
| updateScore(); | |
| gameLoop(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment