Skip to content

Instantly share code, notes, and snippets.

@batazo
Created June 9, 2022 21:15
Show Gist options
  • Select an option

  • Save batazo/1c3bfc63ba475eb237beb0f4c1d8b899 to your computer and use it in GitHub Desktop.

Select an option

Save batazo/1c3bfc63ba475eb237beb0f4c1d8b899 to your computer and use it in GitHub Desktop.
EASY Tetris - v52-Unpublished
<div class="overlay" id="paneloverlay">
<audio id="myAudio">
<source src="https://bzozoo.github.io/Tetris-Basic/tetrisTheme.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<div id="rewardContainer">
<div id="rewardPicDiv">
</div>
</div>
<div id="gameOverDiv" style="display: none;">
<div id="overScore">0000</div>
</div>
<div class="container">
<div class="grid-bg"></div>
<div class="grid">
</div><!-- GRID DIV END-->
<div class="sidebar">
<div id="scoreBox">
<p>
<strong>
S C O R E
</strong>
</p>
<p id="scoreDisplay">0</p>
</div>
<div class="mini-grid">
<div class="first-in-minirow"></div>
<div><strong>N</strong></div>
<div><strong>E</strong></div>
<div><strong>X</strong></div>
<div><strong>T</strong></div>
<div></div>
<div class="first-in-minirow"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="first-in-minirow"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="first-in-minirow"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="first-in-minirow"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="first-in-minirow"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div id="speedBox">
<strong>SPEED</strong><span id="speedcounter">0</span>
</div>
<div class="actions">
<p>
<button class="actionBtn" id="loginBtn">⚡ LOGIN</button>
<button class="actionBtn hidden" id="profileBtn">👤 PROFILE</button>
</p>
<p>
<button class="actionBtn" id="start-button">▶ START</button>
</p>
<p>
<button class="actionBtn" id="muteButton">🔇 MUTE</button>
</p>
<p>
<button class="actionBtn" id="resetButton">↺ RESET GAME</button>
</p>
<p>
<button class="actionBtn" id="optionsButton">⚙️ OPTIONS</button>
</p>
</div>
</div>
</div>
<div id="logo">
Bzozoo Tetris Basic <span id="version">{{ version }}</span>
</div>
<div class="controlls" id="controllButtonsSection">
<p>
<button class="gombBtn" id="leftMove"> ◄ </button>
<button class="gombBtn" id="rightMove"> ► </button>
<button class="gombBtn" id="downMove">▼</button>
<button class="gombBtn" id="rotation">🔄</button>
</p>
</div>
</div>
<div id="highscore" class="modal hidden flexcolumn">
<div class="navbar">
<div class="title">HIGHSCORE</div>
<div class="navbtns"><button class="actionBtn" id="closeHighScore">X</button></div>
</div>
<div id="highscorecontent" class="panel">
<!-- {{ HIGH SCORE }} -->
</div>
</div>
<div id="userzone" class="modal hidden">
<div class="navbar">
<div class="title">USER ZONE</div>
<div class="navbtns"><button class="actionBtn" id="closeUserZone">X</button></div>
</div>
<div id="login" class="panel">
<!-- {{ IF USER NOT LOGGED IN }} -->
</div>
<div id="usercontainer" class="panel">
<!-- {{ IF USER LOGGED IN }} -->
</div>
</div>
<div id="optionspanel" class="modal hidden">
<div class="navbar">
<div class="title">OPTIONS</div>
<div class="navbtns"><button class="actionBtn" id="closeOPtions">X</button></div>
</div>
<div id="optionscontainer">
<div class="actions">
<p>
<input type="checkbox" name="effect" id="effect" checked /><label for="effect">BOOM EFFECT</label>
</p>
<p>
<input type="checkbox" name="invert" id="invert" /> <label for="invert">INVERT ¿</label>
</p>
<p>
<input type="checkbox" name="reward" id="reward" checked /> <label for="reward">REWARD</label>
</p>
<p>
<input type="checkbox" name="weird" id="weird" /> <label for="weird">WEIRDMOD</label>
</p>
</div>
</div>
</div>
<div id="scoresavedbox" class="modal hidden">
SCORE SAVED
</div>
// IIFE DISABLED (function () {
const application = { name: "TETRIS BASIC", version: "v52-Unpublished" };
const gameSettings = {
host: "https://tetris.ga",
rerenderMode: "onelinebased", // usage: [onelinebased, squarebased, old]
rerenderable: true,
width: 10,
speed: 1,
gridNumbers: 250,
lineNumbers: () => {
return gameSettings.gridNumbers / gameSettings.width;
},
controllButtonsDeactivable: true,
tetrominoDropable: true,
displayWidth: 6,
displayIndex: 1,
boomm:
"https://bzozoo.github.io/Tetris-Basic//images/boomm.gif",
rewardExtraPics: [
"https://i.imgur.com/awaQZST.jpg",
"https://i.imgur.com/psZNoKt.jpg",
"https://i.imgur.com/uCvHYUX.jpg",
"https://i.imgur.com/rW0gv4H.jpg",
"https://i.imgur.com/TpZDy0N.jpg",
"https://i.imgur.com/2EjNoQG.jpg",
"https://i.imgur.com/KBY1sRA.jpg",
"https://i.imgur.com/h8SWCow.jpg",
"https://i.imgur.com/UkUQbSO.jpg",
"https://i.imgur.com/YEcYcxl.jpg",
"https://i.imgur.com/voXqUm3.jpg",
"https://i.imgur.com/cTMV0N2.jpg",
"https://i.imgur.com/QQfe4tR.jpg",
"https://i.imgur.com/eaIsfFZ.jpg",
"https://i.imgur.com/whs4Oze.jpg",
"https://i.imgur.com/5EvLQKA.jpg",
"https://i.imgur.com/XMr4syr.jpg",
"https://i.imgur.com/CuC6EMI.jpg",
"https://i.imgur.com/uw8zEr8.jpg",
"https://i.imgur.com/eUgVtPe.jpg"
]
};
// MAIIN FUNCTION DISABLED main(gameSettings); function main(gameSettings){
const {
host,
rerenderMode,
controllButtonsDeactivable,
gridNumbers,
width,
speed,
displayWidth,
displayIndex,
lineNumbers,
rewardExtraPics,
boomm
} = gameSettings;
console.log("RENDER MODE ::: " + rerenderMode);
//Declare DOM elements
const grid = document.querySelector(".grid");
const miniSquares = Array.from(document.querySelectorAll(".mini-grid div"));
const miniGrid = document.querySelector(".mini-grid");
const startBtn = document.querySelector("#start-button");
const invertCheckBox = document.querySelector("#invert");
const rewardCheckBox = document.querySelector("#reward");
const displaySquares = document.querySelectorAll(".mini-grid div");
const gameTimer = new IntervalEncapsulator(tryFreeze, 500);
const speeder = new IntervalEncapsulator(tryFreeze, 100);
const musicInterval = new IntervalEncapsulator(playMusic, 1);
const run = backcounter(3);
let underEffect = false;
const currents = {
random: null,
nextRandom: 0,
currentPosition: 4,
currentRotation: 0,
nextRotation: this.currentRotation + 1,
current: null,
nextRotatedCurrent: null
};
let {
random,
nextRandom,
currentPosition,
currentRotation,
nextRotation,
current,
nextRotatedCurrent
} = currents;
let score = 0;
//The Tetrominoes
/* lTetronimo is the example *
0 1 2 0 1 2 0 1 2 0 1 2
|--------------------------------
0 | X X X
width | X X X X X X
2 * width | X X X X X X X
*/
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 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]
];
//The Tetrominoes
/* oTetronimo is the example *
0 1 2 0 1 2 0 1 2 0 1 2
|--------------------------------
0 |X X X X X X X X
width |X X X X X X X X
2 * width |
*/
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 - 1, width, width + 1, width + 2],
[1, width + 1, width * 2 + 1, width * 3 + 1],
[width - 1, width, width + 1, width + 2]
];
const liTetromino = [
[0, 1, width + 1, width * 2 + 1],
[2, width, width + 1, width + 2],
[0, width, width * 2, width * 2 + 1],
[0, 1, 2, width]
];
const ziTetromino = [
[1, width, width + 1, width * 2],
[0, 1, width + 1, width + 2],
[1, width, width + 1, width * 2],
[0, 1, width + 1, width + 2]
];
//Tetromino pair with colors arrays
const theTetrominoes = [
lTetromino,
zTetromino,
tTetromino,
oTetromino,
iTetromino,
liTetromino,
ziTetromino
];
const tetrominoNames = ["L", "Z", "T", "O", "I", "L-INVERT", "Z-INVERT"];
const colors = [
"orange",
"red",
"purple",
"green",
"blue",
"brown",
"turquoise"
];
//the Tetrominos without rotations
const upNextTetrominoes = [
[
2 * displayWidth + 1,
2 * displayWidth + 2,
3 * displayWidth + 1,
4 * displayWidth + 1
], //lTetromino
[
2 * displayWidth + 1,
3 * displayWidth + 1,
3 * displayWidth + 2,
4 * displayWidth + 2
], //zTetromino
[
2 * displayWidth + 1,
3 * displayWidth,
3 * displayWidth + 1,
3 * displayWidth + 2
], //tTetromino
[
2 * displayWidth + 1,
2 * displayWidth + 2,
3 * displayWidth + 1,
3 * displayWidth + 2
], //oTetromino
[
1 * displayWidth + 1,
2 * displayWidth + 1,
3 * displayWidth + 1,
4 * displayWidth + 1
], //iTetromino
[
2 * displayWidth + 1,
2 * displayWidth + 2,
3 * displayWidth + 2,
4 * displayWidth + 2
], // liTetromino
[
2 * displayWidth + 2,
3 * displayWidth + 1,
3 * displayWidth + 2,
4 * displayWidth + 1
] // ziTetromino
];
//InitGame
initRender();
initGame();
////
///InitDevFunctions
//numberisedSquares();
//numberisedOneline();
//makeTestLines()
//arrToArg([230, 238])
//checkCurrent()
////
function initRender() {
highscorecontent.innerHTML = LoadingComponent();
tryLoginRender()
}
function initGame() {
console.log("Init Game");
version.innerText = application.version;
grid.innerHTML = TemplateForGrid(); //Init Grid template
miniSquaresInit();
gameOverDiv.style.display = "none";
scoreInit();
gameTimer.stop();
currentPosition = 4;
currentRotation = 0;
random = Math.floor(Math.random() * theTetrominoes.length);
nextRandom = Math.floor(Math.random() * theTetrominoes.length);
current = theTetrominoes[random][currentRotation];
nextRotatedCurrent = theTetrominoes[random][nextRotation];
startBtn.innerHTML = "▶ START";
deactivateGameButtons();
rewardPicDivSetHeight(0);
rewardPicDivSetBackground();
rewardCheckBox.checked = checkRewardExtra();
weird.checked = checkWeirdMode();
}
function checkWeirdMode() {
return localStorage.getItem("storedWeirdMode") === null
? false
: JSON.parse(localStorage.getItem("storedWeirdMode"));
}
function checkRewardExtra() {
return localStorage.getItem("storedReward") === null
? true
: JSON.parse(localStorage.getItem("storedReward"));
}
function rewardPicDivSetBackground() {
randomReward = Math.floor(Math.random() * rewardExtraPics.length);
rewardPicDiv.style.backgroundImage =
"url(" + rewardExtraPics[randomReward] + ")";
}
function scoreInit() {
score = 0;
scoreDisplay.innerHTML = score;
}
function miniSquaresInit() {
miniSquares.forEach(function (miniSquare, sqkey) {
miniSquares[sqkey].style = "";
miniSquares[sqkey].classList.remove("tetromino");
});
}
function draw() {
const { squares } = getDOMElements();
current.forEach((index) => {
squares[currentPosition + index].classList.add("tetromino");
squares[currentPosition + index].style.backgroundColor = colors[random];
});
}
function undraw() {
const { squares } = getDOMElements();
current.forEach((index) => {
squares[currentPosition + index].classList.remove("tetromino");
squares[currentPosition + index].style.backgroundColor = "";
});
}
function moveLeft() {
undraw();
const { squares } = getDOMElements();
const isAtLeftEdge = current.some(
(index) => (currentPosition + index) % width === 0
);
if (!isAtLeftEdge) currentPosition -= 1;
if (
current.some((index) =>
squares[currentPosition + index].classList.contains("taken")
)
) {
currentPosition += 1;
}
draw();
}
function moveRight() {
undraw();
const { squares } = getDOMElements();
const isAtRightEdge = current.some(
(index) => (currentPosition + index) % width === width - 1
);
if (!isAtRightEdge) currentPosition += 1;
if (
current.some((index) =>
squares[currentPosition + index].classList.contains("taken")
)
) {
currentPosition -= 1;
}
draw();
}
function moveDown() {
undraw();
currentPosition += width;
draw();
}
function tryFreeze() {
lockCheck() === true && doThisIfLockable();
lockCheck() === false && moveDown();
}
function lockCheck() {
return checkCurrentInSomeInNextRow() ? true : false;
}
function checkCurrentInSomeInNextRow() {
const { squares } = getDOMElements();
return current.some((index) =>
squares[currentPosition + index + width].classList.contains("taken")
);
}
function doThisIfLockable() {
//console.log("doThisIfLockable")
addCurrentToTaken(); //Lock current
tryGameOver();
//let score = 0;
let rowsInTaken = checkRowsInTaken();
rowsInTaken.length && doThisIfRowInTaken(rowsInTaken);
setRewardPic();
!checkGameOver() && dropNewTetromino();
}
function addCurrentToTaken() {
const { squares } = getDOMElements();
current.forEach((index) =>
squares[currentPosition + index].classList.add("taken")
);
}
async function doThisIfRowInTaken(rowsInTaken) {
fasterDownStop();
tryEffect(rowsInTaken);
await breakBeforeRender(1000);
let rendered = doRender(rowsInTaken);
rendered && addScore(rowsInTaken.length);
}
//OLD Try Effect
function tryEffectOLD(rowsInTaken) {
console.log("TRYING EFFECT....")
run.getActualCount() === run.getDefaultCount && doEffect(rowsInTaken);
}
//
//
function tryEffect(rowsInTaken) {
console.log("TRYING EFFECT....");
(!underEffect) && doEffect(rowsInTaken);
}
function doEffect(rowsInTaken) {
console.log("Do EFFECT ::: ");
let colorizeThis =
rerenderMode === "squarebased"
? rowsInTaken.map((rowInTaken) => [squareToOnelineNum(rowInTaken[1])])
: rowsInTaken;
console.log(colorizeThis);
colorizeThis.map((rowInTaken) =>
getOneline(rowInTaken).map(
(cell) => (cell.style.backgroundImage = `url("${boomm}")`)
)
);
return true;
}
////OLD BREAKCOUNTER
function breakBeforeRenderOLD() {
console.log("ACTUAL BREAKCOUNT ::: " + run.getActualCount());
if (run.getActualCount() > 0) {
gameSettings.rerenderable = false;
gameSettings.tetrominoDropable = false;
run.doBackCount();
}
if (run.getActualCount() === 0) {
console.log("REACTIVATE... Renderable and Tetromino dropable...");
gameSettings.rerenderable = true;
gameSettings.tetrominoDropable = true;
run.restartBackCount();
}
//console.log('BEAKCOUNT ::: ' + run.getActualCount())
}
///
////NEWEST BREAKCOUNTER (2022-06-09)
function breakBeforeRender(time) {
console.log("BREAK TIME...");
gameTimer.stop();
underEffect = true;
return new Promise((resolve)=>{
setTimeout(()=>{
gameTimer.start();
underEffect = false;
resolve(true)
}, time)
})
}
///
function doRender(rowsInTaken) {
//console.log("DO RENDER")
if (gameSettings.rerenderable) {
switch (rerenderMode) {
case "onelinebased":
//OnelineBasedRerender
rerenderOnelines(rowsInTaken);
return true;
break;
case "squarebased":
//SquareBasedRerender
rerenderSquares(rowsInTaken);
return true;
break;
case "old":
//OldRerender
rerenderGrids();
return true;
break;
default:
return false;
}
}
return false;
}
function checkRowsInTaken() {
switch (rerenderMode) {
case "onelinebased":
//OnelineBased checker
return whichOnelinesInTaken();
break;
case "squarebased":
//SquareBased checker
return whichSquareInTaken();
break;
case "old":
//Old no checker!
return false;
break;
default:
return false;
}
}
function addScore(lines) {
score += lines * 10;
scoreDisplay.innerHTML = score;
trySaveTheScore(score);
}
async function trySaveTheScore(score){
const isUserLoggedIn = checkUserIsLoggedIn();
const newScoreIsBigger = parseInt(localStorage.maxscore) < score;
const renderableTheSave = (isUserLoggedIn && newScoreIsBigger)? doSaveScore() : false;
console.log('Renderable the Save? ', renderableTheSave);
if(renderableTheSave){
eventAtScoreSavedToServer();
CreateUserMaxScore(score);
console.log('Stop save score : ', score);
}
}
async function doSaveScore(){
console.log('Start save score : ', score);
const response = await sendDataUpdate('score');
const data = (response.status === 200) ? response.json() : false;
const savesatus = (data)? savesatus.isScoreUptate : 'false';
return savesatus;
}
function setRewardPic() {
checkRewardExtra() && rewardPicDivSetHeight(score / 3);
}
function rewardPicDivSetHeight(value) {
rewardPicDiv.style.height = value + "%";
}
function dropNewTetromino() {
if (gameSettings.tetrominoDropable === true) {
random = nextRandom;
nextRandom = Math.floor(Math.random() * theTetrominoes.length);
current = theTetrominoes[random][currentRotation];
currentPosition = 4;
draw();
displayShape();
}
}
//OnelineBasedRerender
function rerenderOnelines(whichOnelinesInTaken) {
whichOnelinesInTaken.map((oneline) => {
removeOnelineFromTaken(oneline);
!checkWeirdMode() && jumpOnelineToFirst(oneline);
removeOnelineFromTetromino(oneline);
});
return whichOnelinesInTaken.length;
}
function removeOnelineFromTaken(oneline) {
[...grid.querySelectorAll(`[data-oneline="${oneline}"]`)].map((cell) =>
cell.classList.remove("taken")
);
}
function removeOnelineFromTetromino(oneline) {
[...grid.querySelectorAll(`[data-oneline="${oneline}"]`)].map((cell) => {
cell.classList.remove("tetromino");
cell.style = "";
});
}
function jumpOnelineToFirst(oneline) {
let firstSquare = getDOMElements().firstSquare();
getOneline(oneline).map((cell) =>
firstSquare.insertAdjacentElement("beforebegin", cell)
);
//syncSuqares();
}
function whichOnelinesInTaken() {
//Check only in Activegameplace!
let takenLineList = [];
for (let oneline = 4; oneline < lineNumbers(); oneline++) {
let result = checkOnlelineInTaken(oneline);
result && takenLineList.push(oneline);
}
return takenLineList;
}
function checkOnlelineInTaken(oneline) {
return [
...grid.querySelectorAll(`[data-oneline="${oneline}"]`)
].every((cell) => cell.classList.contains("taken"));
}
function getOneline(oneline) {
return [...grid.querySelectorAll(`[data-oneline="${oneline}"]`)].map(
(cell) => cell
);
}
function getActivegameplaceOneline(oneline) {
return [
...grid.querySelectorAll(`.activegameplace[data-oneline="${oneline}"]`)
].map((cell) => cell);
}
//SquareBasedRerender
function rerenderSquares(rows) {
rows.map((row) => {
uncolorizeRow(row);
!checkWeirdMode() && jumpSquaresToFirst(row);
});
return rows.length;
}
function whichSquareInTaken() {
const { squares } = getDOMElements();
let takenLineList = [];
for (let i = 0; i < squares.length - width - 1; 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"))) {
takenLineList.push(row);
}
}
return takenLineList;
}
function uncolorizeRow(row) {
const { squares } = getDOMElements();
row.forEach((index) => {
squares[index].classList.remove("taken");
squares[index].classList.remove("tetromino");
squares[index].style.backgroundColor = "";
});
}
function jumpSquaresToFirst(row) {
const { squares } = getDOMElements();
const firstSquare = getDOMElements().firstSquare();
row.forEach((index) => {
firstSquare.insertAdjacentElement("beforebegin", squares[index]);
});
}
//OldRerender
function rerenderGrids() {
const { squares } = getDOMElements();
let count = 0;
for (let i = 0; i < 229; 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"))) {
console.log("ROW :" + row);
count += 1;
//Remove Classes and color from removed SQUARES
row.forEach((index) => {
squares[index].classList.remove("taken");
squares[index].classList.remove("tetromino");
squares[index].style.backgroundColor = "";
});
if (!checkWeirdMode()) {
//Remove Full Squares
const squaresRemoved = squares.splice(i, width);
//Remove hidden SQUARES from Line0-Line1
const hiddenSquaresRemoved = squares.splice(0, width * 3);
//Re-add to SQUARES the removed SQUARES
squares = squaresRemoved.concat(squares);
squares = hiddenSquaresRemoved.concat(squares);
//Render new Squares
squares.forEach((cell, key) => createNewGridLine(cell, key));
}
}
}
return count;
}
function createNewGridLine(cell, key) {
//console.log("CELL IN createNewGridLine ::: ")
//console.log(cell)
grid.appendChild(cell);
}
///FIX ROTATION OF TETROMINOS A THE EDGE
function isAtRight() {
return current.some((index) => (currentPosition + index + 1) % width === 0);
}
function isAtLeft() {
return current.some((index) => (currentPosition + index) % width === 0);
}
//Rotate functions
function rotate() {
undraw();
if (nextRotationInCollision()) {
console.log("I CAN NOT TO ROTATE");
} else {
currentRotation++;
if (currentRotation === current.length) {
//if the current rotation gets to 4, make it go back to 0
currentRotation = 0;
}
current = theTetrominoes[random][currentRotation];
rotationcorrection();
}
draw();
}
function rotationcorrection(P) {
//console.log("CHECK ROTATED POSITION");
//console.log(P);
P = P || currentPosition; //get current position. Then, check if the piece is near the left side.
if ((P + 1) % width < 4) {
//add 1 because the position index can be 1 less than where the piece is (with how they are indexed).
if (isAtRight()) {
//use actual position to check if it's flipped over to right side
currentPosition += 1; //if so, add one to wrap it back around
rotationcorrection(P); //check again. Pass position from start, since long block might need to move more.
}
} else if (P % width > 5) {
if (isAtLeft()) {
currentPosition -= 1;
}
}
}
function nextRotationInCollision() {
return checkNextRotationInTaken() ? true : false;
}
function checkNextRotationInTaken() {
const { squares } = getDOMElements();
nextRotation = currentRotation === 3 ? 0 : currentRotation + 1;
nextRotatedCurrent = theTetrominoes[random][nextRotation];
return nextRotatedCurrent.some((index) =>
squares[currentPosition + index].classList.contains("taken")
)
? true
: false;
}
/////////
//display the shape in the mini-grid display
function displayShape() {
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];
});
}
//Game Over functions
function tryGameOver() {
checkGameOver() && doItAtGameOver();
}
function checkGameOver() {
const { squares } = getDOMElements();
return (
squares[34].classList.contains("taken") ||
squares[35].classList.contains("taken") ||
squares[36].classList.contains("taken")
);
}
function doItAtGameOver() {
actionsAtGameOver();
renderAtGameOver();
}
function actionsAtGameOver() {
stopTimers();
deactivateGameButtons();
}
function stopTimers() {
gameTimer.stop();
speeder.stop();
}
function renderAtGameOver() {
overScore.innerHTML = "SCORE : " + score;
gameOverDiv.style.display = "block";
console.log("GAME OVERED");
}
///
//TEMPLATES - Template Components
// Grid template components
function TemplateForGrid() {
let gridDivs = "";
for (let count = 0; gridNumbers > count; count++) {
let classnames = gridClassCalculator(gridNumbers, count);
gridDivs += TemplateForGridDiv(
classnames,
count,
Math.ceil((count + 1) / 10)
);
}
return `
${gridDivs}
`;
}
function gridClassCalculator(gridNumbers, count) {
let classArray = [];
count <= 29 && classArray.push("hidden");
gridNumbers - width <= count && classArray.push("taken");
gridNumbers - width > count &&
width * 3 <= count &&
classArray.push("activegameplace");
divisible(count, width) === count && classArray.push("first-in-row");
numberLastCharacter(count) === 9 && classArray.push("last-in-row");
let classnames = classArray.join(" ");
return classnames;
}
function TemplateForGridDiv(classnames, count, oneline) {
return `
<div class="${classnames}" data-serialnumber="${count}" data-oneline="${oneline}"></div>
`;
}
// Grid template components END
//HIGH-SCORE Template Component
function HighScoreComponent(datas){
const highScores = datas.map(({UserName, UserScore}, item) =>{
return `
<tr><td>${item+1}.</td><td>${UserName}</td><td>${UserScore}</td></tr>
`;
}).join(' ');
return `
<div id="highscoreinside">
<table id="scorelist">
<tbody>
<tr>
<th>Placed</th>
<th>Name</th>
<th>Score</th>
</tr>
${highScores}
</tbody>
</table>
</div>
`;
}
//HIGH-SCORE Template Component END
//LOADING Component Template
function LoadingComponent(){
return `
<div class="fullcenter">
<img src="https://bzozoo.github.io/Tetris-Basic//images/loading.gif" alt="loading">
</div>
`;
}
//LOADING Component Template END
// LOGIN / REGISTER Template components
function LogRegComponent() {
return `
<form id="loginform">
<fieldset>
<div id="loginformbox">
<div class="navbar"><div class="title">LOGIN</div></div>
<p><label for="username">Username</labe>
<input id="username" name="username" placeholder="Yourname"/></p>
<p><label for="passwd">Password</label>
<input id="passwd" name="passwd" type="password" placeholder="8 character"/></p>
<div class="fullcenter">
<button id="loginsend" class="actionBtn">LOGIN</button>
</div>
</div>
</fieldset>
</form>
<form id="regform" autocomplete="off">
<fieldset>
<div id="regformbox">
<div class="navbar"><div class="title">REGISTRATION</div></div>
<p><label for="regusername">Username</labe>
<input id="regusername" name="regusername" placeholder="Yourname" autocomplete="off" /></p>
<p><label for="regpasswd">Password (min 8 character)</label>
<input id="regpasswd" name="regpasswd" type="password" placeholder="8 character" autocomplete="new-password" /></p>
<p><label for="regpasswdagain">Password-again</label>
<input id="regpasswdagain" name="regpasswdagain" type="password" placeholder="8 character" /></p>
<div class="fullcenter">
<button id="regsend"class="actionBtn">REGISTER</button>
</div>
</div>
</fieldset>
</form>
`;
}
// LOGIN / REGISTER Template components END
//USER PROFILE Template Components
function UserContainerComponent({ UserName, UserScore, UserAvatar, ExpiredTimeStamp }){
const avatar = UserAvatar === null? '<img src="https://bzozoo.github.io/Tetris-Basic/images/defprofpic.jpg" />' : `<img src="${UserAvatar}" />`;
const ExpiredTime = new Date(ExpiredTimeStamp*1000).toLocaleString();
return `
<div class="navbar">
<div class="title">Hi, ${UserName}</div>
</div>
<fieldset>
<div id="userpanel">
<div id="userprofilepicture">
${avatar}
</div>
<div id="userpersonaldatas">
<p>Your own record</p>
<h2>${UserScore} point</h2>
</div>
</div>
<hr />
<div class="fullcenter">
<button id="logoutBtn" class="actionBtn">LOGOUT</button>
<div class="smallfont mt-05rem">Automatical logout at: ${ExpiredTime}</div>
</div>
</fieldset>
`;
}
//USER PROFILE Template Components END
// TEMPLATES END - Template components END
////HELPERS / Checkers
function divisible(dividend, divisor) {
if (dividend % divisor == 0) {
return dividend;
} else {
var num = dividend + (divisor - (dividend % divisor));
return num;
}
}
function numberLastCharacter(number) {
let string = number.toString();
return parseInt(string[string.length - 1]);
}
function recurs(num, max, recurses = []) {
if (max >= num) {
return recurs(num + 1, max, [...recurses, num]);
}
return recurses;
}
function IntervalEncapsulator(fn, time) {
let timer = false;
this.start = function () {
timer = !this.status() ? setInterval(fn, time) : timer;
};
this.stop = function () {
clearInterval(timer);
timer = false;
};
this.setTime = function (newTime) {
if (!isNaN(newTime) && newTime != undefined && newTime) {
console.log("SET NEW TIME ::: " + newTime);
const oldStatus = this.status();
this.stop();
time = newTime;
oldStatus && this.start();
}
};
this.status = function () {
return timer !== false;
};
this.checkInterval = function () {
return time;
};
this.showDefault = time;
}
function backcounter(count) {
return {
doBackCount: doBackCount(),
getActualCount: getActualCount(),
getDefaultCount: getDefaultCount(),
restartBackCount: restartBackCount(count)
};
function doBackCount() {
return function () {
return (count = count === 0 ? 0 : count - 1);
};
}
function getActualCount() {
return function () {
return count;
};
}
function getDefaultCount() {
return count;
}
function restartBackCount(recount) {
return function () {
return (count = recount);
};
}
}
//COMMANDS for Backcounter
//run.doBackCount()
//run.getActualCount()
//run.getDefaultCount
//run.restartBackCount()
//
function getDOMElements() {
return {
squares: Array.from(document.querySelectorAll(".grid div")),
firstSquare: function () {
return this.squares[30];
},
squaresInActiveGameplace: Array.from(
grid.querySelectorAll(".activegameplace")
),
firstSquareInRow: document.querySelectorAll(".first-in-row"),
lastSquareInRow: document.querySelectorAll(".last-in-row"),
music: document.getElementById("myAudio")
};
}
function checkUserIsLoggedIn() {
return (
localStorage.hasOwnProperty("UserName") &&
localStorage.hasOwnProperty("UserJWT") &&
localStorage.hasOwnProperty("maxscore")
);
}
function CreateAllUserInformations(username, usertoken){
localStorage.setItem("UserName", username);
localStorage.setItem("UserJWT", usertoken);
}
function CreateUserMaxScore(score){
localStorage.setItem('maxscore', score);
}
function deleteAllUserInformations(){
localStorage.removeItem("UserName");
localStorage.removeItem("UserJWT");
localStorage.removeItem("maxscore");
return true;
}
function regdatasValidator(){
const username = regform.regusername.value;
const passwd = regform.regpasswd.value;
const passwdagain = regform.regpasswdagain.value;
const usernameNotEmpty = (username !== '');
const usernameIsClean = username.match(/^[a-zA-Z0-9)\(]+$/g) !== null ? true : false;
const passPower = passwd.length >= 8;
const passMatch = (passwd === passwdagain);
const isValid = ( usernameIsClean && passPower && passMatch && usernameNotEmpty);
return {
usernameIsClean,
usernameNotEmpty,
passPower,
passMatch,
isValid
}
}
//HELPERS / Checkers END
//EVENTS
function fasterDown() {
speeder.start();
}
function fasterDownStop() {
speeder.stop();
}
function extraFastDown() {
if (!lockCheck()) {
tryFreeze();
setTimeout(function () {
extraFastDown();
}, 25);
}
}
function control(e) {
e.keyCode === 37 && moveLeft();
e.keyCode === 38 && rotate();
e.keyCode === 39 && moveRight();
e.keyCode === 35 && extraFastDown();
}
function controlDown(e) {
e.keyCode === 40 && fasterDown();
document.removeEventListener("keydown", controlDown);
}
function controlUp(e) {
e.keyCode === 40 && fasterDownStop();
document.addEventListener("keydown", controlDown);
}
function activateGameButtons() {
document.addEventListener("keydown", control);
document.addEventListener("keydown", controlDown);
document.addEventListener("keyup", controlUp);
leftMove.addEventListener("mousedown", moveLeft);
rightMove.addEventListener("mousedown", moveRight);
downMove.addEventListener("click", tryFreeze);
downMove.addEventListener("touchstart", fasterDown);
downMove.addEventListener("touchend", fasterDownStop);
downMove.addEventListener("mousedown", fasterDown);
downMove.addEventListener("mouseup", fasterDownStop);
rotation.addEventListener("mousedown", rotate);
resetButton.addEventListener("click", initGame);
console.log("GAME BUTTONS ACTIVATED");
}
function deactivateGameButtons() {
if (controllButtonsDeactivable) {
document.removeEventListener("keydown", control);
document.removeEventListener("keydown", controlDown);
document.removeEventListener("keyup", controlUp);
controllButtonsSection.innerHTML = controllButtonsSection.innerHTML;
console.log("GAME BUTTONS DEACTIVATED");
}
}
//scoreBox Open Event
scoreBox.addEventListener("click", async () => {
highscorecontent.innerHTML = '';
highscore.classList.remove("hidden");
const datas = await getHighScoreSorted();
const highscorecontentstring = (datas.error === undefined)? await HighScoreComponent(datas) : 'Server error! Try again later!';
highscorecontent.innerHTML = highscorecontentstring;
});
//scoreBox Close Event
closeHighScore.addEventListener("click", () => {
highscore.classList.add("hidden");
});
//Login Button Event
loginBtn.addEventListener("click", () => {
userzone.classList.remove("hidden");
});
//UserZone Close Button Event
closeUserZone.addEventListener("click", () => {
userzone.classList.add("hidden");
});
// Profile Button Events
profileBtn.addEventListener('click', ()=>{
openUserZone();
reloadUserZone();
})
function openUserZone(){
userzone.classList.remove("hidden");
}
async function reloadUserZone(){
const userdatas = await getUserDatas();
if(userdatas.UserName !== undefined && userdatas.UserScore !== undefined){
usercontainer.innerHTML = UserContainerComponent(userdatas);
logoutBtn.addEventListener('click', doLogout);
}
if(userdatas.responsestatus === 401 || (userdatas.UserName !== undefined && userdatas.UserName !== localStorage.UserName)){
Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Invalid identifiers! <br />You have been logged out!',
showConfirmButton: false,
timer: 3000
});
doLogout();
}
if(localStorage.maxscore === undefined){
Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Maxscore datas was removed! <br />You have been logged out!',
showConfirmButton: false,
timer: 5000
});
doLogout();
}
(userdatas.servererror === true) &&
Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Server error!',
showConfirmButton: false,
timer: 3000
});
}
// Profile Button Events END
//START/PAUSE button EVENT
startBtn.addEventListener("click", () => {
let gameTimerStatus = gameTimer.status();
!gameTimerStatus && activateGameButtons();
gameTimerStatus && deactivateGameButtons();
displayShape();
startpauseSwitcher(gameTimer.status());
startpauseButtonSwitcher(gameTimer.status());
});
function startpauseSwitcher(gameTimerStatus) {
console.log(" SWITCH START / PAUSE ");
!gameTimerStatus && gameTimer.start();
gameTimerStatus && gameTimer.stop();
}
function startpauseButtonSwitcher(gameTimerStatus) {
startBtn.innerHTML = !gameTimerStatus ? "▶ RE-START" : "⏸ PAUSE";
}
/////
//Mute button event
muteButton.addEventListener("click", () => {
muteSwitcher(musicInterval.status());
muteButtonSwitcher(musicInterval.status());
});
function muteSwitcher(musicIntervalStatus) {
console.log("MUTE ON / OFF");
musicIntervalStatus === false && musicInterval.start();
musicIntervalStatus === true && musicInterval.stop();
getDOMElements().music.pause();
}
function muteButtonSwitcher(musicIntervalStatus) {
muteButton.innerHTML = musicIntervalStatus === false ? "🔇 MUTE" : "🔈 MUTE";
}
function playMusic() {
getDOMElements().music.play();
}
///
///Options Button events
document.addEventListener("keydown", panelcontrol);
optionsButton.addEventListener("click", toggleOptionPanel);
closeOPtions.addEventListener("click", toggleOptionPanel);
function panelcontrol(e) {
//e.ctrlKey
(e.altKey && e.keyCode === 79) && toggleOptionPanel();
}
function toggleOptionPanel() {
optionspanel.classList.toggle("hidden");
paneloverlay.classList.toggle("blured");
}
///
///Panel Overlay Events
function closeAllModalsAndOverlay() {
console.log("CLOSE ALL MODALS");
paneloverlay.classList.remove("blured");
[...document.querySelectorAll(".modal")].map((modals) =>
modals.classList.add("hidden")
);
}
///
//Invert chkbox event
invertCheckBox.addEventListener("change", transformTheGrid);
function transformTheGrid() {
grid.style.transform = checkGridInTransform() ? "" : "rotate(180deg)";
}
function checkGridInTransform() {
return grid.style.transform === "" ? false : true;
}
///
//Reward chkbox event
rewardCheckBox.addEventListener("change", () => {
rewardFunctionSwitch(checkRewardExtra());
});
function rewardFunctionSwitch(checkRewardExtra) {
checkRewardExtra && doItIfRewardExtra();
!checkRewardExtra && doItIfNotRewardExtra();
console.log(`ACTUAL REWARD: ${localStorage.getItem("storedReward")}`);
}
function doItIfRewardExtra() {
localStorage.setItem("storedReward", false);
rewardPicDivSetHeight(0);
}
function doItIfNotRewardExtra() {
localStorage.setItem("storedReward", true);
setRewardPic();
}
////
//WeirdMode checkbox event
weird.addEventListener("change", () => {
localStorage.setItem("storedWeirdMode", weird.checked);
});
///
//Login Logout Process Event
async function loginProcess(){
console.log('Login process...');
const loginDatas = await getLoginDatas();
const everythingIsGood = (loginDatas.error === undefined && loginDatas.responsestatus === undefined);
everythingIsGood && doLogin(loginDatas.UserName, loginDatas.UTOK, loginDatas.UserScore);
(loginDatas.responsestatus === 401) &&
Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Wrong username or password!',
showConfirmButton: false,
timer: 3000
});
(loginDatas.servererror === true) &&
Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Server error!',
showConfirmButton: false,
timer: 3000
});
}
function doLogin(username, usertoken, maxscore){
CreateAllUserInformations(username, usertoken);
CreateUserMaxScore(maxscore);
tryLoginRender();
}
function doLogout(){
const deleteSuccess = deleteAllUserInformations()
deleteSuccess && emptyPanels();
deleteSuccess && logoutRender();
}
//Login Logout Process Event END
// Register Events
async function registerProcess(){
console.log('Register...');
regsend.disabled = true;
const validator = regdatasValidator();
if(!validator.isValid){
!validator.passMatch && Swal.fire({
position: 'top-end',
icon: 'error',
title: 'The two passwords do not match!',
showConfirmButton: false,
timer: 3000
});
!validator.passPower && Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Min 8 characters!',
showConfirmButton: false,
timer: 3000
});
!validator.usernameIsClean && Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Special characters are not allowed in username!',
showConfirmButton: false,
timer: 3000
});
!validator.usernameNotEmpty && Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Username field is empty!',
showConfirmButton: false,
timer: 3000
});
}
if(validator.isValid){
const regdata = await registrationDataSender();
regdata.responsestatus === 409 && Swal.fire({
position: 'top-end',
icon: 'error',
title: 'User is exist!<br />Choose another name!',
showConfirmButton: false,
timer: 3000
});
regdata.servererror && Swal.fire({
position: 'top-end',
icon: 'error',
title: 'Server Error!',
showConfirmButton: false,
timer: 3000
});
regdata.Registration === 'Success' && Swal.fire({
position: 'top-end',
icon: 'success',
title: 'Registration is success!<br /> You can login now ',
showConfirmButton: false,
timer: 3000
});
}
emptyRegdataFields();
regsend.disabled = false;
}
// Register Events END
//EVENT RENDERS
//Login / Logout Event Renders
function tryLoginRender(){
emptyPanels();
const isUserLoggedIn = checkUserIsLoggedIn();
if(!isUserLoggedIn){
document.querySelector("#login").insertAdjacentHTML("afterbegin", LogRegComponent())
loginform.addEventListener('submit', ()=>{
event.preventDefault();loginProcess();
});
regform.addEventListener('submit', ()=>{
event.preventDefault(),registerProcess();
});
}
if(isUserLoggedIn){
reloadUserZone();
toggleLoginButtonToProfileButton();
}
}
function logoutRender(){
toggleLoginButtonToProfileButton()
document.querySelector("#login").insertAdjacentHTML("afterbegin", LogRegComponent());
loginform.addEventListener('submit', ()=>{
event.preventDefault();loginProcess();
});
regform.addEventListener('submit', ()=>{
event.preventDefault(),registerProcess();
});
}
function toggleLoginButtonToProfileButton(){
document.querySelector('#loginBtn').classList.toggle('hidden');
document.querySelector('#profileBtn').classList.toggle('hidden');
}
//Login /Logout Event Renders END
//Empty Panels renders
function emptyPanels(){
const panels = document.querySelectorAll('.panel');
[...panels].map(panel => panel.innerHTML = '');
}
//Empty Panels renders END
//Empty regdatas
function emptyRegdataFields(){
const regforminput = document.querySelectorAll('#regform input');
[...regforminput].map(regforminput => regforminput.value = '');
}
//Empty regdatas END
//Event at score saved to server
function eventAtScoreSavedToServer(){
scoresavedbox.classList.remove('hidden');
setTimeout(()=>{
scoresavedbox.classList.add('hidden');
}, 3000)
}
//
//EVENT RENDERS
//EVENTS END
///FETCH DATA FUNCTIONS
async function getHighScore(){
try {
const response = await fetch(`${host}/api/userscore`);
const data = await (response.status === 200) ? response.json() : { 'error': `Response staus ::: ${response.status}`, 'responsestatus': response.status };
return data;
}catch(e){
return { 'error': e, 'servererror':true }
}
}
async function getHighScoreSorted(){
const data = await getHighScore();
if(data.error === undefined){
let dataByScore = data.slice(0);
dataByScore.sort(function (a, b) {
return b.UserScore - a.UserScore;
});
return dataByScore;
}
return false;
}
async function getLoginDatas() {
const username = loginform.username.value;
const passwd = loginform.passwd.value;
const formData = new FormData();
formData.append("nameField", username);
formData.append("passField", passwd);
const options = {
method: "POST",
body: formData
};
try {
const response = await fetch(`${host}/api/login`, options);
const data = await (response.status === 200) ? response.json() : { 'error': `Response staus ::: ${response.status}`, 'responsestatus': response.status };
return data;
}catch(e){
return { 'error': e, 'servererror':true }
}
}
async function registrationDataSender(){
const username = regform.regusername.value;
const passwd = regform.regpasswd.value;
const formData = new FormData();
formData.append("reguser", username);
formData.append("regpwd", passwd);
const options = {
method: "POST",
body: formData
};
try {
const response = await fetch(`${host}/api/register`, options);
const data = await (response.status === 201) ? response.json() : { 'error': `Response staus ::: ${response.status}`, 'responsestatus': response.status };
return data;
}catch(e){
return { 'error': e, 'servererror':true }
}
}
async function getUserDatas(){
const options = {
method: "POST",
headers: {
Authorization: `Bearer ${localStorage.UserJWT}`
},
};
try {
const response = await fetch(`${host}/api/user`, options);
const data = await (response.status === 200) ? response.json() : { 'error': `Response staus ::: ${response.status}`, 'responsestatus': response.status };
return data;
}catch(e){
return { 'error': e, 'servererror':true }
}
}
async function sendDataUpdate(type){
let data = '';
if(type === 'score'){
const grid = document.querySelector('.grid').innerHTML;
data = `score=${score}&grid=${grid}`;
}
const options = {
method: "POST",
headers: {
'Content-Type':'application/x-www-form-urlencoded',
Authorization: `Bearer ${localStorage.UserJWT}`
},
body: data
};
const response = await fetch(`${host}/api/user/update`, options);
const datas = await response.json();
return datas;
}
///FETCH DATA FUNCTIONS END
//DevFunctions
function numberisedSquares() {
let counter = 0;
getDOMElements().squares.map((square) => (square.innerHTML = counter++));
}
function numberisedOneline() {
getDOMElements().squares.map(
(square) => (square.innerHTML = square.dataset.oneline)
);
}
function squareToOneline(square) {
const { squares } = getDOMElements();
return squares[square].dataset.oneline;
}
function squareToOnelineNum(square) {
return parseInt(squareToOneline(square));
}
function addOnelineToTaken(oneline) {
[...grid.querySelectorAll(`[data-oneline="${oneline}"]`)].map((cell) =>
cell.classList.add("taken")
);
}
function addToTakenToSquares(squaresStart, squaresMax) {
return recurs(squaresStart, squaresMax).map(
(item) => (squares[item].className += " taken tetromino")
);
}
function squaresInOneline(oneline) {
return getOneline(oneline).map((cell) =>
parseInt(cell.dataset.serialnumber)
);
}
function makeTestLines() {
addToTakenToSquares(200, 208);
addToTakenToSquares(210, 218);
addToTakenToSquares(220, 228);
addToTakenToSquares(230, 238);
}
function arrToArg(squaresArray) {
return squaresArray.map((squareArray) => squareArray);
}
function addOnelineToTakenAndColorizeThat(oneline) {
addOnelineToTaken(oneline);
turnToPinkAllTakensOnActiveGameplace();
}
function removeAllTakenFromActiveGameplace() {
const { squaresInActiveGameplace } = getDOMElements();
squaresInActiveGameplace.map((square) => {
square.classList.remove("taken");
turnToPinkAllTakensOnActiveGameplace();
});
}
function removeOneline(oneline) {
getOneline(oneline).map((cell) => cell.remove());
}
function getAllActiveGameplaces() {
return [...grid.querySelectorAll(".activegameplace")];
}
function turnToPinkActiveGameplace() {
getAllActiveGameplaces().map(
(cell) => (cell.style.backgroundColor = "pink")
);
}
function turnToPinkAllTakensOnActiveGameplace() {
getAllActiveGameplaces().map(
(cell) =>
(cell.style.backgroundColor = cell.classList.contains("taken")
? "pink"
: "")
);
}
function removeOnelineFromTakenAndUnColorizeThat(oneline) {
removeOnelineFromTaken(oneline);
turnToPinkAllTakensOnActiveGameplace();
}
function getOnelineNodes(oneline) {
return grid.querySelectorAll(`.activegameplace[data-oneline="${oneline}"]`);
}
const getCurrentInSquare = () => [
parseInt(currentPosition) + parseInt(current[0]),
parseInt(currentPosition) + parseInt(current[1]),
parseInt(currentPosition) + parseInt(current[2]),
parseInt(currentPosition) + parseInt(current[3])
];
const getNextRotatedCurrentInSquare = () => [
parseInt(currentPosition) + parseInt(nextRotatedCurrent[0]),
parseInt(currentPosition) + parseInt(nextRotatedCurrent[1]),
parseInt(currentPosition) + parseInt(nextRotatedCurrent[2]),
parseInt(currentPosition) + parseInt(nextRotatedCurrent[3])
];
function checkCurrent() {
const { squares } = getDOMElements();
console.log(
"CURRENT TETRROMINO: " +
tetrominoNames[random] +
" - ACTUAL RANDOM: " +
random +
" - PROFILE: " +
current +
"CURRENT POSITION: " +
currentPosition
);
// Show actual current divlist on Console
current.forEach((index) => {
console.log(squares[currentPosition + index]);
});
console.log("SQUARES NUMBERS : " + getCurrentInSquare().join(" - ") + " ! ");
nextRotation = currentRotation === 3 ? 0 : currentRotation + 1;
nextRotatedCurrent = theTetrominoes[random][nextRotation];
console.log("Next Rotation: " + nextRotation);
console.log(
"NEXT ROTATED SQUARES NUMBERS: " +
getNextRotatedCurrentInSquare().join(" - ") +
" ! "
);
// Show next rotation divlist on Console
nextRotatedCurrent.forEach((index) => {
console.log(squares[currentPosition + index]);
});
}
// } //MAIN END })(); //IIFE END
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
body {
font-family: sans-serif;
margin: 5px;
background-color: #00a8f3;
height: 99%;
width: 400px;
overflow: hidden;
touch-action: manipulation;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;*/ /* Non-prefixed version, currently
supported by Chrome, Edge, Opera and Firefox */
}
:root {
--placeholder-color: #1d4762;
--bluetext-color: #3f48cc;
--lcdpanel-color: #bbdaf7;
}
* {
outline: none;
}
#scoresavedbox {
z-index: 11;
position: absolute;
margin-top: 0.2rem;
left: 17.3rem;
font-size: 0.9rem;
font-weight: bold;
color: var(--bluetext-color);
background-color: var(--lcdpanel-color);
}
.container {
margin: 5px;
display: flex;
min-width: 392px;
}
#gameOverDiv {
background: url(https://bzozoo.github.io/Tetris-Basic/images/gameover.jpg);
min-width: 200px;
width: 250px;
height: 526px;
margin-top: 2px;
margin-left: 7px;
position: absolute;
z-index: 1;
font-family: sans-serif;
/*display: none;*/
}
.activegameplace {
/*background-image: url("https://raw.githubusercontent.com/bzozoo/Tetris-Basic/master/images/boomm.gif");*/
background-size: contain;
background-repeat: no-repeat;
}
#rewardContainer {
/* background: green; */
min-width: 200px;
width: 251px;
height: 526px;
margin-top: 5px;
margin-left: 7px;
position: absolute;
/*display: none;*/
z-index: -1;
}
#rewardPicDiv {
background: yellow;
/* opacity: 0.6; */
height: 0%;
max-height: 100%;
width: 100%;
background-repeat: no-repeat;
background-size: 100% 526px;
}
#scoreDisplay {
font-size: 30px;
color: red;
text-align: center;
margin-top: 2px;
margin-bottom: 2px;
font-family: sans-serif;
}
#scoreBox {
font-family: sans-serif;
margin-bottom: 15px;
border: 2px black solid;
padding: 0px;
width: 100%;
height: 60px;
background-color: #bbdaf7;
box-shadow: 5px 5px 10px 5px grey;
text-align: center;
color: #3f48cc;
}
#scoreBox p {
margin: 1px;
}
#overScore {
margin-top: 340px;
width: 100%;
text-align: center;
color: blue;
font-size: 30px;
}
#speedBox {
font-family: sans-serif;
margin-bottom: 15px;
border: 2px black solid;
padding: 0px;
width: 100%;
height: 1rem;
background-color: #bbdaf7;
box-shadow: 5px 5px 10px 5px grey;
text-align: left;
color: #3f48cc;
}
#speedBox strong{
margin-right: 8px;
}
.actions {
text-align: left;
}
.actions button {
width: 115px;
text-align: center;
}
.controlls {
margin-left: 30px;
padding-top: 0px;
}
.gombBtn {
background-color: #3f48cc;
padding: 15px;
border-radius: 50%;
box-shadow: 5px 5px 10px 5px grey;
margin-right: 15px;
border-width: 10px;
font-size: 20px;
}
.actionBtn {
box-shadow:inset 0px 1px 0px 0px #bbdaf7;
background:linear-gradient(to bottom, #79bbff 5%, #378de5 100%);
background-color:#79bbff;
border-radius:6px;
border:1px solid #84bbf3;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:13px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #528ecc;
}
.actionBtn:hover {
background:linear-gradient(to bottom, #378de5 5%, #79bbff 100%);
background-color:#378de5;
}
.actionBtn:active {
position:relative;
top:1px;
}
button:active{
background-color:red;
box-shadow: none;
}
.grid {
/* transform: rotate(180deg);
*/
border: 2px black solid;
min-width: 200px;
width: 250px;
height: 525px;
display: flex;
flex-wrap: wrap;
/* background-color: #d0f5a9;*/
/* box-shadow: 5px 5px 10px 5px grey; */
}
.grid-bg {
border: 2px black solid;
min-width: 200px;
width: 250px;
height: 524px;
flex-wrap: wrap;
background-color: #bbdaf7;
box-shadow: 5px 5px 10px 5px grey;
position: absolute;
z-index: -2;
}
.transformed {
box-shadow: -5px -5px 10px 5px grey;
}
.grid div {
height: 25px;
width: 25px;
font-size: 10px;
}
.tetromino {
background-color: blue;
opacity: 0.6;
}
.sidebar {
margin-left: 10px;
width: 116px;
}
.mini-grid {
font-family: sans-serif;
margin-bottom: 15px;
border: 2px black solid;
padding: 0px;
width: 100%;
height: 120px;
display: flex;
flex-wrap: wrap;
background-color: #bbdaf7;
box-shadow: 5px 5px 10px 5px grey;
text-align: center;
color: #3f48cc;
font-weight: bold;
}
.mini-grid div {
height: 20px;
width: 19px;
}
button:focus {
outline: none;
}
#userzone {
position: fixed;
background: #00a8f3;
border: 5px solid #2b577d;
z-index: 11;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 3px;
margin: 6px;
color: white;
}
#highscore {
position: fixed;
background: #00a8f3;
border: 5px solid #2b577d;
z-index: 11;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 3px;
margin: 6px;
color: white;
}
#highscorecontent {
overflow: auto;
}
.overlay {
position: fixed;
z-index: 10;
top: 0;
right: 0;
bottom: 0;
left: 0;
transition: all 1s linear;
}
.blured {
pointer-events:none;
filter: blur(8px);
-webkit-filter: blur(8px);
}
#optionspanel {
height: auto;
min-width: 180px;
max-width: 300px;
position: fixed;
background: #00a8f3;
border: 5px solid #2b577d;
z-index: 12;
top: 0;
right: 0;
left: 0;
padding: 3px;
margin: 40px;
margin-top: 100px;
color: white;
}
.navbar {
background: #4452985e;
height: 30px;
padding: 5px;
font-size: larger;
margin-bottom: 5px;
}
.title {
float: left;
padding: 3px;
}
.navbtns {
float: right;
}
#logo {
color: #3f48cc;
font-size: inherit;
/* margin: 5px; */
padding-top: 8px;
text-align: center;
max-width: 400px;
}
.fullcenter {
width: 100%;
height: 100%;
text-align: center;
}
.fullcenter img {
width: 30%;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#scorelist {
font-family: Arial, Helvetica, sans-serif;
width: 100%;
}
#scorelist td, #scorelist th {
border: 1px solid #ddd;
padding: 8px;
}
#scorelist td {
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#scorelist tr:nth-child(even){background-color: #0e81bb;}
#scorelist tr:nth-child(2n+1){background-color: #646f9f;}
#scorelist tr:hover {background-color: red;}
#scorelist th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #4452985e;
color: white;
}
#userzone input {
width: -webkit-fill-available;
width: -moz-available;
background: #123fe31f;
padding: 0.5rem;
border: none;
}
#userpanel {
display: flex;
}
#userprofilepicture{
width: 50%;
padding-right: 0.5rem;
}
#userprofilepicture img {
box-shadow: 4px 6px 7px 0px #0000ff47;
width: 100%;
max-width: 35rem;
}
::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: var(--placeholder-color);
opacity: 1; /* Firefox */
}
:-ms-input-placeholder { /* Internet Explorer 10-11 */
color: var(--placeholder-color);
}
::-ms-input-placeholder { /* Microsoft Edge */
color: var(--placeholder-color);
}
.smallfont {
font-size: 0.6rem;
}
.mt-05rem {
margin-top: 0.5rem;
}
fieldset {
margin-bottom: 1rem;
background-color: #00008017;
border: none;
}
hr {
height: 12px;
border: 0;
box-shadow: inset 0 6px 12px -12px rgba(0, 0, 0, 0.5);
}
.flexcolumn {
display: flex;
flex-direction: column;
}
.hidden {
display: none;
}
.height0{
height: 0px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment