pretty dialogue ui
This commit is contained in:
parent
8655f71e8f
commit
0f042d89eb
119
game.css
119
game.css
|
@ -15,33 +15,130 @@ body{
|
|||
|
||||
width: 360px;
|
||||
height: 600px;
|
||||
background: #fff;
|
||||
background: #ccc;
|
||||
|
||||
font-size: 20px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-weight: 100;
|
||||
line-height: 1.3em;
|
||||
|
||||
}
|
||||
#game_text{
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
#game_words{
|
||||
width: auto;
|
||||
height: 450px;
|
||||
|
||||
overflow: scroll;
|
||||
|
||||
position: relative;
|
||||
top: 80px;
|
||||
}
|
||||
#game_text > div{
|
||||
margin: 30px;
|
||||
|
||||
.human-bubble {
|
||||
position: relative;
|
||||
background: #ffffff;
|
||||
color: #000000;
|
||||
border-radius: .4em;
|
||||
padding: 15px;
|
||||
margin: 10px 30px;
|
||||
|
||||
opacity: 0;
|
||||
left: -15px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.human-bubble:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 15px solid transparent;
|
||||
border-right-color: #ffffff;
|
||||
border-left: 0;
|
||||
margin-top: -15px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
.wolf-bubble {
|
||||
position: relative;
|
||||
background: #000000;
|
||||
color: #ffffff;
|
||||
border-radius: .4em;
|
||||
padding: 15px;
|
||||
margin: 10px 30px;
|
||||
|
||||
opacity: 0;
|
||||
left: 15px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.wolf-bubble:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 15px solid transparent;
|
||||
border-left-color: #000000;
|
||||
border-right: 0;
|
||||
margin-top: -15px;
|
||||
margin-right: -15px;
|
||||
}
|
||||
|
||||
#game_choices{
|
||||
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
height: 110px;
|
||||
padding: 20px 0;
|
||||
|
||||
position: absolute;
|
||||
bottom:0;
|
||||
|
||||
background: #666;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-weight: normal;
|
||||
|
||||
}
|
||||
}
|
||||
#game_choices > div{
|
||||
margin-bottom:0.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
/***********************************/
|
||||
/***********************************/
|
||||
|
||||
#game_hp{
|
||||
position: absolute;
|
||||
width: 360px;
|
||||
height: 80px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
|
||||
background: rgb(204,204,204);
|
||||
background: linear-gradient(180deg, rgba(204,204,204,1) 80%, rgba(204,204,204,0) 100%);
|
||||
}
|
||||
#game_hp > div{
|
||||
position: absolute;
|
||||
top:25px;
|
||||
width: 150px;
|
||||
height: 20px;
|
||||
background: #ff4040;
|
||||
}
|
||||
#game_hp > #hp_human{
|
||||
left: 20px;
|
||||
transform: skew(15deg);
|
||||
}
|
||||
#game_hp > #hp_wolf{
|
||||
right: 20px;
|
||||
transform: skew(-15deg);
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
/***********************************/
|
||||
/***********************************/
|
||||
|
||||
#game_canvas{
|
||||
position: absolute;
|
||||
top:0; left:0;
|
||||
border: none;
|
||||
}
|
||||
|
|
177
game.js
177
game.js
|
@ -18,9 +18,11 @@ Game.sections = {};
|
|||
Game.startSectionID = null;
|
||||
|
||||
Game.dom = document.querySelector("#game_container");
|
||||
Game.textDOM = document.querySelector("#game_text");
|
||||
Game.wordsDOM = document.querySelector("#game_words");
|
||||
Game.choicesDOM = document.querySelector("#game_choices");
|
||||
|
||||
Game.queue = [];
|
||||
|
||||
// Parse data!
|
||||
Game.onload = function(data){
|
||||
|
||||
|
@ -54,6 +56,14 @@ Game.onload = function(data){
|
|||
|
||||
});
|
||||
|
||||
// Animation!
|
||||
Game.wordsDOM.style.top = "80px";
|
||||
var animloop = function(){
|
||||
Game.update();
|
||||
requestAnimationFrame(animloop);
|
||||
};
|
||||
requestAnimationFrame(animloop);
|
||||
|
||||
// Let's go!
|
||||
Game.start();
|
||||
|
||||
|
@ -64,6 +74,18 @@ Game.start = function(){
|
|||
Game.goto(Game.startSectionID);
|
||||
};
|
||||
|
||||
Game.update = function(){
|
||||
|
||||
var wordsHeight = 80 + Game.wordsDOM.getBoundingClientRect().height;
|
||||
var currentY = parseFloat(Game.wordsDOM.style.top) || 80;
|
||||
var gotoY = (wordsHeight<260) ? 0 : wordsHeight-260;
|
||||
gotoY = 80 - gotoY;
|
||||
|
||||
var nextY = currentY*0.9 + gotoY*0.1;
|
||||
Game.wordsDOM.style.top = nextY+"px";
|
||||
|
||||
};
|
||||
|
||||
Game.goto = function(sectionID){
|
||||
|
||||
// Clear choices
|
||||
|
@ -71,47 +93,122 @@ Game.goto = function(sectionID){
|
|||
|
||||
// Show each line...
|
||||
var section = Game.sections[sectionID];
|
||||
if(!section){
|
||||
throw "NO SECTION NAMED "+sectionID;
|
||||
}
|
||||
var lines = section.lines;
|
||||
for(var i=0; i<lines.length; i++){
|
||||
|
||||
// Parse handlebars
|
||||
var originalLine = lines[i];
|
||||
line = Game.parseLine(originalLine);
|
||||
Game.queue = Game.queue.concat(lines);
|
||||
Game.executeNextLine();
|
||||
|
||||
// Execute line
|
||||
if(line!=""){ // none, don't execute...
|
||||
};
|
||||
Game.executeNextLine = function(){
|
||||
|
||||
// Execute based on what type it is!
|
||||
var lineType = Game.getLineType(line);
|
||||
switch(lineType){
|
||||
case "text":
|
||||
Game.executeText(line);
|
||||
break;
|
||||
case "choice":
|
||||
Game.executeChoice(line);
|
||||
break;
|
||||
case "code":
|
||||
Game.executeCode(line);
|
||||
break;
|
||||
}
|
||||
var doNextLineImmediately = false;
|
||||
|
||||
// If it's a goto, end THIS section immediately.
|
||||
if(lineType=="goto"){
|
||||
Game.executeGoto(line);
|
||||
// Parse handlebars
|
||||
var originalLine = Game.queue.shift();
|
||||
if(!originalLine) return; // END OF QUEUE.
|
||||
line = Game.parseLine(originalLine);
|
||||
|
||||
// Execute line
|
||||
var promiseNext;
|
||||
if(line!=""){ // none, don't execute...
|
||||
|
||||
// Execute based on what type it is!
|
||||
var lineType = Game.getLineType(line);
|
||||
switch(lineType){
|
||||
case "text":
|
||||
promiseNext = Game.executeText(line);
|
||||
break;
|
||||
}
|
||||
case "choice":
|
||||
promiseNext = Game.executeChoice(line);
|
||||
doNextLineImmediately = true;
|
||||
break;
|
||||
case "code":
|
||||
promiseNext = Game.executeCode(line);
|
||||
doNextLineImmediately = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If it's a goto, end THIS section immediately.
|
||||
if(lineType=="goto"){
|
||||
Game.clearQueue(); // CLEAR ALL ELSE IN QUEUE
|
||||
Game.executeGoto(line);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Do next line?
|
||||
if(Game.queue.length>0){
|
||||
promiseNext.then(function(){
|
||||
Game.executeNextLine();
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
Game.clearQueue = function(){
|
||||
Game.queue = [];
|
||||
};
|
||||
Game.addToQueue = function(line){
|
||||
Game.queue.push(line);
|
||||
}
|
||||
|
||||
// Execute text! Just add it to text DOM.
|
||||
Game.executeText = function(line){
|
||||
|
||||
var div = document.createElement("div");
|
||||
div.innerHTML = line;
|
||||
Game.textDOM.appendChild(div);
|
||||
var promiseDone = pinkySwear();
|
||||
|
||||
// Is it human or wolf?
|
||||
var dialogue;
|
||||
var isWolf = /^\>(.*)/.test(line);
|
||||
if(isWolf){
|
||||
div.className = "wolf-bubble";
|
||||
dialogue = line.match(/^\>(.*)/)[1].trim();
|
||||
}else{
|
||||
div.className = "human-bubble";
|
||||
dialogue = line;
|
||||
}
|
||||
|
||||
// Add the bubble, with animation
|
||||
Game.wordsDOM.appendChild(div);
|
||||
requestAnimationFrame(function(){
|
||||
requestAnimationFrame(function(){
|
||||
div.style.opacity = 1;
|
||||
div.style.left = 0;
|
||||
});
|
||||
});
|
||||
|
||||
// Add the text, letter by letter!
|
||||
var interval = 0;
|
||||
var SPEED = 40;
|
||||
for(var i=0; i<dialogue.length; i++){
|
||||
|
||||
var ch = dialogue[i];
|
||||
|
||||
// for scopin'
|
||||
(function(ch, interval){
|
||||
setTimeout(function(){
|
||||
div.innerHTML += ch;
|
||||
}, interval);
|
||||
})(ch, interval);
|
||||
|
||||
// Bigger interval
|
||||
if(ch=="."){
|
||||
interval += SPEED*10;
|
||||
}else{
|
||||
interval += SPEED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return promise
|
||||
setTimeout(function(){
|
||||
promiseDone(true, []);
|
||||
}, interval+200);
|
||||
return promiseDone;
|
||||
|
||||
}
|
||||
|
||||
// Execute choice! Add it to choice DOM.
|
||||
|
@ -123,22 +220,34 @@ Game.executeChoice = function(line){
|
|||
var div = document.createElement("div");
|
||||
div.innerHTML = choiceText;
|
||||
div.onclick = function(){
|
||||
Game.executeText("> "+choiceText);
|
||||
Game.addToQueue("> "+choiceText);
|
||||
Game.goto(choiceID);
|
||||
};
|
||||
|
||||
Game.choicesDOM.appendChild(div);
|
||||
|
||||
// Return promise
|
||||
var promiseImmediate = new pinkySwear();
|
||||
promiseImmediate(true, []);
|
||||
return promiseImmediate;
|
||||
|
||||
}
|
||||
|
||||
// Execute code!
|
||||
Game.executeCode = function(line){
|
||||
|
||||
var code = line.match(/\`+([^\`]*)\`+/)[1].trim();
|
||||
try{
|
||||
eval(code);
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
// Return promise
|
||||
var promiseImmediate = new pinkySwear();
|
||||
promiseImmediate(true, []);
|
||||
return promiseImmediate;
|
||||
|
||||
}
|
||||
|
||||
// Execute goto! Just goto.
|
||||
|
@ -216,3 +325,15 @@ Game.parseLine = function(line){
|
|||
|
||||
};
|
||||
|
||||
|
||||
/*****************************/
|
||||
/*****************************/
|
||||
/*****************************/
|
||||
|
||||
Game.canvas = document.querySelector("#game_canvas");
|
||||
Game.canvas.width = 360 * 2;
|
||||
Game.canvas.height = 450 * 2;
|
||||
Game.canvas.style.width = Game.canvas.width/2 + "px";
|
||||
Game.canvas.style.height = Game.canvas.height/2 + "px";
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,12 @@
|
|||
<body>
|
||||
|
||||
<div id="game_container">
|
||||
<div id="game_text">
|
||||
<canvas id="game_canvas"></canvas>
|
||||
<div id="game_words">
|
||||
</div>
|
||||
<div id="game_hp">
|
||||
<div id="hp_human"></div>
|
||||
<div id="hp_wolf"></div>
|
||||
</div>
|
||||
<div id="game_choices">
|
||||
</div>
|
||||
|
@ -17,4 +22,5 @@
|
|||
</body>
|
||||
</html>
|
||||
|
||||
<script src="pinkyswear.min.js"></script>
|
||||
<script src="game.js"></script>
|
|
@ -0,0 +1,2 @@
|
|||
(function(e){function g(h){return"function"==typeof h}function k(h){"undefined"!=typeof setImmediate?setImmediate(h):"undefined"!=typeof process&&process.nextTick?process.nextTick(h):setTimeout(h,0)}e[0][e[1]]=function n(f){function a(a,g){null==b&&null!=a&&(b=a,l=g,c.length&&k(function(){for(var a=0;a<c.length;a++)c[a]()}));return b}var b,l=[],c=[];a.then=function(a,e){function m(){try{var c=b?a:e;if(g(c)){var f=function(a){var c,b=0;try{if(a&&("object"==typeof a||g(a))&&g(c=a.then)){if(a===d)throw new TypeError;
|
||||
c.call(a,function(){b++||f.apply(void 0,arguments)},function(a){b++||d(!1,[a])})}else d(!0,arguments)}catch(e){b++||d(!1,[e])}};f(c.apply(void 0,l||[]))}else d(b,l)}catch(k){d(!1,[k])}}var d=n(f);null!=b?k(m):c.push(m);return d};f&&(a=f(a));return a}})("undefined"==typeof module?[window,"pinkySwear"]:[module,"exports"]);
|
15
woods.md
15
woods.md
|
@ -1,10 +1,10 @@
|
|||
# woods
|
||||
|
||||
Two woods diverged in the woods and I...
|
||||
{{if _.eaten}} (this time try not to get eaten by wolves) {{/if}}
|
||||
|
||||
`document.body.style.background = "#ddd"`
|
||||
|
||||
Two roads diverged in the woods and I...
|
||||
{{if _.eaten}} (this time try not to get eaten by wolves) {{/if}}
|
||||
|
||||
[Took the one less travelled by](#woods-less)
|
||||
|
||||
[Took the one more travelled by](#woods-more)
|
||||
|
@ -13,18 +13,17 @@ Two woods diverged in the woods and I...
|
|||
|
||||
# woods-less
|
||||
|
||||
And that's how I got lost in the woods and was eaten by wolves
|
||||
|
||||
`document.body.style.background = "#ff4040"`
|
||||
|
||||
And that's how I got lost in the woods and was eaten by wolves
|
||||
{{if _.eaten}} (...again.) {{/if}}
|
||||
|
||||
`_.eaten = true`
|
||||
|
||||
`_.played_less = true`
|
||||
|
||||
[Try again](#woods)
|
||||
|
||||
[Goodbye](#end)
|
||||
|
||||
# woods-more
|
||||
|
||||
And that's how I found my way back to civilization and was not eaten by wolves
|
||||
|
@ -35,8 +34,6 @@ And that's how I found my way back to civilization and was not eaten by wolves
|
|||
|
||||
[Try again](#woods)
|
||||
|
||||
[Goodbye](#end)
|
||||
|
||||
# home
|
||||
|
||||
Good choice.
|
||||
|
|
Loading…
Reference in New Issue