diff --git a/bg.png b/bg.png new file mode 100644 index 0000000..929ebbd Binary files /dev/null and b/bg.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..e34005f --- /dev/null +++ b/index.html @@ -0,0 +1,45 @@ + + + + + + Whac-A-Mario + + + + + + + + + + + + + + + + + + + + +
LEADERBOARD
PositionNameScore
+
+

Whac-A-Mario

+

DON'T HIT THE PLANTS!

+ + +

Select Difficulty:

+


+
+
+
Sound Effect from Pixabay.   Website made purely using HTML, CSS, JS.
+ + + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..74e297f --- /dev/null +++ b/script.js @@ -0,0 +1,575 @@ +//FIREBASE PART +// Import the functions you need from the SDKs you need +import { initializeApp } from "https://www.gstatic.com/firebasejs/11.0.0/firebase-app.js"; +import {getDatabase, ref, child, get, set, update, remove} from "https://www.gstatic.com/firebasejs/11.0.0/firebase-database.js"; +// TODO: Add SDKs for Firebase products that you want to use +// https://firebase.google.com/docs/web/setup#available-libraries + +// Your web app's Firebase configuration +// For Firebase JS SDK v7.20.0 and later, measurementId is optional +const firebaseConfig = { + apiKey: "AIzaSyDV-NnEFovGS0OmX6OHHIJaqQczP0nF8Yo", + authDomain: "whac-a-mario.firebaseapp.com", + databaseURL: "https://whac-a-mario-default-rtdb.asia-southeast1.firebasedatabase.app", + projectId: "whac-a-mario", + storageBucket: "whac-a-mario.appspot.com", + messagingSenderId: "38376451619", + appId: "1:38376451619:web:050e9a7e5d9fa01a830b96", + measurementId: "G-PMJZ8H6LMF" +}; + +// Initialize Firebase +const app = initializeApp(firebaseConfig); + +const db = getDatabase(app); +let difficulty = "easy"; + +let name = "" + +function addData(EHS, MHS, HHS, IHS){ + set(ref(db, 'PlayerSet/' + name), { + username: {name}, + easy_HS: {EHS}, + medium_HS: {MHS}, + hard_HS: {HHS}, + imp_HS: {IHS} + }) +} + +const dbRef = ref(db) +let playersList = []; +let count = 1; +const getAllData = function(){ + get(child(dbRef, 'PlayerSet')).then((snapshot)=>{ + playersList = []; + count = 1; + document.getElementById("lbbody").innerHTML = 'LEADERBOARD PositionNameScore' + snapshot.forEach(player => { + playersList.push(player.val()) + }); + if (difficulty == "easy"){ + playersList.forEach(player => { + if (player.easy_HS == null){ + delete playersList[playersList.indexOf(player)] + } + }) + playersList.sort((a, b) => b.easy_HS.EHS - a.easy_HS.EHS) + playersList.forEach(player => { + if (count == 1){ + document.getElementById("lbbody").innerHTML += "🥇"+""+player.username.name+""+player.easy_HS.EHS+"" + }else if (count == 2){ + document.getElementById("lbbody").innerHTML += "🥈"+""+player.username.name+""+player.easy_HS.EHS+"" + }else if (count == 3){ + document.getElementById("lbbody").innerHTML += "🥉"+""+player.username.name+""+player.easy_HS.EHS+"" + }else{ + document.getElementById("lbbody").innerHTML += ""+count.toString()+""+player.username.name+""+player.easy_HS.EHS+"" + } + + count++; + }) + }else if (difficulty == "medium"){ + playersList.forEach(player => { + if (player.medium_HS == null){ + delete playersList[playersList.indexOf(player)] + } + }) + playersList.sort((a, b) => b.medium_HS.MHS - a.medium_HS.MHS) + playersList.forEach(player => { + if (count == 1){ + document.getElementById("lbbody").innerHTML += "🥇"+""+player.username.name+""+player.medium_HS.MHS+"" + }else if (count == 2){ + document.getElementById("lbbody").innerHTML += "🥈"+""+player.username.name+""+player.medium_HS.MHS+"" + }else if (count == 3){ + document.getElementById("lbbody").innerHTML += "🥉"+""+player.username.name+""+player.medium_HS.MHS+"" + }else{ + document.getElementById("lbbody").innerHTML += ""+count.toString()+""+player.username.name+""+player.medium_HS.MHS+"" + } + + count++; + }) + }else if (difficulty == "hard"){ + playersList.forEach(player => { + if (player.hard_HS == null){ + delete playersList[playersList.indexOf(player)] + } + }) + playersList.sort((a, b) => b.hard_HS.HHS - a.hard_HS.HHS) + playersList.forEach(player => { + if (count == 1){ + document.getElementById("lbbody").innerHTML += "🥇"+""+player.username.name+""+player.hard_HS.HHS+"" + }else if (count == 2){ + document.getElementById("lbbody").innerHTML += "🥈"+""+player.username.name+""+player.hard_HS.HHS+"" + }else if (count == 3){ + document.getElementById("lbbody").innerHTML += "🥉"+""+player.username.name+""+player.hard_HS.HHS+"" + }else{ + document.getElementById("lbbody").innerHTML += ""+count.toString()+""+player.username.name+""+player.hard_HS.HHS+"" + } + + count++; + }) + }else if (difficulty == "impossible"){ + playersList.forEach(player => { + if (player.imp_HS == null){ + delete playersList[playersList.indexOf(player)] + } + }) + playersList.sort((a, b) => b.imp_HS.IHS - a.imp_HS.IHS) + playersList.forEach(player => { + if (count == 1){ + document.getElementById("lbbody").innerHTML += "🥇"+""+player.username.name+""+player.imp_HS.IHS+"" + }else if (count == 2){ + document.getElementById("lbbody").innerHTML += "🥈"+""+player.username.name+""+player.imp_HS.IHS+"" + }else if (count == 3){ + document.getElementById("lbbody").innerHTML += "🥉"+""+player.username.name+""+player.imp_HS.IHS+"" + }else{ + document.getElementById("lbbody").innerHTML += ""+count.toString()+""+player.username.name+""+player.imp_HS.IHS+"" + } + + count++; + }) + } + }) +} + +getAllData(); + +function getUsername(){ + if (localStorage.getItem("username") == null){ + return null; + }else{ + name = localStorage.getItem("username"); + document.getElementById("username").style.display = "none"; + document.getElementById("save").style.display = "none"; + document.getElementById("warning").innerText = "Hello " + name + ", REMEMBER, DO NOT HIT THE PLANTS!" + } +} + +getUsername(); + +function saveUsername(){ + get(child(dbRef, 'PlayerSet')).then((snapshot)=>{ + playersList = []; + snapshot.forEach(player => { + playersList.push(player.val()) + }); + try { + playersList.forEach(player => { + if (document.getElementById("username").value == player.username.name.toLowerCase()){ + alert("Username already taken!"); + document.getElementById("username").value = "" + throw new Error ("Break the loop") + }else{ + if (document.getElementById("username").value.length > 15){ + alert("Username is too long!"); + document.getElementById("username").value = "" + throw new Error ("Break the loop") + }else{ + name = document.getElementById("username").value; + localStorage.setItem("username", name); + document.getElementById("warning").innerText = "Hello " + name + ", REMEMBER, DO NOT HIT THE PLANTS!" + document.getElementById("username").style.display = "none"; + document.getElementById("save").style.display = "none"; + } + } + }) + }catch { + return; + } + + }) +} + +document.getElementById("save").addEventListener("click", ()=>{ + saveUsername(); +}) + +let lbHidden = false; +document.getElementById("difficulty").addEventListener('change', ()=>{ + difficulty = document.getElementById("difficulty").value; + getAllData(); + setTimeout(()=>{updateLB();}, 500) +}) +// MAIN GAME + +let currentMoleTile; +let currentPlantTile; +let currentPlantTile2; +let prevnum; +let score = 0; +let easy_highScore = 0; +let medium_highScore = 0; +let hard_highScore = 0; +let impossible_highScore = 0; +let gameOver = false; +const whack_sound = document.getElementById("whack-sound"); +const game_over = document.getElementById("game_over"); +const start_effect = document.getElementById("start-button"); +let mute = true; +let moleInterval; +let plantInterval; +let plantInterval2; +let gameTime; +let countdownInterval; +let second = 60; + +function sound(){ + if (mute){ + mute = false; + document.getElementById("sound-button").className = "fa-solid fa-volume-high"; + }else{ + mute = true; + document.getElementById("sound-button").className = "fa-solid fa-volume-xmark"; + } +} + +document.addEventListener('click', ()=>{ + document.body.style.cursor = "url('hammerup.png'), auto"; + setTimeout(()=>{ + document.body.style.cursor = "url('hammerdown.png'), auto"; + }, '100') +}) + + +document.getElementById("mute").addEventListener("click", ()=>{ + sound(); +}) + +function start(){ + score = 0; + const dropdown = document.getElementById("difficulty"); + difficulty = dropdown.value; + document.getElementById("leaderboard").style.display = "none"; + document.getElementById("start-game").innerHTML = '

High Score: 0

Score: 0

60

' + easy_highScore = localStorage.getItem("easyHS"); + medium_highScore = localStorage.getItem("mediumHS"); + hard_highScore = localStorage.getItem("hardHS"); + impossible_highScore = localStorage.getItem("impossibleHS"); + if (difficulty == "easy"){ + document.getElementById("highScore").innerText = "High Score: " + easy_highScore; + }else if (difficulty == "medium"){ + document.getElementById("highScore").innerText = "High Score: " + medium_highScore; + } + else if (difficulty == "hard"){ + document.getElementById("highScore").innerText = "High Score: " + hard_highScore; + } + else if (difficulty == "impossible"){ + document.getElementById("highScore").innerText = "High Score: " + impossible_highScore; + } + if (mute == false){ + start_effect.play() + } + + setGame(); + countdownInterval = setInterval(()=>{ + second -= 1; + document.getElementById("countdowntimer").innerText = second.toString(); + }, 1000) +} + +document.getElementById("start").addEventListener("click", ()=>{ + if (name == null || name == ""){ + alert("Set Username!") + }else{ + start(); + gameTime = setTimeout(()=>{ + if (difficulty == "easy"){ + document.getElementById("board").innerHTML = "TIME UP!
 Your score was:" + score.toString() + "
High Score: " + easy_highScore + "
"; + }else if (difficulty == "medium"){ + document.getElementById("board").innerHTML = "TIME UP!
 Your score was:" + score.toString() + "
High Score: " + medium_highScore + "
"; + } + else if (difficulty == "hard"){ + document.getElementById("board").innerHTML = "TIME UP!
 Your score was:" + score.toString() + "
High Score: " + hard_highScore + "
"; + } + else if (difficulty == "impossible"){ + document.getElementById("board").innerHTML = "TIME UP!
 Your score was:" + score.toString() + "
High Score: " + impossible_highScore + "
"; + } + document.getElementById("score").style.opacity = "0"; + document.getElementById("highScore").style.opacity = "0"; + if (mute == false){ + game_over.play(); + } + gameOver = true; + clearInterval(moleInterval) + clearInterval(plantInterval) + + document.getElementById("restart").addEventListener("click", ()=>{ + restart(); + }) + + clearInterval(countdownInterval) + }, 60000) + } +}) + +function setGame(){ + + document.getElementById('board').addEventListener('click', ()=>{ + document.getElementById('board').style.cursor = "url('hammerup.png'), auto"; + setTimeout(()=>{ + document.getElementById('board').style.cursor = "url('hammerdown.png'), auto"; + }, '100') + }) + + //setup grid for game board in html, grid is 3x3 + for (let i = 0; i < 9; i++){ + let tile = document.createElement("div"); + tile.id = i.toString(); + tile.addEventListener("click", selectTile); + document.getElementById("board").appendChild(tile); + } + + setMole(); + setPlant(); + clearInterval(plantInterval2) + if (difficulty == "easy"){ + moleInterval = setInterval(setMole, 900); + plantInterval = setInterval(setPlant, 800); + }else if (difficulty == "medium"){ + moleInterval = setInterval(setMole, 650); + plantInterval = setInterval(setPlant, 650); + }else if (difficulty == "hard"){ + setPlant2(); + moleInterval = setInterval(setMole, 600); + plantInterval = setInterval(setPlant, 600); + plantInterval2 = setInterval(setPlant2, 610); + }else if (difficulty == "impossible"){ + setPlant2(); + let randomNumber = Math.floor(Math.random()*301)+200 + moleInterval = setInterval(setMole, randomNumber); + plantInterval2 = setInterval(setPlant2, 400); + plantInterval = setInterval(setPlant, 410); + }else{ + console.log("error") + } +} + +function getRandomTile(){ + let num = Math.floor(Math.random()*9); + + if (num == prevnum){ + if (num > 0){ + num -= 1 + }else{ + num += 1 + } + } + prevnum = num; + return num.toString(); +} + +function setMole(){ + if (gameOver){ + return; + } + + if (currentMoleTile){ + currentMoleTile.innerHTML = ""; + } + + let mole = document.createElement("img"); + mole.src = "montymole.png" + mole.style.zIndex = "2" + + let num = getRandomTile(); + + if (currentPlantTile && currentPlantTile.id == num || currentPlantTile2 && currentPlantTile2.id == num){ + return; + } + + currentMoleTile = document.getElementById(num) + currentMoleTile.appendChild(mole) +} + +function setPlant(){ + if (gameOver){ + return; + } + + if (currentPlantTile){ + currentPlantTile.innerHTML = ""; + } + + let plant = document.createElement("img"); + plant.src = "pirhanaplant.png" + plant.style.zIndex = "2"; + + let num = getRandomTile(); + + if (currentMoleTile && currentMoleTile.id == num || currentPlantTile2 && currentPlantTile2.id == num){ + return; + } + + currentPlantTile = document.getElementById(num); + currentPlantTile.appendChild(plant); +} + +function setPlant2(){ + if (gameOver){ + return; + } + + if (difficulty == "hard" || difficulty == "impossible"){ + if (currentPlantTile2){ + currentPlantTile2.innerHTML = ""; + } + + let plant2 = document.createElement("img"); + plant2.src = "pirhanaplant.png" + plant2.style.zIndex = "2"; + + let num = getRandomTile(); + + if (currentMoleTile && currentMoleTile.id == num || currentPlantTile && currentPlantTile.id == num){ + return; + } + + currentPlantTile2 = document.getElementById(num); + currentPlantTile2.appendChild(plant2);} +} + +function selectTile(){ + if (gameOver){ + return; + } + + + if (this == currentMoleTile){ + if (difficulty == "easy"){ + score += 5 + if (easy_highScore < score){ + easy_highScore = parseInt(score); + localStorage.setItem("easyHS", easy_highScore) + document.getElementById("highScore").innerText = "High Score: " + easy_highScore; + addData(easy_highScore, medium_highScore, hard_highScore, impossible_highScore) + } + }else if (difficulty == "medium"){ + score += 10 + if (medium_highScore < score){ + medium_highScore = parseInt(score); + localStorage.setItem("mediumHS", medium_highScore) + document.getElementById("highScore").innerText = "High Score: " + medium_highScore; + addData(easy_highScore, medium_highScore, hard_highScore, impossible_highScore) + } + } + else if (difficulty == "hard"){ + score += 10 + if (hard_highScore < score){ + hard_highScore = parseInt(score); + localStorage.setItem("hardHS", hard_highScore) + document.getElementById("highScore").innerText = "High Score: " + hard_highScore; + addData(easy_highScore, medium_highScore, hard_highScore, impossible_highScore) + } + } + else if (difficulty == "impossible"){ + score += 15 + if (impossible_highScore < score){ + impossible_highScore = parseInt(score); + localStorage.setItem("impossibleHS", impossible_highScore) + document.getElementById("highScore").innerText = "High Score: " + impossible_highScore; + addData(easy_highScore, medium_highScore, hard_highScore, impossible_highScore) + } + } + if (mute == false){ + whack_sound.play(); + } + document.getElementById("score").innerText = "Score: " + score.toString(); + setMole(); + currentMoleTile.innerHTML = ""; + if (difficulty == "impossible"){ + clearInterval(moleInterval); + let randomNumber = Math.floor(Math.random()*301)+200 + moleInterval = setInterval(setMole, randomNumber); + } + } + else if (this == currentPlantTile || this == currentPlantTile2){ + clearTimeout(gameTime) + if (difficulty == "easy"){ + document.getElementById("board").innerHTML = "GAME OVER!
 Your score was:" + score.toString() + "
High Score: " + easy_highScore + "
"; + }else if (difficulty == "medium"){ + document.getElementById("board").innerHTML = "GAME OVER!
 Your score was:" + score.toString() + "
High Score: " + medium_highScore + "
"; + } + else if (difficulty == "hard"){ + document.getElementById("board").innerHTML = "GAME OVER!
 Your score was:" + score.toString() + "
High Score: " + hard_highScore + "
"; + } + else if (difficulty == "impossible"){ + document.getElementById("board").innerHTML = "GAME OVER!
 Your score was:" + score.toString() + "
High Score: " + impossible_highScore + "
"; + } + document.getElementById("score").style.opacity = "0"; + document.getElementById("highScore").style.opacity = "0"; + if (mute == false){ + game_over.play(); + } + gameOver = true; + clearInterval(moleInterval) + clearInterval(plantInterval) + + document.getElementById("restart").addEventListener("click", ()=>{ + restart(); + }) + + clearInterval(countdownInterval) + } +} + +function restart(){ + score = 0; + second = 60; + gameOver = false; + difficulty = "easy"; + document.getElementById("leaderboard").style.display = "block"; + document.getElementById("score").style.opacity = "1"; + document.getElementById("highScore").style.opacity = "1"; + document.getElementById("start-game").innerHTML = '

Whac-A-Mario

HELLO ' + name + ', DONT HIT THE PLANTS!

Select Difficulty:






'; + + document.getElementById("start").addEventListener("click", ()=>{ + start(); + }) + + getAllData(); + document.getElementById("difficulty").addEventListener('change', ()=>{ + difficulty = document.getElementById("difficulty").value; + getAllData(); + }) +} + +//leaderboard + +function updateLB(){ + document.getElementById("lbheading").addEventListener('click', ()=>{ + if (lbHidden){ + document.getElementById("lbheading").innerHTML = 'LEADERBOARD ' + lbHidden = false; + const lb = Array.from(document.getElementById("leaderboard").childNodes[1].children) + lb.splice(0,1) + function setupLeaderboard(){ + lb.forEach(row => { + row.id = "unhidden"; + }) + } + + setupLeaderboard(); + }else{ + document.getElementById("lbheading").innerHTML = 'LEADERBOARD ' + lbHidden = true; + const lb = Array.from(document.getElementById("leaderboard").childNodes[1].children) + lb.splice(0,1) + function setupLeaderboard(){ + lb.forEach(row => { + row.id = "hidden"; + }) + } + + setupLeaderboard(); + } + }) +} +if (window.innerWidth < 769){ + alert("Play on desktop for better gameplay") + setTimeout(()=>{ + updateLB(); + }, 1000) +}else{ + setTimeout(()=>{ + updateLB(); + }, 1000) +} \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..f6ef0f5 --- /dev/null +++ b/style.css @@ -0,0 +1,248 @@ +@import url('https://fonts.googleapis.com/css2?family=Tiny5&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400..900&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400..900&family=Silkscreen:wght@400;700&display=swap'); +@font-face { + font-family: 'SuperMario256'; + src: url('SuperMario256.ttf'); + } + +body{ + font-family: "Silkscreen", sans-serif; + background: url("bg.png") no-repeat no-repeat; + background-size: cover; + text-align: center; + overflow-x: hidden; + overflow-y: hidden; + cursor: url('hammerdown.png'), auto; + user-select: none; +} + +#start{ + padding: 20px; + font-size: 40px; + background-color: gold; + color: white; + font-family: "Silkscreen", sans-serif; + border: 12px ridge green; + border-radius: 15px; + cursor: url('hammerdown.png'), auto; +} + +#save{ + padding: 10px; + font-size: 20px; + background-color: gold; + color: white; + font-family: "Silkscreen", sans-serif; + border: 8px ridge green; + border-radius: 15px; + cursor: url('hammerdown.png'), auto; +} + +@keyframes float-in{ + from{ + transform: translateY(-100%); + } + to{ + transform: translateY(0%); + } +} + +#title{ + font-family: 'SuperMario256'; + margin-top: 0; + padding: 0; + color: rgb(210, 28, 28); + font-size: 4rem; +} + +#start-game{ + margin: 0; + padding: 0; + animation: float-in ease-in-out 2s; +} + +#hs-span{ + padding: 0; + left: 0.5rem; + top: 0; + position: absolute; + width: 100%; + height: fit-content; + text-align: left; +} + +#highScore{ + padding: 0; + top: 0; + color: rgb(17, 115, 59); +} + +#score{ + position: absolute; + top: 2rem; + padding: 0; + color: gold; +} + +#countdowntimer{ + position: absolute; + top: 2rem; + padding: 0; + color: gold; + font-size: 60px; +} + +#board{ + width: 540px; + height: 540px; + background-image: url("soil.png"); + background-size: cover; + border: 3px ridge white; + border-radius: 25px; + + margin: 0 auto; + top: 0; + display: flex; + flex-wrap: wrap; + + align-items: center; + color: rgb(223, 96, 96); + font-size: 3.5rem; +} + +#board div{ + margin: 0; + width: 180px; + height: 180px; + background-image: url("pipe.png"); + background-size: cover; +} + +#board div img{ + width: 100px; + height: 100px; + + user-select: none; + -moz-user-select: none; + -webkit-user-drag: none; + -webkit-user-select: none; + -ms-user-select: none; +} + +#board button{ + width: 70%; + height: fit-content; + padding: 1rem; + margin-left: 81px; + + color: white; + font-size: 40px; + background-color: green; + font-family: "Silkscreen", sans-serif; + border: 7px ridge darkgreen; + border-radius: 30px; + + cursor: url('hammerdown.png'), auto; +} + +#board:hover{ + cursor: url('hammerdown.png'), auto; +} + +#difficulty-label{ + font-family: "Orbitron", sans-serif; + font-size: 25px; + color: #7851A9; +} + +#difficulty{ + font-size: 25px; + padding: 10px; + background-color: gold; + color: white; + font-family: "Orbitron", sans-serif; + border: 10px ridge green; + border-radius: 15px; + appearance: none; +} + +#mute{ + position: absolute; + font-size: 30px; + top:5px; + right:0; + left: 72rem; + bottom:0; + width: 70px; + height: 70px; + border: 5px ridge green; + border-radius: 30px; + background-color: yellow; + cursor: pointer; + z-index: 5; +} + +@keyframes animText { + from { + transform: translateX(-100%); + } + + to{ + transform: translateX(100%); + } + } + +#username{ + padding: 15px; + font-family: "Orbitron", sans-serif; + width: 35%; + position: relative; +} + +#leaderboard{ + position: absolute; + padding:0; + border-collapse: collapse; + table-layout: fixed; +} + +#leaderboard > tbody{ + display: block; + height: 25rem; + width: fit-content; + overflow: auto; +} + +tr:first-child{ + cursor: pointer; +} + +td{ + padding: 5px; + font-size: 15px; + border: 3px solid red; + width: 2rem; +} +th{ + padding: 5px; + font-size: 17px; + border: 3px solid black; +} + +tr:nth-child(even){ + background-color: azure; +} + +tr:nth-child(odd){ + background-color: gold; +} + +#hidden { + display: none; +} + +#scrollable{ + overflow:scroll; + height:100px; +} \ No newline at end of file