diff --git a/01-Candy-Crush-Game/index.html b/01-Candy-Crush-Game/index.html index 20454e5..f9eea7a 100644 --- a/01-Candy-Crush-Game/index.html +++ b/01-Candy-Crush-Game/index.html @@ -19,10 +19,20 @@ + +
+

Choose Game Mode

+ + +
+

score

-

+

0

+
+
+
\ No newline at end of file diff --git a/01-Candy-Crush-Game/script.js b/01-Candy-Crush-Game/script.js index 1267c5e..b0efd72 100644 --- a/01-Candy-Crush-Game/script.js +++ b/01-Candy-Crush-Game/script.js @@ -3,11 +3,23 @@ document.addEventListener("DOMContentLoaded", () => { }); function candyCrushGame() { + // DOM Elements const grid = document.querySelector(".grid"); const scoreDisplay = document.getElementById("score"); + const timerDisplay = document.getElementById("timer"); + const modeSelection = document.getElementById("modeSelection"); + const endlessButton = document.getElementById("endlessMode"); + const timedButton = document.getElementById("timedMode"); + const changeModeButton = document.getElementById("changeMode"); + + // Game State Variables const width = 8; const squares = []; let score = 0; + let currentMode = null; + let timeLeft = 0; + let gameInterval = null; + let timerInterval = null; const candyColors = [ "url(https://raw.githubusercontent.com/arpit456jain/Amazing-Js-Projects/master/Candy%20Crush/utils/red-candy.png)", @@ -18,8 +30,10 @@ function candyCrushGame() { "url(https://raw.githubusercontent.com/arpit456jain/Amazing-Js-Projects/master/Candy%20Crush/utils/purple-candy.png)", ]; - // Creating Game Board + // Create the Game Board function createBoard() { + grid.innerHTML = ""; // Clear existing grid + squares.length = 0; // Clear squares array for (let i = 0; i < width * width; i++) { const square = document.createElement("div"); square.setAttribute("draggable", true); @@ -29,32 +43,21 @@ function candyCrushGame() { grid.appendChild(square); squares.push(square); } + // Add drag event listeners + squares.forEach(square => square.addEventListener("dragstart", dragStart)); + squares.forEach(square => square.addEventListener("dragend", dragEnd)); + squares.forEach(square => square.addEventListener("dragover", dragOver)); + squares.forEach(square => square.addEventListener("dragenter", dragEnter)); + squares.forEach(square => square.addEventListener("dragleave", dragLeave)); + squares.forEach(square => square.addEventListener("drop", dragDrop)); } - createBoard(); - - // Dragging the Candy - let colorBeingDragged; - let colorBeingReplaced; - let squareIdBeingDragged; - let squareIdBeingReplaced; - squares.forEach((square) => - square.addEventListener("dragstart", dragStart) - ); - squares.forEach((square) => square.addEventListener("dragend", dragEnd)); - squares.forEach((square) => square.addEventListener("dragover", dragOver)); - squares.forEach((square) => - square.addEventListener("dragenter", dragEnter) - ); - squares.forEach((square) => - square.addEventListener("drageleave", dragLeave) - ); - squares.forEach((square) => square.addEventListener("drop", dragDrop)); + // Drag and Drop Functions + let colorBeingDragged, colorBeingReplaced, squareIdBeingDragged, squareIdBeingReplaced; function dragStart() { colorBeingDragged = this.style.backgroundImage; squareIdBeingDragged = parseInt(this.id); - // this.style.backgroundImage = '' } function dragOver(e) { @@ -66,20 +69,18 @@ function candyCrushGame() { } function dragLeave() { - this.style.backgroundImage = ""; + // No action needed } function dragDrop() { colorBeingReplaced = this.style.backgroundImage; squareIdBeingReplaced = parseInt(this.id); this.style.backgroundImage = colorBeingDragged; - squares[ - squareIdBeingDragged - ].style.backgroundImage = colorBeingReplaced; + squares[squareIdBeingDragged].style.backgroundImage = colorBeingReplaced; } function dragEnd() { - //Defining, What is a valid move? + // Define valid moves (adjacent squares: left, up, right, down) let validMoves = [ squareIdBeingDragged - 1, squareIdBeingDragged - width, @@ -89,186 +90,157 @@ function candyCrushGame() { let validMove = validMoves.includes(squareIdBeingReplaced); if (squareIdBeingReplaced && validMove) { - squareIdBeingReplaced = null; + squareIdBeingReplaced = null; // Move is valid, keep the swap } else if (squareIdBeingReplaced && !validMove) { - squares[ - squareIdBeingReplaced - ].style.backgroundImage = colorBeingReplaced; - squares[ - squareIdBeingDragged - ].style.backgroundImage = colorBeingDragged; - } else - squares[ - squareIdBeingDragged - ].style.backgroundImage = colorBeingDragged; + // Invalid move, revert the swap + squares[squareIdBeingReplaced].style.backgroundImage = colorBeingReplaced; + squares[squareIdBeingDragged].style.backgroundImage = colorBeingDragged; + } else { + // No drop occurred, revert to original + squares[squareIdBeingDragged].style.backgroundImage = colorBeingDragged; + } } - //Dropping candies once some have been cleared + // Move Candies Down function moveIntoSquareBelow() { - for (i = 0; i < 55; i++) { + // Fill empty squares in the first row + for (let i = 0; i < width; i++) { + if (squares[i].style.backgroundImage === "") { + let randomColor = Math.floor(Math.random() * candyColors.length); + squares[i].style.backgroundImage = candyColors[randomColor]; + } + } + // Move candies down to fill gaps + for (let i = 0; i < width * (width - 1); i++) { if (squares[i + width].style.backgroundImage === "") { - squares[i + width].style.backgroundImage = - squares[i].style.backgroundImage; + squares[i + width].style.backgroundImage = squares[i].style.backgroundImage; squares[i].style.backgroundImage = ""; - const firstRow = [0, 1, 2, 3, 4, 5, 6, 7]; - const isFirstRow = firstRow.includes(i); - if (isFirstRow && squares[i].style.backgroundImage === "") { - let randomColor = Math.floor( - Math.random() * candyColors.length - ); - squares[i].style.backgroundImage = candyColors[randomColor]; - } } } } - ///-> Checking for Matches <-/// - - //For Row of Four + // Check for Matches function checkRowForFour() { - for (i = 0; i < 60; i++) { + for (let i = 0; i < 60; i++) { + if (i % width >= width - 3) continue; // Skip if not enough columns left let rowOfFour = [i, i + 1, i + 2, i + 3]; let decidedColor = squares[i].style.backgroundImage; const isBlank = squares[i].style.backgroundImage === ""; - - const notValid = [ - 5, - 6, - 7, - 13, - 14, - 15, - 21, - 22, - 23, - 29, - 30, - 31, - 37, - 38, - 39, - 45, - 46, - 47, - 53, - 54, - 55 - ]; - if (notValid.includes(i)) continue; - - if ( - rowOfFour.every( - (index) => - squares[index].style.backgroundImage === decidedColor && - !isBlank - ) - ) { + if (rowOfFour.every(index => squares[index].style.backgroundImage === decidedColor && !isBlank)) { score += 4; scoreDisplay.innerHTML = score; - rowOfFour.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + rowOfFour.forEach(index => squares[index].style.backgroundImage = ""); } } } - checkRowForFour(); - //For Column of Four function checkColumnForFour() { - for (i = 0; i < 39; i++) { - let columnOfFour = [i, i + width, i + width * 2, i + width * 3]; + for (let i = 0; i < 40; i++) { + let columnOfFour = [i, i + width, i + 2 * width, i + 3 * width]; let decidedColor = squares[i].style.backgroundImage; const isBlank = squares[i].style.backgroundImage === ""; - - if ( - columnOfFour.every( - (index) => - squares[index].style.backgroundImage === decidedColor && - !isBlank - ) - ) { + if (columnOfFour.every(index => squares[index].style.backgroundImage === decidedColor && !isBlank)) { score += 4; scoreDisplay.innerHTML = score; - columnOfFour.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + columnOfFour.forEach(index => squares[index].style.backgroundImage = ""); } } } - checkColumnForFour(); - //For Row of Three function checkRowForThree() { - for (i = 0; i < 61; i++) { + for (let i = 0; i < 62; i++) { + if (i % width >= width - 2) continue; // Skip if not enough columns left let rowOfThree = [i, i + 1, i + 2]; let decidedColor = squares[i].style.backgroundImage; const isBlank = squares[i].style.backgroundImage === ""; - - const notValid = [ - 6, - 7, - 14, - 15, - 22, - 23, - 30, - 31, - 38, - 39, - 46, - 47, - 54, - 55 - ]; - if (notValid.includes(i)) continue; - - if ( - rowOfThree.every( - (index) => - squares[index].style.backgroundImage === decidedColor && - !isBlank - ) - ) { + if (rowOfThree.every(index => squares[index].style.backgroundImage === decidedColor && !isBlank)) { score += 3; scoreDisplay.innerHTML = score; - rowOfThree.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + rowOfThree.forEach(index => squares[index].style.backgroundImage = ""); } } } - checkRowForThree(); - //For Column of Three function checkColumnForThree() { - for (i = 0; i < 47; i++) { - let columnOfThree = [i, i + width, i + width * 2]; + for (let i = 0; i < 48; i++) { + let columnOfThree = [i, i + width, i + 2 * width]; let decidedColor = squares[i].style.backgroundImage; const isBlank = squares[i].style.backgroundImage === ""; - - if ( - columnOfThree.every( - (index) => - squares[index].style.backgroundImage === decidedColor && - !isBlank - ) - ) { + if (columnOfThree.every(index => squares[index].style.backgroundImage === decidedColor && !isBlank)) { score += 3; scoreDisplay.innerHTML = score; - columnOfThree.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + columnOfThree.forEach(index => squares[index].style.backgroundImage = ""); } } } - checkColumnForThree(); - - window.setInterval(function () { + // Game Loop + function gameLoop() { checkRowForFour(); checkColumnForFour(); checkRowForThree(); checkColumnForThree(); moveIntoSquareBelow(); - }, 100); + } + + // Start the Game + function startGame(mode) { + currentMode = mode; + modeSelection.style.display = "none"; + grid.style.display = "flex"; + scoreDisplay.parentElement.style.display = "flex"; // Show scoreboard + createBoard(); + score = 0; + scoreDisplay.innerHTML = score; + gameInterval = setInterval(gameLoop, 100); + + if (mode === "timed") { + timeLeft = 120; // 2 minutes in seconds + updateTimerDisplay(); + timerInterval = setInterval(() => { + timeLeft--; + updateTimerDisplay(); + if (timeLeft <= 0) { + clearInterval(timerInterval); + endGame(); + } + }, 1000); + } else { + timerDisplay.innerHTML = ""; // Clear timer in Endless Mode + } + } + + // Update Timer Display + function updateTimerDisplay() { + if (currentMode === "timed") { + let minutes = Math.floor(timeLeft / 60); + let seconds = timeLeft % 60; + timerDisplay.innerHTML = `Time Left: ${minutes}:${seconds.toString().padStart(2, "0")}`; + } else { + timerDisplay.innerHTML = ""; + } + } + + // End Game (Timed Mode) + function endGame() { + clearInterval(gameInterval); + squares.forEach(square => square.setAttribute("draggable", false)); + alert(`Time's Up! Your score is ${score}`); + } + + // Change Mode + function changeMode() { + clearInterval(gameInterval); + if (currentMode === "timed") { + clearInterval(timerInterval); + } + grid.style.display = "none"; + scoreDisplay.parentElement.style.display = "none"; + modeSelection.style.display = "flex"; // Show mode selection screen + } + + // Event Listeners + endlessButton.addEventListener("click", () => startGame("endless")); + timedButton.addEventListener("click", () => startGame("timed")); + changeModeButton.addEventListener("click", changeMode); } \ No newline at end of file diff --git a/01-Candy-Crush-Game/style.css b/01-Candy-Crush-Game/style.css index 1b371c4..31f9e51 100644 --- a/01-Candy-Crush-Game/style.css +++ b/01-Candy-Crush-Game/style.css @@ -1,55 +1,121 @@ +/* General Styling */ +body { + background-image: url('https://raw.githubusercontent.com/arpit456jain/Amazing-Js-Projects/master/Candy%20Crush/utils/bg.png'); + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + font-family: 'Montserrat', sans-serif; + color: #85796b; +} + .grid { - display: flex; - flex-wrap: wrap; - height: 560px; - min-width: 560px; - margin-left: 80px; - margin-top: 50px; - background-color: rgba(109, 127, 151, 0.5); - padding: 5px; - color: #85796b; - border-radius: 10px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5) inset, 0 1px 0 #fff; - } - - .grid div { - height: 70px; - width: 70px; - } - - h3 { - font-family: "Montserrat", sans-serif; - text-transform: uppercase; - } - - h1 { - font-family: "Montserrat", sans-serif; - text-transform: uppercase; - margin-top: -10px; - } - - .invisible { - background-color: white; - } - - body { - background-image: url('https://raw.githubusercontent.com/arpit456jain/Amazing-Js-Projects/master/Candy%20Crush/utils/bg.png'); - max-width: 100vh; - display: flex; - } - - .scoreBoard { - background-color: cyan; - border-radius: 20px; - margin-top: 200px; - margin-left: 200px; - width: auto; - height: 120px; - padding: 20px; - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - text-align: center; - color: #85796b; - } \ No newline at end of file + display: flex; + flex-wrap: wrap; + height: 560px; + width: 560px; + background-color: rgba(109, 127, 151, 0.5); + padding: 5px; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5) inset, 0 1px 0 #fff; + margin-left: 80px; + margin-top: 50px; +} + +.grid div { + height: 70px; + width: 70px; + background-size: cover; + background-position: center; + border-radius: 5px; + transition: transform 0.2s ease; /* Smooth animation for interactions */ +} + +/* Hover effect for interactivity */ +.grid div:hover { + transform: scale(1.05); /* Slightly enlarge on hover */ +} + +/* Scoreboard Styling */ +.scoreBoard { + background-color: cyan; + border-radius: 20px; + margin-top: 200px; + margin-left: 200px; + width: auto; + height: 120px; + padding: 20px; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + text-align: center; + color: #85796b; +} + +h3, h1 { + font-family: 'Montserrat', sans-serif; + text-transform: uppercase; + margin: 0; +} + +h1 { + margin-top: -10px; +} + +.grid div:hover { + transform: scale(1.05); /* Slightly enlarge on hover */ +} + +/* Mode Selection Styling */ +#modeSelection { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + background-color: #f0f0f0; + font-family: 'Montserrat', sans-serif; + position: absolute; + top: 0; + left: 0; + width: 100%; + z-index: 10; +} + +#modeSelection h2 { + margin-bottom: 20px; + color: #333; +} + +#modeSelection button { + margin: 10px; + padding: 10px 20px; + font-size: 16px; + cursor: pointer; + background-color: #87ceeb; + border: none; + border-radius: 5px; + color: white; +} + +/* Timer and Change Mode Button */ +#timer { + font-size: 18px; + margin-top: 10px; +} + +#changeMode { + margin-top: 10px; + padding: 5px 10px; + background-color: #ff6347; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +} + +/* Initially Hide Game Elements */ +.grid, .scoreBoard { + display: none; +} \ No newline at end of file