easier saving
This commit is contained in:
parent
03f209ddef
commit
272719736c
|
@ -45,9 +45,10 @@ Object.dainty_assign = function(target, source)
|
|||
{
|
||||
Object.keys(target).forEach(function(key) {
|
||||
if (!(key in source)) return;
|
||||
if (typeof target[key] === 'function') return;
|
||||
|
||||
if (Array.isArray(target[key]))
|
||||
target[key] = source[key];
|
||||
target[key] = deep_copy(source[key]);
|
||||
else if (typeof target[key] === 'object')
|
||||
Object.dainty_assign(target[key], source[key]);
|
||||
else
|
||||
|
@ -736,7 +737,7 @@ Math.angledist = function (a1, a2) {
|
|||
return wrap;
|
||||
};
|
||||
Math.angledist.doc = "Find the shortest angle between two angles.";
|
||||
|
||||
Math.patan2 = function(p) { return Math.atan2(p.y,p.x); };
|
||||
Math.deg2rad = function(deg) { return deg * 0.0174533; };
|
||||
Math.rad2deg = function(rad) { return rad / 0.0174533; };
|
||||
Math.randomint = function(max) { return Math.clamp(Math.floor(Math.random() * max), 0, max-1); };
|
||||
|
|
|
@ -24,6 +24,13 @@ var component = {
|
|||
},
|
||||
};
|
||||
|
||||
component.assign_impl = function(o)
|
||||
{
|
||||
for (var key in o.impl)
|
||||
if (typeof o[key] !== 'undefined' && typeof o[key] !== 'function')
|
||||
o[key] = o.impl[key];
|
||||
}
|
||||
|
||||
component.sprite = Object.copy(component, {
|
||||
pos:[0,0],
|
||||
color:[1,1,1],
|
||||
|
@ -37,20 +44,23 @@ component.sprite = Object.copy(component, {
|
|||
nsprite.gameobject = go;
|
||||
Object.assign(nsprite, make_sprite(go.body));
|
||||
Object.mixin(nsprite, component.sprite.impl);
|
||||
nsprite.kill = component.sprite.impl.kill;
|
||||
|
||||
Object.hide(nsprite, 'gameobject', 'id');
|
||||
for (var p in component.sprite.impl)
|
||||
if (typeof this[p] !== 'undefined')
|
||||
if (typeof this[p] !== 'undefined' && typeof this[p] !== 'function')
|
||||
nsprite[p] = this[p];
|
||||
|
||||
return nsprite;
|
||||
},
|
||||
});
|
||||
|
||||
component.sprite.impl = {
|
||||
set path(x) {
|
||||
cmd(12,this.id,prototypes.resani(this.gameobject.ur, x),this.rect);
|
||||
cmd(12,this.id,prototypes.resani(this.gameobject.__proto__.toString(), x),this.rect);
|
||||
},
|
||||
get path() {
|
||||
return prototypes.resavi(this.gameobject.ur, cmd(116,this.id));
|
||||
return prototypes.resavi(this.gameobject.__proto__.toString(), cmd(116,this.id));
|
||||
},
|
||||
hide() { this.enabled = false; },
|
||||
show() { this.enabled = true; },
|
||||
|
@ -324,9 +334,7 @@ collider2d.inputs['M-t'] = function() { this.enabled = !this.enabled; }
|
|||
collider2d.inputs['M-t'].doc = "Toggle if this collider is enabled.";
|
||||
|
||||
component.polygon2d = Object.copy(collider2d, {
|
||||
sync() {
|
||||
cmd_poly2d(0, this.id, this.spoints);
|
||||
},
|
||||
toString() { return "poly2d"; },
|
||||
|
||||
boundingbox() {
|
||||
return points2bb(this.spoints);
|
||||
|
@ -339,9 +347,13 @@ component.polygon2d = Object.copy(collider2d, {
|
|||
poly.flipx = false;
|
||||
poly.flipy = false;
|
||||
Object.assign(poly, make_poly2d(go.body, poly.points));
|
||||
Object.mixin(poly, poly.impl);
|
||||
Object.hide(poly, 'id', 'shape', 'gameobject', 'flipx', 'flipy');
|
||||
return poly;
|
||||
},
|
||||
|
||||
points:[],
|
||||
|
||||
/* EDITOR */
|
||||
get spoints() {
|
||||
var spoints = this.points.slice();
|
||||
|
@ -361,7 +373,6 @@ component.polygon2d = Object.copy(collider2d, {
|
|||
spoints.push(newpoint);
|
||||
});
|
||||
}
|
||||
|
||||
return spoints;
|
||||
},
|
||||
|
||||
|
@ -376,6 +387,9 @@ component.polygon2d = Object.copy(collider2d, {
|
|||
},
|
||||
|
||||
pick(pos) {
|
||||
if (!Object.hasOwn(this,'points'))
|
||||
this.points = deep_copy(this.__proto__.points);
|
||||
|
||||
var p = Gizmos.pick_gameobject_points(pos, this.gameobject, this.points);
|
||||
if (p) {
|
||||
return {
|
||||
|
@ -390,11 +404,16 @@ component.polygon2d = Object.copy(collider2d, {
|
|||
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
|
||||
component.polygon2d.impl = {
|
||||
sync() {
|
||||
cmd_poly2d(0, this.id, this.spoints);
|
||||
},
|
||||
query() {
|
||||
return cmd(80, this.shape);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
var polygon2d = component.polygon2d;
|
||||
|
||||
|
@ -424,11 +443,13 @@ polygon2d.inputs['C-b'] = function() {
|
|||
};
|
||||
polygon2d.inputs['C-b'].doc = "Freeze mirroring in place.";
|
||||
|
||||
Object.freeze(polygon2d);
|
||||
//Object.freeze(polygon2d);
|
||||
|
||||
component.edge2d = Object.copy(collider2d, {
|
||||
degrees:2,
|
||||
dimensions:2,
|
||||
thickness:0,
|
||||
points: [],
|
||||
/* open: 0
|
||||
clamped: 1
|
||||
beziers: 2
|
||||
|
@ -444,6 +465,7 @@ component.edge2d = Object.copy(collider2d, {
|
|||
|
||||
flipx: false,
|
||||
flipy: false,
|
||||
toString() { return "edge2d"; },
|
||||
|
||||
hollow: false,
|
||||
hollowt: 0,
|
||||
|
@ -508,11 +530,6 @@ component.edge2d = Object.copy(collider2d, {
|
|||
|
||||
return spline_cmd(0, this.degrees, this.dimensions, this.type, spoints, n);
|
||||
},
|
||||
set thickness(x) {
|
||||
cmd_edge2d(1,this.id,x);
|
||||
},
|
||||
|
||||
get thickness() { return cmd(112,this.id); },
|
||||
|
||||
samples: 10,
|
||||
|
||||
|
@ -523,20 +540,14 @@ component.edge2d = Object.copy(collider2d, {
|
|||
make(go) {
|
||||
var edge = Object.create(this);
|
||||
edge.gameobject = go;
|
||||
edge.cpoints = [];
|
||||
edge.points = [];
|
||||
// edge.cpoints = [];
|
||||
// edge.points = [];
|
||||
Object.assign(edge, make_edge2d(go.body, edge.points, 0));
|
||||
edge.thickness = 0;
|
||||
Object.mixin(edge,edge.impl);
|
||||
Object.hide(edge, 'gameobject', 'id', 'shape');
|
||||
return edge;
|
||||
},
|
||||
|
||||
sync() {
|
||||
var sensor = this.sensor;
|
||||
this.points = this.sample(this.samples);
|
||||
cmd_edge2d(0,this.id,this.points);
|
||||
this.sensor = sensor;
|
||||
},
|
||||
|
||||
/* EDITOR */
|
||||
gizmo() {
|
||||
this.spoints.forEach(function(x) {
|
||||
|
@ -565,6 +576,19 @@ component.edge2d = Object.copy(collider2d, {
|
|||
},
|
||||
});
|
||||
|
||||
component.edge2d.impl = {
|
||||
set thickness(x) {
|
||||
cmd_edge2d(1,this.id,x);
|
||||
},
|
||||
get thickness() { return cmd(112,this.id); },
|
||||
sync() {
|
||||
var sensor = this.sensor;
|
||||
this.points = this.sample(this.samples);
|
||||
cmd_edge2d(0,this.id,this.points);
|
||||
this.sensor = sensor;
|
||||
},
|
||||
};
|
||||
|
||||
var bucket = component.edge2d;
|
||||
bucket.inputs = {};
|
||||
bucket.inputs.h = function() { this.hollow = !this.hollow; };
|
||||
|
@ -684,7 +708,7 @@ component.circle2d = Object.copy(collider2d, {
|
|||
set radius(x) { cmd_circle2d(0,this.id,x); },
|
||||
get radius() { return cmd_circle2d(2,this.id); },
|
||||
|
||||
set scale(x) { Log.warn(x);this.radius = x; },
|
||||
set scale(x) { this.radius = x; },
|
||||
get scale() { return this.radius; },
|
||||
|
||||
set offset(x) { cmd_circle2d(1,this.id,x); },
|
||||
|
@ -707,7 +731,9 @@ component.circle2d = Object.copy(collider2d, {
|
|||
Object.assign(circle, make_circle2d(go.body));
|
||||
Object.mixin(circle,this.impl);
|
||||
Object.hide(circle, 'gameobject', 'id', 'shape', 'scale');
|
||||
component.assign_impl(circle);
|
||||
for (var key in this.impl)
|
||||
if (typeof this[key] !== 'undefined' && typeof this[key] !== 'function')
|
||||
if (this[key]) circle[key] = this[key];
|
||||
|
||||
return circle;
|
||||
|
|
|
@ -47,7 +47,7 @@ var Debug = {
|
|||
|
||||
numbered_point(pos, n) {
|
||||
Debug.point(world2screen(pos), 3);
|
||||
gui_text(n, world2screen(pos).add([0,4]), 1);
|
||||
GUI.text(n, world2screen(pos).add([0,4]), 1);
|
||||
},
|
||||
|
||||
phys_drawing: false,
|
||||
|
|
|
@ -83,60 +83,43 @@ function diffassign(target, from) {
|
|||
}
|
||||
};
|
||||
|
||||
function positive_diff(from, to)
|
||||
function ediff(from,to)
|
||||
{
|
||||
var diff = {};
|
||||
}
|
||||
|
||||
function vdiff(from,to)
|
||||
{
|
||||
if (typeof from === 'function') return undefined;
|
||||
if (typeof from === 'number') {
|
||||
var a = Number.prec(from);
|
||||
return a === to ? undefined : a;
|
||||
}
|
||||
|
||||
if (typeof from === 'object') {
|
||||
var ret = {};
|
||||
Object.keys(from).forEach(function(k) {
|
||||
var diff = vdiff(from[k], to[k]);
|
||||
if (diff) ret[k] = diff;
|
||||
});
|
||||
return ret.empty ? undefined : ret;
|
||||
}
|
||||
}
|
||||
|
||||
function gdiff(from, to) {
|
||||
var obj = {};
|
||||
|
||||
Object.entries(from).forEach(function([k,v]) {
|
||||
Object.entries(from).forEach(function([key,v]) {
|
||||
if (typeof v === 'function') return;
|
||||
if (typeof v === 'undefined') return;
|
||||
|
||||
var diff = vdiff(v, to[k]);
|
||||
if (diff) {
|
||||
if (Array.isArray(v))
|
||||
obj[k] = Object.values(diff);
|
||||
else if (!diff.empty)
|
||||
obj[k] = diff;
|
||||
if (Array.isArray(v)) {
|
||||
if (!Array.isArray(to[key]) || v.length !== to[key].length)
|
||||
ret[key] = Object.values(ediff(v, []));
|
||||
|
||||
var diff = ediff(from[key], to[key]);
|
||||
if (diff && !diff.empty)
|
||||
ret[key] = Object.values(ediff(v,[]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof v === 'object') {
|
||||
var diff = ediff(v, to[key]);
|
||||
if (diff && !diff.empty)
|
||||
ret[key] = diff;
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof v === 'number') {
|
||||
var a = Number.prec(v);
|
||||
if (!to || a !== to[key])
|
||||
ret[key] = a;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!to || v !== to[key])
|
||||
ret[key] = v;
|
||||
});
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
function diff(from, to) {
|
||||
var obj = {};
|
||||
|
||||
for (var e in to) {
|
||||
if (typeof to[e] === 'object' && from.hasOwnProperty(e)) {
|
||||
obj[e] = diff(from[e], to[e]);
|
||||
if (obj[e].empty)
|
||||
delete obj[e];
|
||||
} else {
|
||||
if (from[e] !== to[e])
|
||||
obj[e] = to[e];
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
if (ret.empty) return undefined;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -421,7 +421,7 @@ var editor = {
|
|||
|
||||
this.selectlist.forEach(function(x) {
|
||||
var sname = x.__proto__.toString();
|
||||
if (!x.json_obj().empty)
|
||||
if (!x.level_obj().empty)
|
||||
x._ed.dirty = true;
|
||||
else
|
||||
x._ed.dirty = false;
|
||||
|
@ -789,12 +789,12 @@ editor.inputs['C-s'] = function() {
|
|||
};
|
||||
|
||||
if (editor.selectlist.length !== 1 || !editor.selectlist[0]._ed.dirty) return;
|
||||
Object.merge(editor.selectlist[0].ur, editor.selectlist[0].level_obj());
|
||||
Object.merge(editor.selectlist[0].__proto__, editor.selectlist[0].level_obj());
|
||||
var path = editor.selectlist[0].ur.toString();
|
||||
path = path.replaceAll('.','/');
|
||||
path = path + "/" + path.name() + ".json";
|
||||
|
||||
IO.slurpwrite(JSON.stringify(editor.selectlist[0].ur,null,1), path);
|
||||
IO.slurpwrite(JSON.stringify(editor.selectlist[0].__proto__,null,1), path);
|
||||
};
|
||||
editor.inputs['C-s'].doc = "Save selected.";
|
||||
|
||||
|
@ -1273,12 +1273,11 @@ var inputpanel = {
|
|||
guibody() {
|
||||
return [
|
||||
Mum.text({str:this.value, color:Color.green}),
|
||||
Mum.button({str:"Submit", action:this.submit})
|
||||
// Mum.button({str:"Submit", action:this.submit})
|
||||
];
|
||||
},
|
||||
|
||||
open(steal) {
|
||||
Log.warn(gameobject.angle);
|
||||
this.on = true;
|
||||
this.value = "";
|
||||
if (steal) {
|
||||
|
|
|
@ -692,6 +692,7 @@ load("scripts/entity.js");
|
|||
var preprimum = {};
|
||||
preprimum.objects = {};
|
||||
preprimum.worldpos = function() { return [0,0]; };
|
||||
preprimum.worldangle = function() { return 0; };
|
||||
preprimum.pos = [0,0];
|
||||
preprimum.angle = 0;
|
||||
var World = gameobject.make(preprimum);
|
||||
|
|
|
@ -81,21 +81,30 @@ var gameobject = {
|
|||
set_body(2,this.body,x);
|
||||
},
|
||||
|
||||
get angle() { return Math.rad2deg(q_body(2,this.body))%360; },
|
||||
worldangle() { return Math.rad2deg(q_body(2,this.body))%360; },
|
||||
get angle() {
|
||||
if (!this.level) return this.worldangle();
|
||||
return this.worldangle() - this.level.worldangle();
|
||||
},
|
||||
set angle(x) {
|
||||
var diff = x - this.angle;
|
||||
var thatpos = this.pos;
|
||||
this.objects.forEach(function(x) {
|
||||
x.angle = x.angle + diff;
|
||||
var pos = x.pos.sub(thatpos);
|
||||
var r = Vector.length(pos);
|
||||
var p = Math.rad2deg(Math.atan2(pos.y, pos.x));
|
||||
x.rotate(diff);
|
||||
// x.angle = x.angle + diff;
|
||||
var opos = x.pos;
|
||||
var r = Vector.length(opos);
|
||||
var p = Math.rad2deg(Math.atan2(opos.y, opos.x));
|
||||
p += diff;
|
||||
p = Math.deg2rad(p);
|
||||
x.set_worldpos(thatpos.add([r*Math.cos(p), r*Math.sin(p)]));
|
||||
x.pos = [r*Math.cos(p), r*Math.sin(p)];
|
||||
}, this);
|
||||
|
||||
set_body(0,this.body, Math.deg2rad(x));
|
||||
set_body(0,this.body, Math.deg2rad(x - this.level.worldangle()));
|
||||
},
|
||||
|
||||
rotate(x) {
|
||||
this.angle = this.angle + x;
|
||||
},
|
||||
|
||||
|
||||
|
@ -164,7 +173,7 @@ var gameobject = {
|
|||
|
||||
/* Make a unique object the same as its prototype */
|
||||
revert() {
|
||||
Object.totalmerge(this,this.__proto__);
|
||||
Object.merge(this,this.__proto__);
|
||||
},
|
||||
|
||||
check_registers(obj) {
|
||||
|
@ -249,52 +258,8 @@ var gameobject = {
|
|||
return bb ? bb : cwh2bb([0,0], [0,0]);
|
||||
},
|
||||
|
||||
diff(from, to) {
|
||||
var ret = {};
|
||||
|
||||
for (var key in from) {
|
||||
if (!Object.hasOwn(from, key) && !Object.isAccessor(from,key)) continue;
|
||||
if (typeof from[key] === 'undefined' || typeof to[key] === 'undefined') continue;
|
||||
if (typeof from[key] === 'function') continue;
|
||||
// if (typeof to === 'object' && !(key in to)) continue;
|
||||
|
||||
if (Array.isArray(from[key])) {
|
||||
if (!Array.isArray(to[key]))
|
||||
ret[key] = Object.values(gameobject.diff(from[key], []));
|
||||
|
||||
if (from[key].length !== to[key].length)
|
||||
ret[key] = Object.values(gameobject.diff(from[key], []));
|
||||
|
||||
var diff = gameobject.diff(from[key], to[key]);
|
||||
if (diff && !diff.empty)
|
||||
ret[key] = Object.values(diff);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof from[key] === 'object') {
|
||||
var diff = gameobject.diff(from[key], to[key]);
|
||||
if (diff && !diff.empty)
|
||||
ret[key] = diff;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof from[key] === 'number') {
|
||||
var a = Number.prec(from[key]);
|
||||
if (a !== to[key])
|
||||
ret[key] = a;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (from[key] !== to[key])
|
||||
ret[key] = from[key];
|
||||
}
|
||||
if (ret.empty) return undefined;
|
||||
return ret;
|
||||
},
|
||||
|
||||
json_obj() {
|
||||
var d = gdiff(this,this.__proto__);
|
||||
var d = ediff(this,this.__proto__);
|
||||
delete d.pos;
|
||||
delete d.angle;
|
||||
delete d.velocity;
|
||||
|
@ -309,7 +274,7 @@ var gameobject = {
|
|||
},
|
||||
|
||||
level_obj() {
|
||||
var json = gdiff(this,this.__proto__);
|
||||
var json = this.json_obj();
|
||||
|
||||
var objects = {};
|
||||
this.__proto__.objects ??= {};
|
||||
|
@ -321,7 +286,7 @@ var gameobject = {
|
|||
} else {
|
||||
for (var o in this.objects) {
|
||||
var obj = this.objects[o].json_obj();
|
||||
Object.assign(obj, gameobject.diff(this.objects[o].transform(), this.__proto__.objects[o]));
|
||||
Object.assign(obj, ediff(this.objects[o].transform(), this.__proto__.objects[o]));
|
||||
if (!obj.empty)
|
||||
objects[o] = obj;
|
||||
}
|
||||
|
@ -414,11 +379,12 @@ var gameobject = {
|
|||
obj.components = {};
|
||||
obj.objects = {};
|
||||
Object.mixin(obj, gameobject.impl);
|
||||
|
||||
Object.hide(obj, 'components');
|
||||
Object.hide(obj, 'objects');
|
||||
obj._ed = {};
|
||||
Object.hide(obj, '_ed');
|
||||
obj.ur = this.toString();
|
||||
Object.hide(obj,'ur');
|
||||
|
||||
Game.register_obj(obj);
|
||||
|
||||
|
@ -440,13 +406,12 @@ var gameobject = {
|
|||
if (this.objects) {
|
||||
for (var prop in this.objects) {
|
||||
var o = this.objects[prop];
|
||||
var newobj = obj.spawn(prototypes.get_ur(o.ur));
|
||||
var newobj = obj.spawn(o.ur);
|
||||
if (!newobj) continue;
|
||||
obj.rename_obj(newobj.toString(), prop);
|
||||
Object.assign(newobj,o);
|
||||
}
|
||||
}
|
||||
|
||||
Object.dainty_assign(obj, this);
|
||||
|
||||
obj.components.forEach(function(x) { if ('sync' in x) x.sync(); });
|
||||
|
@ -467,7 +432,6 @@ var gameobject = {
|
|||
Log.warn(`Already an object with name ${newname}.`);
|
||||
return;
|
||||
}
|
||||
Log.warn(`Renaming from ${name} to ${newname}.`);
|
||||
|
||||
this.objects[newname] = this.objects[name];
|
||||
delete this.objects[name];
|
||||
|
@ -573,15 +537,14 @@ prototypes.from_file = function(file)
|
|||
if (typeof v !== 'object') return;
|
||||
if (!v.comp) return;
|
||||
v.__proto__ = component[v.comp];
|
||||
delete v.comp;
|
||||
});
|
||||
|
||||
newur.__proto__ = upperur;
|
||||
newur.instances = [];
|
||||
Object.hide(newur, 'instances');
|
||||
|
||||
prototypes.list.push(urpath);
|
||||
newur.toString = function() { return urpath; };
|
||||
newur.ur = urpath;
|
||||
ur[urpath] = newur;
|
||||
|
||||
return ur[urpath];
|
||||
|
|
|
@ -390,8 +390,13 @@ void phys2d_polyaddvert(struct phys2d_poly *poly) {
|
|||
|
||||
void phys2d_poly_setverts(struct phys2d_poly *poly, cpVect *verts) {
|
||||
if (!verts) return;
|
||||
if (poly->points)
|
||||
arrfree(poly->points);
|
||||
poly->points = verts;
|
||||
|
||||
arrsetlen(poly->points, arrlen(verts));
|
||||
for (int i = 0; i < arrlen(verts); i++)
|
||||
poly->points[i] = verts[i];
|
||||
|
||||
phys2d_applypoly(poly);
|
||||
}
|
||||
|
||||
|
|
|
@ -229,6 +229,7 @@ cpBitmask js2bitmask(JSValue v) {
|
|||
|
||||
cpVect *cpvecarr = NULL;
|
||||
|
||||
/* Must be freed */
|
||||
cpVect *js2cpvec2arr(JSValue v) {
|
||||
if (cpvecarr)
|
||||
arrfree(cpvecarr);
|
||||
|
|
Loading…
Reference in a new issue