2018-11-06 19:03:17 +01:00

476 lines
18 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 {Matomo, ScaleHelper, SoundManager} from "../../../../../js/lib/pwa-assets";
import {EndSite} from "./EndSite";
import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
import {SettingsManager} from "../../../../../js/lib/pwa-core";
import {SimpleFourWordsLevel} from "../wordrotator/Level/SimpleFourWordsLevel";
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", "1") !== "1"),
volume: 0.7
}, SoundManager.CHANNELS.SOUND);
soundManager.resume(SoundManager.CHANNELS.MUSIC);
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");
let columnTemplate = this.findBy("#segment-column-template");
leafSegmentTemplate.removeAttribute("id");
parentSegmentTemplate.removeAttribute("id");
rowSegmentTemplate.removeAttribute("id");
triangleTemplate.removeAttribute("id");
columnTemplate.removeAttribute("id");
leafSegmentTemplate.remove();
parentSegmentTemplate.remove();
rowSegmentTemplate.remove();
triangleTemplate.remove();
columnTemplate.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, 2);
this.wonTextScaler = await scaleHelper.scaleToFull(wonText, wonText.parentElement, false, false, 2, 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, columnTemplate);
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();
});
await this.loadLastLevel();
}
async loadLastLevel() {
try {
let currentLevelInfo = localStorage.getItem("currentLevel");
if (Helper.isNotNull(currentLevelInfo)) {
currentLevelInfo = JSON.parse(currentLevelInfo);
const db = await WordRotatorDb.getInstance();
const levelJson = await db.loadLevel(currentLevelInfo["id"]);
if (levelJson === null) {
return this.nextLevel();
}
let 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, 1, level.words[0].length * 1.5, null, 0);
this.level = level;
let res = this.tutorial();
Matomo.push(["trackEvent", "LevelSite", "LoadLastLevel"]);
this.level.checkHasWon();
return res;
}
}
catch (e) {
console.error(e);
}
return this.nextLevel();
}
startEndSite(){
this.startSite(EndSite);
this.finish();
}
async nextLevel() {
try {
this._siteContent.classList.remove('won');
this.wonText.style.fontSize = "0";
const db = await WordRotatorDb.getInstance();
const nextLevelJson = await db.loadNextLevel(LevelSite.RENDERER_TYPES);
console.log("nextLevelJson", nextLevelJson);
if (nextLevelJson === null) {
this.startEndSite();
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, 1, level.words[0].length * 1.5, 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);
Matomo.push(["trackEvent", "LevelSite", "NextLevel", "Level Number Normal", this.levelCounter]);
this.level.checkHasWon();
return this.tutorial();
}
catch (e) {
console.log("Fehler!");
console.error(e);
this.startEndSite();
}
}
onStart(args) {
Matomo.update("Level Site");
let res = super.onStart(args);
if (this.levelCounterAction) {
this.levelCounterAction.innerText = this.levelCounter;
this.levelCounterActionContainer.classList.add("visible");
}
this.levelScaler();
let settingsManager = SettingsManager.getInstance();
let soundManager = SoundManager.getInstance();
soundManager.set({
audio: "sound/single_coin_fall_on_concrete_.mp3",
muted: (settingsManager.getSetting("play-sound", "1") !== "1"),
volume: 0.7
}, SoundManager.CHANNELS.SOUND);
return res;
}
onPause(args) {
super.onPause(args);
this.levelCounterActionContainer.classList.remove("visible");
}
async levelWon(level) {
try {
const db = await 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 = this.coinPromise.then(() => {
coinsBefore = parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"));
localStorage.setItem("coins", coinsBefore + parseInt(coinsPerLevel));
}).then(() => {
return Promise.all([new Promise((r) => {
setTimeout(() => {
r(continueButton.fadeIn());
}, 500)
}), audioOptions.loadedPromise.catch(e => {
console.error(e)
})]);
});
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);
}
else {
r();
}
//Always do the next promise for garbage collection
setTimeout(r, timeout);
})
});
}
this.coinPromise = this.coinPromise.catch((e) => {
console.error(e)
});
this.wonTextScaler();
this.continueButtonScaler();
this.levelScaler();
Matomo.push(["trackEvent", "LevelSite", "LevelWon", "Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
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.isSolved(false));
});
let index = Math.floor(Math.random() * rotatables.length);
let segmentToHelp = rotatables[index];
while (segmentToHelp.rotation !== 0) {
segmentToHelp.rotate();
}
segmentToHelp.setIsRotatable(false);
this.level.saveAsCurrentLevel();
Matomo.push(["trackEvent", "LevelSite", "Help", "Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
}
else {
FlashMessenger.addMessage("not-enough-coins");
Matomo.push(["trackEvent", "LevelSite", "Help", "Not enough Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
}
}
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);
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");
await this.levelScaler();
scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 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();
});
// this.levelScaler();
});
let textElem = this.findBy(".tutorial-text .step-2");
await this.levelScaler();
scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 2);
break;
}
default:{
this._siteContent.classList.remove("tutorial");
}
}
}
else if (this.level.id === LevelSite.TUTORIAL.SECOND_LEVEL) {
let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "3");
switch (currentStep) {
case "3": {
let scaleHelper = new ScaleHelper();
this._siteContent.classList.add("tutorial");
this._siteContent.classList.add("step-" + currentStep);
let eventListener = () => {
this._siteContent.classList.remove("tutorial");
this._siteContent.classList.remove("step-3");
localStorage.setItem("tutorial-step", "4");
this.findBy("#help-button").removeEventListener("click", eventListener);
this.levelScaler();
};
this.findBy("#help-button").addEventListener("click", eventListener);
let textElem = this.findBy(".tutorial-text .step-3");
await this.levelScaler();
scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 2);
break;
}
default:{
this._siteContent.classList.remove("tutorial");
}
}
}
else if (this.level.id === LevelSite.TUTORIAL.BIG_SEGMENT_LEVEL) {
let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "4");
switch (currentStep) {
case "4": {
let scaleHelper = new ScaleHelper();
this._siteContent.classList.add("tutorial");
this._siteContent.classList.add("step-" + currentStep);
let rotatableSegments = this.level.getRotatableSegments();
let firstSegment = rotatableSegments[2];
console.log(firstSegment);
let pointer = this.findBy("#tutorial-pointer");
pointer.remove();
firstSegment.element.appendChild(pointer);
this.level.setSegmentClickedListener((segment) => {
console.log("clicked Segment", segment);
if (firstSegment === segment) {
this._siteContent.classList.remove("tutorial");
this._siteContent.classList.remove("step-4");
localStorage.setItem("tutorial-step", "5");
this.levelScaler();
}
});
let textElem = this.findBy(".tutorial-text .step-4");
await this.levelScaler();
scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 2);
break;
}
default:{
this._siteContent.classList.remove("tutorial");
}
}
}
}
}
LevelSite.RENDERER_TYPES = [20, 40, 60, 80, 81, 82, 83, 100, 120, 140, 160];
LevelSite.TUTORIAL = {
FIRST_LEVEL: 67,
SECOND_LEVEL: 15,
BIG_SEGMENT_LEVEL: 1921
};