easier saving

This commit is contained in:
John Alanbrook 2023-10-05 22:30:17 +00:00
parent 03f209ddef
commit 272719736c
9 changed files with 129 additions and 150 deletions

View file

@ -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); };

View file

@ -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;

View file

@ -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,

View file

@ -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;
}

View file

@ -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) {

View file

@ -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);

View file

@ -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];

View file

@ -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);
}

View file

@ -229,6 +229,7 @@ cpBitmask js2bitmask(JSValue v) {
cpVect *cpvecarr = NULL;
/* Must be freed */
cpVect *js2cpvec2arr(JSValue v) {
if (cpvecarr)
arrfree(cpvecarr);