class Puzzle {
constructor() {
this.puzzleWidth = document.getElementById("puzzle_criric_wrapper").offsetWidth;
this.puzzleHeight = this.aspectRadio(this.puzzleWidth);
this.level = 1;
this.timeslevels = [0, 15, 30, 60, 120, 180, 360, 600, 1200];
this.gameStart = false;
this.correct_position = [];
this.current_position = [];
this.iTimer = null;
this.score = 0;
this.gameover = false;
this.getImages("attrici");
}
aspectRadio(width) {
var aspectRatio = 800 / 600;
return Math.round(width / aspectRatio);
}
getImages(folder) {
this.get('/demos/puzzle_javascript_1/images.php?f=' + folder, (error, response) => {
if (error) {
console.error(error);
} else {
game.images = response;
let loaded_images = 0;
document.getElementById("thumbs").innerHTML = "";
for (var i = 0; i < game.images.length; i++) {
let img = document.createElement('img');
img.src = game.images[i];
// img.style.display = 'hidden'; // don't display preloaded images
img.onload = function () {
loaded_images++;
if (loaded_images === game.images.length) {
document.getElementById("puzzle_criric_percentage").innerHTML = '100%';
} else {
document.getElementById("puzzle_criric_percentage").innerHTML = (100 * loaded_images / game.images.length) + '%';
}
}
document.getElementById("thumbs").append(img);
}
}
});
}
tableScore(data) {
this.get('/demos/puzzle_javascript_1/score.php?s=' + data.s + '&l=' + data.l + "&p=" + data.p, (error, response) => {
if (error) {
console.error(error);
} else {
if (data.g) {
console.log("game over");
}
let table = document.querySelector("#table_score tbody");
table.innerHTML = "";
for (let record of response.records) {
let tr = document.createElement("tr");
let td = document.createElement("td");
td.innerHTML = record.player;
tr.append(td);
td = document.createElement("td");
td.innerHTML = record.score;
tr.append(td);
td = document.createElement("td");
td.innerHTML = record.level;
tr.append(td);
td = document.createElement("td");
td.innerHTML = record.data;
tr.append(td);
table.append(tr);
}
}
});
}
setLevel() {
document.getElementById("puzzle_criric_puzzle").style.height = this.puzzleHeight + "px";
this.rows = this.colums = this.level + 1;
this.divs = this.rows * this.colums;
this.w_div = this.puzzleWidth / this.colums;
console.log("w" + this.w_div);
this.h_div = this.puzzleHeight / this.rows;
console.log("h" + this.h_div);
this.tileSelected = false;
this.timer = this.mosse = this.last_position_correct = 0;
document.getElementById("puzzle_criric_score").innerHTML = "PUNTI " + this.score;
document.getElementById("puzzle_criric_mosse").innerHTML = "MOSSE 0";
document.getElementById("puzzle_criric_timer").innerHTML = "TEMPO 00:00";
document.getElementById("puzzle_criric_count-tiles").innerHTML = "PEZZI " + this.divs + " / " + this.divs;
}
createPuzzle() {
this.setLevel();
let position = this.createPosition();
if (this.gameStart) {
position = this.shuffle(position);
this.current_position = position;
this.checkPosition();
} else {
this.countToStart();
this.correct_position = position;
}
document.getElementById("puzzle_criric_puzzle").innerHTML = "";
document.getElementById("puzzle_criric_livello").innerHTML = "LIVELLO " + this.level;
for (let i = 0; i < this.divs; i++) {
let div = document.createElement("div");
div.style.width = Math.floor(this.puzzleWidth / this.rows) + "px";
div.style.height = this.puzzleHeight / this.colums + "px";
div.style.backgroundImage = "url('" + this.images[this.level - 1] + "')";
div.style.backgroundSize = this.puzzleWidth + "px " + this.puzzleHeight + "px";
div.style.backgroundPosition = position[i];
if (this.gameStart) {
div.addEventListener("click", this.clickTile);
}
document.getElementById("puzzle_criric_puzzle").append(div);
}
}
currentPosition() {
const elements = document.querySelectorAll('#puzzle_criric_puzzle div');
let i = 0;
elements.forEach(el => {
game.current_position[i] = el.style.backgroundPosition;
i++;
});
}
checkPosition() {
let position_correct = 0;
for (let i in this.correct_position) {
if (this.correct_position[i] === this.current_position[i]) {
position_correct++;
}
}
if (position_correct > this.last_position_correct) {
this.score += 5;
} else {
this.score -= 5;
}
this.last_position_correct = position_correct;
document.getElementById("puzzle_criric_score").innerHTML = "PUNTI " + game.score;
document.getElementById("puzzle_criric_count-tiles").innerHTML = "PEZZI " + position_correct + " / " + this.divs;
if (position_correct === this.divs) {
this.gameStart = false;
this.stopTimer();
const elements = document.querySelectorAll('#puzzle_criric_puzzle div');
elements.forEach(el => {
el.style.transition = "border-color 2s linear";
el.style.borderColor = "transparent";
});
if (this.level < this.images.length) {
this.level++;
}
this.updateScore();
}
}
updateScore() {
if (this.gameover) {
setTimeout(game.gameOver, 5000);
return false;
}
let score = this.score + (this.timer * 15);
let increment = 10;
if (score >= 500) {
increment = 50;
}
let u = setInterval(function () {
game.score += increment;
if (game.score >= score) {
game.score = score;
document.getElementById("puzzle_criric_score").innerHTML = "PUNTI " + score;
setTimeout(game.changeLevel, 5000);
clearInterval(u);
} else {
document.getElementById("puzzle_criric_score").innerHTML = "PUNTI " + game.score;
}
}, 100);
}
ucWords(str) {
return (str + '').replace(/^([a-z])|\s+([a-z])/g, function ($1) {
return $1.toUpperCase();
});
}
gameOver() {
document.getElementById("puzzle_criric_changeLevel").style.display = "inline";
document.getElementById("puzzle_criric_changeLevel").innerHTML = "GAME OVER<br>PUNTI TOTALI " + game.score;
const data = {
p: document.getElementById("player").value,
s: game.score,
l: game.level,
g: true
};
game.tableScore(data);
setTimeout(function () {
game.level = 1;
game.gameStart = false;
game.correct_position = [];
game.current_position = [];
game.iTimer = null;
game.score = 0;
game.gameover = false;
document.getElementById("puzzle_criric_start").style.display = "block";
document.getElementById("puzzle_criric_game").style.display = "none";
document.getElementById("puzzle_criric_changeLevel").style.display = "none";
init();
}, 4000);
}
changeLevel() {
game.setLevel();
document.getElementById("puzzle_criric_changeLevel").style.display = "inline";
let name = game.images[game.level - 1].split('/').reverse()[0];
name = name.replace("_", " ");
name = name.replace(".jpg", "");
let text = "LIVELLO " + game.level + "<br>";
text += game.ucWords(name) + "<br>";
text += game.divs + " pezzi<br>";
document.getElementById("puzzle_criric_changeLevel").innerHTML = text;
setTimeout(function () {
document.getElementById("puzzle_criric_changeLevel").style.display = "none";
game.createPuzzle();
game.countToStart();
}, 3000);
}
countToStart() {
game.setTimer(game.timeslevels[game.level]);
let limit = 5;
let count = setInterval(function () {
document.getElementById("puzzle_criric_count-start").innerHTML = limit;
limit--;
if (limit < 0) {
clearInterval(count);
document.getElementById("puzzle_criric_count-start").innerHTML = "";
game.gameStart = true;
game.createPuzzle();
game.startTimer(game.timeslevels[game.level]);
}
}, 1000);
}
clickTile() {
if (game.gameStart) {
if (game.tileSelected) {
game.mosse++;
document.getElementById("puzzle_criric_mosse").innerHTML = "MOSSE " + game.mosse;
game.tileSelected.style.boxShadow = "none";
let pos = game.tileSelected.style.backgroundPosition;
game.tileSelected.style.backgroundPosition = this.style.backgroundPosition;
this.style.backgroundPosition = pos;
game.tileSelected = false;
game.currentPosition();
game.checkPosition();
} else {
game.tileSelected = this;
this.style.boxShadow = "0px 0px 10px 2px #111 inset";
}
}
}
shuffle(o) { //v1.0
for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x)
;
return o;
}
createPosition() {
var x = 0;
var y = 0;
var divs = [];
for (var i = 0; i < this.divs; i++) {
divs[i] = x.toFixed(0) + "px " + y.toFixed(0) + "px";
x = x === 0 ? this.puzzleWidth - this.w_div : x - this.w_div;
if (Math.ceil(x) === 0 || Math.ceil(x) === 1) {
x = 0;
if (Math.ceil(y) === 0) {
y = this.puzzleHeight - this.h_div;
} else {
y = y - this.h_div;
}
}
}
return divs;
}
stopTimer() {
for (let i = 0; i <= this.iTimer; i++) {
clearInterval(i);
}
}
setTimer(duration) {
var timer = duration, minutes, seconds;
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.querySelector('#puzzle_criric_timer').textContent = "TEMPO " + minutes + ":" + seconds;
}
startTimer(duration) {
var timer = duration, minutes, seconds;
game.timer = 0;
game.iTimer = setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.querySelector('#puzzle_criric_timer').textContent = "TEMPO " + minutes + ":" + seconds;
game.timer = timer;
if (--timer < 0) {
document.getElementById("puzzle_criric_changeLevel").innerHTML = "TEMPO SCADUTO";
document.getElementById("puzzle_criric_changeLevel").style.display = "inline";
game.gameover = true;
document.querySelector('#puzzle_criric_timer').textContent = "GAME OVER";
game.stopTimer();
setTimeout(function () {
document.getElementById("puzzle_criric_changeLevel").style.display = "none";
}, 2000);
setTimeout(function () {
game.gameOver();
}, 20000);
}
}, 1000);
}
// Metodo per effettuare una richiesta GET
get(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
callback(null, JSON.parse(xhr.responseText));
} else {
callback(`Error: ${xhr.status} ${xhr.statusText}`);
}
};
xhr.onerror = () => {
callback('Request failed');
};
xhr.send();
}
}