Tutorial angefangen
This commit is contained in:
@@ -16,14 +16,16 @@ import "./lib/pwa-assets"
|
||||
import "./lib/pwa-code-management"
|
||||
import "./lib/pwa-user-management"
|
||||
|
||||
import {SynchronizeSite} from "../module/Application/pwa/js/site/SynchronizeSite";
|
||||
import {SettingsManager, SettingsSite} from "./lib/pwa-core";
|
||||
applyPolyfills();
|
||||
|
||||
import {SoundManager} from "./lib/pwa-assets";
|
||||
import {MenuSite} from "../module/Application/pwa/js/site/MenuSite";
|
||||
import {WordRotatorSettingFragment} from "../module/Application/pwa/js/Fragment/WordRotatorSettingFragment";
|
||||
|
||||
applyPolyfills();
|
||||
|
||||
|
||||
import './settings'
|
||||
import {SoundManager} from "./lib/pwa-assets";
|
||||
|
||||
ThemeManager.addTheme(new Theme('red', ''));
|
||||
ThemeManager.addTheme(new Theme("blue", "blue"));
|
||||
@@ -63,7 +65,7 @@ InitPromise.resolve(app).then(function(){
|
||||
let soundManager = SoundManager.getInstance();
|
||||
soundManager.play(SoundManager.CHANNELS.MUSIC, {audio: "sound/brightAndBeautifull__.mp3", loop: true, volume: 0.6, muted: !settingsManager.getSetting("play-music", true)});
|
||||
|
||||
app.start(SynchronizeSite);
|
||||
app.start(MenuSite);
|
||||
Translator.setLanguage("de");
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ if (window.location.pathname.endsWith("publicTest/"))
|
||||
}
|
||||
|
||||
SystemSettings.setBasePath(basePath);
|
||||
Translator.supportedLanguages = ["de", "en"];
|
||||
Translator.supportedLanguages = ["de"];
|
||||
Translator.markTranslations = false;
|
||||
|
||||
const TRACKING_ID = '';
|
||||
|
||||
@@ -14,10 +14,14 @@
|
||||
</div>
|
||||
<!-- Site Content -->
|
||||
<div class='max-height fill-me'>
|
||||
<!--<div class = 'max-width'>-->
|
||||
<div class="text-right max-width">
|
||||
<button class="button show-while-playing" id='help-button' data-translation="help"></button>
|
||||
</div>
|
||||
<div class = 'height-20 tutorial-text center flex-center hidden'>
|
||||
<div class = 'step-1 hidden' data-translation="tutorial-step-1"></div>
|
||||
<div class = 'step-2 hidden' data-translation="tutorial-step-2"></div>
|
||||
<div class = 'step-3 hidden' data-translation="tutorial-step-3"></div>
|
||||
</div>
|
||||
<div class='height-20 show-when-won center flex-center fill-me'>
|
||||
<div class = 'grow max-width'>
|
||||
<b data-translation="won" id="won-text"></b>
|
||||
@@ -36,4 +40,7 @@
|
||||
<button class='button max-width' id='continue-button' data-translation="continue"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class = 'tutorial-blanket'></div>
|
||||
|
||||
</div>
|
||||
@@ -35,6 +35,7 @@ export class WordRotatorSettingFragment extends LocalStorageSettingsFragment {
|
||||
localStorage.removeItem("currentLevel");
|
||||
localStorage.removeItem("date-last-sync");
|
||||
localStorage.removeItem("levelCounter");
|
||||
localStorage.removeItem("tutorial-step");
|
||||
WordRotatorDb.getInstance().removeAll(WordRotatorDb.OBJECT_STORE.LEVEL);
|
||||
});
|
||||
|
||||
|
||||
@@ -33,11 +33,16 @@ export class LevelSite extends WordRotatorBaseSite {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
@@ -128,7 +133,7 @@ export class LevelSite extends WordRotatorBaseSite {
|
||||
this.levelScaler = await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 2, level.words[0].length * 2, null, 0);
|
||||
|
||||
this.level = level;
|
||||
return;
|
||||
return this.tutorial();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
@@ -174,6 +179,8 @@ export class LevelSite extends WordRotatorBaseSite {
|
||||
|
||||
this.wonParams.aborted = true;
|
||||
clearTimeout(this.wonParams.coinCounterTimer);
|
||||
|
||||
return this.tutorial();
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
@@ -214,24 +221,31 @@ export class LevelSite extends WordRotatorBaseSite {
|
||||
|
||||
this.coinContainer.removeAllChildren();
|
||||
let coinsPerLevel = SystemSettings.get("coinsPerLevel", 5);
|
||||
let coinsBefore = parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"));
|
||||
localStorage.setItem("coins", coinsBefore + parseInt(coinsPerLevel));
|
||||
|
||||
let coinsBefore = 0;
|
||||
|
||||
let soundManager = SoundManager.getInstance();
|
||||
let audioOptions = soundManager.get(SoundManager.CHANNELS.SOUND);
|
||||
|
||||
let coinPromise = Promise.all([new Promise((r) => {
|
||||
this.coinPromise = Promise.all([new Promise((r) => {
|
||||
setTimeout(() => {
|
||||
r(continueButton.fadeIn());
|
||||
}, 500)
|
||||
}), audioOptions.loadedPromise.catch(e => {console.error(e)})]);
|
||||
}), 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);
|
||||
coinPromise = coinPromise.then(() => {
|
||||
this.coinPromise = this.coinPromise.then(() => {
|
||||
return new Promise(r => {
|
||||
let timeout = 350;
|
||||
|
||||
@@ -291,4 +305,81 @@ export class LevelSite extends WordRotatorBaseSite {
|
||||
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,
|
||||
};
|
||||
@@ -3,13 +3,14 @@ import {LevelSite} from "./LevelSite";
|
||||
import {ScaleHelper, SoundManager} from "../../../../../js/lib/pwa-assets";
|
||||
import {TemplateContainer} from "../wordrotator/Segment/TemplateContainer";
|
||||
import {MainMenuLevel} from "../wordrotator/Level/MainMenuLevel";
|
||||
import {Helper, InitPromise} from "../../../../../js/lib/pwa-lib";
|
||||
import {SettingsManager} from "../../../../../js/lib/pwa-core";
|
||||
import {FlashMessenger, Helper, InitPromise} from "../../../../../js/lib/pwa-lib";
|
||||
import {DataManager, SettingsManager} from "../../../../../js/lib/pwa-core";
|
||||
import {WordRotatorDb} from "../WordRotatorDb";
|
||||
|
||||
export class MenuSite extends WordRotatorBaseSite {
|
||||
constructor(siteManager) {
|
||||
super(siteManager, "html/application/menu.html");
|
||||
|
||||
this.loadLevelPromise = this.loadLevels();
|
||||
this.listener = null;
|
||||
}
|
||||
|
||||
@@ -89,7 +90,7 @@ export class MenuSite extends WordRotatorBaseSite {
|
||||
|
||||
let playButton = this.findBy("#play-button");
|
||||
playButton.addEventListener("click", () => {
|
||||
this.startSite(LevelSite);
|
||||
this.startSite(LevelSite, this.loadLevelPromise);
|
||||
});
|
||||
|
||||
let leafSegmentTemplate = this.findBy("#segment-leaf-template");
|
||||
@@ -135,9 +136,6 @@ export class MenuSite extends WordRotatorBaseSite {
|
||||
playSoundButton.addEventListener("change", () => {
|
||||
settingsManager.setSetting("play-sound", playSoundButton.checked);
|
||||
soundManager.set({muted: !playSoundButton.checked}, SoundManager.CHANNELS.SOUND);
|
||||
// if (playSoundButton.checked){
|
||||
// soundManager.play(SoundManager.CHANNELS.MUSIC);
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
@@ -146,6 +144,45 @@ export class MenuSite extends WordRotatorBaseSite {
|
||||
window.removeEventListener("resize", this.listener);
|
||||
super.onPause(args);
|
||||
}
|
||||
|
||||
async loadLevels() {
|
||||
const dateLastSync = Helper.nonNull(localStorage.getItem("date-last-sync"), 0);
|
||||
const db = WordRotatorDb.getInstance();
|
||||
|
||||
let newLastSync = null;
|
||||
let maxRuns = 1;
|
||||
let levelPromises = [];
|
||||
for (let run = 0; run < maxRuns; run++) {
|
||||
let res = await DataManager.load("wordRotator/levels" + DataManager.buildQuery({
|
||||
"currentRun": run,
|
||||
"dateLastSync": dateLastSync
|
||||
}));
|
||||
if (!res["success"]) {
|
||||
FlashMessenger.addMessage("sync-error", null, 6000);
|
||||
newLastSync = null;
|
||||
break;
|
||||
}
|
||||
res = res["result"];
|
||||
newLastSync = Helper.nonNull(newLastSync, res["currentSyncDate"]);
|
||||
maxRuns = res["maxRuns"];
|
||||
|
||||
let levels = res["levels"];
|
||||
for (let i = 0, n = levels.length; i < n; i++) {
|
||||
let currentLevel = levels[i];
|
||||
levelPromises.push(db.loadLevel(levels[i]["id"]).then(level => {
|
||||
currentLevel["played"] = (Helper.nonNull(Helper.nonNull(level, {}).played, false));
|
||||
return currentLevel;
|
||||
}));
|
||||
}
|
||||
}
|
||||
let levels = await Promise.all(levelPromises);
|
||||
await db.saveManyLevels(levels);
|
||||
|
||||
if (newLastSync != null && newLastSync !== "null")
|
||||
{
|
||||
localStorage.setItem("date-last-sync", newLastSync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuSite.app = null;
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import {FlashMessenger, Helper} from "../../../../../js/lib/pwa-lib";
|
||||
import {DataManager} from "../../../../../js/lib/pwa-core";
|
||||
import {WordRotatorDb} from "../WordRotatorDb";
|
||||
import {LevelSite} from "./LevelSite";
|
||||
import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
|
||||
import {MenuSite} from "./MenuSite";
|
||||
|
||||
export class SynchronizeSite extends WordRotatorBaseSite {
|
||||
|
||||
constructor(siteManager) {
|
||||
super(siteManager, "html/application/sync.html");
|
||||
}
|
||||
|
||||
async onConstruct(args) {
|
||||
let res = await super.onConstruct(args);
|
||||
await this.loadLevels();
|
||||
return res;
|
||||
}
|
||||
|
||||
onFirstStart() {
|
||||
super.onFirstStart();
|
||||
this.startSite(MenuSite);
|
||||
this.finish();
|
||||
}
|
||||
|
||||
async loadLevels() {
|
||||
const dateLastSync = Helper.nonNull(localStorage.getItem("date-last-sync"), 0);
|
||||
const db = WordRotatorDb.getInstance();
|
||||
|
||||
let newLastSync = null;
|
||||
let maxRuns = 1;
|
||||
let levelPromises = [];
|
||||
for (let run = 0; run < maxRuns; run++) {
|
||||
let res = await DataManager.load("wordRotator/levels" + DataManager.buildQuery({
|
||||
"currentRun": run,
|
||||
"dateLastSync": dateLastSync
|
||||
}));
|
||||
if (!res["success"]) {
|
||||
FlashMessenger.addMessage("sync-error", null, 6000);
|
||||
newLastSync = null;
|
||||
break;
|
||||
}
|
||||
res = res["result"];
|
||||
newLastSync = Helper.nonNull(newLastSync, res["currentSyncDate"]);
|
||||
maxRuns = res["maxRuns"];
|
||||
|
||||
let levels = res["levels"];
|
||||
for (let i = 0, n = levels.length; i < n; i++) {
|
||||
let currentLevel = levels[i];
|
||||
levelPromises.push(db.loadLevel(levels[i]["id"]).then(level => {
|
||||
currentLevel["played"] = (Helper.nonNull(Helper.nonNull(level, {}).played, false));
|
||||
return currentLevel;
|
||||
}));
|
||||
}
|
||||
}
|
||||
let levels = await Promise.all(levelPromises);
|
||||
await db.saveManyLevels(levels);
|
||||
|
||||
if (newLastSync != null && newLastSync !== "null")
|
||||
{
|
||||
localStorage.setItem("date-last-sync", newLastSync);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ export class Level {
|
||||
self.wonResolver = resolve;
|
||||
self.giveUpResolver = reject;
|
||||
});
|
||||
|
||||
this.segmentClickedListener = () => {};
|
||||
}
|
||||
|
||||
saveAsCurrentLevel(){
|
||||
@@ -130,6 +132,10 @@ export class Level {
|
||||
return Level._getRotatableSegmentsFrom(this.rootSegment);
|
||||
}
|
||||
|
||||
setSegmentClickedListener(listener){
|
||||
this.segmentClickedListener = listener;
|
||||
}
|
||||
|
||||
static _getRotatableSegmentsFrom(segment){
|
||||
let rotatable = [];
|
||||
if (segment.canRotate())
|
||||
|
||||
@@ -35,6 +35,7 @@ export class ParentSegment extends Segment {
|
||||
this.touchendListener = function (e) {
|
||||
let target = document.elementFromPoint(e.changedTouches[0].pageX, e.changedTouches[0].pageY);
|
||||
if (e.targetTouches.length === 0 && e.changedTouches.length === 1 && self.element.contains(ParentSegment.mouseDownTarget) && self.element.contains(target)) {
|
||||
self.getLevel().segmentClickedListener(self);
|
||||
self.rotate(ParentSegment.mouseDownTarget, target);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
@@ -42,6 +43,7 @@ export class ParentSegment extends Segment {
|
||||
};
|
||||
this.mouseupListener = function (e) {
|
||||
if (ParentSegment.mouseDownTarget !== null && self.element.contains(ParentSegment.mouseDownTarget) && self.element.contains(e.target)) {
|
||||
self.getLevel().segmentClickedListener(self);
|
||||
self.rotate(ParentSegment.mouseDownTarget, e.target);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
@@ -8,5 +8,10 @@
|
||||
"sync-error":"Es gab einen Fehler beim Aktualisieren der Level. Bitte stelle sicher, dass du eine aktive Internetverbindung hast und versuche es später erneut.",
|
||||
"game-ended":"<b>Oh nein!</b> <br/>Es sieht so aus, als ob du schon alle Level gespielt hast... <br/>Schau später noch einmal rein, evtl gibt es dann neue Level.",
|
||||
|
||||
"play":"Spielen!"
|
||||
"play":"Spielen!",
|
||||
|
||||
"tutorial-step-1": "Klicke auf ein Feld, um dieses rotieren zu lassen!",
|
||||
"tutorial-step-2": "Um zu gewinnen, drehe die Segmente so, dass du zwei Wörter lesen kannst.",
|
||||
"tutorial-step-3": "Durch die Hilfe kannst du ein Segment lösen lassen. Die Hilfe kostet aber 25 Münzen. Probiere jetzt die Hilfe aus.",
|
||||
"extra-coins-after-first-level":"Für das erste Level gibt es 50 extra Münzen!"
|
||||
}
|
||||
74
src/scss/_tutorial.scss
Normal file
74
src/scss/_tutorial.scss
Normal file
@@ -0,0 +1,74 @@
|
||||
.tutorial-blanket {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
z-index: 9001;
|
||||
background: rgba(98, 98, 98, 0.51);
|
||||
}
|
||||
|
||||
.tutorial {
|
||||
.tutorial-blanket {
|
||||
display: block;
|
||||
}
|
||||
.tutorial-text {
|
||||
color: white;
|
||||
font-size: 1.5rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&.step-1 {
|
||||
#level {
|
||||
.segment-row {
|
||||
position: inherit;
|
||||
}
|
||||
.segment-parent:nth-child(3), .segment-parent:nth-child(3).rotating {
|
||||
z-index: 9900 !important;
|
||||
}
|
||||
}
|
||||
.tutorial-text .step-1 {
|
||||
display: initial;
|
||||
z-index: 9900 !important;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
&.step-2 {
|
||||
#level {
|
||||
z-index: 9900 !important;
|
||||
}
|
||||
.tutorial-text .step-2 {
|
||||
display: initial;
|
||||
z-index: 9900 !important;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
&.step-3 {
|
||||
.tutorial-text .step-3 {
|
||||
display: initial;
|
||||
z-index: 9900 !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#help-button {
|
||||
position: relative;
|
||||
z-index: 9900 !important;
|
||||
overflow: visible;
|
||||
margin-right: 10px;
|
||||
margin-top: 10px;
|
||||
box-shadow: 0 0 10px 5px #fff;
|
||||
//&:after {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// bottom: 0;
|
||||
// right: 0;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
@import "tutorial";
|
||||
|
||||
//ActionBar
|
||||
nav.top-bar.title-bar {
|
||||
padding: 0.3rem 0.6rem 0;
|
||||
@@ -286,12 +288,7 @@ $animationDuration: .25s;
|
||||
//Won-screen
|
||||
#site-content > :not(.won) {
|
||||
.show-when-won {
|
||||
//visibility: hidden;
|
||||
display: none;
|
||||
//transition: none;
|
||||
//* {
|
||||
// transition: none;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user