Simplify components in js
This commit is contained in:
parent
eadfd1dc38
commit
33fdd97bdd
1
Makefile
1
Makefile
|
@ -132,6 +132,7 @@ else
|
|||
CXXFLAGS += -std=c++11
|
||||
LDFLAGS += -framework Cocoa -framework QuartzCore -framework AudioToolbox -framework Metal -framework MetalKit
|
||||
INFO :=$(INFO)_macos
|
||||
STEAMAPI := steam_api
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -358,13 +358,6 @@ Object.readonly = function(o, name, msg)
|
|||
Object.defineProperty(o, name, prop);
|
||||
}
|
||||
|
||||
Object.extend = function(from)
|
||||
{
|
||||
var n = {};
|
||||
Object.mixin(n, from);
|
||||
return n;
|
||||
}
|
||||
|
||||
Object.mixin = function(target, source)
|
||||
{
|
||||
if (typeof source !== 'object') return target;
|
||||
|
@ -810,6 +803,13 @@ Object.defineProperty(String.prototype, 'name', {
|
|||
return this.fromlast('/').tolast('.'); }
|
||||
});
|
||||
|
||||
Object.defineProperty(String.prototype, 'set_name', {
|
||||
value: function(name) {
|
||||
var dir = this.dir();
|
||||
return this.dir() + name + "." + this.ext();
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(String.prototype, 'base', {
|
||||
value: function() { return this.fromlast('/'); }
|
||||
});
|
||||
|
@ -1337,16 +1337,19 @@ Math.snap = function(val, grid) {
|
|||
}
|
||||
|
||||
Math.angledist = function (a1, a2) {
|
||||
a1 = Math.turn2deg(a1);
|
||||
a2 = Math.turn2deg(a2);
|
||||
var dist = a2 - a1;
|
||||
var wrap = dist >= 0 ? dist+360 : dist-360;
|
||||
wrap %= 360;
|
||||
a1 = a1%1;
|
||||
a2 = a2%1;
|
||||
var dist = a2 - a1;
|
||||
if (dist == 0) return dist;
|
||||
|
||||
if (dist > 0) {
|
||||
if (dist > 0.5) return dist-1;
|
||||
return dist;
|
||||
}
|
||||
|
||||
if (dist < -0.5) return dist+1;
|
||||
|
||||
if (Math.abs(dist) < Math.abs(wrap))
|
||||
return Math.deg2turn(dist);
|
||||
|
||||
return Math.deg2turn(wrap);
|
||||
return dist;
|
||||
};
|
||||
Math.angledist.doc = "Find the shortest angle between two angles.";
|
||||
Math.TAU = Math.PI*2;
|
||||
|
@ -1544,8 +1547,8 @@ Math.sortpointsccw = function(points)
|
|||
var cm = points2cm(points);
|
||||
var cmpoints = points.map(function(x) { return x.sub(cm); });
|
||||
var ccw = cmpoints.sort(function(a,b) {
|
||||
aatan = Math.atan2(a.y, a.x);
|
||||
batan = Math.atan2(b.y, b.x);
|
||||
var aatan = Math.atan2(a.y, a.x);
|
||||
var batan = Math.atan2(b.y, b.x);
|
||||
return aatan - batan;
|
||||
});
|
||||
|
||||
|
@ -1604,6 +1607,8 @@ yaml.tojson = function(yaml)
|
|||
return yaml;
|
||||
}
|
||||
|
||||
Math.sign = function(n) { return n >= 0 ? 1 : -1; }
|
||||
|
||||
return {
|
||||
convert,
|
||||
time,
|
||||
|
|
|
@ -1,44 +1,4 @@
|
|||
var component = {
|
||||
components: [],
|
||||
toString() {
|
||||
if ('gameobject' in this)
|
||||
return this.name + " on " + this.gameobject;
|
||||
else
|
||||
return this.name;
|
||||
},
|
||||
name: "component",
|
||||
component: true,
|
||||
enabled: true,
|
||||
enable() { this.enabled = true; },
|
||||
disable() { this.enabled = false; },
|
||||
|
||||
isComponent(c) {
|
||||
if (typeof c !== 'object') return false;
|
||||
if (typeof c.toString !== 'function') return false;
|
||||
if (typeof c.make !== 'function') return false;
|
||||
return (typeof component[c.toString()] === 'object');
|
||||
},
|
||||
|
||||
make(go) {
|
||||
var nc = Object.create(this);
|
||||
nc.gameobject = go;
|
||||
Object.mixin(nc, this._enghook(go, nc));
|
||||
assign_impl(nc,this.impl);
|
||||
Object.hide(nc, 'gameobject', 'id');
|
||||
nc.post();
|
||||
nc.make = undefined;
|
||||
return nc;
|
||||
},
|
||||
|
||||
kill() { console.info("Kill not created for this component yet"); },
|
||||
sync(){},
|
||||
post(){},
|
||||
gui(){},
|
||||
gizmo(){},
|
||||
|
||||
finish_center() {},
|
||||
extend(spec) { return Object.copy(this, spec); },
|
||||
};
|
||||
var component = {};
|
||||
|
||||
var make_point_obj = function(o, p)
|
||||
{
|
||||
|
@ -53,41 +13,8 @@ var make_point_obj = function(o, p)
|
|||
}
|
||||
}
|
||||
|
||||
var assign_impl = function(obj, impl)
|
||||
{
|
||||
var tmp = {};
|
||||
for (var key of Object.keys(impl))
|
||||
if (typeof obj[key] !== 'undefined' && typeof obj[key] !== 'function')
|
||||
tmp[key] = obj[key];
|
||||
|
||||
Object.mixin(obj, impl);
|
||||
|
||||
for (var key in tmp)
|
||||
obj[key] = tmp[key];
|
||||
}
|
||||
|
||||
function json_from_whitelist(whitelist)
|
||||
{
|
||||
return function() {
|
||||
var o = {};
|
||||
for (var p of whitelist)
|
||||
o[p] = this[p];
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
var sprite = {
|
||||
loop: true,
|
||||
toJSON:json_from_whitelist([
|
||||
"path",
|
||||
"pos",
|
||||
"scale",
|
||||
"angle",
|
||||
"color",
|
||||
"emissive",
|
||||
"parallax",
|
||||
"frame"
|
||||
]),
|
||||
anim:{},
|
||||
playing: 0,
|
||||
play(str = 0) {
|
||||
|
@ -155,7 +82,6 @@ var sprite = {
|
|||
this.anim_done = undefined;
|
||||
delete allsprites[this.guid];
|
||||
},
|
||||
toString() { return "sprite"; },
|
||||
move(d) { this.pos = this.pos.add(d); },
|
||||
grow(x) {
|
||||
this.scale = this.scale.scale(x);
|
||||
|
@ -181,15 +107,6 @@ var sprite = {
|
|||
height() { return this.dimensions().y; },
|
||||
};
|
||||
globalThis.allsprites = {};
|
||||
sprite.make = function(go)
|
||||
{
|
||||
var sp = Object.create(sprite);
|
||||
sp.go = go;
|
||||
sp.gameobject = go;
|
||||
sp.guid = prosperon.guid();
|
||||
allsprites[sp.guid] = sp;
|
||||
return sp;
|
||||
}
|
||||
|
||||
sprite.doc = {
|
||||
path: "Path to the texture.",
|
||||
|
@ -225,9 +142,18 @@ sprite.inputs.kp3 = function() { this.setanchor("ur"); }
|
|||
sprite.inputs.kp2 = function() { this.setanchor("um"); }
|
||||
sprite.inputs.kp1 = function() { this.setanchor("ul"); }
|
||||
|
||||
component.sprite = sprite;
|
||||
component.sprite = function(obj) {
|
||||
var sp = Object.create(sprite);
|
||||
sp.gameobject = obj;
|
||||
sp.guid = prosperon.guid();
|
||||
allsprites[sp.guid] = sp;
|
||||
return sp;
|
||||
}
|
||||
sprite.shade = [1,1,1,1];
|
||||
|
||||
//Object.seal(sprite);
|
||||
Object.mixin(os.make_seg2d(), {
|
||||
sync() { this.set_endpoints(this.points[0], this.points[1]); }
|
||||
});
|
||||
|
||||
/* sprite anim returns a data structure for the given file path
|
||||
frames: array of frames
|
||||
|
@ -364,18 +290,7 @@ SpriteAnim.strip.doc = 'Given a path and number of frames, converts a horizontal
|
|||
SpriteAnim.aseprite.doc = 'Given an aseprite json metadata, returns an object of animations defined in the aseprite file.';
|
||||
SpriteAnim.find.doc = 'Given a path, find the relevant animation for the file.';
|
||||
|
||||
/* For all colliders, "shape" is a pointer to a phys2d_shape, "id" is a pointer to the shape data */
|
||||
var collider2d = Object.copy(component, {
|
||||
impl: {
|
||||
set sensor(x) { pshape.set_sensor(this.shape,x); },
|
||||
get sensor() { return pshape.get_sensor(this.shape); },
|
||||
set enabled(x) { pshape.set_enabled(this.shape,x); },
|
||||
get enabled() { return pshape.get_enabled(this.shape); }
|
||||
},
|
||||
});
|
||||
|
||||
Object.hide(collider2d.impl, 'enabled');
|
||||
|
||||
var collider2d = {};
|
||||
collider2d.inputs = {};
|
||||
collider2d.inputs['M-s'] = function() { this.sensor = !this.sensor; }
|
||||
collider2d.inputs['M-s'].doc = "Toggle if this collider is a sensor.";
|
||||
|
@ -383,27 +298,11 @@ collider2d.inputs['M-s'].doc = "Toggle if this collider is a sensor.";
|
|||
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, {
|
||||
toJSON:json_from_whitelist([
|
||||
'points',
|
||||
'sensor'
|
||||
]),
|
||||
toString() { return "polygon2d"; },
|
||||
flipx: false,
|
||||
flipy: false,
|
||||
|
||||
Object.mix(os.make_poly2d(), {
|
||||
boundingbox() {
|
||||
return bbox.frompoints(this.spoints());
|
||||
},
|
||||
|
||||
hides: ['id', 'shape', 'gameobject'],
|
||||
_enghook: os.make_poly2d,
|
||||
points:[],
|
||||
setpoints(points) {
|
||||
this.points = points;
|
||||
this.sync();
|
||||
},
|
||||
|
||||
/* EDITOR */
|
||||
spoints() {
|
||||
var spoints = this.points.slice();
|
||||
|
@ -411,7 +310,7 @@ component.polygon2d = Object.copy(collider2d, {
|
|||
if (this.flipx) {
|
||||
spoints.forEach(function(x) {
|
||||
var newpoint = x.slice();
|
||||
newpoint.x = -newpoint.x;
|
||||
newpoint.x = -newpoint.x;
|
||||
spoints.push(newpoint);
|
||||
});
|
||||
}
|
||||
|
@ -419,8 +318,8 @@ component.polygon2d = Object.copy(collider2d, {
|
|||
if (this.flipy) {
|
||||
spoints.forEach(function(x) {
|
||||
var newpoint = x.slice();
|
||||
newpoint.y = -newpoint.y;
|
||||
spoints.push(newpoint);
|
||||
newpoint.y = -newpoint.y;
|
||||
spoints.push(newpoint);
|
||||
});
|
||||
}
|
||||
return spoints;
|
||||
|
@ -449,63 +348,71 @@ function pointscaler(x) {
|
|||
this.points = this.points.map(p => p.mult(x));
|
||||
}
|
||||
|
||||
component.polygon2d.impl = Object.mix(collider2d.impl, {
|
||||
sync() { poly2d.setverts(this.id,this.spoints()); },
|
||||
query() { return physics.shape_query(this.shape); },
|
||||
Object.mixin(os.make_poly2d(), {
|
||||
sync() {
|
||||
this.setverts(this.points);
|
||||
},
|
||||
grow: pointscaler,
|
||||
});
|
||||
|
||||
var polygon2d = component.polygon2d;
|
||||
var polyinputs = Object.create(collider2d.inputs);
|
||||
os.make_poly2d().inputs = polyinputs;
|
||||
|
||||
polygon2d.inputs = {};
|
||||
//polygon2d.inputs.post = function() { this.sync(); };
|
||||
polygon2d.inputs.f10 = function() {
|
||||
polyinputs = {};
|
||||
polyinputs.f10 = function() {
|
||||
this.points = Math.sortpointsccw(this.points);
|
||||
};
|
||||
polygon2d.inputs.f10.doc = "Sort all points to be CCW order.";
|
||||
polyinputs.f10.doc = "Sort all points to be CCW order.";
|
||||
|
||||
polygon2d.inputs['C-lm'] = function() {
|
||||
polyinputs['C-lm'] = function() {
|
||||
this.points.push(this.gameobject.world2this(input.mouse.worldpos()));
|
||||
};
|
||||
polygon2d.inputs['C-lm'].doc = "Add a point to location of mouse.";
|
||||
polygon2d.inputs.lm = function(){};
|
||||
polygon2d.inputs.lm.released = function(){};
|
||||
polyinputs['C-lm'].doc = "Add a point to location of mouse.";
|
||||
polyinputs.lm = function(){};
|
||||
polyinputs.lm.released = function(){};
|
||||
|
||||
polygon2d.inputs['C-M-lm'] = function() {
|
||||
polyinputs['C-M-lm'] = function() {
|
||||
var idx = Math.grab_from_points(input.mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
|
||||
if (idx === -1) return;
|
||||
this.points.splice(idx, 1);
|
||||
};
|
||||
polygon2d.inputs['C-M-lm'].doc = "Remove point under mouse.";
|
||||
polyinputs['C-M-lm'].doc = "Remove point under mouse.";
|
||||
|
||||
polygon2d.inputs['C-b'] = function() {
|
||||
polyinputs['C-b'] = function() {
|
||||
this.points = this.spoints;
|
||||
this.flipx = false;
|
||||
this.flipy = false;
|
||||
};
|
||||
polygon2d.inputs['C-b'].doc = "Freeze mirroring in place.";
|
||||
polyinputs['C-b'].doc = "Freeze mirroring in place.";
|
||||
|
||||
component.edge2d = Object.copy(collider2d, {
|
||||
toJSON:json_from_whitelist([
|
||||
'sensor',
|
||||
'thickness',
|
||||
'points',
|
||||
'hollow',
|
||||
'hollowt',
|
||||
'angle',
|
||||
]),
|
||||
var edge2d = {
|
||||
dimensions:2,
|
||||
thickness:0,
|
||||
thickness:1,
|
||||
/* if type === -1, point to point */
|
||||
type: Spline.type.catmull,
|
||||
C: 1, /* when in bezier, continuity required. 0, 1 or 2. */
|
||||
looped: false,
|
||||
angle: 0.5, /* smaller for smoother bezier */
|
||||
elasticity: 0,
|
||||
friction: 0,
|
||||
sync() {
|
||||
var ppp = this.sample();
|
||||
this.segs ??= [];
|
||||
var count = ppp.length-1;
|
||||
this.segs.length = count;
|
||||
for (var i = 0; i < count; i++) {
|
||||
this.segs[i] ??= os.make_seg2d(this.body);
|
||||
this.segs[i].set_endpoints(ppp[i],ppp[i+1]);
|
||||
this.segs[i].set_neighbors(ppp[i],ppp[i+1]);
|
||||
this.segs[i].radius = this.thickness;
|
||||
this.segs[i].elasticity = this.elasticity;
|
||||
this.segs[i].friction = this.friction;
|
||||
this.segs[i].collide = this.collide;
|
||||
}
|
||||
},
|
||||
|
||||
flipx: false,
|
||||
flipy: false,
|
||||
points:[],
|
||||
toString() { return "edge2d"; },
|
||||
|
||||
hollow: false,
|
||||
hollowt: 0,
|
||||
|
@ -544,14 +451,12 @@ component.edge2d = Object.copy(collider2d, {
|
|||
return arr1.concat(arr2.reverse());
|
||||
}
|
||||
|
||||
if (this.looped)
|
||||
spoints = spoints.wrapped(1);
|
||||
|
||||
return spoints;
|
||||
},
|
||||
|
||||
setpoints(points) {
|
||||
this.points = points;
|
||||
// this.sync();
|
||||
},
|
||||
|
||||
post() {
|
||||
this.points = [];
|
||||
},
|
||||
|
@ -582,9 +487,6 @@ component.edge2d = Object.copy(collider2d, {
|
|||
|
||||
boundingbox() { return bbox.frompoints(this.points.map(x => x.scale(this.gameobject.scale))); },
|
||||
|
||||
hides: ['gameobject', 'id', 'shape'],
|
||||
_enghook: os.make_edge2d,
|
||||
|
||||
/* EDITOR */
|
||||
gizmo() {
|
||||
if (this.type === Spline.type.catmull || this.type === -1) {
|
||||
|
@ -660,12 +562,12 @@ component.edge2d = Object.copy(collider2d, {
|
|||
var idx = 0;
|
||||
if (Spline.is_catmull(this.type) || this.type === -1) {
|
||||
if (this.points.length >= 2)
|
||||
idx = physics.closest_point(pos, this.points, 400);
|
||||
idx = physics.closest_point(pos, this.points, 400);
|
||||
|
||||
if (idx === this.points.length)
|
||||
this.points.push(pos);
|
||||
this.points.push(pos);
|
||||
else
|
||||
this.points.splice(idx, 0, pos);
|
||||
this.points.splice(idx, 0, pos);
|
||||
}
|
||||
|
||||
if (Spline.is_bezier(this.type)) {
|
||||
|
@ -675,11 +577,11 @@ component.edge2d = Object.copy(collider2d, {
|
|||
|
||||
if (idx === 0) {
|
||||
this.points.unshift(pos.slice(), pos.add([-100,0]), Vector.reflect_point(this.points[1], this.points[0]));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if (idx === Spline.bezier_node_count(this.points)) {
|
||||
this.points.push(Vector.reflect_point(this.points.at(-2), this.points.at(-1)), pos.add([-100,0]), pos.slice());
|
||||
return;
|
||||
return;
|
||||
}
|
||||
idx = 2 + (idx-1)*3;
|
||||
var adds = [pos.add([100,0]), pos.slice(), pos.add([-100,0])];
|
||||
|
@ -692,71 +594,64 @@ component.edge2d = Object.copy(collider2d, {
|
|||
this.points.forEach(x =>picks.push(make_point_obj(this,x)));
|
||||
return picks;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
component.edge2d.impl = Object.mix(collider2d.impl, {
|
||||
set thickness(x) { edge2d.set_thickness(this.id,x); },
|
||||
get thickness() { return edge2d.get_thickness(this.id); },
|
||||
grow: pointscaler,
|
||||
sync() {
|
||||
var sensor = this.sensor;
|
||||
var points = this.sample();
|
||||
if (!points) return;
|
||||
edge2d.setverts(this.id,points);
|
||||
this.sensor = sensor;
|
||||
},
|
||||
});
|
||||
component.edge2d = function(obj) {
|
||||
if (!obj.body) obj.rigidify();
|
||||
var edge = Object.create(edge2d);
|
||||
edge.body = obj.body;
|
||||
return edge;
|
||||
}
|
||||
|
||||
var bucket = component.edge2d;
|
||||
bucket.spoints.doc = "Returns the controls points after modifiers are applied, such as it being hollow or mirrored on its axises.";
|
||||
bucket.inputs = {};
|
||||
bucket.inputs.h = function() { this.hollow = !this.hollow; };
|
||||
bucket.inputs.h.doc = "Toggle hollow.";
|
||||
edge2d.spoints.doc = "Returns the controls points after modifiers are applied, such as it being hollow or mirrored on its axises.";
|
||||
edge2d.inputs = {};
|
||||
edge2d.inputs.h = function() { this.hollow = !this.hollow; };
|
||||
edge2d.inputs.h.doc = "Toggle hollow.";
|
||||
|
||||
bucket.inputs['C-g'] = function() { if (this.hollowt > 0) this.hollowt--; };
|
||||
bucket.inputs['C-g'].doc = "Thin the hollow thickness.";
|
||||
bucket.inputs['C-g'].rep = true;
|
||||
edge2d.inputs['C-g'] = function() { if (this.hollowt > 0) this.hollowt--; };
|
||||
edge2d.inputs['C-g'].doc = "Thin the hollow thickness.";
|
||||
edge2d.inputs['C-g'].rep = true;
|
||||
|
||||
bucket.inputs['C-f'] = function() { this.hollowt++; };
|
||||
bucket.inputs['C-f'].doc = "Increase the hollow thickness.";
|
||||
bucket.inputs['C-f'].rep = true;
|
||||
edge2d.inputs['C-f'] = function() { this.hollowt++; };
|
||||
edge2d.inputs['C-f'].doc = "Increase the hollow thickness.";
|
||||
edge2d.inputs['C-f'].rep = true;
|
||||
|
||||
bucket.inputs['M-v'] = function() { if (this.thickness > 0) this.thickness--; };
|
||||
bucket.inputs['M-v'].doc = "Decrease spline thickness.";
|
||||
bucket.inputs['M-v'].rep = true;
|
||||
edge2d.inputs['M-v'] = function() { if (this.thickness > 0) this.thickness--; };
|
||||
edge2d.inputs['M-v'].doc = "Decrease spline thickness.";
|
||||
edge2d.inputs['M-v'].rep = true;
|
||||
|
||||
bucket.inputs['C-y'] = function() {
|
||||
edge2d.inputs['C-y'] = function() {
|
||||
this.points = this.spoints();
|
||||
this.flipx = false;
|
||||
this.flipy = false;
|
||||
this.hollow = false;
|
||||
};
|
||||
bucket.inputs['C-y'].doc = "Freeze mirroring,";
|
||||
bucket.inputs['M-b'] = function() { this.thickness++; };
|
||||
bucket.inputs['M-b'].doc = "Increase spline thickness.";
|
||||
bucket.inputs['M-b'].rep = true;
|
||||
edge2d.inputs['C-y'].doc = "Freeze mirroring,";
|
||||
edge2d.inputs['M-b'] = function() { this.thickness++; };
|
||||
edge2d.inputs['M-b'].doc = "Increase spline thickness.";
|
||||
edge2d.inputs['M-b'].rep = true;
|
||||
|
||||
bucket.inputs.plus = function() {
|
||||
edge2d.inputs.plus = function() {
|
||||
if (this.angle <= 1) {
|
||||
this.angle = 1;
|
||||
return;
|
||||
}
|
||||
this.angle *= 0.9;
|
||||
};
|
||||
bucket.inputs.plus.doc = "Increase the number of samples of this spline.";
|
||||
bucket.inputs.plus.rep = true;
|
||||
edge2d.inputs.plus.doc = "Increase the number of samples of this spline.";
|
||||
edge2d.inputs.plus.rep = true;
|
||||
|
||||
bucket.inputs.minus = function() { this.angle *= 1.1; };
|
||||
bucket.inputs.minus.doc = "Decrease the number of samples on this spline.";
|
||||
bucket.inputs.minus.rep = true;
|
||||
edge2d.inputs.minus = function() { this.angle *= 1.1; };
|
||||
edge2d.inputs.minus.doc = "Decrease the number of samples on this spline.";
|
||||
edge2d.inputs.minus.rep = true;
|
||||
|
||||
bucket.inputs['C-r'] = function() { this.points = this.points.reverse(); };
|
||||
bucket.inputs['C-r'].doc = "Reverse the order of the spline's points.";
|
||||
edge2d.inputs['C-r'] = function() { this.points = this.points.reverse(); };
|
||||
edge2d.inputs['C-r'].doc = "Reverse the order of the spline's points.";
|
||||
|
||||
bucket.inputs['C-l'] = function() { this.looped = !this.looped};
|
||||
bucket.inputs['C-l'].doc = "Toggle spline being looped.";
|
||||
edge2d.inputs['C-l'] = function() { this.looped = !this.looped};
|
||||
edge2d.inputs['C-l'].doc = "Toggle spline being looped.";
|
||||
|
||||
bucket.inputs['C-c'] = function() {
|
||||
edge2d.inputs['C-c'] = function() {
|
||||
switch(this.type) {
|
||||
case Spline.type.bezier:
|
||||
this.points = Spline.bezier2catmull(this.points);
|
||||
|
@ -765,9 +660,9 @@ bucket.inputs['C-c'] = function() {
|
|||
this.type = Spline.type.catmull;
|
||||
};
|
||||
|
||||
bucket.inputs['C-c'].doc = "Set type of spline to catmull-rom.";
|
||||
edge2d.inputs['C-c'].doc = "Set type of spline to catmull-rom.";
|
||||
|
||||
bucket.inputs['C-b'] = function() {
|
||||
edge2d.inputs['C-b'] = function() {
|
||||
switch(this.type) {
|
||||
case Spline.type.catmull:
|
||||
this.points = Spline.catmull2bezier(Spline.catmull_caps(this.points));
|
||||
|
@ -776,10 +671,10 @@ bucket.inputs['C-b'] = function() {
|
|||
this.type = Spline.type.bezier;
|
||||
};
|
||||
|
||||
bucket.inputs['C-o'] = function() { this.type = -1; };
|
||||
bucket.inputs['C-o'].doc = "Set spline to linear.";
|
||||
edge2d.inputs['C-o'] = function() { this.type = -1; };
|
||||
edge2d.inputs['C-o'].doc = "Set spline to linear.";
|
||||
|
||||
bucket.inputs['C-M-lm'] = function() {
|
||||
edge2d.inputs['C-M-lm'] = function() {
|
||||
if (Spline.is_catmull(this.type)) {
|
||||
var idx = Math.grab_from_points(input.mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
|
||||
if (idx === -1) return;
|
||||
|
@ -789,12 +684,12 @@ bucket.inputs['C-M-lm'] = function() {
|
|||
|
||||
this.points = this.points.newfirst(idx);
|
||||
};
|
||||
bucket.inputs['C-M-lm'].doc = "Select the given point as the '0' of this spline.";
|
||||
edge2d.inputs['C-M-lm'].doc = "Select the given point as the '0' of this spline.";
|
||||
|
||||
bucket.inputs['C-lm'] = function() { this.add_node(input.mouse.worldpos()); }
|
||||
bucket.inputs['C-lm'].doc = "Add a point to the spline at the mouse position.";
|
||||
edge2d.inputs['C-lm'] = function() { this.add_node(input.mouse.worldpos()); }
|
||||
edge2d.inputs['C-lm'].doc = "Add a point to the spline at the mouse position.";
|
||||
|
||||
bucket.inputs['C-M-lm'] = function() {
|
||||
edge2d.inputs['C-M-lm'] = function() {
|
||||
var idx = -1;
|
||||
if (Spline.is_catmull(this.type))
|
||||
idx = Math.grab_from_points(input.mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
|
||||
|
@ -806,12 +701,12 @@ bucket.inputs['C-M-lm'] = function() {
|
|||
|
||||
this.rm_node(idx);
|
||||
};
|
||||
bucket.inputs['C-M-lm'].doc = "Remove point from the spline.";
|
||||
edge2d.inputs['C-M-lm'].doc = "Remove point from the spline.";
|
||||
|
||||
bucket.inputs.lm = function(){};
|
||||
bucket.inputs.lm.released = function(){};
|
||||
edge2d.inputs.lm = function(){};
|
||||
edge2d.inputs.lm.released = function(){};
|
||||
|
||||
bucket.inputs.lb = function() {
|
||||
edge2d.inputs.lb = function() {
|
||||
var np = [];
|
||||
|
||||
this.points.forEach(function(c) {
|
||||
|
@ -820,10 +715,10 @@ bucket.inputs.lb = function() {
|
|||
|
||||
this.points = np;
|
||||
};
|
||||
bucket.inputs.lb.doc = "Rotate the points CCW.";
|
||||
bucket.inputs.lb.rep = true;
|
||||
edge2d.inputs.lb.doc = "Rotate the points CCW.";
|
||||
edge2d.inputs.lb.rep = true;
|
||||
|
||||
bucket.inputs.rb = function() {
|
||||
edge2d.inputs.rb = function() {
|
||||
var np = [];
|
||||
|
||||
this.points.forEach(function(c) {
|
||||
|
@ -832,37 +727,27 @@ bucket.inputs.rb = function() {
|
|||
|
||||
this.points = np;
|
||||
};
|
||||
bucket.inputs.rb.doc = "Rotate the points CW.";
|
||||
bucket.inputs.rb.rep = true;
|
||||
edge2d.inputs.rb.doc = "Rotate the points CW.";
|
||||
edge2d.inputs.rb.rep = true;
|
||||
|
||||
component.circle2d = Object.copy(collider2d, {
|
||||
radius:10,
|
||||
offset:[0,0],
|
||||
toString() { return "circle2d"; },
|
||||
|
||||
boundingbox() {
|
||||
return bbox.fromcwh([0,0], [this.radius,this.radius]);
|
||||
},
|
||||
/* CIRCLE */
|
||||
|
||||
hides: ['gameobject', 'id', 'shape', 'scale'],
|
||||
_enghook: os.make_circle2d,
|
||||
});
|
||||
|
||||
component.circle2d.impl = Object.mix({
|
||||
toJSON:json_from_whitelist([
|
||||
"pos",
|
||||
"radius",
|
||||
]),
|
||||
|
||||
set radius(x) { circle2d.set_radius(this.id,x); circle2d.sync(this.id); },
|
||||
get radius() { return circle2d.get_radius(this.id); },
|
||||
function shape_maker(maker) {
|
||||
return function(obj) {
|
||||
if (!obj.body) obj.rigidify();
|
||||
return maker(obj.body);
|
||||
}
|
||||
}
|
||||
component.circle2d = shape_maker(os.make_circle2d);
|
||||
component.poly2d = shape_maker(os.make_poly2d);
|
||||
component.seg2d = shape_maker(os.make_seg2d);
|
||||
|
||||
Object.mix(os.make_circle2d(), {
|
||||
boundingbox() { return bbox.fromcwh(this.offset, [this.radius,this.radius]); },
|
||||
|
||||
set scale(x) { this.radius = x; },
|
||||
get scale() { return this.radius; },
|
||||
|
||||
set offset(x) { circle2d.set_offset(this.id,x); circle2d.sync(this.id); },
|
||||
get offset() { circle2d.get_offset(this.id); },
|
||||
|
||||
get pos() { return this.offset; },
|
||||
set pos(x) { this.offset = x; },
|
||||
|
||||
|
@ -870,7 +755,6 @@ component.circle2d.impl = Object.mix({
|
|||
if (typeof x === 'number') this.scale *= x;
|
||||
else if (typeof x === 'object') this.scale *= x[0];
|
||||
},
|
||||
|
||||
}, collider2d.impl);
|
||||
});
|
||||
|
||||
return {component, SpriteAnim};
|
||||
|
|
|
@ -33,6 +33,11 @@ var entity = {
|
|||
return undefined;
|
||||
},
|
||||
|
||||
rigidify() {
|
||||
this.body = os.make_body(this.transform);
|
||||
},
|
||||
|
||||
|
||||
path_from(o) {
|
||||
var p = this.toString();
|
||||
var c = this.master;
|
||||
|
@ -178,9 +183,8 @@ var entity = {
|
|||
for (var [prop, p] of Object.entries(ent)) {
|
||||
if (!p) continue;
|
||||
if (typeof p !== 'object') continue;
|
||||
if (component.isComponent(p)) continue;
|
||||
if (!p.comp) continue;
|
||||
ent[prop] = component[p.comp].make(ent);
|
||||
ent[prop] = component[p.comp](ent);
|
||||
Object.merge(ent[prop], p);
|
||||
ent.components[prop] = ent[prop];
|
||||
};
|
||||
|
@ -347,9 +351,8 @@ dup(diff) {
|
|||
for (var key in this.components) {
|
||||
this.components[key].kill?.();
|
||||
this.components[key].gameobject = undefined;
|
||||
this[key].enabled = false;
|
||||
this.components[key].enabled = false;
|
||||
delete this.components[key];
|
||||
delete this[key];
|
||||
}
|
||||
delete this.components;
|
||||
|
||||
|
@ -393,15 +396,14 @@ dup(diff) {
|
|||
return this.objects[newname];
|
||||
},
|
||||
|
||||
add_component(comp, data, name = comp.toString()) {
|
||||
if (typeof comp.make !== 'function') return;
|
||||
name = obj_unique_name(name, this);
|
||||
this[name] = comp.make(this);
|
||||
this[name].comp = comp.toString();
|
||||
this.components[name] = this[name];
|
||||
if (data)
|
||||
Object.assign(this[name], data);
|
||||
return this[name];
|
||||
add_component(comp, data) {
|
||||
var name = prosperon.guid();
|
||||
this.components[name] = comp(this);
|
||||
if (data) {
|
||||
Object.assign(this.components[name], data);
|
||||
this.components[name].sync?.();
|
||||
}
|
||||
return this.components[name];
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ JSValue arb2js(cpArbiter *arb)
|
|||
cpShape *shape2;
|
||||
cpArbiterGetShapes(arb, &shape1, &shape2);
|
||||
|
||||
JSValue j = cpShape2js(shape2);
|
||||
JSValue j = *(JSValue*)cpShapeGetUserData(shape2);
|
||||
|
||||
JSValue jg = body2go(body2)->ref;
|
||||
|
||||
|
@ -69,8 +69,8 @@ void register_hit(cpArbiter *arb, gameobject *go, const char *name)
|
|||
|
||||
cpShape *s1, *s2;
|
||||
cpArbiterGetShapes(arb, &s1, &s2);
|
||||
JSValue j1 = cpShape2js(s1);
|
||||
JSValue j2 = cpShape2js(s2);
|
||||
JSValue j1 = *(JSValue*)cpShapeGetUserData(s1);
|
||||
JSValue j2 = *(JSValue*)cpShapeGetUserData(s2);
|
||||
cb = JS_GetPropertyStr(js, j1, name);
|
||||
if (!JS_IsUndefined(cb)) {
|
||||
JSValue jarb = arb2js(arb);
|
||||
|
|
|
@ -32,6 +32,7 @@ void gameobject_apply(gameobject *go) { *go->t = go2t(go); }
|
|||
static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
|
||||
{
|
||||
gameobject *go = body2go(body);
|
||||
gameobject_apply(go);
|
||||
cpVect pos = cpBodyGetPosition(body);
|
||||
HMM_Vec2 g = warp_force((HMM_Vec3){pos.x, pos.y, 0}, go->warp_mask).xy;
|
||||
if (!go) {
|
||||
|
@ -91,9 +92,3 @@ void gameobject_free(gameobject *go) {
|
|||
cpBodyFree(go->body);
|
||||
free(go);
|
||||
}
|
||||
|
||||
void gameobject_setpos(gameobject *go, cpVect vec) {
|
||||
if (!go || !go->body) return;
|
||||
cpBodySetPosition(go->body, vec);
|
||||
// phys2d_reindex_body(go->body);
|
||||
}
|
||||
|
|
|
@ -1324,17 +1324,6 @@ JSC_CCALL(physics_box_query,
|
|||
return ret;
|
||||
)
|
||||
|
||||
static void shape_query_fn(cpShape *shape, cpContactPointSet *points, JSValue *cb)
|
||||
{
|
||||
JSValue go = JS_DupValue(js,shape2go(shape)->ref);
|
||||
script_call_sym(*cb, 1, &go);
|
||||
JS_FreeValue(js, go);
|
||||
}
|
||||
|
||||
JSC_CCALL(physics_shape_query,
|
||||
//cpSpaceShapeQuery(space, ((struct phys2d_shape*)js2ptr(argv[0]))->shape, shape_query_fn, &argv[1]);
|
||||
)
|
||||
|
||||
static void ray_query_fn(cpShape *shape, float t, cpVect n, float a, JSValue *cb)
|
||||
{
|
||||
JSValue argv[3] = {
|
||||
|
@ -1429,7 +1418,6 @@ static const JSCFunctionListEntry js_physics_funcs[] = {
|
|||
MIST_FUNC_DEF(physics, point_query_nearest, 2),
|
||||
MIST_FUNC_DEF(physics, ray_query, 4),
|
||||
MIST_FUNC_DEF(physics, box_query, 2),
|
||||
MIST_FUNC_DEF(physics, shape_query, 1),
|
||||
MIST_FUNC_DEF(physics, closest_point, 3),
|
||||
MIST_FUNC_DEF(physics, make_damp, 0),
|
||||
MIST_FUNC_DEF(physics, make_gravity, 0),
|
||||
|
@ -1591,7 +1579,6 @@ JSC_GETSET(gameobject, warp_mask, bitmask)
|
|||
JSC_CCALL(gameobject_sleeping, return boolean2js(cpBodyIsSleeping(js2gameobject(self)->body)))
|
||||
JSC_CCALL(gameobject_sleep, cpBodySleep(js2gameobject(self)->body))
|
||||
JSC_CCALL(gameobject_wake, cpBodyActivate(js2gameobject(self)->body))
|
||||
JSC_CCALL(gameobject_selfsync, gameobject_apply(js2gameobject(self)))
|
||||
|
||||
void body_shape_fn(cpBody *body, cpShape *shape, JSValue *fn) {
|
||||
JSValue v = *(JSValue*)cpShapeGetUserData(shape);
|
||||
|
@ -1600,8 +1587,7 @@ void body_shape_fn(cpBody *body, cpShape *shape, JSValue *fn) {
|
|||
|
||||
JSC_CCALL(gameobject_eachshape,
|
||||
gameobject *g = js2gameobject(self);
|
||||
JSValue fn = argv[0];
|
||||
cpBodyEachShape(g->body, body_shape_fn, &fn);
|
||||
cpBodyEachShape(g->body, body_shape_fn, &argv[0]);
|
||||
)
|
||||
|
||||
void body_constraint_fn(cpBody *body, cpConstraint *c, JSValue *fn) {
|
||||
|
@ -1648,7 +1634,6 @@ static const JSCFunctionListEntry js_gameobject_funcs[] = {
|
|||
MIST_FUNC_DEF(gameobject, impulse, 1),
|
||||
MIST_FUNC_DEF(gameobject, force, 1),
|
||||
MIST_FUNC_DEF(gameobject, force_local, 2),
|
||||
MIST_FUNC_DEF(gameobject, selfsync, 0),
|
||||
MIST_FUNC_DEF(gameobject, eachshape, 1),
|
||||
MIST_FUNC_DEF(gameobject, eachconstraint, 1),
|
||||
MIST_FUNC_DEF(gameobject, eacharbiter, 1),
|
||||
|
@ -2096,7 +2081,7 @@ JSC_CCALL(os_reindex_static, cpSpaceReindexStatic(space));
|
|||
JSC_CCALL(os_gc, script_gc());
|
||||
JSC_SSCALL(os_eval, ret = script_eval(str, str2))
|
||||
|
||||
JSC_CCALL(os_make_gameobject,
|
||||
JSC_CCALL(os_make_body,
|
||||
gameobject *g = MakeGameobject();
|
||||
g->t = js2transform(argv[0]);
|
||||
ret = gameobject2js(g);
|
||||
|
@ -2146,6 +2131,16 @@ JSC_CCALL(cpShape_body,
|
|||
return JS_DupValue(js,gameobject2js(go));
|
||||
)
|
||||
|
||||
static void shape_query_fn(cpShape *shape, cpContactPointSet *points, JSValue *cb)
|
||||
{
|
||||
JSValue v = *(JSValue*)cpShapeGetUserData(shape);
|
||||
script_call_sym(*cb, 1, &v);
|
||||
}
|
||||
|
||||
JSC_CCALL(cpShape_query,
|
||||
cpSpaceShapeQuery(space, js2cpShape(self), shape_query_fn, &argv[0]);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_cpShape_funcs[] = {
|
||||
CGETSET_ADD(cpShape, sensor),
|
||||
CGETSET_ADD(cpShape, friction),
|
||||
|
@ -2156,6 +2151,7 @@ static const JSCFunctionListEntry js_cpShape_funcs[] = {
|
|||
CGETSET_ADD(cpShape, mass),
|
||||
MIST_FUNC_DEF(cpShape, area, 0),
|
||||
MIST_FUNC_DEF(cpShape, body, 0),
|
||||
MIST_FUNC_DEF(cpShape, query, 1),
|
||||
};
|
||||
|
||||
JSValue js_circle2d_set_radius(JSContext *js, JSValue self, JSValue val) {
|
||||
|
@ -2203,15 +2199,16 @@ JSC_CCALL(os_make_circle2d,
|
|||
JSC_CCALL(poly2d_setverts,
|
||||
cpShape *s = js2cpShape(self);
|
||||
HMM_Vec2 *v = js2cpvec2arr(argv[0]);
|
||||
gameobject *go = shape2go(s);
|
||||
cpTransform t = {0};
|
||||
t.a = 1;
|
||||
t.a = go->t->scale.x;
|
||||
t.b = 0;
|
||||
t.tx = 0;
|
||||
t.c = 0;
|
||||
t.d = 1;
|
||||
t.d = go->t->scale.y;
|
||||
t.ty = 0;
|
||||
cpPolyShapeSetVerts(s, arrlen(v), v, t);
|
||||
arrfree(v);
|
||||
arrfree(v);
|
||||
)
|
||||
|
||||
JSValue js_poly2d_set_radius(JSContext *js, JSValue self, JSValue val) {
|
||||
|
@ -2235,9 +2232,8 @@ JSC_CCALL(os_make_poly2d,
|
|||
)
|
||||
|
||||
JSC_CCALL(seg2d_set_endpoints,
|
||||
HMM_Vec2 a = js2vec2(argv[0]);
|
||||
HMM_Vec2 b = js2vec2(argv[1]);
|
||||
cpSegmentShapeSetEndpoints(js2cpShape(self), a.cp, b.cp);
|
||||
cpSegmentShapeSetEndpoints(js2cpShape(self), js2vec2(argv[0]).cp, js2vec2(argv[1]).cp);
|
||||
cpSpaceReindexShape(space, js2cpShape(self));
|
||||
)
|
||||
|
||||
JSValue js_seg2d_set_radius(JSContext *js, JSValue self, JSValue val) {
|
||||
|
@ -2252,10 +2248,15 @@ JSC_CCALL(seg2d_set_neighbors,
|
|||
cpSegmentShapeSetNeighbors(js2cpShape(self), prev.cp, next.cp);
|
||||
)
|
||||
|
||||
JSC_CCALL(seg2d_a, return cvec22js(cpSegmentShapeGetA(js2cpShape(self))))
|
||||
JSC_CCALL(seg2d_b, return cvec22js(cpSegmentShapeGetB(js2cpShape(self))))
|
||||
|
||||
static const JSCFunctionListEntry js_seg2d_funcs[] = {
|
||||
MIST_FUNC_DEF(seg2d, set_endpoints, 2),
|
||||
CGETSET_ADD(seg2d, radius),
|
||||
MIST_FUNC_DEF(seg2d, set_neighbors, 2)
|
||||
MIST_FUNC_DEF(seg2d, set_neighbors, 2),
|
||||
MIST_FUNC_DEF(seg2d, a, 0),
|
||||
MIST_FUNC_DEF(seg2d, b, 0),
|
||||
};
|
||||
|
||||
JSC_CCALL(os_make_seg2d,
|
||||
|
@ -2496,7 +2497,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
|||
MIST_FUNC_DEF(os, reindex_static, 0),
|
||||
MIST_FUNC_DEF(os, gc, 0),
|
||||
MIST_FUNC_DEF(os, eval, 2),
|
||||
MIST_FUNC_DEF(os, make_gameobject, 1),
|
||||
MIST_FUNC_DEF(os, make_body, 1),
|
||||
MIST_FUNC_DEF(os, make_circle2d, 2),
|
||||
MIST_FUNC_DEF(os, make_poly2d, 2),
|
||||
MIST_FUNC_DEF(os, make_seg2d, 1),
|
||||
|
|
|
@ -98,7 +98,10 @@ static JSClassDef js_##TYPE##_class = {\
|
|||
#TYPE,\
|
||||
.finalizer = js_##TYPE##_finalizer,\
|
||||
};\
|
||||
TYPE *js2##TYPE (JSValue val) { return JS_GetOpaque(val,js_##TYPE##_id); }\
|
||||
TYPE *js2##TYPE (JSValue val) { \
|
||||
assert(JS_GetClassID(val) == js_##TYPE##_id); \
|
||||
return JS_GetOpaque(val,js_##TYPE##_id); \
|
||||
}\
|
||||
JSValue TYPE##2js(TYPE *n) { \
|
||||
JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\
|
||||
YughSpam("Created " #TYPE " at %p", n); \
|
||||
|
|
Loading…
Reference in a new issue