ur reworking; mum improvements
This commit is contained in:
parent
e02054bd10
commit
5578b0f7e4
|
@ -62,6 +62,18 @@ Object.dainty_assign = function(target, source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object.isObject = function(o)
|
||||||
|
{
|
||||||
|
return (typeof o === 'object' && !Array.isArray(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.setter_assign = function(target, source)
|
||||||
|
{
|
||||||
|
for (var key in target)
|
||||||
|
if (Object.isAccessor(target,key) && typeof source[key] !== 'undefined')
|
||||||
|
target[key] = source[key];
|
||||||
|
}
|
||||||
|
|
||||||
Object.containingKey = function(obj, prop)
|
Object.containingKey = function(obj, prop)
|
||||||
{
|
{
|
||||||
if (typeof obj !== 'object') return undefined;
|
if (typeof obj !== 'object') return undefined;
|
||||||
|
@ -822,6 +834,16 @@ function bb_expand(oldbb, x) {
|
||||||
return bb;
|
return bb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function bl2bb(bl, wh)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
b: bl.y,
|
||||||
|
l: bl.x,
|
||||||
|
r: bl.x + wh.x,
|
||||||
|
t: bl.y + wh.y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function bb_from_objects(objs) {
|
function bb_from_objects(objs) {
|
||||||
var bb = objs[0].boundingbox;
|
var bb = objs[0].boundingbox;
|
||||||
objs.forEach(function(obj) { bb = bb_expand(bb, obj.boundingbox); });
|
objs.forEach(function(obj) { bb = bb_expand(bb, obj.boundingbox); });
|
||||||
|
|
|
@ -22,40 +22,9 @@ var component = {
|
||||||
extend(spec) {
|
extend(spec) {
|
||||||
return Object.copy(this, spec);
|
return Object.copy(this, spec);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Given a relative path, return the full path */
|
|
||||||
resani(path) {
|
|
||||||
if (!this.gameobject) return path;
|
|
||||||
if (path[0] === '/') return path.slice(1);
|
|
||||||
var res = this.gameobject.ur.toString();
|
|
||||||
res = res.replaceAll('.', '/');
|
|
||||||
var restry = res + "/" + path;
|
|
||||||
while (!IO.exists(restry)) {
|
|
||||||
res = res.updir() + "/";
|
|
||||||
if (res === "/")
|
|
||||||
return path;
|
|
||||||
|
|
||||||
restry = res + path;
|
|
||||||
}
|
|
||||||
return restry;
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Given the full path, return the most relative path */
|
|
||||||
resavi(path) {
|
|
||||||
if (!this.gameobject) return path;
|
|
||||||
if (path[0] === '/') return path;
|
|
||||||
|
|
||||||
var res = this.gameobject.ur.toString();
|
|
||||||
res = res.replaceAll('.', '/');
|
|
||||||
var dir = path.dir();
|
|
||||||
if (res.startsWith(dir))
|
|
||||||
return path.base();
|
|
||||||
|
|
||||||
return path;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
component.sprite = {
|
component.sprite = Object.copy(component, {
|
||||||
pos:[0,0],
|
pos:[0,0],
|
||||||
color:[1,1,1],
|
color:[1,1,1],
|
||||||
layer:0,
|
layer:0,
|
||||||
|
@ -63,20 +32,25 @@ component.sprite = {
|
||||||
path: "",
|
path: "",
|
||||||
toString() { return "sprite"; },
|
toString() { return "sprite"; },
|
||||||
make(go) {
|
make(go) {
|
||||||
var nsprite = Object.create(component.sprite.maker);
|
var nsprite = Object.create(this);
|
||||||
nsprite.gameobject = go;
|
nsprite.gameobject = go;
|
||||||
Object.assign(nsprite, make_sprite(go.body));
|
Object.assign(nsprite, make_sprite(go.body));
|
||||||
nsprite.ur = this;
|
Object.complete_assign(nsprite, component.sprite.impl);
|
||||||
|
for (var p in component.sprite.impl)
|
||||||
|
if (typeof this[p] !== 'undefined') {
|
||||||
|
Log.warn(`setting ${p}`);
|
||||||
|
nsprite[p] = this[p];
|
||||||
|
}
|
||||||
return nsprite;
|
return nsprite;
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
component.sprite.maker = Object.copy(component, {
|
component.sprite.impl = {
|
||||||
set path(x) {
|
set path(x) {
|
||||||
cmd(12,this.id,this.resani(x),this.rect);
|
cmd(12,this.id,prototypes.resani(this.gameobject.ur, x),this.rect);
|
||||||
},
|
},
|
||||||
get path() {
|
get path() {
|
||||||
return this.resavi(cmd(116,this.id));
|
return prototypes.resavi(this.gameobject.ur, cmd(116,this.id));
|
||||||
},
|
},
|
||||||
hide() { this.enabled = false; },
|
hide() { this.enabled = false; },
|
||||||
show() { this.enabled = true; },
|
show() { this.enabled = true; },
|
||||||
|
@ -105,11 +79,11 @@ component.sprite.maker = Object.copy(component, {
|
||||||
dimensions() { return cmd(64,this.path); },
|
dimensions() { return cmd(64,this.path); },
|
||||||
width() { return cmd(64,this.path).x; },
|
width() { return cmd(64,this.path).x; },
|
||||||
height() { return cmd(64,this.path).y; },
|
height() { return cmd(64,this.path).y; },
|
||||||
});
|
};
|
||||||
|
|
||||||
Object.freeze(sprite);
|
Object.freeze(sprite);
|
||||||
|
|
||||||
var sprite = component.sprite.maker;
|
var sprite = component.sprite;
|
||||||
|
|
||||||
sprite.inputs = {};
|
sprite.inputs = {};
|
||||||
sprite.inputs.kp9 = function() { this.pos = [0,0]; };
|
sprite.inputs.kp9 = function() { this.pos = [0,0]; };
|
||||||
|
@ -707,14 +681,20 @@ bucket.inputs.rb.doc = "Rotate the points CW.";
|
||||||
bucket.inputs.rb.rep = true;
|
bucket.inputs.rb.rep = true;
|
||||||
|
|
||||||
component.circle2d = Object.copy(collider2d, {
|
component.circle2d = Object.copy(collider2d, {
|
||||||
|
impl: {
|
||||||
set radius(x) { cmd_circle2d(0,this.id,x); },
|
set radius(x) { cmd_circle2d(0,this.id,x); },
|
||||||
get radius() { return cmd_circle2d(2,this.id); },
|
get radius() { return cmd_circle2d(2,this.id); },
|
||||||
|
|
||||||
set scale(x) { this.radius = x; },
|
set scale(x) { Log.warn(x);this.radius = x; },
|
||||||
get scale() { return this.radius; },
|
get scale() { return this.radius; },
|
||||||
|
|
||||||
set offset(x) { cmd_circle2d(1,this.id,x); },
|
set offset(x) { cmd_circle2d(1,this.id,x); },
|
||||||
get offset() { return cmd_circle2d(3,this.id); },
|
get offset() { return cmd_circle2d(3,this.id); },
|
||||||
|
},
|
||||||
|
|
||||||
|
radius:10,
|
||||||
|
offset:[0,0],
|
||||||
|
toString() { return "circle2d"; },
|
||||||
|
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
var diameter = this.radius*2*this.gameobject.scale;
|
var diameter = this.radius*2*this.gameobject.scale;
|
||||||
|
@ -725,22 +705,10 @@ component.circle2d = Object.copy(collider2d, {
|
||||||
var circle = Object.create(this);
|
var circle = Object.create(this);
|
||||||
circle.gameobject = go;
|
circle.gameobject = go;
|
||||||
Object.assign(circle, make_circle2d(go.body));
|
Object.assign(circle, make_circle2d(go.body));
|
||||||
|
Object.complete_assign(circle,this.impl);
|
||||||
|
|
||||||
return circle;
|
return circle;
|
||||||
},
|
},
|
||||||
|
|
||||||
gui() {
|
|
||||||
Nuke.newline();
|
|
||||||
Nuke.label("circle2d");
|
|
||||||
this.radius = Nuke.pprop("Radius", this.radius);
|
|
||||||
this.offset = Nuke.pprop("offset", this.offset);
|
|
||||||
},
|
|
||||||
|
|
||||||
ur: {
|
|
||||||
radius:10,
|
|
||||||
offset:[0,0],
|
|
||||||
toString() { return "circle2d"; },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* ASSETS */
|
/* ASSETS */
|
||||||
|
|
|
@ -420,7 +420,7 @@ var editor = {
|
||||||
GUI.text("$$$$$$", [0,ypos],1,lvlcolor);
|
GUI.text("$$$$$$", [0,ypos],1,lvlcolor);
|
||||||
|
|
||||||
this.selectlist.forEach(function(x) {
|
this.selectlist.forEach(function(x) {
|
||||||
var sname = x.ur.toString();
|
var sname = x.__proto__.toString();
|
||||||
if (!x.level_obj().empty)
|
if (!x.level_obj().empty)
|
||||||
x.dirty = true;
|
x.dirty = true;
|
||||||
else
|
else
|
||||||
|
@ -1231,6 +1231,7 @@ editor.inputs.s = function() {
|
||||||
|
|
||||||
if (editor.sel_comp) {
|
if (editor.sel_comp) {
|
||||||
if (!('scale' in editor.sel_comp)) return;
|
if (!('scale' in editor.sel_comp)) return;
|
||||||
|
Log.warn(`scaling ${editor.sel_comp.toString()}`);
|
||||||
editor.scalelist.push({
|
editor.scalelist.push({
|
||||||
obj: editor.sel_comp,
|
obj: editor.sel_comp,
|
||||||
scale: editor.sel_comp.scale,
|
scale: editor.sel_comp.scale,
|
||||||
|
@ -1257,19 +1258,23 @@ var inputpanel = {
|
||||||
value: "",
|
value: "",
|
||||||
on: false,
|
on: false,
|
||||||
stolen: {},
|
stolen: {},
|
||||||
|
pos:[100,Window.height-50],
|
||||||
|
wh:[350,600],
|
||||||
|
anchor: [0,1],
|
||||||
|
|
||||||
gui() {
|
gui() {
|
||||||
this.guibody();
|
var win = Mum.window({width:this.wh.x,height:this.wh.y, color:Color.black.alpha(0.1), anchor:this.anchor});
|
||||||
|
var itms = this.guibody();
|
||||||
|
if (!Array.isArray(itms)) itms = [itms];
|
||||||
|
win.items = itms;
|
||||||
|
win.draw(this.pos.slice());
|
||||||
},
|
},
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
this.value = Nuke.textbox(this.value);
|
return [
|
||||||
|
Mum.text({str:this.value, color:Color.green}),
|
||||||
Nuke.newline(2);
|
Mum.button({str:"Submit", action:this.submit})
|
||||||
if (Nuke.button("submit")) {
|
];
|
||||||
this.submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
open(steal) {
|
open(steal) {
|
||||||
|
@ -1314,6 +1319,8 @@ var inputpanel = {
|
||||||
|
|
||||||
keycb() {},
|
keycb() {},
|
||||||
|
|
||||||
|
caret: 0,
|
||||||
|
|
||||||
input_backspace_pressrep() {
|
input_backspace_pressrep() {
|
||||||
this.value = this.value.slice(0,-1);
|
this.value = this.value.slice(0,-1);
|
||||||
this.keycb();
|
this.keycb();
|
||||||
|
@ -1321,13 +1328,24 @@ var inputpanel = {
|
||||||
};
|
};
|
||||||
|
|
||||||
inputpanel.inputs = {};
|
inputpanel.inputs = {};
|
||||||
inputpanel.inputs.char = function(c) { this.value += c; this.keycb(); }
|
inputpanel.inputs.char = function(c) {
|
||||||
|
this.value = this.value.slice(0,this.caret) + c + this.value.slice(this.caret);
|
||||||
|
this.caret++;
|
||||||
|
Log.warn(this.caret);
|
||||||
|
this.keycb();
|
||||||
|
}
|
||||||
|
inputpanel.inputs['C-d'] = function() { this.value = this.value.slice(0,this.caret) + this.value.slice(this.caret+1); };
|
||||||
inputpanel.inputs.tab = function() { this.value = tab_complete(this.value, this.assets); }
|
inputpanel.inputs.tab = function() { this.value = tab_complete(this.value, this.assets); }
|
||||||
inputpanel.inputs.escape = function() { this.close(); }
|
inputpanel.inputs.escape = function() { this.close(); }
|
||||||
inputpanel.inputs.backspace = function() { this.value = this.value.slice(0,-1); this.keycb(); };
|
inputpanel.inputs.backspace = function() {
|
||||||
|
this.value = this.value.slice(0,this.caret-1) + this.value.slice(this.caret);
|
||||||
|
this.caret--;
|
||||||
|
this.keycb();
|
||||||
|
};
|
||||||
inputpanel.inputs.backspace.rep = true;
|
inputpanel.inputs.backspace.rep = true;
|
||||||
inputpanel.inputs.enter = function() { this.submit(); }
|
inputpanel.inputs.enter = function() { this.submit(); }
|
||||||
|
|
||||||
|
|
||||||
function proto_count_lvls(name)
|
function proto_count_lvls(name)
|
||||||
{
|
{
|
||||||
if (!this.occs) this.occs = {};
|
if (!this.occs) this.occs = {};
|
||||||
|
@ -1376,21 +1394,25 @@ load("scripts/textedit.js");
|
||||||
var replpanel = Object.copy(inputpanel, {
|
var replpanel = Object.copy(inputpanel, {
|
||||||
title: "REPL",
|
title: "REPL",
|
||||||
closeonsubmit:false,
|
closeonsubmit:false,
|
||||||
|
wh: [700,300],
|
||||||
|
pos: [50,50],
|
||||||
|
anchor: [0,0],
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
cmd(141);
|
|
||||||
var w = 700;
|
|
||||||
var h = 300;
|
|
||||||
var p = [50,50];
|
|
||||||
var log = cmd(84);
|
var log = cmd(84);
|
||||||
GUI.window(p, [w,h], Color.black.alpha(0.1));
|
log = log.slice(-500);
|
||||||
GUI.scissor(p.x,p.y,w,h);
|
|
||||||
GUI.text(log, p.add([0,10]), 1, Color.white, w, [0,0]);
|
return [
|
||||||
GUI.text(this.value, p, 1, Color.green, w);
|
Mum.text({str:log, anchor:[0,0], offset:[0,-300]}),
|
||||||
cmd(141);
|
Mum.text({str:this.value,color:Color.green, offset:[0,-290], caret: this.caret})
|
||||||
GUI.scissor(0,0,Window.width, Window.height);
|
];
|
||||||
},
|
},
|
||||||
|
prevmark:-1,
|
||||||
|
prevthis:[],
|
||||||
|
|
||||||
action() {
|
action() {
|
||||||
|
if (!this.value) return;
|
||||||
|
this.prevthis.unshift(this.value);
|
||||||
var ecode = "";
|
var ecode = "";
|
||||||
var repl_obj = (editor.selectlist.length === 1) ? editor.selectlist[0] : editor.edit_level;
|
var repl_obj = (editor.selectlist.length === 1) ? editor.selectlist[0] : editor.edit_level;
|
||||||
ecode += `var $ = repl_obj.objects;`;
|
ecode += `var $ = repl_obj.objects;`;
|
||||||
|
@ -1400,11 +1422,31 @@ var replpanel = Object.copy(inputpanel, {
|
||||||
ecode += this.value;
|
ecode += this.value;
|
||||||
Log.say(this.value);
|
Log.say(this.value);
|
||||||
this.value = "";
|
this.value = "";
|
||||||
|
this.caret = 0;
|
||||||
var ret = function() {return eval(ecode);}.call(repl_obj);
|
var ret = function() {return eval(ecode);}.call(repl_obj);
|
||||||
|
if (ret)
|
||||||
Log.say(ret);
|
Log.say(ret);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
replpanel.inputs = Object.create(inputpanel.inputs);
|
||||||
|
replpanel.inputs['C-p'] = function()
|
||||||
|
{
|
||||||
|
if (this.prevmark >= this.prevthis.length) return;
|
||||||
|
this.prevmark++;
|
||||||
|
this.value = this.prevthis[this.prevmark];
|
||||||
|
}
|
||||||
|
|
||||||
|
replpanel.inputs['C-n'] = function()
|
||||||
|
{
|
||||||
|
this.prevmark--;
|
||||||
|
if (this.prevmark < 0) {
|
||||||
|
this.prevmark = -1;
|
||||||
|
this.value = "";
|
||||||
|
} else
|
||||||
|
this.value = this.prevthis[this.prevmark];
|
||||||
|
}
|
||||||
|
|
||||||
var objectexplorer = Object.copy(inputpanel, {
|
var objectexplorer = Object.copy(inputpanel, {
|
||||||
title: "object explorer",
|
title: "object explorer",
|
||||||
obj: undefined,
|
obj: undefined,
|
||||||
|
@ -1601,7 +1643,9 @@ var openlevelpanel = Object.copy(inputpanel, {
|
||||||
},
|
},
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
Mum.column({items:Object.values(this.mumlist)}).draw([100,100]);
|
var a = [Mum.text({str:this.value,color:Color.green})];
|
||||||
|
var b = a.concat(Object.values(this.mumlist));
|
||||||
|
return Mum.column({items:b});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1804,3 +1848,6 @@ Game.stop();
|
||||||
Game.editor_mode(true);
|
Game.editor_mode(true);
|
||||||
|
|
||||||
load("editorconfig.js");
|
load("editorconfig.js");
|
||||||
|
|
||||||
|
Log.warn(ur.ball);
|
||||||
|
Log.warn(ur['ball.big']);
|
||||||
|
|
|
@ -690,8 +690,8 @@ Register.update.register(Game.exec, Game);
|
||||||
load("scripts/entity.js");
|
load("scripts/entity.js");
|
||||||
|
|
||||||
var preprimum = {};
|
var preprimum = {};
|
||||||
preprimum.objects = [];
|
preprimum.objects = {};
|
||||||
var World = gameobject.make(gameobject.ur, preprimum);
|
var World = gameobject.make(preprimum);
|
||||||
var Primum = World;
|
var Primum = World;
|
||||||
Primum.level = undefined;
|
Primum.level = undefined;
|
||||||
Primum.toString = function() { return "Primum"; };
|
Primum.toString = function() { return "Primum"; };
|
||||||
|
|
|
@ -11,102 +11,7 @@ function grab_from_points(pos, points, slop) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var gameobject = {
|
var gameobject = {
|
||||||
|
impl: {
|
||||||
layer_nuke() {
|
|
||||||
Nuke.label("Collision layer");
|
|
||||||
Nuke.newline(Collision.num);
|
|
||||||
for (var i = 0; i < Collision.num; i++)
|
|
||||||
this.layer = Nuke.radio(i, this.layer, i);
|
|
||||||
},
|
|
||||||
|
|
||||||
draw_layer: 1,
|
|
||||||
draw_layer_nuke() {
|
|
||||||
Nuke.label("Draw layer");
|
|
||||||
Nuke.newline(5);
|
|
||||||
for (var i = 0; i < 5; i++)
|
|
||||||
this.draw_layer = Nuke.radio(i, this.draw_layer, i);
|
|
||||||
},
|
|
||||||
|
|
||||||
hide() { this.components.forEach(function(x) { x.hide(); }); this.objects.forEach(function(x) { x.hide(); }); },
|
|
||||||
show() { this.components.forEach(function(x) { x.show(); }); this.objects.forEach(function(x) { x.show(); }); },
|
|
||||||
|
|
||||||
phys_nuke() {
|
|
||||||
Nuke.newline(1);
|
|
||||||
Nuke.label("phys");
|
|
||||||
Nuke.newline(3);
|
|
||||||
this.phys = Nuke.radio("dynamic", this.phys, 0);
|
|
||||||
this.phys = Nuke.radio("kinematic", this.phys, 1);
|
|
||||||
this.phys = Nuke.radio("static", this.phys, 2);
|
|
||||||
},
|
|
||||||
|
|
||||||
set_center(pos) {
|
|
||||||
var change = pos.sub(this.pos);
|
|
||||||
this.pos = pos;
|
|
||||||
|
|
||||||
for (var key in this.components) {
|
|
||||||
this.components[key].finish_center(change);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get_relangle() {
|
|
||||||
if (!this.level) return this.angle;
|
|
||||||
return this.angle - this.level.angle;
|
|
||||||
},
|
|
||||||
|
|
||||||
width() {
|
|
||||||
var bb = this.boundingbox();
|
|
||||||
return bb.r - bb.l;
|
|
||||||
},
|
|
||||||
|
|
||||||
height() {
|
|
||||||
var bb = this.boundingbox();
|
|
||||||
return bb.t-bb.b;
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Make a unique object the same as its prototype */
|
|
||||||
revert() {
|
|
||||||
// var t = this.transform();
|
|
||||||
Object.totalmerge(this,this.ur);
|
|
||||||
// Object.merge(this,t);
|
|
||||||
},
|
|
||||||
|
|
||||||
gui() {
|
|
||||||
var go_guis = walk_up_get_prop(this, 'go_gui');
|
|
||||||
Nuke.newline();
|
|
||||||
|
|
||||||
go_guis.forEach(function(x) { x.call(this); }, this);
|
|
||||||
|
|
||||||
for (var key in this) {
|
|
||||||
if (typeof this[key] === 'object' && 'gui' in this[key]) this[key].gui();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
check_registers(obj) {
|
|
||||||
Register.unregister_obj(this);
|
|
||||||
|
|
||||||
if (typeof obj.update === 'function')
|
|
||||||
Register.update.register(obj.update, obj);
|
|
||||||
|
|
||||||
if (typeof obj.physupdate === 'function')
|
|
||||||
Register.physupdate.register(obj.physupdate, obj);
|
|
||||||
|
|
||||||
if (typeof obj.collide === 'function')
|
|
||||||
obj.register_hit(obj.collide, obj);
|
|
||||||
|
|
||||||
if (typeof obj.separate === 'function')
|
|
||||||
obj.register_separate(obj.separate, obj);
|
|
||||||
|
|
||||||
if (typeof obj.draw === 'function')
|
|
||||||
Register.draw.register(obj.draw,obj);
|
|
||||||
|
|
||||||
if (typeof obj.debug === 'function')
|
|
||||||
Register.debug.register(obj.debug, obj);
|
|
||||||
|
|
||||||
obj.components.forEach(function(x) {
|
|
||||||
if (typeof x.collide === 'function')
|
|
||||||
register_collide(1, x.collide, x, obj.body, x.shape);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
get scale() { return cmd(103, this.body); },
|
get scale() { return cmd(103, this.body); },
|
||||||
set scale(x) {
|
set scale(x) {
|
||||||
var pct = x/this.scale;
|
var pct = x/this.scale;
|
||||||
|
@ -141,12 +46,34 @@ var gameobject = {
|
||||||
},this);
|
},this);
|
||||||
},
|
},
|
||||||
|
|
||||||
set pos(x) { this.set_worldpos(Vector.rotate(x, Math.deg2rad(this.level.angle)).add(this.level.worldpos())); },
|
set pos(x) {
|
||||||
|
this.set_worldpos(x); return;
|
||||||
|
this.set_worldpos(Vector.rotate(x,Math.deg2rad(this.level.angle)).add(this.level.worldpos()));
|
||||||
|
},
|
||||||
get pos() {
|
get pos() {
|
||||||
var offset = this.worldpos().sub(this.level.worldpos());
|
var offset = this.worldpos().sub(this.level.worldpos());
|
||||||
return Vector.rotate(offset, -Math.deg2rad(this.level.angle));
|
return Vector.rotate(offset, -Math.deg2rad(this.level.angle));
|
||||||
},
|
},
|
||||||
|
get elasticity() { return cmd(107,this.body); },
|
||||||
|
set elasticity(x) { cmd(106,this.body,x); },
|
||||||
|
|
||||||
|
get friction() { return cmd(109,this.body); },
|
||||||
|
set friction(x) { cmd(108,this.body,x); },
|
||||||
|
|
||||||
|
set mass(x) { set_body(7,this.body,x); },
|
||||||
|
get mass() {
|
||||||
|
if (!(this.phys === Physics.dynamic))
|
||||||
|
return this.__proto__.mass;
|
||||||
|
|
||||||
|
return q_body(5, this.body);
|
||||||
|
},
|
||||||
|
|
||||||
|
set phys(x) { set_body(1, this.body, x); },
|
||||||
|
get phys() { return q_body(0,this.body); },
|
||||||
|
get velocity() { return q_body(3, this.body); },
|
||||||
|
set velocity(x) { set_body(9, this.body, x); },
|
||||||
|
get angularvelocity() { return Math.rad2deg(q_body(4, this.body)); },
|
||||||
|
set angularvelocity(x) { set_body(8, this.body, Math.deg2rad(x)); },
|
||||||
worldpos() { return q_body(1,this.body); },
|
worldpos() { return q_body(1,this.body); },
|
||||||
set_worldpos(x) {
|
set_worldpos(x) {
|
||||||
var diff = x.sub(this.worldpos());
|
var diff = x.sub(this.worldpos());
|
||||||
|
@ -170,30 +97,10 @@ var gameobject = {
|
||||||
set_body(0,this.body, Math.deg2rad(x));
|
set_body(0,this.body, Math.deg2rad(x));
|
||||||
},
|
},
|
||||||
|
|
||||||
get elasticity() { return cmd(107,this.body); },
|
|
||||||
set elasticity(x) { cmd(106,this.body,x); },
|
|
||||||
|
|
||||||
get friction() { return cmd(109,this.body); },
|
|
||||||
set friction(x) { cmd(108,this.body,x); },
|
|
||||||
|
|
||||||
set mass(x) { set_body(7,this.body,x); },
|
|
||||||
get mass() {
|
|
||||||
if (!(this.phys === Physics.dynamic))
|
|
||||||
return this.ur.mass;
|
|
||||||
|
|
||||||
return q_body(5, this.body);
|
|
||||||
},
|
|
||||||
|
|
||||||
set phys(x) { set_body(1, this.body, x); },
|
|
||||||
get phys() { return q_body(0,this.body); },
|
|
||||||
get velocity() { return q_body(3, this.body); },
|
|
||||||
set velocity(x) { set_body(9, this.body, x); },
|
|
||||||
get angularvelocity() { return Math.rad2deg(q_body(4, this.body)); },
|
|
||||||
set angularvelocity(x) { set_body(8, this.body, Math.deg2rad(x)); },
|
|
||||||
|
|
||||||
pulse(vec) { set_body(4, this.body, vec);},
|
pulse(vec) { set_body(4, this.body, vec);},
|
||||||
|
|
||||||
push(vec) { set_body(12,this.body,vec);},
|
shove(vec) { set_body(12,this.body,vec);},
|
||||||
world2this(pos) { return cmd(70, this.body, pos); },
|
world2this(pos) { return cmd(70, this.body, pos); },
|
||||||
this2world(pos) { return cmd(71, this.body,pos); },
|
this2world(pos) { return cmd(71, this.body,pos); },
|
||||||
set layer(x) { cmd(75,this.body,x); },
|
set layer(x) { cmd(75,this.body,x); },
|
||||||
|
@ -201,11 +108,6 @@ var gameobject = {
|
||||||
alive() { return this.body >= 0; },
|
alive() { return this.body >= 0; },
|
||||||
in_air() { return q_body(7, this.body);},
|
in_air() { return q_body(7, this.body);},
|
||||||
on_ground() { return !this.in_air(); },
|
on_ground() { return !this.in_air(); },
|
||||||
|
|
||||||
disable() { this.components.forEach(function(x) { x.disable(); });},
|
|
||||||
enable() { this.components.forEach(function(x) { x.enable(); });},
|
|
||||||
sync() { },
|
|
||||||
|
|
||||||
spawn(ur) {
|
spawn(ur) {
|
||||||
if (typeof ur === 'string')
|
if (typeof ur === 'string')
|
||||||
ur = prototypes.get_ur(ur);
|
ur = prototypes.get_ur(ur);
|
||||||
|
@ -214,10 +116,104 @@ var gameobject = {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
var go = gameobject.make(ur, this);
|
var go = ur.make(this);
|
||||||
return go;
|
return go;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reparent(parent) {
|
||||||
|
if (this.level === parent)
|
||||||
|
this.level.remove_obj(this);
|
||||||
|
|
||||||
|
var name = parent.objects.push(this);
|
||||||
|
this.toString = function() { return name; };
|
||||||
|
|
||||||
|
if (this.level)
|
||||||
|
this.level.objects.remove(this);
|
||||||
|
this.level = parent;
|
||||||
|
},
|
||||||
|
remove_obj(obj) {
|
||||||
|
delete this[obj.toString()];
|
||||||
|
this.objects.remove(obj);
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
draw_layer: 1,
|
||||||
|
components: [],
|
||||||
|
objects: [],
|
||||||
|
level: undefined,
|
||||||
|
|
||||||
|
hide() { this.components.forEach(function(x) { x.hide(); }); this.objects.forEach(function(x) { x.hide(); }); },
|
||||||
|
show() { this.components.forEach(function(x) { x.show(); }); this.objects.forEach(function(x) { x.show(); }); },
|
||||||
|
|
||||||
|
get_relangle() {
|
||||||
|
if (!this.level) return this.angle;
|
||||||
|
return this.angle - this.level.angle;
|
||||||
|
},
|
||||||
|
|
||||||
|
width() {
|
||||||
|
var bb = this.boundingbox();
|
||||||
|
return bb.r - bb.l;
|
||||||
|
},
|
||||||
|
|
||||||
|
height() {
|
||||||
|
var bb = this.boundingbox();
|
||||||
|
return bb.t-bb.b;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Make a unique object the same as its prototype */
|
||||||
|
revert() {
|
||||||
|
Object.totalmerge(this,this.__proto__);
|
||||||
|
},
|
||||||
|
|
||||||
|
check_registers(obj) {
|
||||||
|
Register.unregister_obj(obj);
|
||||||
|
|
||||||
|
if (typeof obj.update === 'function')
|
||||||
|
Register.update.register(obj.update, obj);
|
||||||
|
|
||||||
|
if (typeof obj.physupdate === 'function')
|
||||||
|
Register.physupdate.register(obj.physupdate, obj);
|
||||||
|
|
||||||
|
if (typeof obj.collide === 'function')
|
||||||
|
obj.register_hit(obj.collide, obj);
|
||||||
|
|
||||||
|
if (typeof obj.separate === 'function')
|
||||||
|
obj.register_separate(obj.separate, obj);
|
||||||
|
|
||||||
|
if (typeof obj.draw === 'function')
|
||||||
|
Register.draw.register(obj.draw,obj);
|
||||||
|
|
||||||
|
if (typeof obj.debug === 'function')
|
||||||
|
Register.debug.register(obj.debug, obj);
|
||||||
|
|
||||||
|
obj.components.forEach(function(x) {
|
||||||
|
if (typeof x.collide === 'function')
|
||||||
|
register_collide(1, x.collide, x, obj.body, x.shape);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pos: [0,0],
|
||||||
|
angle:0,
|
||||||
|
phys:1,
|
||||||
|
flipx:false,
|
||||||
|
flipy:false,
|
||||||
|
scale:1,
|
||||||
|
elasticity:0.5,
|
||||||
|
friction:1,
|
||||||
|
mass:1,
|
||||||
|
velocity:[0,0],
|
||||||
|
angularvelocity:0,
|
||||||
|
layer:0,
|
||||||
|
save:true,
|
||||||
|
selectable:true,
|
||||||
|
ed_locked:false,
|
||||||
|
|
||||||
|
|
||||||
|
disable() { this.components.forEach(function(x) { x.disable(); });},
|
||||||
|
enable() { this.components.forEach(function(x) { x.enable(); });},
|
||||||
|
sync() { },
|
||||||
|
|
||||||
|
|
||||||
/* Bounding box of the object in world dimensions */
|
/* Bounding box of the object in world dimensions */
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
var boxes = [];
|
var boxes = [];
|
||||||
|
@ -296,7 +292,8 @@ var gameobject = {
|
||||||
},
|
},
|
||||||
|
|
||||||
json_obj() {
|
json_obj() {
|
||||||
var ur = gameobject.diff(this,this.ur);
|
var ur = gameobject.diff(this,this.__proto__);
|
||||||
|
|
||||||
return ur ? ur : {};
|
return ur ? ur : {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -309,8 +306,8 @@ var gameobject = {
|
||||||
level_obj() {
|
level_obj() {
|
||||||
var json = this.json_obj();
|
var json = this.json_obj();
|
||||||
var objects = {};
|
var objects = {};
|
||||||
this.ur.objects ??= {};
|
this.__proto__.objects ??= {};
|
||||||
if (!Object.keys(this.objects).equal(Object.keys(this.ur.objects))) {
|
if (!Object.keys(this.objects).equal(Object.keys(this.__proto__.objects))) {
|
||||||
for (var o in this.objects) {
|
for (var o in this.objects) {
|
||||||
objects[o] = this.objects[o].transform_obj();
|
objects[o] = this.objects[o].transform_obj();
|
||||||
objects[o].ur = this.objects[o].ur.toString();
|
objects[o].ur = this.objects[o].ur.toString();
|
||||||
|
@ -318,7 +315,7 @@ var gameobject = {
|
||||||
} else {
|
} else {
|
||||||
for (var o in this.objects) {
|
for (var o in this.objects) {
|
||||||
var obj = this.objects[o].json_obj();
|
var obj = this.objects[o].json_obj();
|
||||||
Object.assign(obj, gameobject.diff(this.objects[o].transform(), this.ur.objects[o]));
|
Object.assign(obj, gameobject.diff(this.objects[o].transform(), this.__proto__.objects[o]));
|
||||||
if (!obj.empty)
|
if (!obj.empty)
|
||||||
objects[o] = obj;
|
objects[o] = obj;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +358,7 @@ var gameobject = {
|
||||||
},
|
},
|
||||||
|
|
||||||
dup(diff) {
|
dup(diff) {
|
||||||
var n = this.level.spawn(this.ur);
|
var n = this.level.spawn(this.__proto__);
|
||||||
Object.totalmerge(n, this.make_ur());
|
Object.totalmerge(n, this.make_ur());
|
||||||
return n;
|
return n;
|
||||||
},
|
},
|
||||||
|
@ -380,6 +377,7 @@ var gameobject = {
|
||||||
|
|
||||||
Player.uncontrol(this);
|
Player.uncontrol(this);
|
||||||
Register.unregister_obj(this);
|
Register.unregister_obj(this);
|
||||||
|
this.instances.remove(this);
|
||||||
|
|
||||||
this.body = -1;
|
this.body = -1;
|
||||||
for (var key in this.components) {
|
for (var key in this.components) {
|
||||||
|
@ -395,75 +393,61 @@ var gameobject = {
|
||||||
// });
|
// });
|
||||||
},
|
},
|
||||||
|
|
||||||
remove_obj(obj) {
|
|
||||||
delete this[obj.toString()];
|
|
||||||
this.objects.remove(obj);
|
|
||||||
},
|
|
||||||
|
|
||||||
up() { return [0,1].rotate(Math.deg2rad(this.angle));},
|
up() { return [0,1].rotate(Math.deg2rad(this.angle));},
|
||||||
down() { return [0,-1].rotate(Math.deg2rad(this.angle));},
|
down() { return [0,-1].rotate(Math.deg2rad(this.angle));},
|
||||||
right() { return [1,0].rotate(Math.deg2rad(this.angle));},
|
right() { return [1,0].rotate(Math.deg2rad(this.angle));},
|
||||||
left() { return [-1,0].rotate(Math.deg2rad(this.angle));},
|
left() { return [-1,0].rotate(Math.deg2rad(this.angle));},
|
||||||
reparent(parent) {
|
instances: [],
|
||||||
if (this.level === parent)
|
make(level) {
|
||||||
this.level.remove_obj(this);
|
|
||||||
var name = parent.objects.push(this);
|
|
||||||
this.toString = function() { return name; };
|
|
||||||
|
|
||||||
if (this.level)
|
|
||||||
this.level.objects.remove(this);
|
|
||||||
this.level = parent;
|
|
||||||
},
|
|
||||||
|
|
||||||
make(ur, level) {
|
|
||||||
level ??= Primum;
|
level ??= Primum;
|
||||||
var obj = Object.create(gameobject);
|
var obj = Object.create(this);
|
||||||
|
this.instances.push(obj);
|
||||||
obj.body = make_gameobject();
|
obj.body = make_gameobject();
|
||||||
obj.components = {};
|
obj.components = {};
|
||||||
obj.objects = {};
|
obj.objects = {};
|
||||||
|
Object.complete_assign(obj, gameobject.impl);
|
||||||
Object.hide(obj, 'components');
|
Object.hide(obj, 'components');
|
||||||
Object.hide(obj, 'objects');
|
Object.hide(obj, 'objects');
|
||||||
obj.toString = function() { return obj.ur.toString(); };
|
obj.toJSON = gameobject.level_json;
|
||||||
|
|
||||||
Game.register_obj(obj);
|
Game.register_obj(obj);
|
||||||
|
|
||||||
cmd(113, obj.body, obj); // set the internal obj reference to this obj
|
cmd(113, obj.body, obj); // set the internal obj reference to this obj
|
||||||
|
|
||||||
obj.ur = ur;
|
|
||||||
|
|
||||||
obj.reparent(level);
|
obj.reparent(level);
|
||||||
|
|
||||||
for (var prop in ur) {
|
for (var prop in this) {
|
||||||
var p = ur[prop];
|
var p = this[prop];
|
||||||
if (typeof p !== 'object') continue;
|
if (typeof p !== 'object') continue;
|
||||||
|
|
||||||
if ('ur' in p) {
|
if ('ur' in p) {
|
||||||
obj[prop] = obj.spawn(prototypes.get_ur(p.ur));
|
obj[prop] = obj.spawn(prototypes.get_ur(p.ur));
|
||||||
obj.rename_obj(obj[prop].toString(), prop);
|
obj.rename_obj(obj[prop].toString(), prop);
|
||||||
} else if ('comp' in p) {
|
} else if ('comp' in p) {
|
||||||
obj[prop] = component[p.comp].make(obj);
|
Log.warn(p);
|
||||||
|
obj[prop] = Object.assign(component[p.comp].make(obj), p);
|
||||||
obj.components[prop] = obj[prop];
|
obj.components[prop] = obj[prop];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ur.objects) {
|
if (this.objects) {
|
||||||
for (var prop in ur.objects) {
|
for (var prop in this.objects) {
|
||||||
var o = ur.objects[prop];
|
Log.warn(this.objects[prop]);
|
||||||
|
continue;
|
||||||
|
var o = this.objects[prop];
|
||||||
var newobj = obj.spawn(prototypes.get_ur(o.ur));
|
var newobj = obj.spawn(prototypes.get_ur(o.ur));
|
||||||
if (!newobj) continue;
|
if (!newobj) continue;
|
||||||
obj.rename_obj(newobj.toString(), prop);
|
obj.rename_obj(newobj.toString(), prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var save_tostr = obj.toString;
|
for (var p in this.impl) {
|
||||||
Object.totalmerge(obj,ur);
|
if (Object.isAccessor(this.impl, p))
|
||||||
obj.toString = save_tostr;
|
obj[p] = this[p];
|
||||||
obj.components.forEach(function(x) { if ('sync' in x) x.sync(); });
|
}
|
||||||
obj.check_registers(obj);
|
|
||||||
|
|
||||||
obj.objects.forEach(function(x) {
|
obj.components.forEach(function(x) { if ('sync' in x) x.sync(); });
|
||||||
x.ur = prototypes.get_ur(x.ur);
|
gameobject.check_registers(obj);
|
||||||
});
|
|
||||||
|
|
||||||
if (typeof obj.start === 'function') obj.start();
|
if (typeof obj.start === 'function') obj.start();
|
||||||
|
|
||||||
|
@ -501,26 +485,7 @@ var gameobject = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
gameobject.toJSON = gameobject.level_obj;
|
gameobject.impl.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
||||||
|
|
||||||
gameobject.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
|
||||||
|
|
||||||
gameobject.ur = {
|
|
||||||
// pos: [0,0],
|
|
||||||
scale:1,
|
|
||||||
flipx:false,
|
|
||||||
flipy:false,
|
|
||||||
// angle:0,
|
|
||||||
elasticity:0.5,
|
|
||||||
friction:1,
|
|
||||||
mass:1,
|
|
||||||
// velocity:[0,0],
|
|
||||||
// angularvelocity:0,
|
|
||||||
layer: 0,
|
|
||||||
save: true,
|
|
||||||
selectable: true,
|
|
||||||
ed_locked: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Default objects */
|
/* Default objects */
|
||||||
var prototypes = {};
|
var prototypes = {};
|
||||||
|
@ -560,7 +525,7 @@ prototypes.from_file = function(file)
|
||||||
return prototypes.get_ur(urpath);
|
return prototypes.get_ur(urpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
var upperur = gameobject.ur;
|
var upperur = gameobject;
|
||||||
|
|
||||||
if (path.length > 1) {
|
if (path.length > 1) {
|
||||||
var upperpath = path.slice(0,-1);
|
var upperpath = path.slice(0,-1);
|
||||||
|
@ -571,7 +536,8 @@ prototypes.from_file = function(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newur = Object.create(upperur);
|
var newur = {};//Object.create(upperur);
|
||||||
|
|
||||||
file = file.replaceAll('.','/');
|
file = file.replaceAll('.','/');
|
||||||
|
|
||||||
var jsfile = prototypes.get_ur_file(urpath, ".js");
|
var jsfile = prototypes.get_ur_file(urpath, ".js");
|
||||||
|
@ -594,8 +560,16 @@ prototypes.from_file = function(file)
|
||||||
json ??= {};
|
json ??= {};
|
||||||
Object.merge(newur,json);
|
Object.merge(newur,json);
|
||||||
|
|
||||||
|
for (var p in newur)
|
||||||
|
if (Object.isObject(newur[p]) && Object.isObject(upperur[p]))
|
||||||
|
newur[p].__proto__ = upperur[p];
|
||||||
|
|
||||||
|
newur.__proto__ = upperur;
|
||||||
|
newur.instances = [];
|
||||||
|
|
||||||
prototypes.list.push(urpath);
|
prototypes.list.push(urpath);
|
||||||
newur.toString = function() { return urpath; };
|
newur.toString = function() { return urpath; };
|
||||||
|
newur.ur = urpath;
|
||||||
ur[urpath] = newur;
|
ur[urpath] = newur;
|
||||||
|
|
||||||
return ur[urpath];
|
return ur[urpath];
|
||||||
|
@ -605,7 +579,7 @@ prototypes.list = [];
|
||||||
|
|
||||||
prototypes.from_obj = function(name, obj)
|
prototypes.from_obj = function(name, obj)
|
||||||
{
|
{
|
||||||
var newur = Object.copy(gameobject.ur, obj);
|
var newur = Object.copy(gameobject, obj);
|
||||||
prototypes.ur[name] = newur;
|
prototypes.ur[name] = newur;
|
||||||
newur.toString = function() { return name; };
|
newur.toString = function() { return name; };
|
||||||
return prototypes.ur[name];
|
return prototypes.ur[name];
|
||||||
|
@ -715,3 +689,36 @@ prototypes.from_obj("camera2d", {
|
||||||
});
|
});
|
||||||
|
|
||||||
prototypes.from_obj("arena", {});
|
prototypes.from_obj("arena", {});
|
||||||
|
|
||||||
|
prototypes.resavi = function(ur, path)
|
||||||
|
{
|
||||||
|
if (!ur) return path;
|
||||||
|
if (path[0] === '/') return path;
|
||||||
|
|
||||||
|
var res = ur.replaceAll('.', '/');
|
||||||
|
var dir = path.dir();
|
||||||
|
if (res.startsWith(dir))
|
||||||
|
return path.base();
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
prototypes.resani = function(ur, path)
|
||||||
|
{
|
||||||
|
if (!path) return "";
|
||||||
|
Log.warn(`Sanitizing ${path} from ${ur}`);
|
||||||
|
if (!ur) return path;
|
||||||
|
if (path[0] === '/') return path.slice(1);
|
||||||
|
|
||||||
|
var res = ur.replaceAll('.', '/');
|
||||||
|
var restry = res + "/" + path;
|
||||||
|
while (!IO.exists(restry)) {
|
||||||
|
res = res.updir() + "/";
|
||||||
|
if (res === "/")
|
||||||
|
return path;
|
||||||
|
|
||||||
|
restry = res + path;
|
||||||
|
}
|
||||||
|
return restry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
var GUI = {
|
var GUI = {
|
||||||
text(str, pos, size, color, wrap, anchor, frame) {
|
text(str, pos, size, color, wrap, anchor, cursor) {
|
||||||
size ??= 1;
|
size ??= 1;
|
||||||
color ??= Color.white;
|
color ??= Color.white;
|
||||||
wrap ??= -1;
|
wrap ??= -1;
|
||||||
anchor ??= [0,1];
|
anchor ??= [0,1];
|
||||||
frame ??= Window.boundingbox();
|
|
||||||
|
cursor ??= -1;
|
||||||
|
|
||||||
var bb = cmd(118, str, size, wrap);
|
var bb = cmd(118, str, size, wrap);
|
||||||
var w = bb.r*2;
|
var w = bb.r*2;
|
||||||
|
@ -18,15 +19,11 @@ var GUI = {
|
||||||
p.y += h * (1 - anchor.y);
|
p.y += h * (1 - anchor.y);
|
||||||
bb.t += h*(1-anchor.y);
|
bb.t += h*(1-anchor.y);
|
||||||
bb.b += h*(1-anchor.y);
|
bb.b += h*(1-anchor.y);
|
||||||
ui_text(str, p, size, color, wrap, bb);
|
ui_text(str, p, size, color, wrap, cursor);
|
||||||
|
|
||||||
return bb;
|
return bb;
|
||||||
},
|
},
|
||||||
|
|
||||||
text_cursor(str, pos, size, cursor) {
|
|
||||||
cursor_text(str,pos,size,Color.white,cursor);
|
|
||||||
},
|
|
||||||
|
|
||||||
scissor(x,y,w,h) {
|
scissor(x,y,w,h) {
|
||||||
cmd(140,x,y,w,h);
|
cmd(140,x,y,w,h);
|
||||||
},
|
},
|
||||||
|
@ -68,13 +65,14 @@ var GUI = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var Mum = {
|
var Mum = {
|
||||||
padding:[2,2], /* Each element inset with this padding on all sides */
|
padding:[0,0], /* Each element inset with this padding on all sides */
|
||||||
|
offset:[0,0],
|
||||||
font: "fonts/LessPerfectDOSVGA.ttf",
|
font: "fonts/LessPerfectDOSVGA.ttf",
|
||||||
font_size: 1,
|
font_size: 1,
|
||||||
text_align: "left",
|
text_align: "left",
|
||||||
scale: 1,
|
scale: 1,
|
||||||
angle: 0,
|
angle: 0,
|
||||||
anchor: [0,0],
|
anchor: [0,1],
|
||||||
text_shadow: {
|
text_shadow: {
|
||||||
pos: [0,0],
|
pos: [0,0],
|
||||||
color: Color.white,
|
color: Color.white,
|
||||||
|
@ -93,6 +91,8 @@ var Mum = {
|
||||||
return n;
|
return n;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
start() {},
|
||||||
|
|
||||||
extend(def) {
|
extend(def) {
|
||||||
var n = Object.create(this);
|
var n = Object.create(this);
|
||||||
Object.assign(n, def);
|
Object.assign(n, def);
|
||||||
|
@ -103,22 +103,58 @@ var Mum = {
|
||||||
Mum.text = Mum.extend({
|
Mum.text = Mum.extend({
|
||||||
draw(cursor) {
|
draw(cursor) {
|
||||||
if (this.hide) return;
|
if (this.hide) return;
|
||||||
this.calc_bb(cursor);
|
this.caret ??= -1;
|
||||||
|
|
||||||
|
/* if (!this.bb)
|
||||||
|
this.calc_bb(cursor);
|
||||||
|
else
|
||||||
|
this.update_bb(cursor);
|
||||||
|
*/
|
||||||
if (this.selected) {
|
if (this.selected) {
|
||||||
Object.assign(this,this.hovered);
|
Object.assign(this,this.hovered);
|
||||||
this.calc_bb(cursor);
|
this.calc_bb(cursor);
|
||||||
}
|
}
|
||||||
|
this.calc_bb(cursor);
|
||||||
var pos = cursor.sub(bb2wh(this.bb).scale(this.anchor));
|
var aa = [0,1].sub(this.anchor);
|
||||||
ui_text(this.str, pos, this.font_size, this.color, this.width);
|
var pos = cursor.add(this.wh.scale(aa)).add(this.offset);
|
||||||
|
if (this.caret > -1) Log.warn(`Drawing box at pos ${this.caret} over letter ${this.str[this.caret-1]}`);
|
||||||
|
ui_text(this.str, pos, this.font_size, this.color, -1, this.width, this.caret);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
update_bb(cursor) {
|
||||||
|
this.bb = movebb(this.bb, cursor.sub(this.wh.scale(this.anchor)));
|
||||||
|
},
|
||||||
|
|
||||||
calc_bb(cursor) {
|
calc_bb(cursor) {
|
||||||
var bb = cmd(118,this.str, this.font_size, this.width);
|
var bb = cmd(118,this.str, this.font_size, this.width);
|
||||||
var wh = bb2wh(bb);
|
this.wh = bb2wh(bb);
|
||||||
var pos = cursor.sub(wh.scale(this.anchor));
|
var pos = cursor.sub(this.wh.scale(this.anchor));
|
||||||
this.bb = movebb(bb,pos);
|
this.bb = movebb(bb,pos);
|
||||||
},
|
},
|
||||||
|
start() {
|
||||||
|
this.calc_bb([0,0]);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Mum.window = Mum.extend({
|
||||||
|
start() {
|
||||||
|
this.wh = [this.width, this.height];
|
||||||
|
this.bb = cwh2bb([0,0], this.wh);
|
||||||
|
},
|
||||||
|
draw(pos) {
|
||||||
|
var p = pos.sub(this.wh.scale(this.anchor));
|
||||||
|
GUI.window(p,this.wh, this.color);
|
||||||
|
this.bb = bl2bb(p, this.wh);
|
||||||
|
var pos = [this.bb.l, this.bb.t];
|
||||||
|
GUI.flush();
|
||||||
|
GUI.scissor(p.x,p.y,this.wh.x,this.wh.y);
|
||||||
|
this.items.forEach(function(item) {
|
||||||
|
if (item.hide) return;
|
||||||
|
item.draw(pos.slice());
|
||||||
|
});
|
||||||
|
GUI.flush();
|
||||||
|
GUI.scissor_win();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Mum.image = Mum.extend({
|
Mum.image = Mum.extend({
|
||||||
|
@ -130,9 +166,9 @@ Mum.image = Mum.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
var tex_wh = cmd(64, this.path);
|
var tex_wh = cmd(64, this.path);
|
||||||
var wh = tex_wh.slice();
|
this.wh = tex_wh.slice();
|
||||||
if (this.width !== 0) wh.x = this.width;
|
if (this.width !== 0) this.wh.x = this.width;
|
||||||
if (this.height !== 0) wh.y = this.height;
|
if (this.height !== 0) this.wh.y = this.height;
|
||||||
|
|
||||||
this.wh = wh.scale(this.scale);
|
this.wh = wh.scale(this.scale);
|
||||||
this.sendscale = [wh.x/tex_wh.x, wh.y/tex_wh.y];
|
this.sendscale = [wh.x/tex_wh.x, wh.y/tex_wh.y];
|
||||||
|
@ -156,9 +192,8 @@ Mum.column = Mum.extend({
|
||||||
this.items.forEach(function(item) {
|
this.items.forEach(function(item) {
|
||||||
if (item.hide) return;
|
if (item.hide) return;
|
||||||
item.draw(cursor);
|
item.draw(cursor);
|
||||||
var wh = bb2wh(item.bb);
|
cursor.y -= item.wh.y;
|
||||||
cursor.y -= wh.y*2;
|
cursor.y -= this.padding.y;
|
||||||
cursor.y -= this.padding.y*2;
|
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -282,26 +282,12 @@ JSValue duk_ui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
|
||||||
float size = js2number(argv[2]);
|
float size = js2number(argv[2]);
|
||||||
struct rgba c = js2color(argv[3]);
|
struct rgba c = js2color(argv[3]);
|
||||||
int wrap = js2int(argv[4]);
|
int wrap = js2int(argv[4]);
|
||||||
struct boundingbox bb = js2bb(argv[5]);
|
int cursor = js2int(argv[5]);
|
||||||
JSValue ret = JS_NewInt64(js, renderText(s, pos, size, c, wrap, -1, 1.0, bb));
|
JSValue ret = JS_NewInt64(js, renderText(s, pos, size, c, wrap, cursor, 1.0));
|
||||||
JS_FreeCString(js, s);
|
JS_FreeCString(js, s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue duk_cursor_text(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
|
||||||
const char *s = JS_ToCString(js, argv[0]);
|
|
||||||
HMM_Vec2 pos = js2hmmv2(argv[1]);
|
|
||||||
|
|
||||||
float size = js2number(argv[2]);
|
|
||||||
struct rgba c = js2color(argv[3]);
|
|
||||||
int wrap = js2int(argv[5]);
|
|
||||||
int cursor = js2int(argv[4]);
|
|
||||||
struct boundingbox bb = js2bb(argv[6]);
|
|
||||||
renderText(s, pos, size, c, wrap, cursor, 1.0,bb);
|
|
||||||
JS_FreeCString(js, s);
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue duk_gui_img(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
JSValue duk_gui_img(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||||
const char *img = JS_ToCString(js, argv[0]);
|
const char *img = JS_ToCString(js, argv[0]);
|
||||||
gui_draw_img(img, js2hmmv2(argv[1]), js2hmmv2(argv[2]), js2number(argv[3]), js2bool(argv[4]), js2hmmv2(argv[5]), 1.0, js2color(argv[6]));
|
gui_draw_img(img, js2hmmv2(argv[1]), js2hmmv2(argv[2]), js2number(argv[3]), js2bool(argv[4]), js2hmmv2(argv[5]), 1.0, js2color(argv[6]));
|
||||||
|
@ -1636,8 +1622,7 @@ void ffi_load() {
|
||||||
DUK_FUNC(register, 3)
|
DUK_FUNC(register, 3)
|
||||||
DUK_FUNC(register_collide, 6)
|
DUK_FUNC(register_collide, 6)
|
||||||
|
|
||||||
DUK_FUNC(ui_text, 5)
|
DUK_FUNC(ui_text, 6)
|
||||||
DUK_FUNC(cursor_text, 5)
|
|
||||||
DUK_FUNC(gui_img, 10)
|
DUK_FUNC(gui_img, 10)
|
||||||
|
|
||||||
DUK_FUNC(inflate_cpv, 3)
|
DUK_FUNC(inflate_cpv, 3)
|
||||||
|
|
|
@ -191,6 +191,7 @@ void draw_char_box(struct Character c, HMM_Vec2 cursor, float scale, struct rgba
|
||||||
cpVect b;
|
cpVect b;
|
||||||
b.x = cursor.X;
|
b.x = cursor.X;
|
||||||
b.y = cursor.Y;
|
b.y = cursor.Y;
|
||||||
|
color.a = 30;
|
||||||
|
|
||||||
draw_box(b, wh, color);
|
draw_box(b, wh, color);
|
||||||
}
|
}
|
||||||
|
@ -210,10 +211,8 @@ void text_flush(HMM_Mat4 *proj) {
|
||||||
curchar = 0;
|
curchar = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drawcaret = 0;
|
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) {
|
||||||
|
if (curchar+1 >= max_chars)
|
||||||
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color, struct boundingbox frame) {
|
|
||||||
if (curchar == max_chars)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct text_vert vert;
|
struct text_vert vert;
|
||||||
|
@ -279,13 +278,12 @@ struct boundingbox text_bb(const char *text, float scale, float lw, float tracki
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){cursor.X,-cursor.Y});
|
return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){cursor.X,font->linegap-cursor.Y});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pos given in screen coordinates */
|
/* pos given in screen coordinates */
|
||||||
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking, struct boundingbox frame) {
|
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking) {
|
||||||
int len = strlen(text);
|
int len = strlen(text);
|
||||||
drawcaret = caret;
|
|
||||||
|
|
||||||
HMM_Vec2 cursor = pos;
|
HMM_Vec2 cursor = pos;
|
||||||
|
|
||||||
|
@ -295,15 +293,15 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f
|
||||||
struct rgba usecolor = color;
|
struct rgba usecolor = color;
|
||||||
|
|
||||||
while (*line != '\0') {
|
while (*line != '\0') {
|
||||||
if (caret == curchar)
|
if (caret >= 0 && caret == curchar)
|
||||||
draw_char_box(font->Characters[69], cursor, scale, color);
|
draw_char_box(font->Characters[69], cursor, scale, color);
|
||||||
|
|
||||||
if (isblank(*line)) {
|
if (isblank(*line)) {
|
||||||
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor, frame);
|
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
||||||
cursor.X += font->Characters[*line].Advance * tracking * scale;
|
cursor.X += font->Characters[*line].Advance * tracking * scale;
|
||||||
line++;
|
line++;
|
||||||
} else if (isspace(*line)) {
|
} else if (isspace(*line)) {
|
||||||
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor, frame);
|
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
||||||
cursor.Y -= scale * font->linegap;
|
cursor.Y -= scale * font->linegap;
|
||||||
cursor.X = pos.X;
|
cursor.X = pos.X;
|
||||||
line++;
|
line++;
|
||||||
|
@ -322,7 +320,7 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f
|
||||||
}
|
}
|
||||||
|
|
||||||
while (wordstart < line) {
|
while (wordstart < line) {
|
||||||
sdrawCharacter(font->Characters[*wordstart], cursor, scale, usecolor, frame);
|
sdrawCharacter(font->Characters[*wordstart], cursor, scale, usecolor);
|
||||||
cursor.X += font->Characters[*wordstart].Advance * tracking * scale;
|
cursor.X += font->Characters[*wordstart].Advance * tracking * scale;
|
||||||
wordstart++;
|
wordstart++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@ struct sFont {
|
||||||
|
|
||||||
void font_init();
|
void font_init();
|
||||||
struct sFont *MakeFont(const char *fontfile, int height);
|
struct sFont *MakeFont(const char *fontfile, int height);
|
||||||
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color, struct boundingbox frame);
|
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color);
|
||||||
void text_settype(struct sFont *font);
|
void text_settype(struct sFont *font);
|
||||||
struct boundingbox text_bb(const char *text, float scale, float lw, float tracking);
|
struct boundingbox text_bb(const char *text, float scale, float lw, float tracking);
|
||||||
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking, struct boundingbox frame);
|
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking);
|
||||||
|
|
||||||
// void text_frame();
|
// void text_frame();
|
||||||
void text_flush(HMM_Mat4 *proj);
|
void text_flush(HMM_Mat4 *proj);
|
||||||
|
|
Loading…
Reference in a new issue