Some hero thing
by Sam Fereday
HTML
<p>
Current State:
</p>
<div data-bind="text: hero.mode" id="currentState">
???
</div>
<p>
Overall Health:
</p>
<div data-bind="text: hero.health">
???
</div>
<p>
Tiredness:
</p>
<div data-bind="text: hero.tiredness">
???
</div>
<p>
Hunger:
</p>
<div data-bind="text: hero.hunger">
???
</div>
<p>
Forage:
</p>
<div data-bind="visible: hero.lookingForFood()">
Looking for something to eat...
</div>
<div data-bind="visible: !hero.lookingForFood()">
Not looking.
</div>
<p>
Training:
</p>
<div data-bind="text: hero.combatSkill">
???
</div>
<p>
Combat Proficiency:
</p>
<div data-bind="visible: hero.combatSkill() < 5">
Idiot
</div>
<div data-bind="visible: hero.combatSkill() > 5 && hero.combatSkill() < 15">
Trainee
</div>
<div data-bind="visible: hero.combatSkill() > 15 && hero.combatSkill() < 25">
Promising
</div>
<div data-bind="visible: hero.combatSkill() > 25 && hero.combatSkill() < 35">
Well Seasoned
</div>
<div data-bind="visible: hero.combatSkill() > 35 && hero.combatSkill() < 45">
Skilled
</div>
<div data-bind="visible: hero.combatSkill() > 45 && hero.combatSkill() < 55">
Expert
</div>
<div data-bind="visible: hero.combatSkill() > 55 && hero.combatSkill() < 65">
Slayer
</div>
<div data-bind="visible: hero.combatSkill() > 65 && hero.combatSkill() < 75">
Hero
</div>
<div data-bind="visible: hero.combatSkill() > 75">
Legendary
</div>
<button data-bind="hunt">
Hunt
</button>
<button data-bind="forage">
Forage
</button>
<button data-bind="eat">
Eat
</button>
<button data-bind="sleep">
Sleep
</button>
CSS
body {
padding: 2em;
margin: 0;
font: 75%/1.4em arial;
}
p {
margin: 0;
padding: 0;
}
div {
padding: 1em;
}
.bar {
width: 100%;
padding: 1em;
box-sizing: border-box;
background: #333;
}
JavaScript
//
console.clear();
var gameloop = (function() {
'use strict';
var reqAnimFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
return function(callback) {
var lastUpdate = +new Date();
(function loop() {
callback(((+new Date()) - lastUpdate) / 1000);
reqAnimFrame(loop);
lastUpdate = +new Date();
}());
};
}());
//
let fsm = function() {
this.states = [];
this.currentState = [];
this.initialized = false;
}
fsm.prototype.update = function() {
this.currentState[this.currentState.length - 1].fn();
}
fsm.prototype.init = function(name) {
if (this.initialized)
return;
let st = this.states.find(function(item) {
return item.name === name;
});
this.currentState.push(st);
this.initialized = true;
}
fsm.prototype.push = function(name) {
if (this.currentState.length > 0 && this.currentState[this.currentState.length - 1].name === name)
return;
let st = this.states.find(function(item) {
return item.name === name;
});
this.currentState.push(st);
}
fsm.prototype.pop = function() {
if (this.currentState.length > 1)
this.currentState.pop();
}
fsm.prototype.addState = function(name, state) {
this.states.push({
name: name,
fn: state
});
}
//
var Entity = function() {
var self = this;
this.health = ko.observable(100);
this.tiredness = ko.observable(0);
this.hunger = ko.observable(0);
this.forage = ko.observable(false);
this.lookingForFood = ko.observable(false);
this.combatSkill = ko.observable(0);
this.modes = {
IDLE: 0,
SLEEP: 1,
FORAGE: 2,
EAT: 3,
TRAIN: 4
}
this.mode = ko.observable(this.modes.IDLE);
this.fsm = new fsm();
// Push idle state (you need this first)
this.fsm.addState('idle', function() {
console.log("Idle state.");
let health =...