remake hologram
This commit is contained in:
parent
4a8299e5a6
commit
9d3f4714d2
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"elle",
|
||||||
|
"fixée"
|
||||||
|
]
|
||||||
|
}
|
313
index.js
313
index.js
@ -104,292 +104,67 @@ const templateColor = [
|
|||||||
[177, 225, 218, 255]
|
[177, 225, 218, 255]
|
||||||
];
|
];
|
||||||
|
|
||||||
const MOVELEFT = 1;
|
|
||||||
const MOVERIGHT = 2;
|
|
||||||
const MOVEDOWN = 3;
|
|
||||||
const ROTATE = 4;
|
|
||||||
const MOVEDOWNFAST = 5;
|
|
||||||
const RESPAWN = 6;
|
|
||||||
const CHANGENEXTPIECE = 7;
|
|
||||||
|
|
||||||
function ifPiece(x, y, board) {
|
|
||||||
if (x < 0 || x >= 10 || y >= 20) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (board[x][y][0] == 0 && board[x][y][1] == 0 && board[x][y][2] == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function canMoveTo(x, y, piece, board) {
|
|
||||||
for (let i = 0; i < piece.length - 1; i++) {
|
|
||||||
if (piece[i][0] + x < 0 || piece[i][0] + x >= 10 || piece[i][1] + y >= 20 || ifPiece(piece[i][0] + x, piece[i][1] + y, board)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ifRotate(piece, board) {
|
|
||||||
for (let i = 0; i < piece.length - 1; i++) {
|
|
||||||
if (piece[i][0] < 0 || piece[i][0] >= 10 || piece[i][1] >= 20 || ifPiece(piece[i][0], piece[i][1], board)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveDown(piece, board) {
|
|
||||||
if (canMoveTo(0, 1, piece, board)) {
|
|
||||||
for (let i = 0; i < piece.length; i++) {
|
|
||||||
piece[i][1]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveLeft(piece, board) {
|
|
||||||
if (canMoveTo(-1, 0, piece, board)) {
|
|
||||||
for (let i = 0; i < piece.length; i++) {
|
|
||||||
piece[i][0]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveRight(piece, board) {
|
|
||||||
if (canMoveTo(1, 0, piece, board)) {
|
|
||||||
for (let i = 0; i < piece.length; i++) {
|
|
||||||
piece[i][0]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function rotate(piece, board) {
|
|
||||||
if (piece.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentPieceCopy = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < piece.length; i++) {
|
|
||||||
currentPieceCopy.push([piece[i][0], piece[i][1]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const center = currentPieceCopy[currentPieceCopy.length - 1];
|
|
||||||
for (let i = 0; i < piece.length - 1; i++) {
|
|
||||||
const x = currentPieceCopy[i][0] - center[0];
|
|
||||||
const y = currentPieceCopy[i][1] - center[1];
|
|
||||||
|
|
||||||
currentPieceCopy[i][0] = center[0] - y;
|
|
||||||
currentPieceCopy[i][1] = center[1] + x;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (ifRotate(currentPieceCopy, board)) {
|
|
||||||
piece = currentPieceCopy;
|
|
||||||
// Don't modify history in verification function
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (let x = -1; x <= 1; x++) {
|
|
||||||
for (let y = 0; y >= -1; y--) {
|
|
||||||
if (canMoveTo(x, y, currentPieceCopy, board)) {
|
|
||||||
moveToPiece(x, y, currentPieceCopy);
|
|
||||||
piece = currentPieceCopy;
|
|
||||||
|
|
||||||
x = 2;
|
|
||||||
y = -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveToPiece(x, y, piece) {
|
|
||||||
for (let i = 0; i < piece.length; i++) {
|
|
||||||
piece[i][0] += x;
|
|
||||||
piece[i][1] += y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkLine(board, scoreObject) {
|
|
||||||
let lineFilled = 0;
|
|
||||||
let score = 0;
|
|
||||||
let lines = 0;
|
|
||||||
let level = 0;
|
|
||||||
|
|
||||||
for (let i = 0; i < 20; i++) {
|
|
||||||
let check = true;
|
|
||||||
|
|
||||||
for (let j = 0; j < 10; j++) {
|
|
||||||
if (board[j][i][0] == 0 && board[j][i][1] == 0 && board[j][i][2] == 0) {
|
|
||||||
check = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check) {
|
|
||||||
for (let j = i; j > 0; j--) {
|
|
||||||
for (let k = 0; k < 10; k++) {
|
|
||||||
board[k][j] = board[k][j - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let k = 0; k < 10; k++) {
|
|
||||||
board[k][0] = [0, 0, 0, 255];
|
|
||||||
}
|
|
||||||
|
|
||||||
lineFilled++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lineFilled == 1) {
|
|
||||||
score += 40;
|
|
||||||
}
|
|
||||||
else if (lineFilled == 2) {
|
|
||||||
score += 100;
|
|
||||||
}
|
|
||||||
else if (lineFilled == 3) {
|
|
||||||
score += 300;
|
|
||||||
}
|
|
||||||
else if (lineFilled == 4) {
|
|
||||||
score += 1200;
|
|
||||||
}
|
|
||||||
|
|
||||||
lines += lineFilled;
|
|
||||||
level = Math.floor(lines / 10);
|
|
||||||
|
|
||||||
scoreObject.score += score;
|
|
||||||
scoreObject.lines += lineFilled;
|
|
||||||
scoreObject.level = Math.floor(scoreObject.lines / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function verifieHystoryAndScore(score, history) {
|
|
||||||
let board = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
board[i] = [];
|
|
||||||
for (let j = 0; j < 20; j++) {
|
|
||||||
board[i][j] = [0, 0, 0, 255];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let piece = [];
|
|
||||||
let nextPiece = [];
|
|
||||||
let nextIndex = 0;
|
|
||||||
|
|
||||||
let scoreObject = {
|
|
||||||
score: 0,
|
|
||||||
lines: 0,
|
|
||||||
level: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let i = 0; i < history.length; i++) {
|
|
||||||
if (history[i][0] === CHANGENEXTPIECE) {
|
|
||||||
// Only place non-fractional coordinates on the board
|
|
||||||
for (let j = 0; j < piece.length - 1; j++) {
|
|
||||||
if (Number.isInteger(piece[j][0]) && Number.isInteger(piece[j][1]) &&
|
|
||||||
piece[j][0] >= 0 && piece[j][0] < 10 &&
|
|
||||||
piece[j][1] >= 0 && piece[j][1] < 20) {
|
|
||||||
board[piece[j][0]][piece[j][1]] = [templateColor[nextIndex][0], templateColor[nextIndex][1], templateColor[nextIndex][2], templateColor[nextIndex][3]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkLine(board, scoreObject);
|
|
||||||
|
|
||||||
nextIndex = history[i][1];
|
|
||||||
|
|
||||||
// Reset piece and copy from template
|
|
||||||
piece = [];
|
|
||||||
for (let j = 0; j < templatePiece[nextIndex].length; j++) {
|
|
||||||
piece.push([templatePiece[nextIndex][j][0], templatePiece[nextIndex][j][1]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up next piece
|
|
||||||
nextPiece = [];
|
|
||||||
let nextNextIndex = (i+1 < history.length && history[i+1][0] === CHANGENEXTPIECE) ? history[i+1][1] : 0;
|
|
||||||
for (let j = 0; j < templatePiece[nextNextIndex].length; j++) {
|
|
||||||
nextPiece.push([templatePiece[nextNextIndex][j][0], templatePiece[nextNextIndex][j][1]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (history[i][0] === MOVEDOWN) {
|
|
||||||
moveDown(piece, board);
|
|
||||||
}
|
|
||||||
else if (history[i][0] === MOVELEFT) {
|
|
||||||
moveLeft(piece, board);
|
|
||||||
}
|
|
||||||
else if (history[i][0] === MOVERIGHT) {
|
|
||||||
moveRight(piece, board);
|
|
||||||
}
|
|
||||||
else if (history[i][0] === ROTATE) {
|
|
||||||
rotate(piece, board);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Calculated score:", scoreObject.score, "Submitted score:", score);
|
|
||||||
return score === scoreObject.score;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.put('/api/sendScore', (req, res) => {
|
app.put('/api/sendScore', (req, res) => {
|
||||||
|
|
||||||
let score = req.body.score;
|
let score = req.body.score;
|
||||||
let history = req.body.history;
|
// let history = req.body.history;
|
||||||
|
let lines = req.body.lines;
|
||||||
let playerName = req.body.playerName;
|
let playerName = req.body.playerName;
|
||||||
|
|
||||||
// if (score === null || history === null || playerName === null) {
|
// Vérifier si le score est un nombre valide
|
||||||
// return res.status(400).send('Missing required fields');
|
if (isNaN(score) || score < 0) {
|
||||||
|
return res.status(400).send('Invalid score');
|
||||||
|
}
|
||||||
|
// Vérifier si l'historique est un tableau valide
|
||||||
|
// if (!Array.isArray(history)) {
|
||||||
|
// return res.status(400).send('Invalid history');
|
||||||
// }
|
// }
|
||||||
|
// Vérifier si le nom du joueur est une chaîne de caractères valide
|
||||||
// if (score < 0) {
|
if (typeof playerName !== 'string' || playerName.trim() === '') {
|
||||||
// return res.status(400).send('Score cannot be negative');
|
return res.status(400).send('Invalid player name');
|
||||||
// }
|
}
|
||||||
|
// Vérifier si le score est supérieur à 0 et inférieur à 1200 * (lines/4)
|
||||||
// if (history.length === 0) {
|
if ((lines/4) * 1200 < score) {
|
||||||
// return res.status(400).send('History cannot be empty');
|
return res.status(400).send('Invalid score');
|
||||||
// }
|
}
|
||||||
|
// Vérifier si la line est un nombre valide
|
||||||
if (!verifieHystoryAndScore(score, history)) {
|
if (isNaN(lines) || lines < 0) {
|
||||||
return res.status(400).send('Invalid history or score');
|
return res.status(400).send('Invalid lines');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si le dossier des historiques existe, le créer si nécessaire
|
// Vérifier si le dossier des historiques existe, le créer si nécessaire
|
||||||
const historyDir = './datas/histories';
|
// const historyDir = './datas/histories';
|
||||||
if (!fs.existsSync(historyDir)) {
|
// if (!fs.existsSync(historyDir)) {
|
||||||
fs.mkdirSync(historyDir, { recursive: true });
|
// fs.mkdirSync(historyDir, { recursive: true });
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Date du jour
|
// Date du jour
|
||||||
|
|
||||||
const date = new Date();
|
// const date = new Date();
|
||||||
const dateString = date.toISOString().split('T')[0]; // Format YYYY-MM-DD
|
// const dateString = date.toISOString().split('T')[0]; // Format YYYY-MM-DD
|
||||||
|
|
||||||
// Vérifier si un fichier avec ce nom existe déjà et ajouter un chiffre si nécessaire
|
// // Vérifier si un fichier avec ce nom existe déjà et ajouter un chiffre si nécessaire
|
||||||
let finalPlayerName = playerName + dateString;
|
// let finalPlayerName = playerName + dateString;
|
||||||
let counter = 0;
|
// let counter = 0;
|
||||||
let historyFilePath = `${historyDir}/${finalPlayerName}.json`;
|
// let historyFilePath = `${historyDir}/${finalPlayerName}.json`;
|
||||||
|
|
||||||
while (fs.existsSync(historyFilePath)) {
|
// while (fs.existsSync(historyFilePath)) {
|
||||||
counter++;
|
// counter++;
|
||||||
finalPlayerName = `${playerName}${dateString}${counter}`;
|
// finalPlayerName = `${playerName}${dateString}${counter}`;
|
||||||
historyFilePath = `${historyDir}/${finalPlayerName}.json`;
|
// historyFilePath = `${historyDir}/${finalPlayerName}.json`;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Écrire l'historique dans le fichier
|
// // Écrire l'historique dans le fichier
|
||||||
try {
|
// try {
|
||||||
fs.writeFileSync(historyFilePath, JSON.stringify(history));
|
// fs.writeFileSync(historyFilePath, JSON.stringify(history));
|
||||||
console.log(`History written to ${historyFilePath}`);
|
// console.log(`History written to ${historyFilePath}`);
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
console.error('Error writing history file:', err);
|
// console.error('Error writing history file:', err);
|
||||||
return res.status(500).send('Error writing history file');
|
// return res.status(500).send('Error writing history file');
|
||||||
}
|
// }
|
||||||
|
|
||||||
//
|
//
|
||||||
db.run('INSERT INTO scores (player_name, score, pathHistory) VALUES (?, ?, ?)', [playerName, score, historyFilePath])
|
db.run('INSERT INTO scores (player_name, score, pathHistory) VALUES (?, ?, ?)', [playerName, score, "/"])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log(`Score inserted for ${playerName}`);
|
console.log(`Score inserted for ${playerName}`);
|
||||||
})
|
})
|
||||||
|
BIN
public/font/Pixeboy-z8XGD.ttf
Normal file
BIN
public/font/Pixeboy-z8XGD.ttf
Normal file
Binary file not shown.
@ -44,20 +44,20 @@
|
|||||||
<div class="hidden" id="board-container">
|
<div class="hidden" id="board-container">
|
||||||
<canvas id="tetris-canvas" width="300" height="600"></canvas>
|
<canvas id="tetris-canvas" width="300" height="600"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-menu" id="main-menu" >
|
<div class="main-menu menu" id="main-menu" >
|
||||||
<button id="start-button">Start</button>
|
<label id="start-button" class="button">Start</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="gameOver hidden" id="game-over-menu">
|
<div class="gameOver-menu menu hidden" id="game-over-menu">
|
||||||
<p>Game Over</p>
|
<p>Game Over</p>
|
||||||
<label id="restart-button">Restart</label>
|
<label id="restart-button" class="button">Restart</label>
|
||||||
<button id="main-menu">Main Menu</button>
|
<label id="main-menu-button2">Main Menu</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="pause hidden" id="pause-menu">
|
<div class="pause-menu menu hidden" id="pause-menu">
|
||||||
<p>Paused</p>
|
<p>Paused</p>
|
||||||
<button id="resume-button">Resume</button>
|
<label id="resume-button" class="button">Resume</label>
|
||||||
<button id="main-menu">Main Menu</button>
|
<label id="main-menu-button" class="button">Main Menu</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="load-menu hidden" id="load-menu">
|
<div class="load-menu menu hidden" id="load-menu">
|
||||||
<span class="loader"></span>
|
<span class="loader"></span>
|
||||||
<p>Loading...</p>
|
<p>Loading...</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,10 @@ function initGame() {
|
|||||||
refreshInterval = setInterval(() => {
|
refreshInterval = setInterval(() => {
|
||||||
refreshBoard(game.board);
|
refreshBoard(game.board);
|
||||||
displayPreview(game);
|
displayPreview(game);
|
||||||
|
scoreElement.innerText = game.score;
|
||||||
}, 16);
|
}, 16);
|
||||||
|
|
||||||
|
history = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function initOrChangeDropInterval(speed) {
|
function initOrChangeDropInterval(speed) {
|
||||||
|
@ -90,8 +90,8 @@ function refreshBoard() {
|
|||||||
drawSquare(square.x, square.y, square);
|
drawSquare(square.x, square.y, square);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawCurrentPiece();
|
|
||||||
drawHologram();
|
drawHologram();
|
||||||
|
drawCurrentPiece();
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawHologram() {
|
function drawHologram() {
|
||||||
|
@ -22,3 +22,7 @@ const buttonContainer = document.getElementById('pause-container');
|
|||||||
const highScoreTemplate = document.getElementById('high-score-template');
|
const highScoreTemplate = document.getElementById('high-score-template');
|
||||||
|
|
||||||
const highScoresList = document.getElementById('high-scores-list');
|
const highScoresList = document.getElementById('high-scores-list');
|
||||||
|
|
||||||
|
const resumeButton = document.getElementById('resume-button');
|
||||||
|
const mainMenuButton = document.getElementById('main-menu-button');
|
||||||
|
const mainMenuButtonBis = document.getElementById('main-menu-button2');
|
@ -1,4 +1,4 @@
|
|||||||
function ifPieceInBoard(x, y, game) {
|
function ifPieceInBoard(x, y) {
|
||||||
let board = game.board;
|
let board = game.board;
|
||||||
|
|
||||||
if (x < 0 || x >= width || y >= height) {
|
if (x < 0 || x >= width || y >= height) {
|
||||||
@ -14,32 +14,32 @@ function ifPieceInBoard(x, y, game) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ifMovePiece(x, y, piece, game) {
|
function ifMovePiece(x, y, piece = game.currentPiece) {
|
||||||
for (let i = 0; i < piece.squares.length; i++) {
|
for (let i = 0; i < piece.squares.length; i++) {
|
||||||
let square = piece.squares[i];
|
let square = piece.squares[i];
|
||||||
let newX = square.x + x;
|
let newX = square.x + x;
|
||||||
let newY = square.y + y;
|
let newY = square.y + y;
|
||||||
|
|
||||||
if (ifPieceInBoard(newX, newY, game)) {
|
if (ifPieceInBoard(newX, newY)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ifMoveDown(piece, game) {
|
function ifMoveDown(piece = game.currentPiece) {
|
||||||
return ifMovePiece(0, 1, piece, game);
|
return ifMovePiece(0, 1, piece);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ifMoveLeft(piece, game) {
|
function ifMoveLeft(piece = game.currentPiece) {
|
||||||
return ifMovePiece(-1, 0, piece, game);
|
return ifMovePiece(-1, 0, piece);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ifMoveRight(piece, game) {
|
function ifMoveRight(piece = game.currentPiece) {
|
||||||
return ifMovePiece(1, 0, piece, game);
|
return ifMovePiece(1, 0, piece);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ifRotate(piece, game) {
|
function ifRotate(piece = game.currentPiece) {
|
||||||
let centerX = piece.xCenter;
|
let centerX = piece.xCenter;
|
||||||
let centerY = piece.yCenter;
|
let centerY = piece.yCenter;
|
||||||
|
|
||||||
@ -51,14 +51,14 @@ function ifRotate(piece, game) {
|
|||||||
let newX = -y + centerX;
|
let newX = -y + centerX;
|
||||||
let newY = x + centerY;
|
let newY = x + centerY;
|
||||||
|
|
||||||
if (ifPieceInBoard(newX, newY, game)) {
|
if (ifPieceInBoard(newX, newY)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveDown(piece) {
|
function moveDown(piece = game.currentPiece) {
|
||||||
for (let i = 0; i < piece.squares.length; i++) {
|
for (let i = 0; i < piece.squares.length; i++) {
|
||||||
let square = piece.squares[i];
|
let square = piece.squares[i];
|
||||||
square.y += 1;
|
square.y += 1;
|
||||||
@ -67,8 +67,8 @@ function moveDown(piece) {
|
|||||||
piece.yCenter += 1;
|
piece.yCenter += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveLeft(piece) {
|
function moveLeft(piece = game.currentPiece) {
|
||||||
if (!ifMoveLeft(piece, game)) {
|
if (!ifMoveLeft(piece)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,8 +80,8 @@ function moveLeft(piece) {
|
|||||||
piece.xCenter -= 1;
|
piece.xCenter -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveRight(piece) {
|
function moveRight(piece = game.currentPiece) {
|
||||||
if (!ifMoveRight(piece, game)) {
|
if (!ifMoveRight(piece)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ function rotatePiece(piece) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixPieceToBoard(piece, game) {
|
function fixPieceToBoard(piece = game.currentPiece) {
|
||||||
for (let i = 0; i < piece.squares.length; i++) {
|
for (let i = 0; i < piece.squares.length; i++) {
|
||||||
let square = piece.squares[i];
|
let square = piece.squares[i];
|
||||||
game.board.push(square);
|
game.board.push(square);
|
||||||
@ -163,18 +163,18 @@ function fixPieceToBoard(piece, game) {
|
|||||||
|
|
||||||
opacityCurrentPiece = 1;
|
opacityCurrentPiece = 1;
|
||||||
|
|
||||||
checkLine(game);
|
checkLine();
|
||||||
// Vous pouvez également gérer ici la création d'une nouvelle pièce
|
// Vous pouvez également gérer ici la création d'une nouvelle pièce
|
||||||
// ou vérifier si des lignes doivent être supprimées.
|
// ou vérifier si des lignes doivent être supprimées.
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkLine(game, ifNoFall = false) {
|
function checkLine(ifNoFall = false) {
|
||||||
let lineFilled = [];
|
let lineFilled = [];
|
||||||
|
|
||||||
for (let i = 0; i < 20; i++) {
|
for (let i = 0; i < 20; i++) {
|
||||||
let filled = true;
|
let filled = true;
|
||||||
for (let j = 0; j < 10; j++) {
|
for (let j = 0; j < 10; j++) {
|
||||||
if (!ifPieceInBoard(j, i, game)) {
|
if (!ifPieceInBoard(j, i)) {
|
||||||
filled = false;
|
filled = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -217,46 +217,108 @@ function checkLine(game, ifNoFall = false) {
|
|||||||
game.score += 1200;
|
game.score += 1200;
|
||||||
}
|
}
|
||||||
|
|
||||||
scoreElement.innerText = game.score;
|
|
||||||
game.lines += lineFilled.length;
|
game.lines += lineFilled.length;
|
||||||
game.level = Math.floor(game.lines / 10);
|
game.level = Math.floor(game.lines / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchPiece(game) {
|
function switchPiece() {
|
||||||
game.currentPiece = game.nextPiece;
|
game.currentPiece = game.nextPiece;
|
||||||
game.nextPiece = getRandomPiece();
|
game.nextPiece = getRandomPiece();
|
||||||
|
|
||||||
for (let i = 0; i < game.currentPiece.squares.length; i++) {
|
for (let i = 0; i < game.currentPiece.squares.length; i++) {
|
||||||
if (ifPieceInBoard(game.currentPiece.squares[i].x, game.currentPiece.squares[i].y, game)) {
|
let x = game.currentPiece.squares[i].x;
|
||||||
game.gameOver = true;
|
let y = game.currentPiece.squares[i].y;
|
||||||
clearInterval(dropInterval);
|
if (ifPieceInBoard(x, y)) {
|
||||||
clearInterval(leftInterval);
|
finishGame();
|
||||||
clearInterval(rightInterval);
|
|
||||||
clearInterval(refreshInterval);
|
|
||||||
|
|
||||||
clearInterval(endDropInterval);
|
|
||||||
endDropInterval = null;
|
|
||||||
opacityCurrentPiece = 1;
|
|
||||||
game.currentPiece = null;
|
|
||||||
dropInterval = null;
|
|
||||||
refreshInterval = null;
|
|
||||||
|
|
||||||
displayGameOver();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSpeed(game) {
|
function finishGame(sendScore = true, gameOver = true) {
|
||||||
if (game.level > 29) {
|
game.gameOver = true;
|
||||||
game.speed = (speedSecondsToBotomPerLevel[29] / 20) * 1000;
|
clearInterval(dropInterval);
|
||||||
|
clearInterval(leftInterval);
|
||||||
|
clearInterval(rightInterval);
|
||||||
|
clearInterval(refreshInterval);
|
||||||
|
|
||||||
|
clearInterval(endDropInterval);
|
||||||
|
endDropInterval = null;
|
||||||
|
opacityCurrentPiece = 1;
|
||||||
|
game.currentPiece = null;
|
||||||
|
dropInterval = null;
|
||||||
|
refreshInterval = null;
|
||||||
|
|
||||||
|
if (gameOver) {
|
||||||
|
displayGameOver();
|
||||||
|
} else {
|
||||||
|
displayMainMenu();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
game.speed = (speedSecondsToBotomPerLevel[game.level] / 20) * 1000;
|
if (sendScore) {
|
||||||
|
const playerName = prompt('Enter your name:');
|
||||||
|
|
||||||
|
sendScore(game, playerName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function endDrop(game) {
|
async function sendScore(playerName) {
|
||||||
|
if (playerName) {
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
score: game.score,
|
||||||
|
lines: game.lines,
|
||||||
|
playerName
|
||||||
|
};
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send a PUT request to the server
|
||||||
|
const query = await fetch('/api/sendScore', {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if the response is ok before parsing
|
||||||
|
if (!query.ok) {
|
||||||
|
throw new Error(`Server returned ${query.status}: ${query.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the content type to ensure it's JSON
|
||||||
|
const contentType = query.headers.get('content-type');
|
||||||
|
if (!contentType || !contentType.includes('application/json')) {
|
||||||
|
throw new Error('Server did not return JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the response body
|
||||||
|
const response = await query.json();
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
console.log('Score and history saved successfully');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error('Error saving score and history:', response.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to save score:', error.message);
|
||||||
|
alert('Could not save your score. Please try again later.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSpeed() {
|
||||||
|
if (game.level > 29) {
|
||||||
|
game.speed = (speedSecondsToBottomPerLevel[29] / 20) * 1000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
game.speed = (speedSecondsToBottomPerLevel[game.level] / 20) * 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function endDrop() {
|
||||||
let piece = game.currentPiece;
|
let piece = game.currentPiece;
|
||||||
|
|
||||||
// La pièce ne peut plus descendre, elle est fixée sur le plateau
|
// La pièce ne peut plus descendre, elle est fixée sur le plateau
|
||||||
@ -278,18 +340,18 @@ function endDrop(game) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fastDrop(game, piece = game.currentPiece) {
|
function fastDrop(piece = game.currentPiece) {
|
||||||
if (piece) {
|
if (piece) {
|
||||||
let canMoveDown = true;
|
let canMoveDown = true;
|
||||||
|
|
||||||
while (canMoveDown) {
|
while (canMoveDown) {
|
||||||
canMoveDown = ifMoveDown(piece, game);
|
canMoveDown = ifMoveDown();
|
||||||
if (canMoveDown) {
|
if (canMoveDown) {
|
||||||
moveDown(piece);
|
moveDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fixPieceToBoard(piece, game);
|
fixPieceToBoard();
|
||||||
|
|
||||||
clearInterval(endDropInterval);
|
clearInterval(endDropInterval);
|
||||||
endDropInterval = null; // Réinitialisez après l'arrêt
|
endDropInterval = null; // Réinitialisez après l'arrêt
|
||||||
|
@ -231,7 +231,7 @@ function pauseGame() {
|
|||||||
|
|
||||||
function iniGame() {
|
function iniGame() {
|
||||||
// Initialisation de la vitesse de chute
|
// Initialisation de la vitesse de chute
|
||||||
speed = (speedSecondsToBotomPerLevel[level]/20) * 1000;
|
speed = (speedSecondsToBottomPerLevel[level]/20) * 1000;
|
||||||
|
|
||||||
spawnPiece();
|
spawnPiece();
|
||||||
|
|
||||||
@ -521,10 +521,10 @@ function checkLine() {
|
|||||||
|
|
||||||
function initAndChangeSpeedDrop() {
|
function initAndChangeSpeedDrop() {
|
||||||
if (level > 29) {
|
if (level > 29) {
|
||||||
speed = (speedSecondsToBotomPerLevel[29]/20) * 1000;
|
speed = (speedSecondsToBottomPerLevel[29]/20) * 1000;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
speed = (speedSecondsToBotomPerLevel[level]/20) * 1000;
|
speed = (speedSecondsToBottomPerLevel[level]/20) * 1000;
|
||||||
}
|
}
|
||||||
clearDownInterval();
|
clearDownInterval();
|
||||||
downInterval = setInterval(() => {
|
downInterval = setInterval(() => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const speedSecondsToBotomPerLevel = [
|
const speedSecondsToBottomPerLevel = [
|
||||||
15.974, //0
|
15.974, //0
|
||||||
14.31, //1
|
14.31, //1
|
||||||
12.646, //2
|
12.646, //2
|
||||||
@ -33,3 +33,10 @@ const speedSecondsToBotomPerLevel = [
|
|||||||
|
|
||||||
const width = 10;
|
const width = 10;
|
||||||
const height = 20;
|
const height = 20;
|
||||||
|
|
||||||
|
const DOWNHISTORY = 1;
|
||||||
|
const LEFTHISTORY = 2;
|
||||||
|
const RIGHTHISTORY = 3;
|
||||||
|
const ROTATEHISTORY = 4;
|
||||||
|
const ENDPARTYHISTORY = 5;
|
||||||
|
const ISNEXTHISTORY = 6;
|
@ -7,3 +7,12 @@ pauseButton.addEventListener('click', function() {
|
|||||||
restartButton.addEventListener('click', function() {
|
restartButton.addEventListener('click', function() {
|
||||||
initGame();
|
initGame();
|
||||||
});
|
});
|
||||||
|
resumeButton.addEventListener('click', function() {
|
||||||
|
pauseGame();
|
||||||
|
});
|
||||||
|
mainMenuButton.addEventListener('click', function() {
|
||||||
|
finishGame(false, false);
|
||||||
|
});
|
||||||
|
mainMenuButtonBis.addEventListener('click', function() {
|
||||||
|
finishGame(false, false);
|
||||||
|
});
|
@ -9,3 +9,5 @@ let refreshInterval = null;
|
|||||||
let endDropInterval = null;
|
let endDropInterval = null;
|
||||||
|
|
||||||
let opacityCurrentPiece = 1;
|
let opacityCurrentPiece = 1;
|
||||||
|
|
||||||
|
let history = [];
|
@ -1,24 +1,30 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'PixelatedElegance';
|
||||||
|
src: url('../font/Pixeboy-z8XGD.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100svh;
|
height: 100svh;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
background: repeating-conic-gradient(
|
background: repeating-conic-gradient(from 45deg,
|
||||||
from 45deg,
|
|
||||||
#7FB196 0% 25%,
|
#7FB196 0% 25%,
|
||||||
#3C425A 0% 50%
|
#3C425A 0% 50%);
|
||||||
);
|
background-size: max(10vw, 10svh) max(10vw, 10svh);
|
||||||
background-size: max(10vw, 10svh) max(10vw, 10svh);
|
|
||||||
|
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
|
|
||||||
align-self: center;
|
align-self: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
|
font-family: 'PixelatedElegance', monospace;
|
||||||
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@ -28,8 +34,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tetris {
|
.tetris {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 600px;
|
height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame {
|
.frame {
|
||||||
@ -41,7 +47,8 @@ body {
|
|||||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
|
||||||
|
|
||||||
background: #414241a0;
|
background: #414241a0;
|
||||||
position: relative; /* Nécessaire pour le positionnement du pseudo-élément */
|
position: relative;
|
||||||
|
/* Nécessaire pour le positionnement du pseudo-élément */
|
||||||
|
|
||||||
p {
|
p {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
@ -57,10 +64,13 @@ body {
|
|||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: #4E4F4DA0;
|
background: #4E4F4DA0;
|
||||||
border-radius: 10px; /* Même border-radius que le parent */
|
border-radius: 10px;
|
||||||
|
/* Même border-radius que le parent */
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
-webkit-backdrop-filter: blur(8px); /* Pour Safari */
|
-webkit-backdrop-filter: blur(8px);
|
||||||
z-index: -1; /* Assure que le fond est derrière le contenu */
|
/* Pour Safari */
|
||||||
|
z-index: -1;
|
||||||
|
/* Assure que le fond est derrière le contenu */
|
||||||
}
|
}
|
||||||
|
|
||||||
.first {
|
.first {
|
||||||
@ -81,25 +91,25 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.main-menu {
|
.main-menu {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-menu {
|
.load-menu {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.play-pause {
|
.icon.play-pause {
|
||||||
@ -107,18 +117,21 @@ body {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 37px; /* Réduit de moitié (était 74px) */
|
height: 37px;
|
||||||
|
/* Réduit de moitié (était 74px) */
|
||||||
|
|
||||||
border-color: transparent transparent transparent #74dc74;
|
border-color: transparent transparent transparent #74dc74;
|
||||||
transition: 100ms all ease;
|
transition: 100ms all ease;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 18.5px 0 18.5px 30px; /* Réduit proportionnellement (était 37px 0 37px 60px) */
|
border-width: 18.5px 0 18.5px 30px;
|
||||||
|
/* Réduit proportionnellement (était 37px 0 37px 60px) */
|
||||||
|
|
||||||
&.paused {
|
&.paused {
|
||||||
border-style: double;
|
border-style: double;
|
||||||
border-width: 0px 0 0px 30px; /* Réduit (était 60px) */
|
border-width: 0px 0 0px 30px;
|
||||||
|
/* Réduit (était 60px) */
|
||||||
border-color: transparent transparent transparent #ff5e5e;
|
border-color: transparent transparent transparent #ff5e5e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,41 +151,53 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.loader {
|
.loader {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
border: 5px solid #FFF;
|
border: 5px solid #FFF;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
animation: pulse 1s linear infinite;
|
animation: pulse 1s linear infinite;
|
||||||
}
|
}
|
||||||
.loader:after {
|
|
||||||
content: '';
|
.loader:after {
|
||||||
position: absolute;
|
content: '';
|
||||||
width: 48px;
|
position: absolute;
|
||||||
height: 48px;
|
width: 48px;
|
||||||
border: 5px solid #FFF;
|
height: 48px;
|
||||||
border-radius: 50%;
|
border: 5px solid #FFF;
|
||||||
display: inline-block;
|
border-radius: 50%;
|
||||||
box-sizing: border-box;
|
display: inline-block;
|
||||||
left: 50%;
|
box-sizing: border-box;
|
||||||
top: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
top: 50%;
|
||||||
animation: scaleUp 1s linear infinite;
|
transform: translate(-50%, -50%);
|
||||||
|
animation: scaleUp 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleUp {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) scale(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes scaleUp {
|
60%,
|
||||||
0% { transform: translate(-50%, -50%) scale(0) }
|
100% {
|
||||||
60% , 100% { transform: translate(-50%, -50%) scale(1)}
|
transform: translate(-50%, -50%) scale(1)
|
||||||
}
|
}
|
||||||
@keyframes pulse {
|
}
|
||||||
0% , 60% , 100%{ transform: scale(1) }
|
|
||||||
80% { transform: scale(1.2)}
|
@keyframes pulse {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
60%,
|
||||||
|
100% {
|
||||||
|
transform: scale(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
80% {
|
||||||
display: none;
|
transform: scale(1.2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.scoreboard {
|
.scoreboard {
|
||||||
@ -189,3 +214,36 @@ body {
|
|||||||
width: 200px;
|
width: 200px;
|
||||||
height: 600px;
|
height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: #4E4F4DA0;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0px;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user