Updated dialog and styles
|
|
@ -10,6 +10,7 @@ body {
|
|||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@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>
|
||||
import Dialog from "./pages/dialog.svelte";
|
||||
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";
|
||||
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 preloads = [];
|
||||
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) {
|
||||
(new Image).src = d.background; // preload art
|
||||
var img = new Image();
|
||||
img.src = d.background; // preload art
|
||||
preloads.push(img);
|
||||
}
|
||||
|
||||
var music = new Howl({
|
||||
|
|
@ -42,12 +26,24 @@
|
|||
loop: 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>
|
||||
|
||||
<svelte:window on:click={startPlaying} on:keydown={startPlaying} />
|
||||
|
||||
<svelte:head>
|
||||
<title>Heaventaker</title>
|
||||
</svelte:head>
|
||||
|
||||
{#if page === "game"}
|
||||
<Overlay active={gameActive}>
|
||||
<Dialog {dialog} bind:current {characters} bind:page />
|
||||
{/if}
|
||||
</Overlay>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import Button from "./button.svelte";
|
||||
import { Howl } from "howler";
|
||||
|
||||
/** @type {any[]} */
|
||||
export var dialog;
|
||||
|
|
@ -42,6 +43,7 @@
|
|||
if(d.buttons && activeButton > d.buttons.length - 1) activeButton = d.buttons.length - 1;
|
||||
break;
|
||||
case "Enter":
|
||||
case "Space":
|
||||
select(activeButton);
|
||||
break;
|
||||
}
|
||||
|
|
@ -59,6 +61,9 @@
|
|||
var success = false;
|
||||
$: success = d.flags && d.flags.includes("success");
|
||||
|
||||
var successSound = new Howl({
|
||||
src: "/sound/success.wav"
|
||||
});
|
||||
var textElement;
|
||||
$: {
|
||||
if(textElement) {
|
||||
|
|
@ -67,6 +72,9 @@
|
|||
void textElement.offsetWidth;
|
||||
textElement.classList.add("animate");
|
||||
}
|
||||
if(success) {
|
||||
successSound.play();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -119,6 +127,7 @@
|
|||
text-align: center;
|
||||
margin: 15px auto;
|
||||
text-shadow: 0 0 6px white;
|
||||
animation: shadowAppear .4s ease-out;
|
||||
}
|
||||
h2::before, h2::after {
|
||||
position: absolute;
|
||||
|
|
@ -130,34 +139,44 @@
|
|||
transform: translateY(-50%);
|
||||
}
|
||||
h2::before {
|
||||
animation: successLeft .4s;
|
||||
animation: successLeft .4s, appear .2s;
|
||||
animation-timing-function: ease-out;
|
||||
animation-delay: .2s, 0;
|
||||
}
|
||||
h2::after {
|
||||
animation: successRight .4s;
|
||||
animation: successRight .4s, appear .2s;
|
||||
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 {
|
||||
0% {
|
||||
left: 50%;
|
||||
left: 40%;
|
||||
width: 100px;
|
||||
height: 10px;
|
||||
height: 15px;
|
||||
}
|
||||
100% {
|
||||
left: -60px;
|
||||
width: 50px;
|
||||
width: 100px;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
@keyframes successRight {
|
||||
0% {
|
||||
right: 50%;
|
||||
right: 40%;
|
||||
width: 100px;
|
||||
height: 10px;
|
||||
height: 15px;
|
||||
}
|
||||
100% {
|
||||
right: -60px;
|
||||
width: 50px;
|
||||
width: 100px;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
|
|
@ -199,6 +218,6 @@
|
|||
}
|
||||
.background .character {
|
||||
height: 100%;
|
||||
bottom: -30px;
|
||||
bottom: 0px;
|
||||
}
|
||||
</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"
|
||||
}];
|
||||