+var gamedata = {};
+var gfx = {};
+
+function Textfile(txtfile) {
+ var lines, fetch = new XMLHttpRequest();
+ fetch.open("GET", txtfile, false);
+ fetch.send();
+
+ var line, key, value, ref = this, section;
+ for (line of fetch.responseText.split('\n')) switch(true) {
+ case /^\[.*\]$/.test(line):
+ section = line.split(/[\]\[]/)[1];
+ if (!this[section]) this[section] = {};
+ else if (!Array.isArray(this[section])) this[section] = [this[section],{}];
+ else if ( Array.isArray(this[section])) this[section].push({});
+ ref = this[section];
+ break;
+ case /^frame=[0-9]+,[0-7](,[0-9-]+){6}$/.test(line):
+ key = line.split(/[=,]/).slice(1,3); value = line.split(/,/).slice(-6);
+ if (!ref.frame) ref.frame = [];
+ if (!ref.frame[key[0]]) ref.frame[key[0]] = [];
+ ref.frame[key[0]][key[1]] = value;
+ break;
+ case /^layer=[0-9]+,/.test(line):
+ key = line.split(/[=,]/)[1]; value = line.split(/,/).slice(1);
+ if (!ref.layer) ref.layer = [];
+ ref.layer[key] = value;
+ break;
+ case /^duration=[0-9]+ms$/.test(line):
+ ref["duration"] = parseInt(line.split(/=|ms$/)[1]);
+ break;
+ case /^duration=[0-9]+s$/.test(line):
+ ref["duration"] = parseInt(line.split(/=|s$/)[1]) * 1000;
+ break;
+ case /^[^#].*=.+$/.test(line):
+ key = line.split(/[=]/)[0]; value = line.split(/=/).slice(1).join("=");
+ if (!ref[key]) ref[key] = value;
+ else if (!Array.isArray(ref[key])) ref[key] = [ref[key],value];
+ else if ( Array.isArray(ref[key])) ref[key].push(value);
+ break;
+ }
+}
+
function Mob(textdef) {
+ if (! gamedata[textdef]) gamedata[textdef] = new Textfile(textdef);
+ this.info = gamedata[textdef];
this.direction = 0;
this.position = [0, 0];
- this.info = gamedata[textdef];
this.animation = "stance";
this.previous_animation = "";
this.frametime = performance.now();
- this.image = document.querySelector("img[src='"+ this.info.image +"']");
+ if (! gfx[this.info.image]) {
+ gfx[this.info.image] = document.createElement("img");
+ gfx[this.info.image].setAttribute("src", this.info.image);
+ }
this.place = function(x, y) { this.position = [x, y]; return this; }
this.direct = function(d) { this.direction = d % 8; return this; }
this.draw = function(){
var f, a = this.info[this.animation];
- var frame = ( performance.now() - this.frametime ) * a.frames.length / a.duration | 0;
+ var frame = ( performance.now() - this.frametime ) * a.frames / a.duration | 0;
switch(a.type){
case "looped":
- frame = frame % a.frames.length;
+ frame = frame % a.frames;
break;
case "play_once":
- if ( frame >= a.frames.length ){
+ if ( frame >= a.frames ){
this.animation = this.previous_animation;
this.previous_animation = "";
this.frametime = performance.now();
}
break;
case "back_forth":
- frame = frame % (a.frames.length * 2 - 2);
- if ( frame >= a.frames.length ){
- frame = a.frames.length - frame % a.frames.length - 1;
+ frame = frame % (a.frames * 2 - 2);
+ if ( frame >= a.frames ){
+ frame = a.frames - frame % a.frames - 1;
}
break;
default: break;
}
- f = a.frames[frame][this.direction];
+ f = a.frame[frame][this.direction];
- canvas.drawImage(this.image, f[0], f[1], f[2], f[3],
+ canvas.drawImage(gfx[this.info.image], f[0], f[1], f[2], f[3],
this.position[0] - f[4], this.position[1] - f[5],
f[2], f[3]);
-
- // var fetch = new XMLHttpRequest();
- // fetch.open("GET", textdef, false); fetch.send();
- // this.description = fetch.responseText.split('\n');
}
+
+ this.block = function() { this.animate("block" ); return this; };
+ this.cast = function() { this.animate("cast" ); return this; };
+ this.die = function() { this.animate("die" ); return this; };
+ this.hit = function() { this.animate("hit" ); return this; };
+ this.run = function() { this.animate("run" ); return this; };
+ this.shoot = function() { this.animate("shoot" ); return this; };
+ this.stance = function() { this.animate("stance"); return this; };
+ this.swing = function() { this.animate("swing" ); return this; };
}
-function Player(gender = "female", hair = "short"){
- // this.head = new Mob("/animations/avatar/"+gender+"/head_short.txt")
- // this.chest = new Mob("/animations/avatar/"+gender+"/default_chest.txt")
- // this.hands = new Mob("/animations/avatar/"+gender+"/default_hands.txt")
- // this.legs = new Mob("/animations/avatar/"+gender+"/default_legs.txt")
- // this.feet = new Mob("/animations/avatar/"+gender+"/default_feet.txt")
- this.limbs = [
- (gender == "female")?new Mob("/animations/avatar/female/head_long.txt"):new Mob("/animations/avatar/male/head_"+hair+".txt"),
- new Mob("/animations/avatar/"+gender+"/default_chest.txt"),
- new Mob("/animations/avatar/"+gender+"/default_hands.txt"),
- new Mob("/animations/avatar/"+gender+"/default_legs.txt"),
- new Mob("/animations/avatar/"+gender+"/default_feet.txt")
- ]
+function Hero(gender = "female", hair = "short"){
+ this.position = [0,0]; this.direction = 0;
+ this.hair = (gender == "female")?"long":hair;
+ this.animation = "stance";
+
+ if (! gamedata["/engine/hero_layers.txt"])
+ gamedata["/engine/hero_layers.txt"] = new Textfile("/engine/hero_layers.txt");
+ this.limbs = {
+ head: new Mob("/animations/avatar/"+gender+"/head_"+this.hair+".txt"),
+ chest: new Mob("/animations/avatar/"+gender+"/default_chest.txt"),
+ hands: new Mob("/animations/avatar/"+gender+"/default_hands.txt"),
+ legs : new Mob("/animations/avatar/"+gender+"/default_legs.txt"),
+ feet : new Mob("/animations/avatar/"+gender+"/default_feet.txt"),
+ main : new Mob("/animations/avatar/"+gender+"/dagger.txt"),
+ off : new Mob("/animations/avatar/"+gender+"/shield.txt")
+ }
+
+ this.dress = function(limb, item) {
+ this.limbs[limb] = new Mob("/animations/avatar/"+gender+"/"+item+".txt")
+ this.limbs[limb].place(this.position[0], this.position[1]).direct(this.direction);
+ this.animate(this.animation);
+ return this;
+ }
+
+ this.place = function(x,y) {
+ this.position = [x,y];
+ for (var limb in this.limbs) this.limbs[limb].place(x,y);
+ return this;
+ }
+ this.direct = function(d) {
+ this.direction = d;
+ for (var limb in this.limbs) this.limbs[limb].direct(d);
+ return this;
+ }
+ this.animate = function(anim){
+ this.animation = anim;
+ for (var limb in this.limbs) this.limbs[limb].animate(anim);
+ return this;
+ }
+ this.draw = function(){
+ gamedata["/engine/hero_layers.txt"].layer[this.direction].forEach(limb => this.limbs[limb].draw());
+ return this;
+ }
- this.place = function(x,y){ this.limbs.forEach(limb => limb.place(x,y)); return this; }
- this.direct = function(x,y){ this.limbs.forEach(limb => limb.direct(x,y)); return this; }
- this.animate = function(x,y){ this.limbs.forEach(limb => limb.animate(x,y)); return this; }
- this.draw = function(x,y){ this.limbs.forEach(limb => limb.draw(x,y)); return this; }
+ this.block = function() { this.animate("block" ); return this; };
+ this.cast = function() { this.animate("cast" ); return this; };
+ this.die = function() { this.animate("die" ); return this; };
+ this.hit = function() { this.animate("hit" ); return this; };
+ this.run = function() { this.animate("run" ); return this; };
+ this.shoot = function() { this.animate("shoot" ); return this; };
+ this.stance = function() { this.animate("stance"); return this; };
+ this.swing = function() { this.animate("swing" ); return this; };
}
canvas = document.getElementById("view").getContext("2d");
-// player = new Mob("/animations/avatar/male/clothes.txt");
-player = new Player().place(240, 160).direct(5);
+player = new Hero().place(240, 160).direct(5);
-setInterval( function() { canvas.clearRect(0,0, 480, 320); player.draw(); }, 50);
+setInterval( function() { canvas.clearRect(0,0, 480, 320); player.draw(); }, 33.33);