mirror of
https://github.com/danbulant/heaventaker
synced 2026-06-23 16:52:21 +00:00
Multiple pages, background sound, success animation
This commit is contained in:
parent
7b6058290c
commit
1cabad9339
8 changed files with 166 additions and 14 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
|
@ -326,6 +326,11 @@
|
|||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"howler": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/howler/-/howler-2.2.1.tgz",
|
||||
"integrity": "sha512-0iIXvuBO/81CcrQ/HSSweYmbT50fT2mIc9XMFb+kxIfk2pW/iKzDbX1n3fZmDXMEIpYvyyfrB+gXwPYSDqUxIQ=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
"svelte": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"howler": "^2.2.1",
|
||||
"sirv-cli": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
public/sound/thought_patterns.m4a
Normal file
BIN
public/sound/thought_patterns.m4a
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 317 KiB After Width: | Height: | Size: 316 KiB |
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import Dialog from "./pages/dialog.svelte";
|
||||
import { Howl } from "howler";
|
||||
|
||||
var page = "game";
|
||||
const characters = [{
|
||||
|
|
@ -11,15 +12,36 @@
|
|||
name: "michael_heretic",
|
||||
background: "/sprite/fin_backg.png",
|
||||
character: "Michael",
|
||||
pose: null,
|
||||
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."
|
||||
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 = 0;
|
||||
var current = localStorage.getItem("dialog-page") || 0;
|
||||
|
||||
for(let character of characters) {
|
||||
(new Image).src = character.art; // preload art
|
||||
}
|
||||
for(let d of dialog) {
|
||||
(new Image).src = d.background; // preload art
|
||||
}
|
||||
|
||||
var music = new Howl({
|
||||
src: "/sound/thought_patterns.m4a",
|
||||
html5: true,
|
||||
loop: true,
|
||||
autoplay: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<script>
|
||||
export var self;
|
||||
export var active = false;
|
||||
export var self = null;
|
||||
</script>
|
||||
|
||||
<div class="button" on:click tabindex="-1" bind:this={self}>
|
||||
<div class="button" on:click tabindex="-1" bind:this={self} class:active>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
|
|
@ -19,15 +20,16 @@
|
|||
text-align: center;
|
||||
background-position-x: center;
|
||||
cursor: pointer;
|
||||
opacity: 0.7;
|
||||
opacity: 0.8;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
transition: opacity .3s, margin .3s, transform .3s;
|
||||
}
|
||||
.button:first-child:hover, .button:first-child:focus {
|
||||
.button:first-child:hover, .button:first-child:focus, .button:first-child.active {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.button:hover, .button:focus {
|
||||
.button:hover, .button:focus, .button.active {
|
||||
outline: none;
|
||||
opacity: 1;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import Button from "./button.svelte";
|
||||
import Button from "./button.svelte";
|
||||
|
||||
/** @type {any[]} */
|
||||
export var dialog;
|
||||
export var current;
|
||||
/** @type {any[]} */
|
||||
|
|
@ -15,8 +16,62 @@ import Button from "./button.svelte";
|
|||
|
||||
var art;
|
||||
$: art = d.character_art || d.pose ? character.poses[d.pose] : character.art;
|
||||
|
||||
var activeButton = -1;
|
||||
function select(i) {
|
||||
var next;
|
||||
if(d.buttons) {
|
||||
if(!d.buttons[i]) return;
|
||||
next = dialog.findIndex(t => t.name === d.buttons[i].next);
|
||||
} else {
|
||||
next = dialog.findIndex(t => t.name === d.next);
|
||||
}
|
||||
if(next === -1) return;
|
||||
current = next;
|
||||
localStorage.setItem("dialog-page", next);
|
||||
}
|
||||
|
||||
function keydown(e) {
|
||||
switch(e.key) {
|
||||
case "ArrowUp":
|
||||
activeButton--;
|
||||
if(activeButton < 0) activeButton = 0;
|
||||
break;
|
||||
case "ArrowDown":
|
||||
activeButton++;
|
||||
if(d.buttons && activeButton > d.buttons.length - 1) activeButton = d.buttons.length - 1;
|
||||
break;
|
||||
case "Enter":
|
||||
select(activeButton);
|
||||
break;
|
||||
}
|
||||
}
|
||||
function reset() {
|
||||
activeButton = -1;
|
||||
}
|
||||
var buttons;
|
||||
function next(e) {
|
||||
if(e.path.includes(buttons)) return;
|
||||
reset();
|
||||
select();
|
||||
}
|
||||
|
||||
var success = false;
|
||||
$: success = d.flags && d.flags.includes("success");
|
||||
|
||||
var textElement;
|
||||
$: {
|
||||
if(textElement) {
|
||||
d; // everytime d is changed
|
||||
textElement.classList.remove("animate");
|
||||
void textElement.offsetWidth;
|
||||
textElement.classList.add("animate");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={keydown} on:mousemove={reset} on:click={next} />
|
||||
|
||||
<div class="dialog">
|
||||
<div class="background">
|
||||
<img src={d.background} alt="" class="full" draggable={false}>
|
||||
|
|
@ -24,12 +79,17 @@ import Button from "./button.svelte";
|
|||
</div>
|
||||
<div class="text">
|
||||
<h1>{character.name}, {character.title}</h1>
|
||||
<p>{d.text}</p>
|
||||
<div class="buttons">
|
||||
{#each d.buttons as button}
|
||||
<Button>{button.text}</Button>
|
||||
{/each}
|
||||
<p class="animate" bind:this={textElement}>{d.text}</p>
|
||||
<div class="buttons" bind:this={buttons}>
|
||||
{#if d.buttons}
|
||||
{#each d.buttons as button, i}
|
||||
<Button active={i === activeButton} on:click={() => select(i)}>{button.text}</Button>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
{#if success}
|
||||
<h2>SUCCESS</h2>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -50,12 +110,74 @@ import Button from "./button.svelte";
|
|||
text-align: center;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
h2 {
|
||||
position: relative;
|
||||
width: 400px;
|
||||
color: white;
|
||||
font-size: 70px;
|
||||
letter-spacing: 12px;
|
||||
text-align: center;
|
||||
margin: 15px auto;
|
||||
text-shadow: 0 0 6px white;
|
||||
}
|
||||
h2::before, h2::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
background: white;
|
||||
box-shadow: 0 0 15px white;
|
||||
border-radius: 50%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
h2::before {
|
||||
animation: successLeft .4s;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
h2::after {
|
||||
animation: successRight .4s;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
@keyframes successLeft {
|
||||
0% {
|
||||
left: 50%;
|
||||
width: 100px;
|
||||
height: 10px;
|
||||
}
|
||||
100% {
|
||||
left: -60px;
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
@keyframes successRight {
|
||||
0% {
|
||||
right: 50%;
|
||||
width: 100px;
|
||||
height: 10px;
|
||||
}
|
||||
100% {
|
||||
right: -60px;
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
font-size: 25px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.animate {
|
||||
animation: appear .3s;
|
||||
}
|
||||
@keyframes appear {
|
||||
from {
|
||||
transform: scale(0.7);
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
.text {
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
|
|
|
|||
Loading…
Reference in a new issue