JS update, story

This commit is contained in:
Alexander Yakovlev 2021-11-20 00:29:25 +07:00
parent 1cfb2ead27
commit f721efcd83
Signed by: oreolek
GPG key ID: 8D24103F5EE2A6C0
4 changed files with 155 additions and 81 deletions

View file

@ -7,9 +7,12 @@ He came to you in a night dream. A monster is terrorising the city, he said, and
=== start2 ===
// The moon never sets on a British vampire.
You don't know when He watches your night fights but he does. It has to look perfect.
You still don't know His name, only the surname: Toreador. He's foreign.
// after the jam we can drop more subtle hints? "He is a patron of arts" that way
<em>Your</em> name is Tabitha, and today you feel like…
-> clothing
@ -27,7 +30,7 @@ You still don't know His name, only the surname: Toreador. He's foreign.
Just right.
He sends you a message with an address, no details. It leads you to a loud car party. Some sad old guys loudly arguing about their cars. You feel a faint scent of something <em>evil</em> nearby.
He sends you a message with an address, no details. It leads you to a dark parking lot occupied by a loud car party. Some sad old guys loudly arguing about their cars. You feel a faint scent of something <em>evil</em> nearby.
->choices
@ -41,8 +44,58 @@ He sends you a message with an address, no details. It leads you to a loud car p
„Get lost, kid.“
Okay, you know <b>nothing</b> about these cars.
-> choices
* <ell> There are some people fussing around two of the cars roaring next to each other. You heard about underground races, but this just looks <em>sad.</em>
-> choices
-> start4
=== start4 ===
You wander around. Why did He send you here?
A new car comes to the parking lot. The feeling of <em>wrongness</em> rises in you.
=== battle1 ===
He's about to jump at you.
* Prepare for the attack. []
You take a step back and do a twirl.
// I have an unhealthy relationship with this meter. Sorry.
<q>I call the generous moon: give me strength for this battle.</q>
Then you pose with the mace. Now you feel truly confident.
* Skip the ritual and hit. []
You jump back - quicker than he expects. Then you bash him in the head.
He shrugs off your mace like it's nothing.
* Skip the ritual and make him jump straight on your mace. [] Yo
He just stands there, confused. and never sees your mace when you bash him in the head.
=== battleends ===
Clap. Clap. Clap.
Oh shit, it's Him. He was here and He watched. Drat.
<q>Thou art the most gracious person, dear.</q>
* [State your pride]
<q>I am proud to be the best, my lord. This man won't try this again.</q> -> battleends2
* [State your mission]
<q>I could not let this vermin to go free.</q> -> battleends2
=== battleends2 ===
<q>Oh, he's certainly learned his lesson. Now, I think this was a nice fight. You can rest for the night.</q>
<q>But I'm not…</q>
<q>I never give you any presents, don't I? Here, take this.</q>
He throws you something small and you greedily catch it. Your fingers trace his fingerprints like you're touching his hands.
<q>I'm sure the city will be safe tonight.</q>
You skip on the way out, throwing a last glance at the scene. He's hunched above the unconscious girl. You know she will be fine, now that your lord is here.
And you spend the night sleeping with his locket, tight in your arms.
<h1>THE END</h1>
// You can outrun and jump over anyone, even in your puffy skirts. (He's obsessed with nice clothing, and honestly you caught a bit of this too. You can't go out in anything <em>drab.</em>)

View file

@ -2,13 +2,24 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title></title>
<title>Magical Soldier of the Night</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="main.css" />
</head>
<body>
<div id="page" class="container">
<button id="restart" type="button" class="btn btn-warning">Restart</button>
<div class="row">
<div class="col-sm-3 col-md-2">
<button id="undo" style="display:none" type="button" class="btn btn-warning">Undo</button>
</div>
<div class="col-sm-6 col-md-8 text-center">
<h3>Magical Soldier of the Night</h3>
</div>
<div class="col-sm-3 col-md-2 text-right">
<button id="restart" type="button" class="btn btn-danger">Restart</button>
</div>
</div>
<hr>
<div class="row">
<div id="content" class="col-sm-12 col-md-12"></div>
<div class="col-sm-12 col-md-10 offset-md-1">

View file

@ -1,40 +1,35 @@
import jQuery from 'jquery'
const inkjs = require('inkjs').Story;
/**
* Path to your game's compiled JSON.
* It is relative to index.html file.
*/
const entryPoint = 'game/game.ink.json';
let continueToNextChoice, displayText, loadGame, saveChoice, s;
/**
* You can change this function.
* It's an easy way to define your own tags and text transformations.
*/
function transform (text) {
text = text.replace('<st>', '<span class="subtitle">');
text = text.replace('</st>', '</span>');
text = text.replace('<ell>', '<span class="ellipsis">⏸️&nbsp;</span>');
return text;
}
saveChoice = function(index) {
/**
* You don't need to change anything past this point.
*/
function saveChoice(index) {
window.progress.push(index);
return localStorage.setItem("progress", JSON.stringify(window.progress));
};
function listCharacters (paragraphs) {
const chars = [
{
match: "Я:",
title: "🙉",
},
{
match: "ПОЛ:",
title: "🙍‍♀️"
}
]
let output = "<p>На сцене:</p>"
for (let j = 0; j < chars.length; j++) {
const e = chars[j];
if (paragraphs.match(e.match)) {
output += "<p>"+e.title+"</p>"
}
}
return output.trim()
}
displayText = function(s, interactive = true) {
function displayText(interactive = true) {
let block, delay, html, i, paragraphs, results;
results = [];
while (s.canContinue) {
paragraphs = s.Continue().split("\n");
while (window.s.canContinue) {
paragraphs = window.s.Continue().split("\n");
if (interactive) {
delay = 1000;
}
@ -44,8 +39,7 @@ displayText = function(s, interactive = true) {
for (j = 0, len = paragraphs.length; j < len; j++) {
i = paragraphs[j];
if (i !== "") {
i = i.replace('<st>', '<span class="subtitle">');
i = i.replace('</st>', '</span>');
i = transform(i);
html = jQuery.parseHTML(i);
block = jQuery('<p>').html(html);
if (interactive) {
@ -68,26 +62,16 @@ displayText = function(s, interactive = true) {
return results;
};
continueToNextChoice = function(s) {
function continueToNextChoice () {
let choice, j, len, ref, scrollTo;
displayText(s, true);
displayText(true);
scrollTo = jQuery('#options').offset().top;
if (s.currentChoices.length > 0) {
const characters = listCharacters(jQuery("#content").text());
if (characters.trim().length > 0) {
if (jQuery("#content .portraits").length === 0) {
jQuery("#content").prepend('<div class="portraits">'+characters.trim()+'</div>')
} else {
jQuery(".portraits").html(characters.trim())
}
}
jQuery("#options").html("").hide();
ref = s.currentChoices;
ref = window.s.currentChoices;
for (j = 0, len = ref.length; j < len; j++) {
choice = ref[j];
let text = choice.text.replace('<st>', '<span class="subtitle">');
text = text.replace('</st>', '</span>')
text = text.replace('<ell>', '<span class="ellipsis">⏸️&nbsp;</span>');
let text = transform(choice.text)
jQuery("#options").append(`<li><a href='#' id='choice-${choice.index}' data-index=${choice.index}>${text}</a></li>`);
}
jQuery("#options").fadeIn(500);
@ -95,31 +79,27 @@ continueToNextChoice = function(s) {
jQuery("#content").append("<p>THE END</p>");
jQuery("#options").html("");
}
return jQuery('html, body').animate({
scrollTop: scrollTo
}, 800);
if (window.progress.length > 0) {
return jQuery('html, body').animate({
scrollTop: scrollTo
}, 800);
}
};
loadGame = function(s) {
let index, j, ref, results;
function loadGame () {
let index, j, len, ref, results;
document.getElementById("content").innerHTML = ""
document.getElementById("options").innerHTML = ""
ref = window.progress;
results = [];
const len = ref.length;
while(s.canContinue) {
displayText(s, false);
}
for (j = 0; j < len; j++) {
index = ref[j];
if (!index) {
continue
}
if (!s.currentChoices[index]) {
continue
}
s.ChooseChoiceIndex(index)
while(s.canContinue) {
displayText(s, false);
if (ref.length > 0) {
for (j = 0, len = ref.length; j < len; j++) {
index = ref[j];
displayText(false);
results.push(window.s.ChooseChoiceIndex(index));
}
} else {
continueToNextChoice(window.s);
}
return results;
};
@ -135,11 +115,11 @@ jQuery.ajax({
} else {
window.progress = [];
}
s = new inkjs(data);
window.s = new inkjs(data)
if (window.progress !== []) {
loadGame(s);
loadGame(window.s);
}
return continueToNextChoice(s);
return continueToNextChoice(window.s);
}
});
@ -148,15 +128,46 @@ jQuery(document).on('click', "#restart", function() {
window.location.reload();
});
jQuery(document).on('click', "#options li a", function() {
s.ChooseChoiceIndex(jQuery(this).data("index"));
saveChoice(jQuery(this).data("index"));
jQuery(document).on('click', "#undo", function() {
jQuery("#undo").hide();
window.progress.pop()
localStorage.setItem("progress", JSON.stringify(window.progress));
window.location.reload();
});
function choose(index) {
window.s.ChooseChoiceIndex(index);
jQuery("#undo").show()
saveChoice(index);
continueToNextChoice(s);
}
jQuery(document).on('click', "#options li a", function() {
choose(jQuery(this).data("index"));
return false;
});
jQuery(document).on('click', "#options li", function() {
s.ChooseChoiceIndex(jQuery(this).find('a').data("index"));
saveChoice(jQuery(this).find('a').data("index"));
continueToNextChoice(s);
choose(jQuery(this).find('a').data("index"));
return false;
});
jQuery(document).on('keydown', function(key) {
key = key.key
switch (key) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
jQuery(`#options li:nth-child(${key})`).first().trigger("click")
break;
case '0':
jQuery(`#options li:nth-child(10)`).first().trigger("click")
break;
}
return false;
});

View file

@ -65,11 +65,6 @@ h2 {
margin-top: $font-size-base;
padding-top: $font-size-base * 0.5;
}
#restart {
position: fixed;
top: $font-size-base * 0.5;
right: $font-size-base * 0.5;
}
#content {
.subtitle {
display: none;
@ -120,3 +115,7 @@ h2 {
float: right;
margin: ($font-size-base * 0.5);
}
.text-right {
text-align: right;
}