import {FlashMessenger, Helper, Menu, MenuAction, SystemSettings} from "../../../../../js/lib/pwa-lib"; import {TemplateContainer} from "../wordrotator/Segment/TemplateContainer"; import {LevelHelper} from "../wordrotator/Level/LevelHelper"; import {WordRotatorDb} from "../WordRotatorDb"; import {ScaleHelper, SoundManager} from "../../../../../js/lib/pwa-assets"; import {EndSite} from "./EndSite"; import {WordRotatorBaseSite} from "./WordRotatorBaseSite"; import {SettingsManager} from "../../../../../js/lib/pwa-core"; export class LevelSite extends WordRotatorBaseSite { constructor(siteManager) { super(siteManager, "html/application/level.html"); } createActionBarMenu(menu) { menu = super.createActionBarMenu(menu); let coinAction = new MenuAction(Helper.nonNull(localStorage.getItem("coins"), "0"), () => { }, MenuAction.SHOW_ALWAYS, 900); coinAction.setShouldTranslate(false); coinAction._liClass = "coin-counter"; menu.addAction(coinAction); this.coinAction = coinAction; return menu; } onConstruct(args) { this.levelCounter = Helper.nonNull(localStorage.getItem("levelCounter"), 1); this.levelScaler = () => { }; this.wonParams = { aborted: false, coinCounterTimer: null, }; this.coinPromise = Promise.resolve(); let settingsManager = SettingsManager.getInstance(); let soundManager = SoundManager.getInstance(); soundManager.set({ audio: "sound/single_coin_fall_on_concrete_.mp3", muted: !settingsManager.getSetting("play-sound", true), volume: 0.7 }, SoundManager.CHANNELS.SOUND); return super.onConstruct(args); } async onFirstStart() { super.onFirstStart(); let leafSegmentTemplate = this.findBy("#segment-leaf-template"); let parentSegmentTemplate = this.findBy("#segment-parent-template"); let rowSegmentTemplate = this.findBy("#segment-row-template"); let triangleTemplate = this.findBy("#segment-triangle-template"); leafSegmentTemplate.id = null; parentSegmentTemplate.id = null; rowSegmentTemplate.id = null; triangleTemplate.id = null; leafSegmentTemplate.remove(); parentSegmentTemplate.remove(); rowSegmentTemplate.remove(); triangleTemplate.remove(); let self = this; let continueButton = this.findBy("#continue-button"); continueButton.addEventListener("click", () => { self.nextLevel(); }); let wonText = this.findBy("#won-text"); let scaleHelper = new ScaleHelper(); this.continueButtonScaler = await scaleHelper.scaleToFull(continueButton, continueButton.parentElement, false, true); this.wonTextScaler = await scaleHelper.scaleToFull(wonText, wonText.parentElement, false, false, 10, null, 5); this.wonText = wonText; this.wonText.style.fontSize = "0"; //Benutze Document, da Element außerhalb von Seite (eigentlich unschön!) this.levelCounterActionContainer = document.getElementById("level-number-container"); this.levelCounterAction = document.getElementById("level-number"); this.levelCounterAction.innerText = this.levelCounter; this.levelNumberScaler = await scaleHelper.scaleToFull(this.levelCounterAction, this.levelCounterActionContainer, false, false, 4); this.levelCounterActionContainer.classList.add("visible"); this.templateContainer = new TemplateContainer(leafSegmentTemplate, parentSegmentTemplate, rowSegmentTemplate, triangleTemplate); this.coinTemplate = this.findBy("#coin-template"); this.coinContainer = this.findBy("#coin-container"); this.coinTemplate.id = null; this.coinContainer.removeAllChildren(); this.findBy("#help-button").addEventListener("click", () => { this.help(); }); this.loadLastLevel(); } async loadLastLevel() { try { let currentLevelInfo = localStorage.getItem("currentLevel"); if (currentLevelInfo !== null) { currentLevelInfo = JSON.parse(currentLevelInfo); // console.log("LevelID: ", currentLevelInfo["id"]); const db = WordRotatorDb.getInstance(); const levelJson = await db.loadLevel(currentLevelInfo["id"]); if (levelJson === null) { return this.nextLevel(); } const level = LevelHelper.inflateLevel(levelJson, this.templateContainer); level.setStartRotations(currentLevelInfo["rotations"]); const self = this; level.getWonPromise().then(() => { self.levelWon(level); }); level.createSegments(); level.setLocks(currentLevelInfo["locks"]); level.getRootSegment()._updateElement(); level.saveAsCurrentLevel(); let levelSegment = this.findBy("#level"); levelSegment.removeAllChildren().appendChild(level.getRootSegment().getElement()); let scaleHelper = new ScaleHelper(); this.levelScaler = await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 2, level.words[0].length * 2, null, 0); this.level = level; return this.tutorial(); } } catch (e) { console.error(e); } return this.nextLevel(); } async nextLevel() { try { this._siteContent.classList.remove('won'); this.wonText.style.fontSize = "0"; const db = WordRotatorDb.getInstance(); const nextLevelJson = await db.loadNextLevel([20, 40, 60, 100, 120, 140, 160]); if (nextLevelJson === null) { this.startSite(EndSite); return; } const level = LevelHelper.inflateLevel(nextLevelJson, this.templateContainer); const self = this; level.getWonPromise().then(() => { self.levelWon(level); }); level.createSegments(); level.getRootSegment()._updateElement(); level.saveAsCurrentLevel(); let levelSegment = this.findBy("#level"); levelSegment.removeAllChildren().appendChild(level.getRootSegment().getElement()); let scaleHelper = new ScaleHelper(); this.levelScaler = await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 2, level.words[0].length * 2, null, 0); this.level = level; this.levelCounterAction.innerText = this.levelCounter; this.levelNumberScaler(); this.coinAction.setTitle(Helper.nonNull(localStorage.getItem("coins"), "0")); this.coinAction.redraw(); this.wonParams.aborted = true; clearTimeout(this.wonParams.coinCounterTimer); return this.tutorial(); } catch (e) { console.error(e); } } onStart(args) { let res = super.onStart(args); if (this.levelCounterAction) { this.levelCounterAction.innerText = this.levelCounter; this.levelCounterActionContainer.classList.add("visible"); } this.levelScaler(); return res; } onPause(args) { super.onPause(args); this.levelCounterActionContainer.classList.remove("visible"); } async levelWon(level) { try { const db = WordRotatorDb.getInstance(); const savePromise = db.saveLevelPlayed(level.getId()); this.levelCounter++; localStorage.setItem("levelCounter", this.levelCounter); this._siteContent.classList.add('won'); localStorage.removeItem("currentLevel"); let continueButton = this.findBy("#continue-button"); continueButton.style.transition = "none"; continueButton.style.opacity = 0; this.coinContainer.removeAllChildren(); let coinsPerLevel = SystemSettings.get("coinsPerLevel", 5); let coinsBefore = 0; let soundManager = SoundManager.getInstance(); let audioOptions = soundManager.get(SoundManager.CHANNELS.SOUND); this.coinPromise = Promise.all([new Promise((r) => { setTimeout(() => { r(continueButton.fadeIn()); }, 500) }), audioOptions.loadedPromise.catch(e => { console.error(e) }), this.coinPromise.then(() => { coinsBefore = parseInt(Helper.nonNull(localStorage.getItem("coins"), "0")); localStorage.setItem("coins", coinsBefore + parseInt(coinsPerLevel)); }) ]); this.wonParams.aborted = false; for (let i = 0; i < coinsPerLevel; i++) { let coinElem = Helper.cloneNode(this.coinTemplate); this.coinContainer.appendChild(coinElem); this.coinPromise = this.coinPromise.then(() => { return new Promise(r => { let timeout = 350; if (!this.wonParams.aborted) { coinElem.fadeIn(timeout / 1000); soundManager.play(SoundManager.CHANNELS.SOUND); this.wonParams.coinCounterTimer = setTimeout(() => { if (!this.wonParams.aborted) { this.coinAction.setTitle(++coinsBefore); this.coinAction.redraw(); } }, timeout / 2); } //Always do the next promise for garbage collection setTimeout(r, timeout); }) }); } this.wonTextScaler(); this.continueButtonScaler(); this.levelScaler(); await savePromise; } catch (e) { console.error(e); } } help() { let cost = SystemSettings.get("costForHelp", 25); let currentCoins = parseInt(Helper.nonNull(localStorage.getItem("coins"), 0)); if (currentCoins >= cost) { currentCoins -= cost; localStorage.setItem("coins", currentCoins); this.coinAction.title = currentCoins; this.coinAction.redraw(); let rotatables = this.level.getRotatableSegments(); rotatables = rotatables.filter((segment) => { return (segment.rotation !== 0); }); let index = Math.floor(Math.random() * rotatables.length); let segmentToHelp = rotatables[index]; while (segmentToHelp.rotation !== 0) { segmentToHelp.rotate(); } segmentToHelp.setIsRotatable(false); this.level.saveAsCurrentLevel(); } else { FlashMessenger.addMessage("not-enough-coins"); } } async tutorial() { if (this.level.id === LevelSite.TUTORIAL.FIRST_LEVEL) { let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "1"); let scaleHelper = new ScaleHelper(); this._siteContent.classList.add("tutorial"); this._siteContent.classList.add("step-" + currentStep); this.levelScaler(); switch (currentStep) { case "1": { this.level.setSegmentClickedListener(() => { this._siteContent.classList.remove("step-1"); localStorage.setItem("tutorial-step", "2"); this.tutorial(); }); let textElem = this.findBy(".tutorial-text .step-1"); scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, null, 2); break; } case "2": { this.level.setSegmentClickedListener(() => { }); this.level.getWonPromise().then(() => { this._siteContent.classList.remove("tutorial"); this._siteContent.classList.remove("step-2"); localStorage.removeItem("tutorial-step"); this.coinPromise = this.coinPromise.then(() => { FlashMessenger.addMessage("extra-coins-after-first-level"); localStorage.setItem("coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0")) + 50); this.coinAction.setTitle(Helper.nonNull(localStorage.getItem("coins"), "0")); this.coinAction.redraw(); }); }); let textElem = this.findBy(".tutorial-text .step-2"); scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, null, 2); break; } } } else if (this.level.id === LevelSite.TUTORIAL.SECOND_LEVEL) { let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "3"); let scaleHelper = new ScaleHelper(); this._siteContent.classList.add("tutorial"); this._siteContent.classList.add("step-" + currentStep); this.levelScaler(); switch (currentStep) { case "3": { let eventListener = () => { this._siteContent.classList.remove("tutorial"); this._siteContent.classList.remove("step-2"); localStorage.removeItem("tutorial-step"); this.findBy("#help-button").removeEventListener("click", eventListener); }; this.findBy("#help-button").addEventListener("click", eventListener); let textElem = this.findBy(".tutorial-text .step-3"); scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, null, 2); break; } } } } } LevelSite.TUTORIAL = { FIRST_LEVEL: 67, SECOND_LEVEL: 15, };