mirror of
https://github.com/danbulant/heaventaker
synced 2026-07-07 04:00:40 +00:00
main menu
This commit is contained in:
parent
3c7597f030
commit
ff37f5b6f9
7 changed files with 155 additions and 24 deletions
|
|
@ -14,10 +14,14 @@
|
||||||
preloads.get(url).src = url;
|
preloads.get(url).src = url;
|
||||||
}
|
}
|
||||||
for(let character of characters) {
|
for(let character of characters) {
|
||||||
preload(character.art); // preload art
|
if(character.art) {
|
||||||
|
preload(character.art); // preload art
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for(let d of dialog) {
|
for(let d of dialog) {
|
||||||
preload(d.background); // preload art
|
if(d.background) {
|
||||||
|
preload(d.background); // preload art
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var music = new Howl({
|
var music = new Howl({
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ export class GameScene extends Phaser.Scene {
|
||||||
this.load.setBaseURL();
|
this.load.setBaseURL();
|
||||||
this.load.image("level1", "/sprite/level1.webp");
|
this.load.image("level1", "/sprite/level1.webp");
|
||||||
this.load.image("level2", "/sprite/level2.webp");
|
this.load.image("level2", "/sprite/level2.webp");
|
||||||
|
this.load.image("level3", "/sprite/level3.webp");
|
||||||
this.load.image("lyre", "/sprite/lyre.webp");
|
this.load.image("lyre", "/sprite/lyre.webp");
|
||||||
this.load.image("cloud", "/sprite/clouds.webp");
|
this.load.image("cloud", "/sprite/clouds.webp");
|
||||||
this.load.image("pillar", "/sprite/pillar.webp");
|
this.load.image("pillar", "/sprite/pillar.webp");
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
import Button from "./button.svelte";
|
import Button from "./button.svelte";
|
||||||
import { Howl } from "howler";
|
import { Howl } from "howler";
|
||||||
import { dialog } from "../stores/dialog.js";
|
import { chapters, dialog } from "../stores/dialog.js";
|
||||||
import { characters } from "../stores/characters.js";
|
import { characters } from "../stores/characters.js";
|
||||||
import { gameActive } from "../stores/gameActive";
|
import { gameActive } from "../stores/gameActive";
|
||||||
|
import { toRoman } from "../utils";
|
||||||
|
|
||||||
export var current;
|
export var current;
|
||||||
export var page;
|
export var page;
|
||||||
|
|
@ -28,6 +29,7 @@ import { gameActive } from "../stores/gameActive";
|
||||||
|
|
||||||
var activeButton = -1;
|
var activeButton = -1;
|
||||||
function select(i) {
|
function select(i) {
|
||||||
|
console.log("Switching", i);
|
||||||
if(!allowSwitch) return;
|
if(!allowSwitch) return;
|
||||||
var next;
|
var next;
|
||||||
if(d.buttons) {
|
if(d.buttons) {
|
||||||
|
|
@ -61,20 +63,33 @@ import { gameActive } from "../stores/gameActive";
|
||||||
failure = false;
|
failure = false;
|
||||||
current = next;
|
current = next;
|
||||||
d = dialog[current];
|
d = dialog[current];
|
||||||
art = !character ? null : d.character_art || d.pose ? character.poses[d.pose] : character.art;
|
art = !character ? null : (d.character_art || d.pose && character.poses ? character.poses[d.pose] : character.art);
|
||||||
background = d.background;
|
background = d.background;
|
||||||
if(d.map) {
|
if(d.map) {
|
||||||
$gameActive = true;
|
setTimeout(() => {
|
||||||
|
$gameActive = true;
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
console.log("selected", d);
|
||||||
|
if(!d.flags || !d.flags.includes("nosave")) localStorage.setItem("dialog-page", next);
|
||||||
|
if(d.chapter) {
|
||||||
|
if(!chaptersDone.includes(d.chapter)) {
|
||||||
|
chaptersDone.push(d.chapter);
|
||||||
|
localStorage.setItem("chapters", JSON.stringify(chaptersDone));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
localStorage.setItem("dialog-page", next);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var chaptersDone = JSON.parse(localStorage.getItem("chapters") || "[]");
|
||||||
|
|
||||||
function keydown(e) {
|
function keydown(e) {
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
case "ArrowUp":
|
case "ArrowUp":
|
||||||
|
case "ArrowLeft":
|
||||||
activeButton--;
|
activeButton--;
|
||||||
if(activeButton < 0) activeButton = 0;
|
if(activeButton < 0) activeButton = 0;
|
||||||
break;
|
break;
|
||||||
|
case "ArrowRight":
|
||||||
case "ArrowDown":
|
case "ArrowDown":
|
||||||
activeButton++;
|
activeButton++;
|
||||||
if(d.buttons && activeButton > d.buttons.length - 1) activeButton = d.buttons.length - 1;
|
if(d.buttons && activeButton > d.buttons.length - 1) activeButton = d.buttons.length - 1;
|
||||||
|
|
@ -94,7 +109,7 @@ import { gameActive } from "../stores/gameActive";
|
||||||
*/
|
*/
|
||||||
function next(e) {
|
function next(e) {
|
||||||
var path = e.composedPath();
|
var path = e.composedPath();
|
||||||
if(path.includes(buttons)) return;
|
if(buttons && path.includes(buttons)) return;
|
||||||
reset();
|
reset();
|
||||||
select();
|
select();
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +157,15 @@ import { gameActive } from "../stores/gameActive";
|
||||||
{:else}
|
{:else}
|
||||||
<h1>???</h1>
|
<h1>???</h1>
|
||||||
{/if}
|
{/if}
|
||||||
<p class="animate" bind:this={textElement}>{d.text}</p>
|
{#if d.text}
|
||||||
|
<p class="animate" bind:this={textElement}>
|
||||||
|
{#if d.flags && d.flags.includes("chapters") && chaptersDone.length === 0}
|
||||||
|
{d.alt}
|
||||||
|
{:else}
|
||||||
|
{d.text}
|
||||||
|
{/if}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons" bind:this={buttons}>
|
<div class="buttons" bind:this={buttons}>
|
||||||
{#if d.buttons}
|
{#if d.buttons}
|
||||||
|
|
@ -150,6 +173,15 @@ import { gameActive } from "../stores/gameActive";
|
||||||
<Button active={i === activeButton} on:click={() => select(i)}>{button.text}</Button>
|
<Button active={i === activeButton} on:click={() => select(i)}>{button.text}</Button>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if d && d.flags && d.flags.includes("chapters") && chaptersDone.length}
|
||||||
|
<div class="chapters">
|
||||||
|
{#each Object.keys(chapters) as chapter}
|
||||||
|
<div class="chapter" class:active={chaptersDone && chaptersDone.includes(chapter)}>
|
||||||
|
{toRoman(chapters[chapter])}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if success}
|
{#if success}
|
||||||
<h2>SUCCESS</h2>
|
<h2>SUCCESS</h2>
|
||||||
|
|
@ -159,6 +191,22 @@ import { gameActive } from "../stores/gameActive";
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.chapters {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.chapter {
|
||||||
|
border: 2px solid rgb(155, 0, 0);
|
||||||
|
padding: 4px;
|
||||||
|
margin: 3px;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.chapter.active {
|
||||||
|
cursor: pointer;
|
||||||
|
border-color: red;
|
||||||
|
}
|
||||||
.dialog {
|
.dialog {
|
||||||
background: #02021A;
|
background: #02021A;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { setCanvas, setMap, resize, stop } from "../game";
|
import { setCanvas, setMap, resize, stop } from "../game";
|
||||||
import { steps } from "../stores/step";
|
import { steps } from "../stores/step";
|
||||||
|
import { toRoman } from "../utils";
|
||||||
|
|
||||||
export var current;
|
export var current;
|
||||||
|
|
||||||
|
|
@ -16,20 +17,6 @@
|
||||||
var character;
|
var character;
|
||||||
$: character = characters[characterIndex];
|
$: character = characters[characterIndex];
|
||||||
|
|
||||||
function toRoman(num) {
|
|
||||||
if (isNaN(num))
|
|
||||||
return NaN;
|
|
||||||
var digits = String(+num).split(""),
|
|
||||||
key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
|
|
||||||
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
|
|
||||||
"","I","II","III","IV","V","VI","VII","VIII","IX"],
|
|
||||||
roman = "",
|
|
||||||
i = 3;
|
|
||||||
while (i--)
|
|
||||||
roman = (key[+digits.pop() + (i * 10)] || "") + roman;
|
|
||||||
return Array(+digits.join("") + 1).join("M") + roman;
|
|
||||||
}
|
|
||||||
|
|
||||||
var canvas;
|
var canvas;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
|
|
||||||
|
|
@ -41,4 +41,7 @@ export const characters = [{
|
||||||
happy: "/sprite/azrael_happy.webp",
|
happy: "/sprite/azrael_happy.webp",
|
||||||
angry: "/sprite/azrael_angry.webp"
|
angry: "/sprite/azrael_angry.webp"
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
name: "Hadraniel",
|
||||||
|
title: "the seraphim"
|
||||||
}];
|
}];
|
||||||
|
|
@ -1,4 +1,68 @@
|
||||||
|
export const chapters = {
|
||||||
|
uriel: 1,
|
||||||
|
michael: 2,
|
||||||
|
uziel: 3,
|
||||||
|
gabriel: 4,
|
||||||
|
azrael: 5
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {{
|
||||||
|
* name: string,
|
||||||
|
* background: string,
|
||||||
|
* character: string,
|
||||||
|
* text: string,
|
||||||
|
* next?: string,
|
||||||
|
* pose?: string,
|
||||||
|
* map?: string,
|
||||||
|
* chapter?: keyof typeof chapters,
|
||||||
|
* buttons: { text: string, next: string }[],
|
||||||
|
* flags?: string[]
|
||||||
|
* }[]}
|
||||||
|
*/
|
||||||
export const dialog = [{
|
export const dialog = [{
|
||||||
|
name: "start",
|
||||||
|
background: "/sprite/menu.webp",
|
||||||
|
text: "Hello and welcome on your way to heaven. My name is Hadraniel, and I'm the one appointed to you at the moment.",
|
||||||
|
next: "start2",
|
||||||
|
buttons: [{
|
||||||
|
text: "I'd like to go to the heaven's gate.",
|
||||||
|
next: "start2"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
name: "start2",
|
||||||
|
background: "/sprite/menu.webp",
|
||||||
|
character: "Hadraniel",
|
||||||
|
text: "Sure. Oh and before you go there, just a warning: don't even think about trying to seduce the angels. It doesn't work here the same as down there.",
|
||||||
|
next: "start3"
|
||||||
|
}, {
|
||||||
|
name: "start3",
|
||||||
|
background: "/sprite/menu.webp",
|
||||||
|
character: "Hadraniel",
|
||||||
|
text: "Wait where are you going? That's not the way to the main gate-",
|
||||||
|
next: "uriel_entrance"
|
||||||
|
}, {
|
||||||
|
name: "menu",
|
||||||
|
background: "/sprite/menu.webp",
|
||||||
|
character: "Hadraniel",
|
||||||
|
text: "",
|
||||||
|
buttons: [{
|
||||||
|
text: "Start",
|
||||||
|
next: "uriel_entrance"
|
||||||
|
}, {
|
||||||
|
text: "Chapter select",
|
||||||
|
next: "chapters"
|
||||||
|
}],
|
||||||
|
flags: ["menu", "nosave"]
|
||||||
|
}, {
|
||||||
|
name: "chapters",
|
||||||
|
background: "/sprite/menu.webp",
|
||||||
|
character: "Hadraniel",
|
||||||
|
text: "Which chapter would you like to solve?",
|
||||||
|
alt: "You must first complete a chapter to be able to solve it.",
|
||||||
|
next: "menu",
|
||||||
|
flags: ["chapters", "nosave"]
|
||||||
|
}, {
|
||||||
name: "uriel_entrance",
|
name: "uriel_entrance",
|
||||||
background: "/sprite/backg.webp",
|
background: "/sprite/backg.webp",
|
||||||
character: "Uriel",
|
character: "Uriel",
|
||||||
|
|
@ -28,6 +92,7 @@ export const dialog = [{
|
||||||
pose: "bat"
|
pose: "bat"
|
||||||
}, {
|
}, {
|
||||||
name: "uriel_success",
|
name: "uriel_success",
|
||||||
|
chapter: "uriel",
|
||||||
background: "/sprite/backg.webp",
|
background: "/sprite/backg.webp",
|
||||||
character: "Uriel",
|
character: "Uriel",
|
||||||
text: "Well since it already got boring around here, and how can I say no to pancakes.",
|
text: "Well since it already got boring around here, and how can I say no to pancakes.",
|
||||||
|
|
@ -49,6 +114,7 @@ export const dialog = [{
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
name: "michael_success",
|
name: "michael_success",
|
||||||
|
chapter: "michael",
|
||||||
background: "/sprite/backg.webp",
|
background: "/sprite/backg.webp",
|
||||||
character: "Michael",
|
character: "Michael",
|
||||||
pose: "happy",
|
pose: "happy",
|
||||||
|
|
@ -85,6 +151,7 @@ export const dialog = [{
|
||||||
pose: "dead"
|
pose: "dead"
|
||||||
}, {
|
}, {
|
||||||
name: "uziel_success",
|
name: "uziel_success",
|
||||||
|
chapter: "uziel",
|
||||||
background: "/sprite/backg.webp",
|
background: "/sprite/backg.webp",
|
||||||
character: "Uziel",
|
character: "Uziel",
|
||||||
pose: "happy",
|
pose: "happy",
|
||||||
|
|
@ -105,6 +172,7 @@ export const dialog = [{
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
name: "gabriel_success",
|
name: "gabriel_success",
|
||||||
|
chapter: "gabriel",
|
||||||
background: "/sprite/backg.webp",
|
background: "/sprite/backg.webp",
|
||||||
character: "Gabriel",
|
character: "Gabriel",
|
||||||
text: "That... That would be lovely actually. Could you buy me some coffee? After my department got defund I can't even afford it.",
|
text: "That... That would be lovely actually. Could you buy me some coffee? After my department got defund I can't even afford it.",
|
||||||
|
|
@ -152,7 +220,8 @@ export const dialog = [{
|
||||||
pose: "angry"
|
pose: "angry"
|
||||||
}, {
|
}, {
|
||||||
name: "azrael_win",
|
name: "azrael_win",
|
||||||
next: "uriel_entrance",
|
chapter: "azrael",
|
||||||
|
next: "menu",
|
||||||
background: "/sprite/backg.webp",
|
background: "/sprite/backg.webp",
|
||||||
character: "Azrael",
|
character: "Azrael",
|
||||||
pose: "happy",
|
pose: "happy",
|
||||||
|
|
|
||||||
19
src/utils.js
Normal file
19
src/utils.js
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts given number to string roman numeral
|
||||||
|
* @param {number} num
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function toRoman(num) {
|
||||||
|
if (isNaN(num))
|
||||||
|
return NaN;
|
||||||
|
var digits = String(+num).split(""),
|
||||||
|
key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
|
||||||
|
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
|
||||||
|
"","I","II","III","IV","V","VI","VII","VIII","IX"],
|
||||||
|
roman = "",
|
||||||
|
i = 3;
|
||||||
|
while (i--)
|
||||||
|
roman = (key[+digits.pop() + (i * 10)] || "") + roman;
|
||||||
|
return Array(+digits.join("") + 1).join("M") + roman;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue