Some work on story player

This commit is contained in:
Adam Blažek 2021-05-13 20:50:41 +02:00
parent 3e881c19de
commit 7c6f7f1001
6 changed files with 158 additions and 0 deletions

37
c/iprib/app.coffee Normal file
View File

@ -0,0 +1,37 @@
import {createApp} from '../../scripts/vue.esm-browser.min.js'
app = createApp
data: =>
gender: 'm'
formal: false
reader: new FileReader()
methods:
parseSwtches: (text) ->
swtches = while match = text.match /^([+-])([\p{L}\d_]+) (.*)/u
text = match[3]
{value: match[1] == '+', name: match[2]}
{text, swtches}
loadStory: (story, version = 0) ->
paragraphs = story.split('\n\n')
scenes = new Map paragraphs.map (paragraph) =>
[title, text, options...] = paragraph.split('\n').filter((line) => line)
scene =
title: title
text: if version >= 1 then this.parseSwtches(text) else {text: text, switches: []}
options: options.map (option) =>
[left, right] = option.split(' > ')
{text, swtches: prerequisites} = this.parseSwtches(left)
{text: next, swtches: consequences} = this.parseSwtches(right)
{prerequisites, text, next, consequences}
[title, scene]
scenes.forEach (scene) =>
scene.options.forEach (option) =>
option.next = scenes.get option.next
throw "Neexistující scéna: #{option.next}" if not option.next?
this.initialScene = scenes.get story.match(/.*/)[0]
loadStoryFromFile: (file) ->
version = parseInt(file.name.match(/\.iprib(\d+)$/)[1])
this.reader.onload = (event) => this.loadStory(event.target.result, version)
this.reader.readAsText file
window.vm = app.mount '#app'

84
c/iprib/app.js Normal file
View File

@ -0,0 +1,84 @@
// Generated by CoffeeScript 2.5.1
var app;
import {
createApp
} from '../../scripts/vue.esm-browser.min.js';
app = createApp({
data: () => {
return {
gender: 'm',
formal: false,
reader: new FileReader()
};
},
methods: {
parseSwtches: function(text) {
var match, swtches;
swtches = (function() {
var results;
results = [];
while (match = text.match(/^([+-])([\p{L}\d_]+) (.*)/u)) {
text = match[3];
results.push({
value: match[1] === '+',
name: match[2]
});
}
return results;
})();
return {text, swtches};
},
loadStory: function(story, version = 0) {
var paragraphs, scenes;
paragraphs = story.split('\n\n');
scenes = new Map(paragraphs.map((paragraph) => {
var options, scene, text, title;
[title, text, ...options] = paragraph.split('\n').filter((line) => {
return line;
});
scene = {
title: title,
text: version >= 1 ? this.parseSwtches(text) : {
text: text,
switches: []
},
options: options.map((option) => {
var consequences, left, next, prerequisites, right;
[left, right] = option.split(' > ');
({
text,
swtches: prerequisites
} = this.parseSwtches(left));
({
text: next,
swtches: consequences
} = this.parseSwtches(right));
return {prerequisites, text, next, consequences};
})
};
return [title, scene];
}));
scenes.forEach((scene) => {
return scene.options.forEach((option) => {
option.next = scenes.get(option.next);
if (option.next == null) {
throw `Neexistující scéna: ${option.next}`;
}
});
});
return this.initialScene = scenes.get(story.match(/.*/)[0]);
},
loadStoryFromFile: function(file) {
var version;
version = parseInt(file.name.match(/\.iprib(\d+)$/)[1]);
this.reader.onload = (event) => {
return this.loadStory(event.target.result, version);
};
return this.reader.readAsText(file);
}
}
});
window.vm = app.mount('#app');

1
c/iprib/index.html Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><script defer src="app.js" type="module"></script><title>Interaktivní příběhy | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Interaktivní příběhy</h1><div id="app"><p>Příběh:<input type="file" accept=".iprib0,.iprib1" v-on:input="loadStoryFromFile($event.target.files[0])"></p><p>Pohlaví:<input name="gender" type="radio" v-model="gender" value="m" id="male-radio"><label for="male-radio">Muž</label><input name="gender" type="radio" v-model="gender" value="f" id="female-radio"><label for="female-radio">Žena</label></p><p>Formalita:<input name="formal" type="radio" v-model="formal" v-bind:value="false" id="informal-radio"><label for="male-radio">Tykat</label><input name="formal" type="radio" v-model="formal" v-bind:value="true" id="formal-radio"><label for="female-radio">Vykat</label></p></div></body></html>

23
c/iprib/index.jade Normal file
View File

@ -0,0 +1,23 @@
extends ../../templates/main.jade
block head
script(defer src="app.js" type="module")
block title
| Interaktivní příběhy | xigoi
block content
h1 Interaktivní příběhy
#app
p Příběh:
input(type="file" accept=".iprib0,.iprib1" v-on:input="loadStoryFromFile($event.target.files[0])")
p Pohlaví:
input(name="gender" type="radio" v-model="gender" value="m" id="male-radio")
label(for="male-radio") Muž
input(name="gender" type="radio" v-model="gender" value="f" id="female-radio")
label(for="female-radio") Žena
p Formalita:
input(name="formal" type="radio" v-model="formal" v-bind:value="false" id="informal-radio")
label(for="male-radio") Tykat
input(name="formal" type="radio" v-model="formal" v-bind:value="true" id="formal-radio")
label(for="female-radio") Vykat

8
scripts/vue.esm-browser.min.js vendored Normal file

File diff suppressed because one or more lines are too long

5
scripts/vue.esm-browser.prod.min.js vendored Normal file

File diff suppressed because one or more lines are too long