2018-09-27 12:32:28 +02:00

385 lines
14 KiB
JavaScript
Executable File

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,
};