Updated dialog and styles
|
|
@ -10,6 +10,7 @@ body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
|
|
|
||||||
BIN
public/sound/success.wav
Normal file
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
BIN
public/sprite/fin_michael_normal.png
Normal file
|
After Width: | Height: | Size: 360 KiB |
BIN
public/sprite/fin_michael_wings.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 370 KiB After Width: | Height: | Size: 370 KiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprite/michael_wings.xcf
Normal file
|
Before Width: | Height: | Size: 387 KiB After Width: | Height: | Size: 387 KiB |
|
|
@ -1,39 +1,23 @@
|
||||||
<script>
|
<script>
|
||||||
import Dialog from "./pages/dialog.svelte";
|
import Dialog from "./pages/dialog.svelte";
|
||||||
import { Howl } from "howler";
|
import { Howl } from "howler";
|
||||||
|
import Overlay from "./pages/overlay.svelte";
|
||||||
|
import { characters } from "./stores/characters.js";
|
||||||
|
import { dialog } from "./stores/dialog.js";
|
||||||
|
|
||||||
var page = "game";
|
var page = "game";
|
||||||
const characters = [{
|
|
||||||
name: "Michael",
|
|
||||||
art: "/sprite/fin_22.png",
|
|
||||||
title: "the high marshal"
|
|
||||||
}]
|
|
||||||
var dialog = [{
|
|
||||||
name: "michael_heretic",
|
|
||||||
background: "/sprite/fin_backg.png",
|
|
||||||
character: "Michael",
|
|
||||||
text: "How did you... You know I don't even care. Heretic like you needs to be punished.",
|
|
||||||
buttons: [{
|
|
||||||
text: "Jokes on you I'm into that shit.",
|
|
||||||
next: "michael_success"
|
|
||||||
}, {
|
|
||||||
text: "I have something to offer."
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
name: "michael_success",
|
|
||||||
background: "/sprite/fin_backg.png",
|
|
||||||
character: "Michael",
|
|
||||||
text: "Really then? If you survive this whole ordeal, prepare a room and we'll see how into this shit you really are.",
|
|
||||||
flags: ["success"],
|
|
||||||
next: "michael_heretic"
|
|
||||||
}];
|
|
||||||
var current = localStorage.getItem("dialog-page") || 0;
|
var current = localStorage.getItem("dialog-page") || 0;
|
||||||
|
|
||||||
|
var preloads = [];
|
||||||
for(let character of characters) {
|
for(let character of characters) {
|
||||||
(new Image).src = character.art; // preload art
|
var img = new Image();
|
||||||
|
img.src = character.art; // preload art
|
||||||
|
preloads.push(img);
|
||||||
}
|
}
|
||||||
for(let d of dialog) {
|
for(let d of dialog) {
|
||||||
(new Image).src = d.background; // preload art
|
var img = new Image();
|
||||||
|
img.src = d.background; // preload art
|
||||||
|
preloads.push(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
var music = new Howl({
|
var music = new Howl({
|
||||||
|
|
@ -42,12 +26,24 @@
|
||||||
loop: true,
|
loop: true,
|
||||||
autoplay: true
|
autoplay: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var gameActive = true;
|
||||||
|
function startPlaying(e) {
|
||||||
|
if(!music.playing()) music.play();
|
||||||
|
if(e.key === "Escape") {
|
||||||
|
gameActive = !gameActive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Pancake recipe at https://github.com/danbulant/heaventaker");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<svelte:window on:click={startPlaying} on:keydown={startPlaying} />
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Heaventaker</title>
|
<title>Heaventaker</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
{#if page === "game"}
|
<Overlay active={gameActive}>
|
||||||
<Dialog {dialog} bind:current {characters} bind:page />
|
<Dialog {dialog} bind:current {characters} bind:page />
|
||||||
{/if}
|
</Overlay>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import Button from "./button.svelte";
|
import Button from "./button.svelte";
|
||||||
|
import { Howl } from "howler";
|
||||||
|
|
||||||
/** @type {any[]} */
|
/** @type {any[]} */
|
||||||
export var dialog;
|
export var dialog;
|
||||||
|
|
@ -42,6 +43,7 @@
|
||||||
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;
|
||||||
break;
|
break;
|
||||||
case "Enter":
|
case "Enter":
|
||||||
|
case "Space":
|
||||||
select(activeButton);
|
select(activeButton);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -59,6 +61,9 @@
|
||||||
var success = false;
|
var success = false;
|
||||||
$: success = d.flags && d.flags.includes("success");
|
$: success = d.flags && d.flags.includes("success");
|
||||||
|
|
||||||
|
var successSound = new Howl({
|
||||||
|
src: "/sound/success.wav"
|
||||||
|
});
|
||||||
var textElement;
|
var textElement;
|
||||||
$: {
|
$: {
|
||||||
if(textElement) {
|
if(textElement) {
|
||||||
|
|
@ -67,6 +72,9 @@
|
||||||
void textElement.offsetWidth;
|
void textElement.offsetWidth;
|
||||||
textElement.classList.add("animate");
|
textElement.classList.add("animate");
|
||||||
}
|
}
|
||||||
|
if(success) {
|
||||||
|
successSound.play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -119,6 +127,7 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 15px auto;
|
margin: 15px auto;
|
||||||
text-shadow: 0 0 6px white;
|
text-shadow: 0 0 6px white;
|
||||||
|
animation: shadowAppear .4s ease-out;
|
||||||
}
|
}
|
||||||
h2::before, h2::after {
|
h2::before, h2::after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -130,34 +139,44 @@
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
h2::before {
|
h2::before {
|
||||||
animation: successLeft .4s;
|
animation: successLeft .4s, appear .2s;
|
||||||
animation-timing-function: ease-out;
|
animation-timing-function: ease-out;
|
||||||
|
animation-delay: .2s, 0;
|
||||||
}
|
}
|
||||||
h2::after {
|
h2::after {
|
||||||
animation: successRight .4s;
|
animation: successRight .4s, appear .2s;
|
||||||
animation-timing-function: ease-out;
|
animation-timing-function: ease-out;
|
||||||
|
animation-delay: .2s, 0;
|
||||||
|
}
|
||||||
|
@keyframes shadowAppear {
|
||||||
|
0% {
|
||||||
|
text-shadow: 0 0 20px white;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
text-shadow: 0 0 6px white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@keyframes successLeft {
|
@keyframes successLeft {
|
||||||
0% {
|
0% {
|
||||||
left: 50%;
|
left: 40%;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 10px;
|
height: 15px;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
left: -60px;
|
left: -60px;
|
||||||
width: 50px;
|
width: 100px;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@keyframes successRight {
|
@keyframes successRight {
|
||||||
0% {
|
0% {
|
||||||
right: 50%;
|
right: 40%;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 10px;
|
height: 15px;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
right: -60px;
|
right: -60px;
|
||||||
width: 50px;
|
width: 100px;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -199,6 +218,6 @@
|
||||||
}
|
}
|
||||||
.background .character {
|
.background .character {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
bottom: -30px;
|
bottom: 0px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
35
src/pages/overlay.svelte
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<script>
|
||||||
|
export var active = true;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class:active class="main">
|
||||||
|
<div class="positioner">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.main {
|
||||||
|
width: 100vw;
|
||||||
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
overflow: hidden;
|
||||||
|
top: 50vh;
|
||||||
|
transition: top .2s, height .2s;
|
||||||
|
}
|
||||||
|
.positioner {
|
||||||
|
position: absolute;
|
||||||
|
top: -50vh;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
transition: top .2s;
|
||||||
|
}
|
||||||
|
.main.active {
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.active .positioner {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
8
src/stores/characters.js
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
export const characters = [{
|
||||||
|
name: "Michael",
|
||||||
|
art: "/sprite/fin_michael_normal.png",
|
||||||
|
title: "the high marshal",
|
||||||
|
poses: {
|
||||||
|
wings: "/sprite/fin_michael_wings.png"
|
||||||
|
}
|
||||||
|
}];
|
||||||
27
src/stores/dialog.js
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
export const dialog = [{
|
||||||
|
name: "michael_heretic",
|
||||||
|
background: "/sprite/fin_backg.png",
|
||||||
|
character: "Michael",
|
||||||
|
text: "How did you... You know what I don't even care. Heretic like you needs to be punished.",
|
||||||
|
buttons: [{
|
||||||
|
text: "Jokes on you I'm into that shit.",
|
||||||
|
next: "michael_success"
|
||||||
|
}, {
|
||||||
|
text: "I have something to offer.",
|
||||||
|
next: "michael_failure"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
name: "michael_success",
|
||||||
|
background: "/sprite/fin_backg.png",
|
||||||
|
character: "Michael",
|
||||||
|
text: "Really? Well, big man: if you survive this whole ordeal, prepare a room and we shall see how into this shit you really are",
|
||||||
|
flags: ["success"],
|
||||||
|
next: "michael_heretic"
|
||||||
|
}, {
|
||||||
|
name: "michael_failure",
|
||||||
|
background: "/sprite/fin_backg.png",
|
||||||
|
character: "Michael",
|
||||||
|
text: "I also have something to offer: eat shit and die.",
|
||||||
|
pose: "wings",
|
||||||
|
next: "michael_heretic"
|
||||||
|
}];
|
||||||