diff --git a/30DaysOfJavaScript/assets/38.png b/30DaysOfJavaScript/assets/38.png new file mode 100644 index 00000000..5ba4382d Binary files /dev/null and b/30DaysOfJavaScript/assets/38.png differ diff --git a/38 - Snake-Game/assets/snake-game.png b/38 - Snake-Game/assets/snake-game.png new file mode 100644 index 00000000..56697ece Binary files /dev/null and b/38 - Snake-Game/assets/snake-game.png differ diff --git a/38 - Snake-Game/audio/food.mp3 b/38 - Snake-Game/audio/food.mp3 new file mode 100644 index 00000000..076198c9 Binary files /dev/null and b/38 - Snake-Game/audio/food.mp3 differ diff --git a/38 - Snake-Game/audio/gameover.mp3 b/38 - Snake-Game/audio/gameover.mp3 new file mode 100644 index 00000000..414bf651 Binary files /dev/null and b/38 - Snake-Game/audio/gameover.mp3 differ diff --git a/38 - Snake-Game/audio/move.mp3 b/38 - Snake-Game/audio/move.mp3 new file mode 100644 index 00000000..4d3d245d Binary files /dev/null and b/38 - Snake-Game/audio/move.mp3 differ diff --git a/38 - Snake-Game/audio/music.mp3 b/38 - Snake-Game/audio/music.mp3 new file mode 100644 index 00000000..f1507af3 Binary files /dev/null and b/38 - Snake-Game/audio/music.mp3 differ diff --git a/38 - Snake-Game/index.html b/38 - Snake-Game/index.html new file mode 100644 index 00000000..8f5f418f --- /dev/null +++ b/38 - Snake-Game/index.html @@ -0,0 +1,35 @@ + + + + + + + + + + + Snake Game + + + +

Snake Game

+
+
+
+
+
Score: 0
+
Hi Score: 0
+
+ + + + + + \ No newline at end of file diff --git a/38 - Snake-Game/script.js b/38 - Snake-Game/script.js new file mode 100644 index 00000000..afd7e6f4 --- /dev/null +++ b/38 - Snake-Game/script.js @@ -0,0 +1,125 @@ +let inputDir = { x: 0, y: 0 }; +const moveSound = new Audio('audio/move.mp3'); +const foodSound = new Audio('audio/food.mp3'); +const gameOverSound = new Audio('audio/gameover.mp3'); +let speed = 5; +let lastPaintTime = 0; +let snakeArr = [{ x: 13, y: 15 }] +food = { x: 6, y: 7 }; +let score = 0; +// Game Functions +function main(ctime) { + window.requestAnimationFrame(main); + if ((ctime - lastPaintTime) / 1000 < 1 / speed) { + return; + } + lastPaintTime = ctime; + gameEngine(); +} + +function isCollide(snake) { + // If you bump into yourself + for (let i = 1; i < snakeArr.length; i++) { + if (snake[i].x === snake[0].x && snake[i].y === snake[0].y) { + return true; + } + } + // If you bump into the wall + if (snake[0].x >= 18 || snake[0].x <= 0 || snake[0].y >= 18 || snake[0].y <= 0) { + return true; + } + return false; +} + +function gameEngine() { + // Updating the snake array & Food + if (isCollide(snakeArr)) { + gameOverSound.play(); + inputDir = { x: 0, y: 0 }; + alert("Game Over. Press Any Key To Continue"); + snakeArr = [{ x: 13, y: 15 }]; + score = 0; + scoreBox.innerHTML = 'Score: ' + score; + } + if (snakeArr[0].x === food.x && snakeArr[0].y === food.y) { + foodSound.play(); + score += 1; + if (score > hiscoreval) { + hiscoreval = score; + localStorage.setItem("hiscore", JSON.stringify(hiscoreval)); + hiscoreBox.innerHTML = "Hi Score: " + hiscoreval; + } + scoreBox.innerHTML = 'Score: ' + score; + snakeArr.unshift({ x: snakeArr[0].x + inputDir.x, y: snakeArr[0].y + inputDir.y }); + let a = 2; + let b = 16; + food = { x: Math.round(a + (b - 1) * Math.random()), y: Math.round(a + (b - 1) * Math.random()) }; + } + // Moving the snake + for (let i = snakeArr.length - 2; i >= 0; i--) { + snakeArr[i + 1] = {...snakeArr[i] }; + } + snakeArr[0].x += inputDir.x; + snakeArr[0].y += inputDir.y; + + // Display the snake and Food + // Display the snake + board.innerHTML = ""; + snakeArr.forEach((e, index) => { + snakeElement = document.createElement('div'); + snakeElement.style.gridRowStart = e.y; + snakeElement.style.gridColumnStart = e.x; + if (index === 0) { + snakeElement.classList.add('head'); + } else { + snakeElement.classList.add('snake'); + } + board.appendChild(snakeElement); + }); + // Display the food + foodElement = document.createElement('div'); + foodElement.style.gridRowStart = food.y; + foodElement.style.gridColumnStart = food.x; + foodElement.classList.add('food'); + board.appendChild(foodElement); +} + +// Main logic starts here +let hiscore = localStorage.getItem("hiscore"); +if (hiscore === null) { + hiscoreval = 0; + localStorage.setItem("hiscore", JSON.stringify(hiscoreval)); +} else { + hiscoreval = JSON.parse(hiscore); + hiscoreBox.innerHTML = "Hi Score: " + hiscore; +} + +window.requestAnimationFrame(main); +window.addEventListener('keydown', e => { + inputDir = { x: 0, y: 1 }; + moveSound.play(); + switch (e.key) { + case "ArrowUp": + console.log(e.key); + inputDir.x = 0; + inputDir.y = -1; + break; + case "ArrowDown": + console.log(e.key); + inputDir.x = 0; + inputDir.y = 1; + break; + case "ArrowLeft": + console.log(e.key); + inputDir.x = -1; + inputDir.y = 0; + break; + case "ArrowRight": + console.log(e.key); + inputDir.x = 1; + inputDir.y = 0; + break; + default: + break; + } +}); \ No newline at end of file diff --git a/38 - Snake-Game/style.css b/38 - Snake-Game/style.css new file mode 100644 index 00000000..24ac003b --- /dev/null +++ b/38 - Snake-Game/style.css @@ -0,0 +1,108 @@ +@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap'); +* { + padding: 0; + margin: 0; +} + +body { + overflow: hidden; + background: #19172e; + font-size: 40px; + } + +.main { + background: #614385; + background: -webkit-linear-gradient(to right, #516395, #614385); + background: linear-gradient(to right, #516395, #614385); + background-repeat: no-repeat; + align-items: center; + justify-content: center; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: block; +} + +.content { + width: 300px; + height: 365px; + padding-top: 8px; +} +h1 { + color: #fff; + text-align: center; + position: absolute; + left: 0; + right: 0; + top: 30px; + padding-top: 10px; + font-size: 2rem !important; + } + +#board { + background-color: #260e44; + width: 260px; + height: 285px; + border: 4px solid white; + border-radius: 4px; + display: grid; + grid-template-rows: repeat(18, 1fr); + grid-template-columns: repeat(18, 1fr); + box-shadow: rgba(0, 0, 0, 0.56) 0px 22px 70px 4px; + margin-left: 18px; + margin-top:5px; + +} + +#scoreBox { + position: absolute; + font-size: 14px; + color: white; + bottom: 11%; + left: 30%; + font-family: 'Press Start 2P', cursive; +} + +#hiscoreBox { + position: absolute; + font-size: 14px; + color: white; + bottom: 5%; + left: 16%; + font-family: 'Press Start 2P', cursive; +} + + +.head { + background: yellow; + border: 2px solid rgb(26, 1, 26); + transform: scale(1.02); + border-radius: 9px; +} + +.snake { + background-color: rgb(0, 225, 255); +} + +.food { + background: red; + border: .25vmin solid black; + border-radius: 8px; +} + +footer { + text-align: center; + color: white; + font-size: 1rem !important; + position: absolute; + left: 0; + right: 0; + bottom: 0; + margin-bottom: 0; + padding: 5px; + } + + footer a:visited { + color: inherit; + } \ No newline at end of file diff --git a/README.md b/README.md index 4c901385..66443464 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,9 @@ Repo containing all the projects made in 30 Days while completing the 30 Days ## [Day 33 - Feedback UI](https://30daysofjs.netlify.app/33%20-%20feedback%20ui/index.html) ![Feedback UI](https://github.com/swapnilsparsh/30DaysOfJavaScript/blob/master/30DaysOfJavaScript/assets/33.png) + +## [Day 38 - Snake Game](https://30daysofjs.netlify.app/32%20-%20Snake%20Game/index.html) +![Snake Game](https://github.com/swapnilsparsh/30DaysOfJavaScript/blob/master/30DaysOfJavaScript/assets/38.png) ## License This project follows the [MIT License](/LICENSE). diff --git a/index.html b/index.html index ca12171d..dc370dd9 100644 --- a/index.html +++ b/index.html @@ -264,6 +264,13 @@

Rock Paper Scissors Game

Rock Paper Scissors Game + +
+ +

Snake Game

+ Snake Game +
+