const KEY_NAMES = new Proxy({ ["ArrowLeft"] : "←", ["←"] : "ArrowLeft", ["ArrowRight"] : "→", ["→"] : "ArrowRight", ["ArrowUp"] : "↑", ["↑"] : "ArrowUp", ["ArrowDown"] : "↓", ["↓"] : "ArrowDown", [" "] : "Espace", ["Espace"] : " ", ["Escape"] : "Échap.", ["Échap."] : "Escape", ["Backspace"] : "Ret. arrière", ["Ret. arrière"]: "Backspace", ["Enter"] : "Entrée", ["Entrée"] : "Enter", }, { get(target, key) { return key in target? target[key] : key } }) class Settings { constructor() { this.form = settingsForm this.load() this.modal = new bootstrap.Modal('#settingsModal') settingsModal.addEventListener('shown.bs.modal', () => resumeButton.focus()) } load() { this.form.querySelectorAll("[name]").forEach(element => { if (element.name in localStorage) element.value = localStorage[element.name] }) window.document.selectedStyleSheetSet = stylesheetSelect.value } save() { this.form.querySelectorAll("[name]").forEach(element => localStorage[element.name] = element.value) } init() { this.form.onsubmit = newGame levelInput.name = "startLevel" levelInput.disabled = false titleHeader.innerHTML = "QUATUOR" resumeButton.innerHTML = "Jouer" } show() { resumeButton.disabled = false settings.form.classList.remove('was-validated') settings.modal.show() settings.form.reportValidity() } getInputs() { for (let input of this.form.querySelectorAll("input[type='text']")) { this[input.name] = KEY_NAMES[input.value] } for (let input of this.form.querySelectorAll("input[type='number'], input[type='range']")) { this[input.name] = input.valueAsNumber } for (let input of this.form.querySelectorAll("input[type='checkbox']")) { this[input.name] = input.checked == true } this.keyBind = new Proxy({}, { get: (target, key) => target[key.toLowerCase()], set: (target, key, value) => target[key.toLowerCase()] = value, has: (target, key) => key.toLowerCase() in target }) for (let actionName in playerActions) { this.keyBind[settings[actionName]] = playerActions[actionName] } } } function changeKey(input) { prevValue = input.value input.value = "" keyInputs = Array.from(input.form.querySelectorAll("input[type='text']")) input.onkeydown = function (event) { event.preventDefault() input.value = KEY_NAMES[event.key] keyInputs.forEach(input => { input.setCustomValidity("") input.classList.remove("is-invalid") }) keyInputs.sort((input1, input2) => { if(input1.value == input2.value) { input1.setCustomValidity("Touche déjà utilisée") input1.classList.add("is-invalid") input2.setCustomValidity("Touche déjà utilisée") input2.classList.add("is-invalid") } return input1.value > input2.value }) if (input.checkValidity()) { input.blur() } } input.onblur = function (event) { if (!input.value) input.value = prevValue input.onkeydown = null input.onblur = null } } class Stats { constructor() { this.modal = new bootstrap.Modal('#statsModal') this.load() } load() { this.highScore = Number(localStorage["highScore"]) || 0 } init() { levelInput.value = localStorage["startLevel"] || 1 this.score = 0 this.goal = 0 this.combo = 0 this.b2b = 0 this.startTime = new Date() this.lockDelay = DELAY.LOCK this.totalClearedLines = 0 this.nbQuatuors = 0 this.nbTSpin = 0 this.maxCombo = 0 this.maxB2B = 0 } set score(score) { this._score = score scoreCell.innerText = score.toLocaleString() if (score > this.highScore) { this.highScore = score } } get score() { return this._score } set highScore(highScore) { this._highScore = highScore highScoreCell.innerText = highScore.toLocaleString() } get highScore() { return this._highScore } set level(level) { this._level = level this.goal += level * 5 if (level <= 20){ this.fallPeriod = 1000 * Math.pow(0.8 - ((level - 1) * 0.007), level - 1) } if (level > 15) this.lockDelay = 500 * Math.pow(0.9, level - 15) levelInput.value = level levelCell.innerText = level messagesSpan.addNewChild("div", { className: "show-level-animation", innerHTML: `