diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..38986a5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu +LABEL maintainer="Rohan Rustagi" +RUN apt update -y +RUN apt install nginx -y +COPY . /var/www/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/README.md b/README.md index 4c31a99..4e7f3a2 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,15 @@ To run the Snake Game locally or try it out, follow these steps: - `style.css`: CSS styles for styling the game layout. - `script.js`: JavaScript code that handles the game logic and functionality. +## Run the snake game using docker container + + ```bash + docker build -t snake: . + ``` + ```bash + docker run -itd -p 80:80 snake: + ``` + ## Issues and Feedback If you encounter any issues, have ideas for improvements, or want to report a bug, please [create an issue](https://github.com/your-username/Snake-Game/issues). Your feedback is valuable to us, and we appreciate your contributions to make this project better. diff --git a/food_G1U6tlb.mp3 b/food_G1U6tlb.mp3 new file mode 100644 index 0000000..0b0efde Binary files /dev/null and b/food_G1U6tlb.mp3 differ diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 0000000..001052e Binary files /dev/null and b/images/favicon.ico differ diff --git a/index.html b/index.html index 4088198..befc21f 100644 --- a/index.html +++ b/index.html @@ -6,26 +6,39 @@ Snake Game + + + + + + + +

Snake Game

+ Replay button initially hidden
- +
Score: 0
+
Highest Score: 0
+
- + \ No newline at end of file diff --git a/script.js b/script.js index 6368ce7..6fa667b 100644 --- a/script.js +++ b/script.js @@ -17,9 +17,17 @@ var foodY; var gameOver = false; var score = 0; +var highestScore = 0; var difficulty = 5; // Adjust this value for difficulty level -window.onload = function() { +const eatSound = document.getElementById("eatSound"); +const gameOverSound = document.getElementById("gameOverSound"); + + +var startButton = document.getElementById("start-button"); +var replayButton = document.getElementById("replay-button"); + +function init() { board = document.getElementById("board"); board.height = total_row * blockSize; board.width = total_col * blockSize; @@ -28,7 +36,41 @@ window.onload = function() { placeFood(); document.addEventListener("keyup", changeDirection); setInterval(update, 1000 / difficulty); -}; +} + +function createSnakeSegment(x, y) { + // Draw snake body + context.beginPath(); + context.arc(x + blockSize / 2, y + blockSize / 2, blockSize / 2, 0, Math.PI * 2); + context.fillStyle = "white"; + context.fill(); + context.closePath(); + + // Draw eyes only on the head + if (x === snakeX && y === snakeY) { + let eyeRadius = blockSize / 10; + let eyeOffsetX = blockSize / 4; + let eyeOffsetY = blockSize / 4; + + // Left eye + let eyeX1 = x + eyeOffsetX; + let eyeY = y + eyeOffsetY; + context.beginPath(); + context.arc(eyeX1, eyeY, eyeRadius, 0, Math.PI * 2); + context.fillStyle = "black"; + context.fill(); + context.closePath(); + + // Right eye + let eyeX2 = x + 3 * eyeOffsetX; + context.beginPath(); + context.arc(eyeX2, eyeY, eyeRadius, 0, Math.PI * 2); + context.fillStyle = "black"; + context.fill(); + context.closePath(); + } +} + function update() { if (gameOver) { @@ -45,8 +87,12 @@ function update() { snakeBody.push([foodX, foodY]); placeFood(); score += 10; + if (score > highestScore) { + highestScore = score; + } document.getElementById("score").innerText = "Score: " + score; } + document.getElementById("highest-score").innerText = "Highest Score: " + highestScore; for (let i = snakeBody.length - 1; i > 0; i--) { snakeBody[i] = snakeBody[i - 1]; @@ -58,13 +104,22 @@ function update() { context.fillStyle = "white"; snakeX += speedX * blockSize; snakeY += speedY * blockSize; - context.fillRect(snakeX, snakeY, blockSize, blockSize); + + createSnakeSegment(snakeX, snakeY); for (let i = 0; i < snakeBody.length; i++) { - context.fillRect(snakeBody[i][0], snakeBody[i][1], blockSize, blockSize); + createSnakeSegment(snakeBody[i][0], snakeBody[i][1]); if (snakeX == snakeBody[i][0] && snakeY == snakeBody[i][1]) { gameOver = true; - alert("Game Over\nScore: " + score); + high - score + alert("Game Over\nScore: " + score + "\nHighest Score: " + highestScore); + location.reload(); + document.getElementById('highest').innerText = "Highest Score: " + highestScore; + + document.getElementById("game-over").style.display = "block"; + replayButton.style.display = "block"; + startButton.style.display = "none"; + } } @@ -75,7 +130,14 @@ function update() { snakeY > total_row * blockSize ) { gameOver = true; - alert("Game Over\nScore: " + score); + gameOverSound.play(); + alert("Game Over\nScore: " + score + "\nHighest Score: " + highestScore); + document.getElementById('highest').innerText = "Highest Score: " + highestScore; + + document.getElementById("game-over").style.display = "block"; + replayButton.style.display = "block"; + startButton.style.display = "none"; + } } @@ -95,19 +157,84 @@ function changeDirection(e) { } } + + function placeFood() { foodX = Math.floor(Math.random() * total_col) * blockSize; foodY = Math.floor(Math.random() * total_row) * blockSize; } +function saveHighestScore() { + localStorage.setItem("highestScore", highestScore); +} + +function loadHighestScore() { + highestScore = localStorage.getItem("highestScore") || 0; +} + +loadHighestScore(); + +// When the window closes, it saves the high score +window.addEventListener("beforeunload", saveHighestScore); + // Add an event listener to the "Start Game" button -document.getElementById("start-button").addEventListener("click", startGame); +startButton.addEventListener("click", startGame); function startGame() { + eatSound.play(); // Retrieve the selected difficulty level from the dropdown var selectedDifficulty = parseInt(document.getElementById("difficulty").value); // Clear the existing canvas and start the game with the selected difficulty resetGame(selectedDifficulty); -} \ No newline at end of file +} + + +function resetGame() { + location.reload(); +} + +// Add an event listener to the "Replay" button +replayButton.addEventListener("click", function () { + document.getElementById("game-over").style.display = "none"; + replayButton.style.display = "none"; + startButton.style.display = "block"; + resetGame(difficulty); +}); + +// Function to reset the game +// Function to reset the game +function resetGame(selectedDifficulty) { + snakeX = blockSize * 5; + snakeY = blockSize * 5; + speedX = 0; + speedY = 0; + snakeBody = []; + gameOver = false; + score = 0; + + // Set the difficulty based on the selectedDifficulty or default to 5 if not provided + difficulty = selectedDifficulty || 5; + + // Clear the existing interval timer + clearInterval(interval); + + // Set the difficulty before initializing the game + interval = setInterval(update, 1000 / difficulty); + + document.getElementById("score").innerText = "Score: " + score; + + init(); +} + +// To restart game with spacebar +document.addEventListener("keydown", function(event) { + if(event.code==="Space"){ + resetGame(); + } +}); + +// Initial game setup +init(); + diff --git a/sound_ErK79lZ.mp3 b/sound_ErK79lZ.mp3 new file mode 100644 index 0000000..7fd0f87 Binary files /dev/null and b/sound_ErK79lZ.mp3 differ diff --git a/style.css b/style.css index 49b3e70..551b47d 100644 --- a/style.css +++ b/style.css @@ -30,14 +30,15 @@ body { } .game-container { + box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px; display: flex; flex-direction: column; align-items: center; background-color: #fff; - border: 1px solid #ccc; + border: 2px solid grey; padding: 20px; border-radius: 5px; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2); + } canvas { @@ -51,7 +52,7 @@ canvas { flex-direction: column; align-items: center; } - +/* Added hovering effect to the buttons to look good */ button { padding: 10px 20px; background-color: #333; @@ -60,8 +61,32 @@ button { border-radius: 5px; cursor: pointer; margin-bottom: 10px; + transition: transform 0.5s ease; + font-size: 18px; +} +button:hover{ + background-color: grey; + color: black; + transform: scale(1.1); +} +#span1{ + text-shadow: 2px 2px 8px #FF0000; + font-size: 19px; +} +/* Added text shadow to the text */ +#label1,#score,#highest-score,#game-over{ + text-shadow: 2px 2px 8px #FF0000; + font-size: 19px; +} + + +#start-button:hover { + background-color: #ccc; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); + color: #060000; } + select { padding: 5px; border: 1px solid #333; @@ -69,13 +94,57 @@ select { margin-bottom: 10px; } -#score { +#score, +#highest-score { font-size: 18px; font-weight: bold; } .game-title { + text-shadow: 0 0 3px #FF0000, 0 0 5px #0000FF; font-size: 36px; font-weight: bold; margin-bottom: 20px; +} + +#game-over { + font-size: 36px; + font-weight: bold; + color: red; + animation: blink 1s infinite; +} + +@keyframes blink { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +#game-over { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + color: red; + font-size: 4rem; + animation: fadeIn 2s; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } } \ No newline at end of file