1
0
Fork 0
mirror of https://github.com/Oreolek/raconteur.git synced 2024-05-17 08:18:17 +03:00
This commit is contained in:
Bruno Dias 2015-04-07 21:44:08 -03:00
parent 9473cbfa6e
commit fb170cf4d0
5 changed files with 382 additions and 103 deletions

3
.gitignore vendored
View file

@ -1,3 +1,4 @@
node_modules/**
devel/node_modules/**
devel/build/**
game/**
*.sublime-workspace

74
devel/Gulpfile.js Normal file
View file

@ -0,0 +1,74 @@
/*
This Gulpfile is used to build a development version of the library and
example game all together from the main sources, for development use.
*/
var gulp = require('gulp'),
browserify = require('browserify'),
babelify = require('babelify'),
source = require('vinyl-source-stream'),
less = require ('gulp-less'),
browserSync = require('browser-sync');
var reload = browserSync.reload;
gulp.task('lib', function () {
return gulp.src('../undum/lib/*.js')
.pipe(gulp.dest('./build/lib/'));
});
gulp.task('undularity', function () {
return gulp.src('../undularity/undularity.js')
.pipe(gulp.dest('./build/lib/'));
});
gulp.task('js-template', function () {
return gulp.src('../template/js/*.js')
.pipe(gulp.dest('./build/game/'));
});
gulp.task('browserify', ['lib', 'undularity', 'js-template'], function () {
return browserify('./build/game/main.js')
.transform(babelify)
.bundle()
.on("error", function (err) { console.log ("Error: " + err.message)})
.pipe(source('undum.js'))
.pipe(gulp.dest('./build/game/'))
.pipe(reload({stream: true}));
});
gulp.task('less', function () {
return gulp.src('../template/less/undum.less')
.pipe(less())
.pipe(gulp.dest('./build/css/'))
.pipe(reload({stream: true}));
});
gulp.task('html', function () {
return gulp.src('../template/html/index.html')
.pipe(gulp.dest('./build/'))
.pipe(reload({stream: true}));
});
gulp.task('default', function () {
gulp.start('browserify');
gulp.start('less');
gulp.start('html');
});
gulp.task('serve', ['default'], function () {
browserSync({
notify: false,
port: 9000,
server: './build'
});
gulp.watch('../template/less/*.less', ['less']);
gulp.watch('../template/html/*.html', ['html']);
gulp.watch('../undum/lib/*.js', ['browserify']);
gulp.watch('../undularity/undularity.js', ['browserify']);
gulp.watch('../template/js/*.js', ['browserify']);
});

View file

@ -2,11 +2,67 @@ var situation = require('../lib/undularity.js'),
$ = require('jquery'),
undum = require('../lib/undum.js');
var a = situation.a;
undum.game.id = "my_game_id";
undum.game.version = "1.0";
situation('start', {
content: `This is a -- "testing" situation.`
content:
`This is a testing situation for Undularity, a better development system for Undum.
Choose one of the options below to see the relevant content and test it.`,
choices: ['#testing-option']
});
situation('functions-as-properties', {
content: (character, system, from) =>
`This property of this situation is outputted by a function, which allows
us to incorporate variables such as the name of the situation we came
from; in this case, "${from}."
Undularity allows most properties that are text to be defined as
functions; the notable exception is optionText. Those functions are
passed the character and system objects, in that order, and a third
object that is usually either the current situation, or the situation
we just came from.`,
tags: ['testing-option'],
optionText: 'Functions as properties'
});
situation('markdown-features', {
content: `
# Markdown Support
Undularity uses Markdown for formatting the content of individual
situations. Supported features include **strong** and *emphasis*,
headers (as above), [external links](http://github.com), and even
preformatted blocks of text:
situation('start', {
content: "This is an example."
});
Additionally, we also support "smart quotes" and -- dashes.`,
tags: ['testing-option'],
optionText: 'Markdown support'
});
situation('special-links', {
content: `
# Special Links
Undularity supports various special types of links, starting with
${a().content('writer').once.writer('writerlink')} links.
Also notable are ${a().id('replacer-link').content('replacer').replacer('replacer-link')}
links, which replace the content of a given id.
`,
writers: {
writerlink: "Writer links can only be clicked once.",
'replacer-link': "switching"
},
tags: ['testing-option']
});
$(function(){undum.begin()});

View file

@ -1,12 +1,14 @@
@import "undum-mobile";
@body_bg: tan;
@content_bg: white;
@title_bg: steelblue;
@text-color: black;
body {
background: #170804 url("../img/page_bg.jpg") repeat-x left top;
font-family: Palatino, Times, "Times New Roman", serif;
background: @body_bg;
color: @text-color;
font-size: 18px;
line-height: 1.6em;
background-attachment: fixed;
overflow-y: scroll;
}
/* Basic structure */
@ -14,91 +16,85 @@ body {
margin: 0 auto;
position: relative;
}
#mid_panel {
margin: 0 10.5em;
}
/* The title block */
#title, #title .label, #content, .tools {
border-radius: 2px;
}
#title {
max-width: 28em;
background: #e6e6c6 url("../img/title_bg.jpg") repeat -1.1em -1.1em;
margin: 2.2em auto 1.1em auto;
background: @title_bg;
padding: 1.7em;
border: 1.1em solid rgba(0,0,0,0.25);
border: 1px solid black;
cursor: pointer; /* Until we click to start. */
}
#title .label {
overflow: hidden;
background: #e6e6c6 url("../img/text_bg.jpg") repeat left top;
padding: 2.0em;
margin: auto;
max-width: 18em;
-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.4);
box-shadow: 0 0 4px rgba(0,0,0,0.4);
position: relative;
}
#title h1 {
font-size: 1.6em;
line-height: 1.4em;
letter-spacing: 0.2em;
font-weight: normal;
padding-bottom: 1.1em;
border-bottom: 1px solid #321;
}
#title h2 {
font-size: 1.2em;
font-weight: normal;
text-align: center;
margin: 1.1em 0 0 0;
}
#title h3 {
font-size: 1.0em;
font-weight: normal;
text-align: center;
margin: 1.1em 0 0 0;
}
#title h1, #title h2, #title h3 {
color: rgba(33,17,0,0.9);
text-shadow: rgba(255,255,255,0.5) 2px 2px 2px,
rgba(0,0,0,0.1) -1px -1px 2px;
}
#title h1 span.fancy {
font-size: 2.5em;
line-height: 0;
font-family: Tangerine, Palatino, Times, "Times New Roman", serif;
font-style: italic;
margin: 0 -0.2em;
}
#title .click_message {
display: none;
left: 0;
right: 0;
bottom: 0;
position: absolute;
font-size: 0.9em;
font-style: italic;
text-align: center;
color: #987;
}
#title .noscript_message {
left: 0;
right: 0;
bottom: 0;
position: absolute;
font-size: 0.9em;
font-style: italic;
text-align: center;
color: #943;
.label {
overflow: hidden;
padding: 2.0em;
margin: auto;
max-width: 18em;
position: relative;
border: 1px dashed black;
}
h1 {
font-size: 1.6em;
line-height: 1.4em;
letter-spacing: 0.2em;
font-weight: normal;
padding-bottom: 1.1em;
border-bottom: 1px solid #321;
}
h2 {
font-size: 1.2em;
font-weight: normal;
text-align: center;
margin: 1.1em 0 0 0;
}
h3 {
font-size: 1.0em;
font-weight: normal;
text-align: center;
margin: 1.1em 0 0 0;
}
.click_message {
display: none;
left: 0;
right: 0;
bottom: 0;
position: absolute;
font-size: 0.9em;
font-style: italic;
text-align: center;
color: #987;
}
.noscript_message {
left: 0;
right: 0;
bottom: 0;
position: absolute;
font-size: 0.9em;
font-style: italic;
text-align: center;
color: #943;
}
}
/* Main content */
#content_wrapper {
max-width: 28em;
position: relative;
background: #e6e6c6 url("../img/text_bg.jpg") repeat left top;
background: @content_bg;
margin: 0.6em auto 1.1em auto;
padding: 2.8em;
display: none; /* Shown by Javascript */
@ -107,11 +103,13 @@ body {
span.drop + p {
text-indent: -0.4em;
}
p {
margin: 0;
-webkit-transition: text-indent 0.25s ease;
transition: text-indent 0.25s ease;
}
hr {
border: none;
background-color: rgba(0,0,0,0.25);
@ -119,29 +117,16 @@ hr {
width: 1.1em;
height: 2px;
}
p + p, p + img + p, p + hr + p {
text-indent: 1.6em;
}
#content h1 + p:first-line,
#content h1 + img + p:first-line {
font-weight: bold;
color: rgba(0,0,0,0.85);
}
#content h1 + p:first-letter,
#content h1 + img + p:first-letter {
position: relative;
padding-top: 0.1em;
display: block;
float: left;
font-weight: normal;
font-size: 3.2em;
line-height: 0.8em;
color: #210;
}
ul {
margin: 0;
padding: 0 0 0 1em;
}
ul.options {
border: 2px solid #876;
padding: 0;
@ -150,14 +135,17 @@ ul.options {
list-style-type: none;
border-radius: 4px;
}
ul.options li {
border-bottom: 1px solid #876;
padding: 0.5em;
}
ul.options li:hover {
background-color: rgba(153,136,119,0.2);
cursor: pointer;
}
ul.options li:last-child {
border-bottom: none;
}
@ -170,9 +158,11 @@ h1 {
color: #210;
text-align: center;
}
h1:first-child {
margin-top: 0;
}
a {
color: #900;
text-decoration: none;
@ -180,7 +170,6 @@ a {
}
a.raw {
padding-right: 14px;
background: transparent url("../img/external_link.png") no-repeat right 4px;
}
a:hover {
border-bottom: 1px dotted #900;
@ -212,7 +201,7 @@ img.float_left {
.tools {
padding: 0.6em;
width: 8.9em;
background: #cec3ae url("../img/tools_bg.jpg") repeat left top;
background: #cec3ae;
position: absolute;
}
.tools p {
@ -357,3 +346,26 @@ img.float_left {
#menu {
display: none;
}
@keyframes fade_in{
from {
color: rgba(0,0,0,0);
}
to {
color: rgba(0,0,0,1);
}
}
@-webkit-keyframes fade_in{
from {
color: rgba(0,0,0,0);
}
to {
color: rgba(0,0,0,1);
}
}
.fade {
animation: fade_in 500ms ease-in-out;
-webkit-animation: fade_in 500ms ease-in-out;
}

View file

@ -1,10 +1,53 @@
var undum = require('./undum.js'),
marked = require('marked'),
md = require('markdown-it'),
$ = require('jquery');
var markdown = function (content) {
return marked(content, {smartypants: true});
}
/*
Helper functions
*/
/*
Normalises the whitespace on a string. So the indentation level of the
first line will become 0.
*/
String.prototype.normaliseTabs = function () {
let lines = this.split('\n');
let indent = lines[0].match(/^\s+/) || lines[1].match(/^\s/);
if (!indent) return this;
return lines.map( s => s.replace('^' + indent[0], '')).join('\n');
};
/* Agnostic Call */
Function.prototype.fcall = Function.prototype.call;
String.prototype.fcall = function () {return this;};
/*
Markdown renderer.
*/
var markdown = new md({
typographer: true,
html: true
});
/*
Ensures a string is a HTML string, by wrapping span tags.
*/
String.prototype.spanWrap = function () {
return `<span>${this}</span>`;
};
/*
Adds the "fade" class to some html.
*/
String.prototype.fade = function () {
return $(this).addClass('fade');
};
var UndularitySituation = function (spec) {
undum.Situation.call(this, spec);
@ -12,20 +55,113 @@ var UndularitySituation = function (spec) {
// API properties
this.content = spec.content;
this.choices = (spec.choices === undefined) ? [] : spec.choices;
this.writers = (spec.writers === undefined) ? {} : spec.writers;
this.visited = false;
};
UndularitySituation.prototype.enter = function (character, system, from) {
console.log("got here");
console.log(this);
UndularitySituation.inherits(undum.Situation);
UndularitySituation.prototype.enter = function (character, system, f) {
if (this.content) {
system.write(this.content);
system.write(markdown.render(this.content.fcall(this, character, system, f).normaliseTabs()));
}
if (this.choices) {
let choices = system.getSituationIdChoices(this.choices,
this.minChoices, this.maxChoices);
system.writeChoices(choices);
}
};
UndularitySituation.prototype.act = function (character, system, action) {
var actionClass,
self = this;
var responses = {
writer: function (ref) {
system.write(
markdown.render(
self.writers[ref].fcall(this, character, system, action)
).fade());
},
replacer: function (ref) {
console.log('Replacer called ', ref);
system.replaceWith(
markdown.renderInline(
self.writers[ref].fcall(this, character, system, action)
).spanWrap().fade(), `#${ref}`);
}
};
if (actionClass = action.match(/^_(\w+)_(.+)$/)) {
responses[actionClass[1]](actionClass[2]);
}
};
/* Element Helpers */
/*
While you can write HTML elements by hand, those helpers make it easier to
place anchors (especially with special purpose) and spans.
They define a monadic interface:
a().id('my-link').content('link').writer('my-ref')
-> <a id="my-link" href="./_writer_my-ref">link</a>
span().here -> <span></span>
*/
/* Anchor element */
/* Transforms:
content: The inner content of the link, as inline Markdown.
id: A space-separated list of element ids.
once: The 'once' special link class. A getter.
*/
var a = function () {
var once = "",
id = "",
content = "";
var monad = {
writer: (ref) => `<a ${id} class="${once} writer" href="./_writer_${ref}">${markdown.renderInline(content)}</a>`,
replacer: (ref) => `<a ${id} class="${once} replacer" href="./_replacer_${ref}">${markdown.renderInline(content)}</a>`,
content: function (s) { content = s; return monad; },
id: function (s) {id = `id="${s}"`; return monad; },
get once () { once = "once"; return monad; }
};
return monad;
};
var span = function (content) {
var elementClass = "",
id = "",
content = "";
var monad = {
get here () { return `<span ${id} ${elementClass}>${content}</span>`; },
id: function (s) {
id = `id="${s}"`;
return monad;
},
content: function (s) {
content = s;
return monad;
},
class: function (s) {
elementClass = `class="${s}"`;
return monad;
}
};
return monad;
}
module.exports = function (name, spec) {
spec.name = name;
spec.content = markdown(spec.content);
undum.game.situations[name] = new UndularitySituation(spec);
};
module.exports.a = a;