Начало

This commit is contained in:
Alexander Yakovlev 2019-01-12 18:24:16 +07:00
commit a209caa42d
Signed by: oreolek
GPG key ID: 1CDC4B7820C93BD3
6 changed files with 413 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
index.html

4
Makefile Normal file
View file

@ -0,0 +1,4 @@
all:
tweego src -o index.html
test:
tweego -t src -o index.html

93
src/game.css Normal file
View file

@ -0,0 +1,93 @@
html {
/* Vertical colour gradient */
background-image: linear-gradient(to bottom, gainsboro, silver);
background-image: -webkit-linear-gradient(top, gainsboro, silver);
background-attachment: fixed;
width: 100%;
/* Fallback colour */
background-color: papayawhip;
}
body {
background-color: transparent;
margin: 10% 0 0 0;
font-size: 100%;
text-align: center;
width: 100%;
}
hr {
border-top: 1px solid #000;
}
#passages {
/* Box background (white with 70% opacity) */
background-color: rgba(255, 255, 255, 0.7);
/* Border */
border: 2px solid white;
/* Rounded corners */
border-radius: 1em;
/* Centered box */
display: inline-block;
width: 60%;
min-height: 40%;
margin:auto;
margin-bottom: 5%;
padding: 0px;
}
.passage {
margin: 0px;
padding: 2em;
/* Text formatting */
color: black;
font-size: 100%;
text-align:justify;
}
.red,
.green {,
transition: all .7s;
-webkit-transition: all .7s;
}
.red {
color: #420000;
}
.red:hover {
color: #DD0000;
}
.green {
color: #004200;
}
.green:hover {
color: #00DD00;
}
/* Links */
a.internalLink,
a.externalLink {
color: royalblue;
padding: 2px;
}
a.internalLink:hover,
a.externalLink:hover {
color: deepskyblue;
text-decoration: none;
}
a.gamepadSelected {
border: 2px dotted blue;
padding: 0px;
}
/* Shrink the page when viewed on devices with a low screen width */
@media screen and (max-width: 960px) {
#passages { width: 75%; }
}
@media screen and (max-width: 840px) {
#passages { width: 85%; }
}
@media screen and (max-width: 720px) {
#passages { width: 95%; }
}

111
src/game.tw Normal file
View file

@ -0,0 +1,111 @@
::StoryTitle
Космические Волны
::StorySettings
ifid:dcd7d6b9-0f25-4ce1-bff1-e603c67066d5
::StoryConfig [script]
Config.debug = true;
Config.ui.stowBarInitially = true;
Config.passages.nobr = true;
::Start
<!-- «Четвёртое измерение», «Дворцовые интриги» и «Городской житель случайно попадает в глухую деревню» -->
<center>
<h1 class="red">Космические Волны</h1>
<small>Oreolek</small>
</center>
<p>Сегодня вечером группа «Космические Волны» выступает с единственным концертом на Луне. Вам <b>необходимо</b> попасть на ракету Москва-кратер Аль-Баттани C. Сумка уже собрана, но можно что-то повесить на себя. Что же взять с собой в дорогу?</p>
<ul class="choices">
<li>[[Гитару, чтобы получить на ней автограф|guitar]]</li>
<li>[[Вязаную шапку, чтобы не замёрзли уши|hat]]</li>
<li>[[Бутылочку домашней настойки|bottle]]</li>
</ul>
::guitar
<<set $inventory to 'guitar' >>
<p>Вряд ли получится протолкнуться в зону автографов, но вы очень надеетесь на свою уникальную удачу. Без гитары — никуда.</p>
<<include flight>>
::hat
<<set $inventory to 'hat' >>
<p>На этой шапке тоже нарисованы уши. Говорят, что сначала лунный холод отмораживает их, а потом уже принимается за ваши собственные.</p>
<<include flight>>
::bottle
<<set $inventory to 'bottle' >>
<p>Чёрная смородина, мёд, шишки и немного веселья для полного отрыва на концерте.
Будет незабываемо.</p>
<<include flight>>
::flight
<hr>
<p>В ракете вас пристёгивают к жёсткому креслу. <<if $inventory is 'guitar'>> Вы отвоевали право не расставаться с гитарой, но вот сумку пришлось отдать стюардессе на хранение. <<else>> Сумку пришлось отдать на хранение стюардессе. <</if>></p>
<p>На подлёте к Луне вы слышите громкое <span class="red">хлоп.</span> Затем мимо вас проплывает пилот в пухлом скафандре, отталкиваясь руками от кресел.</p>
<ul class="choices">
<li>[[Попробовать освободиться|escape]]</li>
<li>[[Ждать|wait]]</li>
</ul>
::escape
<<set $escape to true >>
<p>Вы отстёгиваете один из ремней. Теперь вы можете поворачивать туловище.</p>
<<include escape2>>
::wait
<<include escape2>>
::escape2
<p><span class="red">хлоп.</span></p>
<p>Внезапно ракета вокруг просто… перестаёт быть. С тихим <span class="red">пуф</span> вы падаете спиной назад на что-то тёплое.
Над головой светит красное небо.
<<if $escape is true>>
<<if $inventory is 'guitar'>>
И гитары в руках тоже больше нет.
<<elseif $inventory is 'hat'>>
И шапки на голове тоже больше нет.
<<else>>
И бутылки в кармане тоже больше нет.
<</if>>
<<set $inventory to ''>>
<</if>>
</p>
<p><span class="green">— Паис! Паис!</span> — кричит женский голос.</p>
<p>К вам подбегает <<link "чумазая девушка">><<replace "#look" t8n>>
Русоволосая девушка лет двадцати в рабочем комбинезоне и резиновых сапогах.
<</replace>><</link>> и помогает встать. Вы оглядываетесь: под вами без чувств лежит какой-то мужчина.</p>
<p><span class="green">— Паис! Вставай!</span></p>
<p>Вы оглядываетесь. Кроваво-красное небо, жёлтые колосья пшеницы в чёрном песке, какие-то дома вдалеке.
Вы не знаете, где очутились.</p>
<span id="look"></span>
<ul class="choices">
<li>[[Разбудить мужчину|man]]</li>
<li>[[Тихо уйти|away]]</li>
</ul>
::away
<p>Вы отходите на несколько шагов и наступаете на незаметную яму.
Нога вязнет в чёрном песке, за ней застревает и вторая.</p>
<p>Девушка расталкивает мужчину; тот встаёт

23
src/gamepad.min.js vendored Normal file

File diff suppressed because one or more lines are too long

181
src/twine_gamepad.js Normal file
View file

@ -0,0 +1,181 @@
/* @license
The MIT License (MIT)
Copyright (c) 2014 mildmojo
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function(exports) {
var Gamepad = window.Gamepad;
// Removed until it's tested with node-webkit.
// if ((typeof(module) !== 'undefined') && module.exports) {
// Gamepad = require('gamepad');
// } else {
// Gamepad = window.Gamepad;
// }
var gamepad = new Gamepad();
var axes = { LEFT_STICK_X: 0, LEFT_STICK_Y: 0 };
var DEADZONE = 0.5;
gamepad.bind(Gamepad.Event.CONNECTED, function(_device) {
console.log('Gamepad connected.');
});
gamepad.bind(Gamepad.Event.DISCONNECTED, function(_device) {
console.log('Gamepad disconnected.');
});
gamepad.bind(Gamepad.Event.BUTTON_DOWN, function(e) {
switch(e.control) {
case 'DPAD_DOWN':
case 'DPAD_RIGHT':
nextLink();
break;
case 'DPAD_UP':
case 'DPAD_LEFT':
prevLink();
break;
case 'FACE_1':
case 'FACE_2':
case 'FACE_3':
case 'FACE_4':
var selected = document.querySelector('.gamepadSelected');
if (selected) {
removeClass(selected, 'gamepadSelected');
selected.dispatchEvent(new MouseEvent('click'));
}
break;
}
});
// Treat axes as buttons; register presses and releases.
gamepad.bind(Gamepad.Event.AXIS_CHANGED, function(data) {
var newValue = 0;
if (Math.abs(data.value) > DEADZONE) {
newValue = data.value < 0 ? -1 : 1;
if (axes[data.axis] !== newValue) {
if (data.axis === 'LEFT_STICK_X') {
if (newValue === -1) {
gamepad._fire(Gamepad.Event.BUTTON_DOWN, {control: 'DPAD_LEFT'});
} else {
gamepad._fire(Gamepad.Event.BUTTON_DOWN, {control: 'DPAD_RIGHT'});
}
} else if (data.axis === 'LEFT_STICK_Y') {
if (newValue === 1) {
gamepad._fire(Gamepad.Event.BUTTON_DOWN, {control: 'DPAD_DOWN'});
} else {
gamepad._fire(Gamepad.Event.BUTTON_DOWN, {control: 'DPAD_UP'});
}
}
}
}
axes[data.axis] = newValue;
});
gamepad.init();
function nextLink() {
var links = getTwineLinks();
if (links === null) return;
var selectedIndex = findSelectedIndex(links);
var newIndex = 0;
if (selectedIndex !== null) {
removeClass(links[selectedIndex], 'gamepadSelected');
newIndex = (selectedIndex + 1) % links.length
}
addClass(links[newIndex], 'gamepadSelected');
showLink();
}
function prevLink() {
var links = getTwineLinks();
if (links === null) return;
var selectedIndex = findSelectedIndex(links);
var newIndex = 0;
if (selectedIndex !== null) {
removeClass(links[selectedIndex], 'gamepadSelected');
newIndex = selectedIndex > 0 ? selectedIndex - 1 : links.length - 1;
}
addClass(links[newIndex], 'gamepadSelected');
showLink();
}
function showLink() {
var selected = document.querySelector('.gamepadSelected');
if (selected && !isVisible(selected)) {
var position = isAboveViewport(selected)
selected.scrollIntoView(position);
}
}
function getTwineLinks() {
return document.querySelectorAll('a.internalLink, a.externalLink');
}
function findSelectedIndex(links) {
for (var i = 0; i < links.length; i++) {
if (hasClass(links[i], 'gamepadSelected')) {
return i;
}
}
return null;
}
function isVisible(el) {
var offset = el.getBoundingClientRect();
if (offset.left < 0 || offset.top < 0){
return false;
}
if (offset.left > window.innerWidth || offset.top > window.innerHeight){
return false;
}
return true;
}
function isAboveViewport(el) {
return el.getBoundingClientRect().top < 0;
}
// From youmightnotneedjquery.com
function hasClass(el, className) {
if (el.classList)
return el.classList.contains(className);
else
return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
}
// From youmightnotneedjquery.com
function removeClass(el, className) {
if (el.classList)
el.classList.remove(className);
else
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
// From youmightnotneedjquery.com
function addClass(el, className) {
if (el.classList)
el.classList.add(className);
else
el.className += ' ' + className;
}
})(((typeof(module) !== 'undefined') && module.exports) || window);