Interactive story

Using the p5.js library and the Javascript code below you can generate an interactive story.

// STATES

var intro; // 0
var goToBed; // 1
var listenNoise; // 2
var keepEyesShut; // 3
var openEyes; // 4
var moreNoise; // 5
var ghostWences; // 6
var keepSleeping; // 7
var turnOnLights; // 8
var ignoreGhost; // 9
var talkToGhost; // 10
var examFail; // 11
var examPassed; // 12
var party; // 13
var thanksGhost; // 14
var nextState = 0;
var state = 0;
var a = 0;
var angle = 0.0;
var speed = 0.05;
var eyesSize = 20;
var sound;

// PRELOAD
function preload() {
soundChains = loadSound(“assets/chains.wav”);
wencesVoice = loadSound(“assets/wences-talking.wav”);
serif = loadFont(“assets/RobotoSlab-Regular.ttf”);
sansSerif = loadFont(“assets/Roboto-Regular.ttf”);
wences = loadImage(‘assets/wences.png’);
}

// TRACKS WHAT USER TYPES
var typed = “”;
function setup() {
createCanvas(windowWidth, windowHeight);
frameRate(30);
}

// DRAW
function draw() {
if (state == ‘0’) {
start();
} else if (state == ‘1’) {
goToBed();
} else if (state == ‘2’) {
listenNoise();
} else if (state == ‘3’) {
keepEyesShut();
} else if (state == ‘4’) {
openEyes();
} else if (state == ‘5’) {
moreNoise();
} else if (state == ‘6’) {
ghostWences();
} else if (state == ‘7’) {
keepSleeping();
} else if (state == ‘8’) {
turnOnLights();
} else if (state == ‘9’) {
ignoreGhost();
} else if (state == ’10’) {
talkToGhost();
} else if (state == ’11’) {
examFail();
} else if (state == ’12’) {
examPassed();
} else if (state == ’13’) {
party();
} else if (state == ’14’) {
thanksGhost();
}
}

// TYPE
function keyPressed() {
if (keyCode == BACKSPACE) {
typed = ”;
}
}

function keyTyped() {
if (keyCode == RETURN) {
if (typed == ‘start’) {
wencesVoice.stop();
soundChains.loop(0, 1, 0.2);
state = 1;
typed = ”;
} else if (typed == ‘keep sleeping’) {
soundChains.stop();
wencesVoice.stop();
soundChains.loop(0, 0.7, 1);
state = 3;
typed = ”;
} else if (typed == ‘open’) {
soundChains.stop();
wencesVoice.stop();
soundChains.loop(0, 0.7, 1);
state = 4;
typed = ”;
} else if (typed == ‘talk’) {
soundChains.stop();
wencesVoice.loop(0, 1, 0.7);
state = 6;
typed = ”;
} else if (typed == ‘afraid’) {
soundChains.stop();
wencesVoice.stop();
state = 11;
typed = ”;
} else if (typed == ‘fear’) {
soundChains.stop();
wencesVoice.stop();
state = 8;
typed = ”;
} else if (typed == ‘turn on’) {
soundChains.stop();
wencesVoice.stop();
state = 8;
typed = ”;
} else if (typed == ‘other side’) {
soundChains.stop();
wencesVoice.stop();
state = 11;
typed = ”;
} else if (typed == ‘bed’) {
soundChains.stop();
wencesVoice.stop();
soundChains.loop(0, 1, 0.2);
state = 1;
typed = ”;
} else if (typed == ‘party’) {
soundChains.stop();
wencesVoice.stop();
state = 13;
typed = ”;
} else if (typed == ‘talking’) {
soundChains.stop();
wencesVoice.stop();
wencesVoice.loop(0, 1, 0.7);
state = 10;
typed = ”;
} else if (typed == ‘write’) {
soundChains.stop();
wencesVoice.stop();
state = 12;
typed = ”;
} else if (typed == ‘thanks’) {
soundChains.stop();
wencesVoice.stop();
state = 14;
typed = ”;
}
else if (typed == ‘stupid’) {
soundChains.stop();
wencesVoice.stop();
state = 11;
typed = ”;
}
} else {
typed += key;
}
}

//// STATES

// START
function start() {
background(0);
fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘Type “start” to begin.’, 100, 100, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
}

// GO TO BED
function goToBed() {
background(0);
push();
translate(100,100);
scale(3,3);
noFill();
stroke(20);
beginShape();
vertex(100,0);
vertex(161,190);
vertex(100,145);
vertex(38,190);
vertex(100,0);
endShape();

beginShape();
vertex(200,72);
vertex(100,145);
vertex(0,72);
vertex(200,72);
endShape();

pop();

fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘You are in bed now, in total darkness,\nthinking about the literatur exam you have to do tomorrow.\nAs you close your eyes, you hear a strange sound.\n\nYou are not sure if you should\n”keep sleeping”\nor “open” your eyes and see what is happening.’, 100, 100, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
}

// KEEP EYES SHUT

function keepEyesShut() {
background(0);
push();
translate(100,100);
scale(3,3);
noFill();
stroke(20);
beginShape();
vertex(100,0);
vertex(161,190);
vertex(100,145);
vertex(38,190);
vertex(100,0);
endShape();

beginShape();
vertex(200,72);
vertex(100,145);
vertex(0,72);
vertex(200,72);
endShape();

pop();

fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘The noise gets louder, and stranger.\n\nShould you “open” your eyes and see what happens?\n\nPerhaps you are too “afraid” and think that it is better for you to stay in bed.’, 100, 100, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
}

// OPEN EYES

function openEyes() {
background(0);
fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘You can see a silhouette, and two glowing eyes staring at you.\n\nMaybe is better being friendly with the unknown,\nso you decide to “talk”. \n\nOr are you too afraid and prefer to “turn on” the lights?’, 100, 100, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);

a = abs(sin(frameCount*0.05) * 255);
m = map(a, 0, 255, 0, 30);

fill(255,255,255,m);
eyesSize = 300;
ellipse(windowWidth/2-eyesSize,windowHeight/2,eyesSize,eyesSize);
ellipse(windowWidth/2+eyesSize,windowHeight/2,eyesSize,eyesSize);
}

// GHOST WENCES

function ghostWences() {
background(0);

push();

a = abs(sin(frameCount*0.05) * 255);
fill(255,255,255, a);
translate(windowWidth/2, windowHeight/2);
rotate(angle);

for (var i=0; i<5; i++) {
push();
rotate(i*TWO_PI/5);
translate(0,200);
ellipse(0, 0, 40, 40);
pop();
}

angle += speed/2;
pop();

fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
image(wences, 100, 100, 120, 120);
text(‘- Hi, my name is Wences.’, 240, 150, 600, 600);
text(‘Trembling with “fear” you think about turning on the lights.\n\nBut you keep “talking”.’, 100, 240, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
}

// TALK TO GHOST

function talkToGhost() {
background(0);
fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
image(wences, 100, 100, 120, 120);
text(‘- I am here to told you the right answers to the literature exam you are facing tomorrow.’, 240, 150, 600, 600);
text(‘As soon as you can, you take a notebook and “write” down all the answers that Wences provided you.\nNah, you think that taking advice from a ghost is a “stupid” idea.’, 100, 240, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
for (var i = 20; i < windowHeight – 20; i += 30) {
stroke(255);
line(30, i, 40, i);
}
}

// EXAM PASSED

function examPassed() {
background(0);
fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘You success and passed the literature exam,\nyou can “party” now or “thanks” Wences the ghost.’, 100, 100, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
}

// THANKS

function thanksGhost() {
background(0);
fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘You run home trying to told Wences the ghost the good news.\n\nBut you never see Wences again.\n\nHe has fulfilled his duty.’, 100, 100, 600, 600);
textFont(sansSerif);
textAlign(LEFT, TOP);
textSize(14);
textLeading(16);
text(‘Wences was a spanish writer. He was born in 1567 in Alcala de Henares, a city near Madrid (Spain).\nMy friend Poe currently lives in the building were he was born…\n\nAnd sometimes he thinks he passes by for a visit.\n\nIf you want more information about Wences check his Wikipedia page:\nhttps://en.wikipedia.org/wiki/Miguel_de_Cervantes’, 100, 460,400,400);
}

// PARTY

function party() {
background(0);
fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘You decided to party with some friends and drank too much. You dont know how, but you awake again in your “bed”.’, 100, 100, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
}

// TURN ON THE LIGHTS

function turnOnLights() {
background(255);
fill(0);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘The ghost suddenly disappears.\n\nBut you can not sleep anymore.\n\nYou were not able to concentrate on the literature exam and you totally failed it.\n\nMaybe you can try going back to “bed”.’, 100, 100, 600, 600);
fill(255);
stroke(0);
strokeWeight(1);
rect(90,356,160,36);
fill(0);
noStroke();
text(typed, 100, 360);
}

// AFRAID

function examFail() {
background(0);
fill(255);
noStroke();
textFont(serif);
textAlign(LEFT, TOP);
textSize(18);
textLeading(28);
text(‘The nightmares did not let you rest enough this night.\nYou were not able to concentrate on the literature exam and you totally failed it.\n\nYou can try to go back to “bed”.’, 100, 100, 600, 600);
fill(255);
rect(90,356,160,36);
fill(0);
text(typed, 100, 360);
}

Erasmus+ project 2017-1-TR01-KA219-045575_3-4. Coordinator: Esen Kuvvet. Webmaster: Dr. Francisco Pérez