Untitled
plain_text
2 months ago
23 kB
1
Indexable
Never
document.addEventListener('DOMContentLoaded', () => { var container = document.getElementById("container"); for (var i = 1; i <= 210; i++) { var div = document.createElement("div"); div.textContent = ""; container.appendChild(div); if (i >= 201) { div.classList.add('taken'); } } var nextContainer = document.getElementById("nextContainer"); for (var i = 1; i <= 16; i++) { var divNext = document.createElement("div"); divNext.textContent = ""; nextContainer.appendChild(divNext); } const colors = [ 'orange', 'red', 'purple', 'green', 'blue', 'cyan', 'yellow' ] const grid = document.querySelector('.grid') const scoreDisplay = document.querySelector('#score'); const startBtn = document.querySelector('#start-button'); const restartBtnGameOver = document.querySelector('#over-restart-button'); const restartBtn = document.querySelector('#paused-restart-button'); const submitNameButton = document.getElementById("submit-name-button"); const nameInput = document.getElementById("name-input"); const timercontainer = document.getElementById('timer'); const minutes = document.getElementById('minutes'); const seconds = document.getElementById('seconds'); const finalScoreElement = document.getElementById('final-score'); const continueBtn = document.getElementById('paused-continue-button'); const scoresPerPage = 10; const previousPageBtn = document.getElementById("previous-page-btn"); const nextPageBtn = document.getElementById("next-page-btn"); const width = 10 let squares = Array.from(document.querySelectorAll('.grid div')) let submittedName = ""; let nextRandom = 0 let score = "0" let isGamePaused = true; let newNext = false; let animationFrameId; let timerInterval = 0 let scoreJSON = []; let totalPages = 0; let currentPage = 1; var sec = 0 var scoreJSONlength = 0; const lTetromino = [ [1, width + 1, width * 2 + 1, 2], [width, width + 1, width + 2, width * 2 + 2], [1, width + 1, width * 2 + 1, width * 2], [width, width * 2, width * 2 + 1, width * 2 + 2] ] const reverseLTetromino = [ [0, 1, width + 1, width * 2 + 1], [width, width + 1, width + 2, 2], [1, width + 1, width * 2 + 1, width * 2 + 2], [width, width + 1, width + 2, width * 2] ]; const zTetromino = [ [0, width, width + 1, width * 2 + 1], [width + 1, width + 2, width * 2, width * 2 + 1], [0, width, width + 1, width * 2 + 1], [width + 1, width + 2, width * 2, width * 2 + 1] ] const tTetromino = [ [1, width, width + 1, width + 2], [1, width + 1, width + 2, width * 2 + 1], [width, width + 1, width + 2, width * 2 + 1], [1, width, width + 1, width * 2 + 1] ] const oTetromino = [ [0, 1, width, width + 1], [0, 1, width, width + 1], [0, 1, width, width + 1], [0, 1, width, width + 1] ] const iTetromino = [ [1, width + 1, width * 2 + 1, width * 3 + 1], [width, width + 1, width + 2, width + 3], [1, width + 1, width * 2 + 1, width * 3 + 1], [width, width + 1, width + 2, width + 3] ] const sTetromino = [ [0, 1, width + 1, width + 2], [1, width + 1, width, width * 2], [0, 1, width + 1, width + 2], [1, width + 1, width, width * 2] ]; const tetrominoes = [lTetromino, reverseLTetromino, zTetromino, tTetromino, oTetromino, iTetromino, sTetromino] let currentPosition = 4 let currentRotation = 0 function generateRandom(min = 0, max = 7) { // find diff let difference = max - min; // generate random number let rand = Math.random(); // multiply with difference rand = Math.floor(rand * difference); // add with min value rand = rand + min; return rand; } let x = generateRandom() let current = tetrominoes[x][currentRotation] var jsonData = {}; async function getJSON() { const response = await fetch("http://localhost:8000/displayscore") scoreJSON = await response.json(); scoreJSONlength = scoreJSON.length totalPages = Math.ceil(scoreJSONlength / scoresPerPage); formatJSON(scoreJSON) } function displayScores(page) { const startIndex = (page - 1) * scoresPerPage; // Calculate the start index for the current page const endIndex = startIndex + scoresPerPage; // Calculate the end index for the current page const currentPageScores = scoreJSON.slice(startIndex, endIndex); // Get the scores for the current page getJSON(currentPageScores); // Display the scores on the page } previousPageBtn.addEventListener('click', () => { if (currentPage > 1) { currentPage--; // Update current page displayScores(currentPage); // Display scores for the updated page updatePaginationButtons(); // Update pagination buttons } }); // Event listener for next page button nextPageBtn.addEventListener('click', () => { if (currentPage < totalPages) { currentPage++; // Update current page displayScores(currentPage); // Display scores for the updated page updatePaginationButtons(); // Update pagination buttons } }); // Display scores for the initial page displayScores(currentPage); updatePaginationButtons(); function updatePaginationButtons() { // Enable/disable previous page button based on the current page if (currentPage === 1) { previousPageBtn.disabled = true; } else { previousPageBtn.disabled = false; } // Enable/disable next page button based on the current page if (currentPage === totalPages) { nextPageBtn.disabled = true; } else { nextPageBtn.disabled = false; } } function formatJSON(scoreJSON) { // Calculate the start and end indices of the scores to display based on the current page const startIndex = (currentPage - 1) * scoresPerPage; const endIndex = startIndex + scoresPerPage; var tableBody = document.getElementById("table_body"); tableBody.innerHTML = ""; // Clear the previous content of the table body // Sort the scores based on score and time scoreJSON.sort((a, b) => { if (a.Score === b.Score) { // If scores are equal, compare the times return a.Time.localeCompare(b.Time); } // Sort by score in descending order return b.Score - a.Score; }); // Iterate over the scores within the current page range and create table rows for (var j = startIndex; j < Math.min(endIndex, scoreJSON.length); j++) { var score = scoreJSON[j]; // Create a row for each score var row = document.createElement("tr"); // Create cells for each property of the score var rankCell = document.createElement("td"); rankCell.textContent = score.Rank; var nameCell = document.createElement("td"); nameCell.textContent = score.Name; var scoreCell = document.createElement("td"); scoreCell.textContent = score.Score; var timeCell = document.createElement("td"); timeCell.textContent = score.Time; // Append cells to the row row.appendChild(rankCell); row.appendChild(nameCell); row.appendChild(scoreCell); row.appendChild(timeCell); // Append the row to the table body tableBody.appendChild(row); var rows = tableBody.getElementsByTagName("tr"); for (var i = 0; i < rows.length; i++) { rows[i].getElementsByTagName("td")[0].textContent = startIndex + i + 1; } } } submitNameButton.addEventListener("click", async (event) => { event.preventDefault(); const name = nameInput.value.trim(); if (name !== "") { const jsonData = {}; // Declare jsonData locally submittedName = name; nameInput.disabled = true; submitNameButton.disabled = true; jsonData.ID = (scoreJSONlength + 2).toString(); jsonData.Rank = scoreJSONlength + 2; jsonData.Name = submittedName; jsonData.Score = score; jsonData.Time = minutes.innerHTML + seconds.innerHTML; console.log(jsonData); // Call the function to submit the JSON data await submitJSON(jsonData); // Pass the jsonData to the submitJSON function } }); async function submitJSON(data) { const url = "http://localhost:8000/submitscore"; const fetchOptions = { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }; console.log(fetchOptions.body); console.log(jsonData); try { const response = await fetch(url, fetchOptions); const result = await response.json(); console.log(result); } catch (error) { console.error("Error submitting JSON:", error); } getJSON(); } function draw() { undraw(); current.forEach(index => { squares[currentPosition + index].classList.add('tetromino') squares[currentPosition + index].style.backgroundColor = colors[x] }) } //undraw the Tetromino function undraw() { current.forEach(index => { squares[currentPosition + index].classList.remove('tetromino') squares[currentPosition + index].style.backgroundColor = '' }) } /* setInterval(moveDown, 500) */ function moveDown() { if (isGamePaused) return; if (!current.some(index => squares[currentPosition + index + width].classList.contains('taken'))) { undraw(); currentPosition += width; draw(); } else { // Check the top rows before freezing the tetromino freeze(); checkTopRows(); } } function freeze() { if (current.some(index => { const nextPosition = currentPosition + index + width; return squares[nextPosition].classList.contains('taken'); })) { current.forEach(index => squares[currentPosition + index].classList.add('taken')); x = nextRandom nextRandom = generateRandom() currentRotation = 0; current = tetrominoes[x][currentRotation]; currentPosition = 4; addScore() draw(); newNext = false; if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) { gameOver(); } else { displayNext(); } } } function moveLeft() { if (isGamePaused) return; undraw(); if (!current.some(index => (currentPosition + index) % width === 0) && !current.some(index => squares[currentPosition + index - 1].classList.contains('taken'))) { currentPosition -= 1; } draw(); } function moveRight() { if (isGamePaused) return; undraw(); if (!current.some(index => (currentPosition + index) % width === width - 1) && !current.some(index => squares[currentPosition + index + 1].classList.contains('taken'))) { currentPosition += 1; } draw(); } function rotate() { if (isGamePaused) return; undraw(); const nextRotation = (currentRotation + 1) % current.length; // Calculate the next rotation index // Create a temporary copy of the tetromino with the next rotation const tempTetromino = tetrominoes[x][nextRotation]; let tempPosition = currentPosition; checkRotatedPosition(tempPosition, nextRotation); // Check if the temporary tetromino position is valid if (!tempTetromino.some(index => { const nextPosition = currentPosition + index; return ( nextPosition < 0 || // Check if it's out of bounds on the left side nextPosition >= squares.length || // Check if it's out of bounds on the right side squares[nextPosition].classList.contains('taken') // Check if it collides with a taken cell ); })) { currentRotation = nextRotation; current = tempTetromino; } draw(); freeze(); } const displaySquares = document.querySelectorAll('.nextUp div') const displayWidth = 4 let displayIndex = 0 // Järjekord loeb const upNextTetrominoes = [ [1, displayWidth + 1, displayWidth * 2 + 1, 2], [0, 1, displayWidth + 1, displayWidth * 2 + 1], [0, displayWidth, displayWidth + 1, displayWidth * 2 + 1], [1, displayWidth, displayWidth + 1, displayWidth + 2], [0, 1, displayWidth, displayWidth + 1], [1, displayWidth + 1, displayWidth * 2 + 1, displayWidth * 3 + 1], [0, 1, displayWidth + 1, displayWidth + 2] ] function displayNext() { if (!newNext) { displaySquares.forEach(square => { square.classList.remove('tetromino') square.style.backgroundColor = '' }) upNextTetrominoes[nextRandom].forEach(index => { displaySquares[displayIndex + index].classList.add('tetromino') displaySquares[displayIndex + index].style.backgroundColor = colors[nextRandom] }) newNext = true; } } let animationTimeout; let gameStart = true; function debounce(delay, func) { let timeoutId; return function (...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; } function clearAnimationTimeout() { clearTimeout(animationTimeout); animationTimeout = null; } function startBtnClick() { // Pausing the game if (animationFrameId) { cancelAnimationFrame(animationFrameId); animationFrameId = null; clearAnimationTimeout(); isGamePaused = true; document.getElementById('paused').style.display = 'block'; document.getElementById('start-button').style.display = 'none'; } else { if (gameStart) { // Starts the countdown for the game when it is first run gameStart = false; document.getElementById('paused').style.display = 'block'; countDownUnpause(); } else { // Start the countdown on when unpausing countDownUnpause(); } } } function countDownUnpause() { let count = 3; const countdownTimer = document.getElementById('countdownTimer'); const countdownContainer = document.getElementById('countdownContainer'); const pauseContainer = document.getElementById('pauseContainer'); countdownContainer.style.display = 'flex'; pauseContainer.style.display = 'none'; const countdownInterval = setInterval(() => { count--; countdownTimer.innerHTML = count; if (count === 0) { clearInterval(countdownInterval); countdownContainer.style.display = 'none'; pauseContainer.style.display = 'block'; startGameLoop(); firstClick = false; document.getElementById('start-button').style.display = 'block'; // Reset the firstClick flag after the countdown finishes } }, 1000); } function startGameLoop() { isGamePaused = false; document.getElementById("countdownTimer").innerHTML = "3"; // Other game setup code timer(); //draw(); document.getElementById('paused').style.display = 'none'; document.getElementById('timer').style.display = 'block'; // Show the timer nextRandom = generateRandom(); displayNext(); // Show the next tetromino immediately let previousTimestamp = 0; animationFrameId = requestAnimationFrame((timestamp) => moveDownLoop(timestamp, previousTimestamp) ); } // Add a debounced version of the startBtnClick function const debouncedStartBtnClick = debounce(400, startBtnClick); startBtn.addEventListener('click', debouncedStartBtnClick); continueBtn.addEventListener('click', debouncedStartBtnClick); function moveDownLoop(timestamp, previousTimestamp) { if (!isGamePaused) { if (timestamp - previousTimestamp >= 500) { // Adjust the delay duration here (in milliseconds) moveDown(); draw(); previousTimestamp = timestamp; } animationFrameId = requestAnimationFrame(newTimestamp => moveDownLoop(newTimestamp, previousTimestamp)); } } timercontainer.style.display = 'block'; // Show the timer seconds.innerHTML = '00'; minutes.innerHTML = '00:'; scoreDisplay.innerHTML = '0'; function timer() { clearInterval(timerInterval); function pad(val) { return val > 9 ? val : "0" + val; } document.getElementById("seconds").innerHTML = pad(sec % 60); document.getElementById("minutes").innerHTML = pad(parseInt(sec / 60, 10)) + ":"; timerInterval = setInterval(function () { if (!isGamePaused) { document.getElementById("seconds").innerHTML = pad(++sec % 60); document.getElementById("minutes").innerHTML = pad(parseInt(sec / 60, 10)) + ":"; } }, 1000); } function gameOver() { if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) { scoreDisplay.innerHTML = 'Game Over' getJSON(); finalScoreElement.innerHTML += score cancelAnimationFrame(animationFrameId) document.getElementById('game-over').style.display = 'block'; document.getElementById('start-button').style.display = 'none'; isGamePaused = true; for (let i = 0; i < squares.length - width; i++) { squares[i].classList.remove('tetromino'); squares[i].classList.remove('taken'); squares[i].style.backgroundColor = '' } displaySquares.forEach(square => { square.classList.remove('tetromino') square.style.backgroundColor = '' }) } } restartBtnGameOver.addEventListener('click', restartGame); restartBtn.addEventListener('click', restartGame); function restartGame() { Restarter(); newNext = false; document.getElementById('start-button').style.display = 'block'; } function Restarter() { currentPage = 1; updatePaginationButtons(); nameInput.disabled = false; submitNameButton.disabled = false; score = 0; sec = 0; minutes.innerHTML = "00:"; seconds.innerHTML = "00"; finalScoreElement.innerHTML = "Final Score: "; for (let i = 0; i < squares.length - width; i++) { squares[i].classList.remove('tetromino'); squares[i].classList.remove('taken'); squares[i].style.backgroundColor = '' document.getElementById('paused').style.display = 'none'; document.getElementById('game-over').style.display = 'none'; startBtn.addEventListener('click', debouncedStartBtnClick); gameStart = true; } score = 0; scoreDisplay.textContent = score; currentPosition = 4; currentRotation = 0; x = generateRandom(); current = tetrominoes[x][currentRotation]; isGamePaused = true; cancelAnimationFrame(animationFrameId); animationFrameId = null; } function isAtRight() { return current.some(index => (currentPosition + index + 1) % width === 0) } function isAtLeft() { return current.some(index => (currentPosition + index) % width === 0) } function checkRotatedPosition(P, rotation) { P = currentPosition; // Assign the current position to P const currentWidth = current.some(index => (P + index) % width === 0); // Calculate the width of the rotated tetromino const rotatedWidth = tetrominoes[x][rotation].some(index => (P + index) % width === 0); // Check if the tetromino is too close to the left or right edge after rotation if (current.some(index => (P + index + 1) % width === 0)) { if (isAtRight() && rotatedWidth) { currentPosition -= 1; } } else if (current.some(index => (P + index) % width === width - 1)) { if (isAtLeft() && rotatedWidth) { currentPosition += 1; } } else if (current.some(index => (P + index) % width === 0)) { if (isAtRight() && rotatedWidth) { currentPosition -= 1; } else if (isAtLeft() && rotatedWidth) { currentPosition += 1; } } // Check if the rotated tetromino overlaps with a taken cell const tempTetromino = tetrominoes[x][rotation]; const tempPosition = currentPosition; let overlapsTakenCell = false; tempTetromino.forEach(index => { const nextPosition = tempPosition + index; if ( nextPosition < 0 || nextPosition >= squares.length || squares[nextPosition].classList.contains('taken') ) { overlapsTakenCell = true; } }); // If there's an overlap, shift the tetromino back toward the wall if (overlapsTakenCell) { if (rotatedWidth) { currentPosition -= 1; } else { currentPosition += 1; } } } function checkTopRows() { for (let row = 0; row <= 2; row++) { for (let col = 3; col <= 5; col++) { const index = row * 10 + col; if (squares[index].classList.contains('taken')) { // The specified rows and cells have taken cells, game over or other action can be taken // ... return true; // Exit the function if any taken cell is found } } } return false; // The top rows are clear, another tetromino can be placed there // ... } setInterval(checkTopRows, 1000); function addScore() { let counter = 0; let currentScore = 0; for (let i = 0; i < 199; i += width) { const row = [i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9]; if (row.every(index => squares[index].classList.contains('taken'))) { counter++; row.forEach(index => { squares[index].classList.remove('taken'); squares[index].classList.remove('tetromino'); squares[index].style.backgroundColor = ''; }); currentScore += 10; const squaresRemoved = squares.splice(i, width); squares = squaresRemoved.concat(squares); squares.forEach(cell => { grid.appendChild(cell); }); } } if (counter === 4) { currentScore *= 2; } if (currentScore !== 0) { score = parseInt(score) + currentScore; } scoreDisplay.innerHTML = parseInt(score); // Convert score to number before displaying } function control(e) { if (e.keyCode === 37) { moveLeft() } else if (e.keyCode === 39) { moveRight() } else if (e.keyCode === 40) { moveDown() } else if (e.keyCode === 38) { rotate() } } document.addEventListener('keydown', control) })