Take animation, text and menus to a separate UI module
This commit is contained in:
parent
2eecc2c7fb
commit
865f7ce83e
5 changed files with 120 additions and 89 deletions
|
@ -1,4 +1,4 @@
|
||||||
function Automaton(async, buttons, dom, messaging, screen, session) {
|
function Automaton(async, dom, messaging, screen, session, ui) {
|
||||||
var menus = {
|
var menus = {
|
||||||
start: {
|
start: {
|
||||||
entries: [
|
entries: [
|
||||||
|
@ -27,67 +27,6 @@ function Automaton(async, buttons, dom, messaging, screen, session) {
|
||||||
// console.log(game);
|
// console.log(game);
|
||||||
//});
|
//});
|
||||||
|
|
||||||
function animation(frames) {
|
|
||||||
var frameCounter = 0;
|
|
||||||
var scheduled;
|
|
||||||
var step = function() {
|
|
||||||
if(frameCounter < frames.length) {
|
|
||||||
scheduled = null;
|
|
||||||
frames[frameCounter].action();
|
|
||||||
if(frames[frameCounter].delay != undefined) {
|
|
||||||
scheduled = setTimeout(step, frames[frameCounter].delay);
|
|
||||||
}
|
|
||||||
frameCounter++
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
run: step,
|
|
||||||
skip: function() { if(scheduled != undefined) { clearTimeout(scheduled); } }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function text(message) {
|
|
||||||
var characters = message.split('');
|
|
||||||
var frames = [];
|
|
||||||
var ready = false;
|
|
||||||
var append = function(c) { return function() { screen.appendText(c); }; };
|
|
||||||
for(var i = 0; i < characters.length; i++) {
|
|
||||||
frames.push({action: append(characters[i]), delay: 50});
|
|
||||||
}
|
|
||||||
frames.push({action: function() { ready = true; screen.markAsRead(); }, delay: null});
|
|
||||||
var remote = animation(frames);
|
|
||||||
return function(f) {
|
|
||||||
buttons.push({
|
|
||||||
'A': function() {
|
|
||||||
if(ready) {
|
|
||||||
f();
|
|
||||||
} else {
|
|
||||||
remote.skip();
|
|
||||||
screen.text(message);
|
|
||||||
ready = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
screen.text('');
|
|
||||||
remote.run();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function menu(config) {
|
|
||||||
var cursor = 0;
|
|
||||||
var m = screen.menu(config.entries);
|
|
||||||
var sync = function() { screen.select(cursor); };
|
|
||||||
var mapping = {
|
|
||||||
'Up': function() { cursor = Math.max(0, cursor - 1); sync(); },
|
|
||||||
'Down': function() { cursor = Math.min(config.entries.length - 1, cursor + 1); sync(); },
|
|
||||||
'A': function() { config.entries[cursor].action(); }
|
|
||||||
};
|
|
||||||
if(config.cancel != undefined) {
|
|
||||||
mapping['B'] = function() { buttons.pop(); screen.clear(m); config.cancel(); }
|
|
||||||
}
|
|
||||||
buttons.push(mapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
intro();
|
intro();
|
||||||
}
|
}
|
||||||
|
@ -95,31 +34,24 @@ function Automaton(async, buttons, dom, messaging, screen, session) {
|
||||||
function intro() {
|
function intro() {
|
||||||
var title = dom.make('p', {textContent: "P O K E M O N", class: 'title'});
|
var title = dom.make('p', {textContent: "P O K E M O N", class: 'title'});
|
||||||
var subtitle = dom.make('p', {textContent: "< press start >", class: 'subtitle'});
|
var subtitle = dom.make('p', {textContent: "< press start >", class: 'subtitle'});
|
||||||
var remote = animation([
|
ui.frame('Intro');
|
||||||
{action: function() {}, delay: 500},
|
async.run(
|
||||||
{action: function() { screen.show(title); }, delay: 1000},
|
ui.cinematic([
|
||||||
{action: function() { screen.show(subtitle); }, delay: null}
|
{action: function() {}, delay: 500},
|
||||||
]);
|
{action: function() { screen.show(title); }, delay: 1000},
|
||||||
buttons.map({
|
{action: function() { screen.show(subtitle); }, delay: null}
|
||||||
'B': function() { remote.skip(); intro() },
|
], {
|
||||||
'Start': function() {
|
'B': intro,
|
||||||
remote.skip();
|
'Start': function() { ui.frame('StartMenu'); ui.menu(menus.start); }
|
||||||
screen.frame(2);
|
})
|
||||||
screen.clear();
|
);
|
||||||
menu(menus.start);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
screen.frame(1);
|
|
||||||
screen.clear();
|
|
||||||
remote.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function newGame() {
|
function newGame() {
|
||||||
screen.frame(3);
|
ui.frame('GameInit');
|
||||||
screen.clear();
|
|
||||||
async.run(
|
async.run(
|
||||||
text("Bonjour ! Bienvenue dans le monde merveilleux des pokémons !"),
|
ui.text("Bonjour ! Bienvenue dans le monde merveilleux des pokémons !"),
|
||||||
text("Pour certains, les pokemons sont des amis. Pour d'autres, ils sont une ressource. "),
|
ui.text("Pour certains, les pokemons sont des amis. Pour d'autres, ils sont une ressource. Pour ma part, hé bien l'étude des pokémons est ma passion et mon métier."),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<script src="screen.js"></script>
|
<script src="screen.js"></script>
|
||||||
<script src="buttons.js"></script>
|
<script src="buttons.js"></script>
|
||||||
<script src="messaging.js"></script>
|
<script src="messaging.js"></script>
|
||||||
|
<script src="ui.js"></script>
|
||||||
<script src="automaton.js"></script>
|
<script src="automaton.js"></script>
|
||||||
<link rel="stylesheet" href="screen.css" type="text/css"/>
|
<link rel="stylesheet" href="screen.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -5,7 +5,8 @@ window.addEventListener('load', function() {
|
||||||
screen = Screen(dom);
|
screen = Screen(dom);
|
||||||
session = Session();
|
session = Session();
|
||||||
buttons = Buttons(session);
|
buttons = Buttons(session);
|
||||||
automaton = Automaton(async, buttons, dom, messaging, screen, session);
|
ui = UI(buttons, screen);
|
||||||
|
automaton = Automaton(async, dom, messaging, screen, session, ui);
|
||||||
|
|
||||||
messaging.start();
|
messaging.start();
|
||||||
automaton.run();
|
automaton.run();
|
||||||
|
|
|
@ -54,27 +54,27 @@ ul.menu .selected:before {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1st frame */
|
/* 1st frame */
|
||||||
#screen.frame1 * {
|
#screen.frameIntro * {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
#screen.frame1 p {
|
#screen.frameIntro p {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
#screen.frame1 .title {
|
#screen.frameIntro .title {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#screen.frame1 .subtitle {
|
#screen.frameIntro .subtitle {
|
||||||
top: 75%;
|
top: 75%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2nd frame */
|
/* 2nd frame */
|
||||||
#screen.frame2 ul {
|
#screen.frameStartMenu ul {
|
||||||
width: 7em;
|
width: 7em;
|
||||||
}
|
}
|
||||||
|
|
97
src/ui.js
Normal file
97
src/ui.js
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
function UI(buttons, screen) {
|
||||||
|
|
||||||
|
return {
|
||||||
|
animation: animation,
|
||||||
|
cinematic: cinematic,
|
||||||
|
frame: frame,
|
||||||
|
menu: menu,
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
|
||||||
|
function animation(frames) {
|
||||||
|
var frameCounter = 0;
|
||||||
|
var scheduled;
|
||||||
|
var step = function() {
|
||||||
|
if(frameCounter < frames.length) {
|
||||||
|
scheduled = null;
|
||||||
|
frames[frameCounter].action();
|
||||||
|
if(frames[frameCounter].delay != undefined) {
|
||||||
|
scheduled = setTimeout(step, frames[frameCounter].delay);
|
||||||
|
}
|
||||||
|
frameCounter++
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
run: step,
|
||||||
|
pause: function() { if(scheduled != undefined) { clearTimeout(scheduled); } }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function cinematic(frames, controls) {
|
||||||
|
var remote = animation(frames);
|
||||||
|
var mapping = {};
|
||||||
|
for(var key in controls) {
|
||||||
|
mapping[key] = function() {
|
||||||
|
buttons.pop();
|
||||||
|
remote.pause();
|
||||||
|
controls[key]();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return function(f) {
|
||||||
|
buttons.push(mapping);
|
||||||
|
remote.run();
|
||||||
|
f();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function frame(id) {
|
||||||
|
screen.clear();
|
||||||
|
screen.frame(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function menu(config) {
|
||||||
|
var cursor = 0;
|
||||||
|
var m = screen.menu(config.entries);
|
||||||
|
var sync = function() { screen.select(cursor); };
|
||||||
|
var mapping = {
|
||||||
|
'Up': function() { cursor = Math.max(0, cursor - 1); sync(); },
|
||||||
|
'Down': function() { cursor = Math.min(config.entries.length - 1, cursor + 1); sync(); },
|
||||||
|
'A': function() { config.entries[cursor].action(); }
|
||||||
|
};
|
||||||
|
if(config.cancel != undefined) {
|
||||||
|
mapping['B'] = function() { buttons.pop(); screen.clear(m); config.cancel(); }
|
||||||
|
}
|
||||||
|
buttons.push(mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
function textScreen(message) {
|
||||||
|
var characters = message.split('');
|
||||||
|
var frames = [];
|
||||||
|
var ready = false;
|
||||||
|
var append = function(c) { return function() { screen.appendText(c); }; };
|
||||||
|
for(var i = 0; i < characters.length; i++) {
|
||||||
|
frames.push({action: append(characters[i]), delay: 50});
|
||||||
|
}
|
||||||
|
frames.push({action: function() { ready = true; screen.markAsRead(); }, delay: null});
|
||||||
|
var remote = animation(frames);
|
||||||
|
return function(f) {
|
||||||
|
buttons.push({
|
||||||
|
'A': function() {
|
||||||
|
if(ready) {
|
||||||
|
f();
|
||||||
|
} else {
|
||||||
|
remote.pause();
|
||||||
|
screen.text(message);
|
||||||
|
ready = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
screen.text('');
|
||||||
|
remote.run();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function text(message) {
|
||||||
|
return textScreen(message);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue