Compare commits

...

4 commits

19 changed files with 339 additions and 659 deletions

View file

@ -8,16 +8,4 @@ this.right = function() { return this.pos.x + (window.rendersize.x/2); }
this.left = function() { return this.pos.x - (window.rendersize.x/2); } this.left = function() { return this.pos.x - (window.rendersize.x/2); }
this.mixin({ this.zoom = 1;
get zoom() {
// var z = game.native.y / window.dimensions.y;
return render.get_zoom(); // /z
},
set zoom(x) {
x = Math.clamp(x,0.1,10);
// var z = game.native.y / window.dimensions.y;
// z *= x;
render.add_zoom(x);
},
});

View file

@ -22,7 +22,7 @@ var component = {
make(go) { make(go) {
var nc = Object.create(this); var nc = Object.create(this);
nc.gameobject = go; nc.gameobject = go;
Object.mixin(nc, this._enghook(go.body)); Object.mixin(nc, this._enghook(go));
assign_impl(nc,this.impl); assign_impl(nc,this.impl);
Object.hide(nc, 'gameobject', 'id'); Object.hide(nc, 'gameobject', 'id');
nc.post(); nc.post();
@ -152,7 +152,7 @@ Object.mixin(os.sprite(true), {
os.sprite(true).make = function(go) os.sprite(true).make = function(go)
{ {
var sp = os.sprite(); var sp = os.sprite();
sp.go = go.body; sp.go = go;
sp.gameobject = go; sp.gameobject = go;
return sp; return sp;
} }
@ -477,7 +477,7 @@ component.edge2d = Object.copy(collider2d, {
} }
if (this.hollow) { if (this.hollow) {
var hpoints = inflate_cpv(spoints, spoints.length, this.hollowt); var hpoints = vector.inflate(spoints, this.hollowt);
if (hpoints.length === spoints.length) return spoints; if (hpoints.length === spoints.length) return spoints;
var arr1 = hpoints.filter(function(x,i) { return i % 2 === 0; }); var arr1 = hpoints.filter(function(x,i) { return i % 2 === 0; });
var arr2 = hpoints.filter(function(x,i) { return i % 2 !== 0; }); var arr2 = hpoints.filter(function(x,i) { return i % 2 !== 0; });

View file

@ -14,7 +14,7 @@ debug.draw_bb = false;
debug.draw_gizmos = false; debug.draw_gizmos = false;
debug.draw_names = false; debug.draw_names = false;
debug.draw = function() { debug.draw = function() {
if (this.draw_phys) game.all_objects(function(x) { debug.draw_gameobject(x.body); }); if (this.draw_phys) game.all_objects(function(x) { debug.draw_gameobject(x); });
if (this.draw_bb) if (this.draw_bb)
game.all_objects(function(x) { debug.boundingbox(x.boundingbox(), Color.debug.boundingbox.alpha(0.05)); }); game.all_objects(function(x) { debug.boundingbox(x.boundingbox(), Color.debug.boundingbox.alpha(0.05)); });

View file

@ -31,8 +31,6 @@ var editor = {
get_this() { return this.edit_level; }, get_this() { return this.edit_level; },
get_that() { return this.selectlist.length === 1 ? this.selectlist[0] : this.get_this(); },
try_select() { /* nullify true if it should set selected to null if it doesn't find an object */ try_select() { /* nullify true if it should set selected to null if it doesn't find an object */
var go = physics.pos_query(Mouse.worldpos()); var go = physics.pos_query(Mouse.worldpos());
return this.do_select(go); return this.do_select(go);
@ -237,11 +235,7 @@ var editor = {
this.selectlist = []; this.selectlist = [];
editor.camera = world.spawn("scripts/camera2d.jso"); editor.camera = world.spawn("scripts/camera2d.jso");
editor.camera._ed.selectable = false; editor.camera._ed.selectable = false;
game.view_camera(editor.camera); game.camera = editor.camera;
},
end_debug() {
}, },
openpanel(panel) { openpanel(panel) {

View file

@ -58,8 +58,6 @@ console.doc = {
clear: "Clear console." clear: "Clear console."
}; };
console.stdout_lvl = 1;
globalThis.global = globalThis; globalThis.global = globalThis;
function use(file) function use(file)
@ -70,7 +68,7 @@ function use(file)
var c = io.slurp(file); var c = io.slurp(file);
var script = `(function() { ${c} })();`; var script = `(function() { ${c} })();`;
use.files[file] = os.eval_env(file,global,script); use.files[file] = os.eval_env(file,script,global);
return use.files[file]; return use.files[file];
} }
@ -90,7 +88,7 @@ function eval_env(script, env, file)
file ??= "SCRIPT"; file ??= "SCRIPT";
console.spam(`eval ${file}`); console.spam(`eval ${file}`);
script = `(function() { ${script}; }).call(this);\n`; script = `(function() { ${script}; }).call(this);\n`;
return os.eval_env(file,env,script); return os.eval_env(file,script,env);
} }
global.check_registers = function(obj) global.check_registers = function(obj)
@ -102,10 +100,10 @@ global.check_registers = function(obj)
obj.timers.push(Register.physupdate.register(obj.physupdate.bind(obj))); obj.timers.push(Register.physupdate.register(obj.physupdate.bind(obj)));
if (typeof obj.collide === 'function') if (typeof obj.collide === 'function')
physics.collide_begin(obj.collide.bind(obj), obj.body); physics.collide_begin(obj.collide.bind(obj), obj);
if (typeof obj.separate === 'function') if (typeof obj.separate === 'function')
physics.collide_separate(obj.separate.bind(obj), obj.body); physics.collide_separate(obj.separate.bind(obj), obj);
if (typeof obj.draw === 'function') if (typeof obj.draw === 'function')
obj.timers.push(Register.draw.register(obj.draw.bind(obj), obj)); obj.timers.push(Register.draw.register(obj.draw.bind(obj), obj));
@ -147,8 +145,7 @@ global.mixin("scripts/render.js");
global.mixin("scripts/debug.js"); global.mixin("scripts/debug.js");
var frame_t = profile.secs(profile.now()); var frame_t = profile.secs(profile.now());
var updateMS = 1/60; var phys_step = 1/60;
var physMS = 1/60;
var sim = { var sim = {
mode: "play", mode: "play",
@ -185,13 +182,16 @@ function process()
physlag += dt; physlag += dt;
while (physlag > physMS) { while (physlag > phys_step) {
physlag -= physMS; physlag -= phys_step;
prosperon.phys2d_step(physMS*timescale); prosperon.phys2d_step(phys_step*timescale);
prosperon.physupdate(physMS*timescale); prosperon.physupdate(phys_step*timescale);
} }
prosperon.window_render(); if (!game.camera)
prosperon.window_render(world, 1);
else
prosperon.window_render(game.camera, game.camera.zoom);
render.sprites(); render.sprites();
render.models(); render.models();
render.emitters(); render.emitters();
@ -224,7 +224,6 @@ game.doc.stop = "Stop game simulation. This does the same thing as 'pause', and
game.doc.play = "Resume or start game simulation."; game.doc.play = "Resume or start game simulation.";
game.doc.editor_mode = "Set to true for the game to only update on input; otherwise the game updates every frame."; game.doc.editor_mode = "Set to true for the game to only update on input; otherwise the game updates every frame.";
game.doc.dt = "Current frame dt."; game.doc.dt = "Current frame dt.";
game.doc.view_camera = "Set the camera for the current view.";
game.doc.camera = "Current camera."; game.doc.camera = "Current camera.";
prosperon.semver = {}; prosperon.semver = {};
@ -429,37 +428,18 @@ global.mixin("scripts/actor.js");
global.mixin("scripts/entity.js"); global.mixin("scripts/entity.js");
function world_start() { function world_start() {
gameobject.body = os.make_gameobject(); globalThis.world = os.make_gameobject();
gameobject.body.setref(gameobject); world.setref(world);
console.info("START WORLD");
globalThis.world = Object.create(gameobject);
gameobject.level = world;
world.objects = {}; world.objects = {};
world.check_dirty = function() {};
world.namestr = function(){};
world._ed = {
selectable:false,
dirty:false,
};
world.toString = function() { return "world"; }; world.toString = function() { return "world"; };
world.master = gameobject;
world.ur = "world"; world.ur = "world";
world.kill = function() { this.clear(); }; world.kill = function() { this.clear(); };
world.phys = 2; world.phys = 2;
world.zoom = 1;
Object.hide(gameobject, 'timescale'); game.cam = world;
var cam = world.spawn("scripts/camera2d.jso");
game.view_camera(cam);
} }
global.mixin("scripts/physics.js"); global.mixin("scripts/physics.js");
game.view_camera = function(cam)
{
game.camera = cam;
render.cam_body(game.camera.body);
}
window.title = `Prosperon v${prosperon.version}`; window.title = `Prosperon v${prosperon.version}`;
window.size = [500,500]; window.size = [500,500];

View file

@ -13,12 +13,12 @@ function obj_unique_name(name, obj) {
var gameobject_impl = { var gameobject_impl = {
get pos() { get pos() {
assert(this.master, `Entity ${this.toString()} has no master.`); assert(this.master, `Entity ${this.toString()} has no master.`);
return this.master.body.world2this(this.worldpos()); return this.master.world2this(this.worldpos());
}, },
set pos(x) { set pos(x) {
assert(this.master, `Entity ${this.toString()} has no master.`); assert(this.master, `Entity ${this.toString()} has no master.`);
this.set_worldpos(this.master.body.this2world(x)); this.set_worldpos(this.master.this2world(x));
}, },
get angle() { get angle() {
@ -56,47 +56,6 @@ var gameobject_impl = {
obj.pos = obj.pos.map((x, i) => x * pct[i]); obj.pos = obj.pos.map((x, i) => x * pct[i]);
}); });
}, },
get draw_layer() { return this.body.drawlayer; },
set draw_layer(x) { this.body.drawlayer = x; },
set layer(x) { this.body.layer = x; },
get layer() { return this.body.layer; },
set warp_layer(x) { this.body.warp_filter = x; },
get warp_layer() { return this.body.warp_filter; },
set mass(x) { this.body.mass = x; },
get mass() {
if (!(this.phys === physics.dynamic))
return undefined;
return this.body.mass;
},
get elasticity() { return this.body.e; },
set elasticity(x) { this.body.e = x; },
get friction() { return this.body.f; },
set friction(x) { this.body.f = x; },
set timescale(x) { this.body.timescale = x; },
get timescale() { return this.body.timescale; },
set phys(x) { this.body.phys = x; },
get phys() { return this.body.phys; },
get velocity() { return this.body.velocity; },
set velocity(x) { this.body.velocity = x; },
get damping() { return this.body.damping; },
set damping(x) { this.body.damping = x },
get angularvelocity() { return Math.rad2turn(this.body.angularvelocity); },
set angularvelocity(x) { this.body.angularvelocity = Math.turn2rad(x); },
get max_velocity() { return this.body.maxvelocity; },
set max_velocity(x) { this.body.maxvelocity = x; },
get max_angularvelocity() { return this.body.maxangularvelocity; },
set max_angularvelocity(x) { this.body.maxangularvelocity = x; },
get_moi() { return this.body.moi; },
set_moi(x) {
if (x <= 0) {
console.error("Cannot set moment of inertia to 0 or less.");
return;
}
this.body.moi = x;
},
}; };
var gameobject = { var gameobject = {
@ -108,6 +67,7 @@ var gameobject = {
if (comps.length) return comps; if (comps.length) return comps;
return undefined; return undefined;
}, },
check_dirty() { check_dirty() {
this._ed.urdiff = this.json_obj(); this._ed.urdiff = this.json_obj();
this._ed.dirty = !Object.empty(this._ed.urdiff); this._ed.dirty = !Object.empty(this._ed.urdiff);
@ -121,6 +81,7 @@ var gameobject = {
else else
this._ed.inst = false; this._ed.inst = false;
}, },
_ed: { _ed: {
selectable: false, selectable: false,
dirty: false dirty: false
@ -144,32 +105,32 @@ var gameobject = {
}, },
/* pin this object to the to object */ /* pin this object to the to object */
pin(to) { pin(to) {
var p = joint.pin(this.body,to.body); var p = joint.pin(this,to);
}, },
slide(to, a, b, min, max) { slide(to, a, b, min, max) {
a ??= [0, 0]; a ??= [0, 0];
b ??= [0, 0]; b ??= [0, 0];
min ??= 0; min ??= 0;
max ??= 50; max ??= 50;
var p = joint.slide(this.body, to.body, a, b, min, max); var p = joint.slide(this, to, a, b, min, max);
p.max_force = 500; p.max_force = 500;
p.break(); p.break();
}, },
pivot(to, piv) { pivot(to, piv) {
piv ??= this.worldpos(); piv ??= this.worldpos();
var p = joint.pivot(this.body, to.body, piv); var p = joint.pivot(this, to, piv);
}, },
/* groove is on to, from local points a and b, anchored to this at local anchor */ /* groove is on to, from local points a and b, anchored to this at local anchor */
groove(to, a, b, anchor) { groove(to, a, b, anchor) {
anchor ??= [0, 0]; anchor ??= [0, 0];
var p = joint.groove(to.body, this.body, a, b, anchor); var p = joint.groove(to, this, a, b, anchor);
}, },
damped_spring(to, length, stiffness, damping) { damped_spring(to, length, stiffness, damping) {
length ??= Vector.length(this.worldpos(), to.worldpos()); length ??= Vector.length(this.worldpos(), to.worldpos());
stiffness ??= 1; stiffness ??= 1;
damping ??= 1; damping ??= 1;
var dc = 2 * Math.sqrt(stiffness * this.mass); var dc = 2 * Math.sqrt(stiffness * this.mass);
var p = joint.damped_spring(this.body, to.body, [0, 0], [0, 0], stiffness, damping * dc); var p = joint.damped_spring(this, to, [0, 0], [0, 0], stiffness, damping * dc);
}, },
damped_rotary_spring(to, angle, stiffness, damping) { damped_rotary_spring(to, angle, stiffness, damping) {
angle ??= 0; angle ??= 0;
@ -179,23 +140,23 @@ var gameobject = {
/* damping = 1 is critical */ /* damping = 1 is critical */
var dc = 2 * Math.sqrt(stiffness * this.get_moi()); /* critical damping number */ var dc = 2 * Math.sqrt(stiffness * this.get_moi()); /* critical damping number */
/* zeta = actual/critical */ /* zeta = actual/critical */
var p = joint.damped_rotary(this.body, to.body, angle, stiffness, damping * dc); var p = joint.damped_rotary(this, to, angle, stiffness, damping * dc);
}, },
rotary_limit(to, min, max) { rotary_limit(to, min, max) {
var p = joint.rotary(this.body, to.body, Math.turn2rad(min), Math.turn2rad(max)); var p = joint.rotary(this, to, Math.turn2rad(min), Math.turn2rad(max));
}, },
ratchet(to, ratch) { ratchet(to, ratch) {
var phase = this.angle - to.angle; var phase = this.angle - to.angle;
var p = joint.ratchet(this.body, to.body, phase, Math.turn2rad(ratch)); var p = joint.ratchet(this, to, phase, Math.turn2rad(ratch));
}, },
gear(to, ratio) { gear(to, ratio) {
phase ??= 1; phase ??= 1;
ratio ??= 1; ratio ??= 1;
var phase = this.angle - to.angle; var phase = this.angle - to.angle;
var p = joint.gear(this.body, to.body, phase, ratio); var p = joint.gear(this, to, phase, ratio);
}, },
motor(to, rate) { motor(to, rate) {
var p = joint.motor(this.body, to.body, rate); var p = joint.motor(this, to, rate);
}, },
path_from(o) { path_from(o) {
@ -254,15 +215,12 @@ var gameobject = {
return killfn; return killfn;
}, },
set torque(x) { if (!(x >= 0 && x <= Infinity)) return; gscale() { return this.scale; },
this.body.torque = x; },
gscale() { return this.body.scale; },
sgscale(x) { sgscale(x) {
if (typeof x === 'number') if (typeof x === 'number')
x = [x, x]; x = [x, x];
physics.sgscale(this.body, x) physics.sgscale(this, x)
}, },
phys_material() { phys_material() {
@ -272,21 +230,18 @@ var gameobject = {
return mat; return mat;
}, },
worldpos() { return this.body.pos; }, worldpos() { return this.pos; },
set_worldpos(x) { set_worldpos(x) {
var poses = this.objects.map(x => x.pos); var poses = this.objects.map(x => x.pos);
this.body.pos = x; this.pos = x;
this.objects.forEach((o, i) => o.set_worldpos(this.this2world(poses[i]))); this.objects.forEach((o, i) => o.set_worldpos(this.this2world(poses[i])));
}, },
screenpos() { return window.world2screen(this.worldpos()); }, screenpos() { return window.world2screen(this.worldpos()); },
worldangle() { return Math.rad2turn(this.body.angle); }, worldangle() { return Math.rad2turn(this.angle); },
sworldangle(x) { this.body.angle = Math.turn2rad(x); }, sworldangle(x) { this.angle = Math.turn2rad(x); },
get_ur() { get_ur() { return Object.access(ur, this.ur); },
// if (this.ur === 'empty') return undefined;
return Object.access(ur, this.ur);
},
/* spawn an entity /* spawn an entity
text can be: text can be:
@ -295,7 +250,7 @@ var gameobject = {
nothing nothing
*/ */
spawn(text) { spawn(text) {
var ent = Object.create(gameobject); var ent = os.make_gameobject();
if (typeof text === 'object') if (typeof text === 'object')
text = text.name; text = text.name;
@ -318,10 +273,7 @@ var gameobject = {
console.info(`Creating entity of type ${ent.ur}`); console.info(`Creating entity of type ${ent.ur}`);
Object.mixin(ent, gameobject_impl);
ent.body = os.make_gameobject();
ent.warp_layer = [true]; ent.warp_layer = [true];
ent.phys = 2;
ent.components = {}; ent.components = {};
ent.objects = {}; ent.objects = {};
ent.timers = []; ent.timers = [];
@ -335,9 +287,9 @@ var gameobject = {
urdiff: {}, urdiff: {},
}; };
ent.body.setref(ent); // set the internal obj reference to this obj ent.setref(ent);
Object.hide(ent, 'ur', 'body', 'components', 'objects', '_ed', 'timers', 'master'); Object.hide(ent, 'ur', 'components', 'objects', '_ed', 'timers', 'master');
if (ent.ur === 'empty') { if (ent.ur === 'empty') {
if (!ur.empty.proto) ur.empty.proto = json.decode(json.encode(ent)); if (!ur.empty.proto) ur.empty.proto = json.decode(json.encode(ent));
return ent; return ent;
@ -361,10 +313,9 @@ var gameobject = {
check_registers(ent); check_registers(ent);
ent.components.forEach(function(x) { ent.components.forEach(function(x) {
if (typeof x.collide === 'function') if (typeof x.collide === 'function')
physics.collide_shape(x.collide.bind(x), ent.body, x.shape); physics.collide_shape(x.collide.bind(x), ent, x.shape);
}); });
if (typeof ent.load === 'function') ent.load(); if (typeof ent.load === 'function') ent.load();
if (sim.playing()) if (sim.playing())
if (typeof ent.start === 'function') ent.start(); if (typeof ent.start === 'function') ent.start();
@ -387,8 +338,6 @@ var gameobject = {
} }
} }
this.body.phys = this.body.phys; // simple way to sync
return ent; return ent;
}, },
@ -436,17 +385,14 @@ var gameobject = {
objects: {}, objects: {},
master: undefined, master: undefined,
pulse(vec) { this.body.impulse(vec); },
shove(vec) { this.body.force(vec); },
shove_at(vec, at) { this.body.force_local(vec,at); },
this2screen(pos) { return window.world2screen(this.this2world(pos)); }, this2screen(pos) { return window.world2screen(this.this2world(pos)); },
screen2this(pos) { return this.world2this(window.screen2world(pos)); }, screen2this(pos) { return this.world2this(window.screen2world(pos)); },
alive() { return this.body >= 0; }, in_air() { return this.in_air(); },
in_air() { return this.body.in_air(); },
hide() { this.components.forEach(x => x.hide?.()); hide() { this.components.forEach(x => x.hide?.());
this.objects.forEach(x => x.hide?.()); }, this.objects.forEach(x => x.hide?.()); },
show() { this.components.forEach(function(x) { x.show?.(); }); show() { this.components.forEach(function(x) { x.show?.(); });
this.objects.forEach(function(x) { x.show?.(); }); }, this.objects.forEach(function(x) { x.show?.(); }); },
@ -484,20 +430,10 @@ var gameobject = {
flipx() { return this.scale.x < 0; }, flipx() { return this.scale.x < 0; },
flipy() { return this.scale.y < 0; }, flipy() { return this.scale.y < 0; },
mirror(plane) { mirror(plane) { this.scale = Vector.reflect(this.scale, plane); },
this.scale = Vector.reflect(this.scale, plane);
},
save: true,
selectable: true,
ed_locked: false,
disable() { this.components.forEach(function(x) { x.disable(); }); }, disable() { this.components.forEach(function(x) { x.disable(); }); },
enable() { this.components.forEach(function(x) { x.enable(); }); }, enable() { this.components.forEach(function(x) { x.enable(); }); },
sync() {
this.components.forEach(function(x) { x.sync?.(); });
this.objects.forEach(function(x) { x.sync?.(); });
},
/* Bounding box of the object in world dimensions */ /* Bounding box of the object in world dimensions */
boundingbox() { boundingbox() {
@ -603,7 +539,7 @@ var gameobject = {
this.timers = []; this.timers = [];
Event.rm_obj(this); Event.rm_obj(this);
Player.do_uncontrol(this); Player.do_uncontrol(this);
physics.collide_rm(this.body); physics.collide_rm(this);
if (this.master) { if (this.master) {
this.master.remove_obj(this); this.master.remove_obj(this);
@ -679,7 +615,16 @@ var gameobject = {
this.objects[o].obj_descend(fn); this.objects[o].obj_descend(fn);
}, },
} }
Object.mixin(gameobject, gameobject_impl);
var gop = os.make_gameobject().__proto__;
Object.mixin(gop, gameobject);
var gsync = gop.sync;
gop.sync = function() {
gsync.call(this);
this.components.forEach(function(x) { x.sync?.(); });
this.objects.forEach(function(x) { x.sync(); });
}
gameobject.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.`;
@ -835,7 +780,3 @@ game.loadurs = function() {
name: "empty" name: "empty"
}; };
}; };
return {
gameobject
}

View file

@ -1,7 +1,7 @@
/* On collisions, entities are sent a 'hit' object, which looks like this: /* On collisions, entities are sent a 'hit' object, which looks like this:
var HIT = { var HIT = {
normal: "The normal of the collision point.", normal: "The normal of the collision point.",
hit: "The gameobject of the object that collided.", obj: "The gameobject of the object that collided.",
sensor: "Boolean for if the colliding object was a sensor.", sensor: "Boolean for if the colliding object was a sensor.",
velocity: "Velocity of the contact.", velocity: "Velocity of the contact.",
pos: "Position in world space of the contact.", pos: "Position in world space of the contact.",

View file

@ -287,9 +287,8 @@ float phys2d_circle_moi(struct phys2d_circle *c) {
return cpMomentForCircle(m, 0, cpCircleShapeGetRadius(c->shape.shape), cpCircleShapeGetOffset(c->shape.shape)); return cpMomentForCircle(m, 0, cpCircleShapeGetRadius(c->shape.shape), cpCircleShapeGetOffset(c->shape.shape));
} }
void phys2d_circledel(struct phys2d_circle *c) { void phys2d_circledel(struct phys2d_circle *c) { phys2d_shape_del(&c->shape); }
phys2d_shape_del(&c->shape); void circle2d_free(circle2d *c) { phys2d_circledel(c); }
}
void phys2d_dbgdrawcpcirc(cpShape *c) { void phys2d_dbgdrawcpcirc(cpShape *c) {
HMM_Vec2 pos = mat_t_pos(t_go2world(shape2go(c)), (HMM_Vec2)cpCircleShapeGetOffset(c)); HMM_Vec2 pos = mat_t_pos(t_go2world(shape2go(c)), (HMM_Vec2)cpCircleShapeGetOffset(c));
@ -310,6 +309,7 @@ void phys2d_shape_apply(struct phys2d_shape *s)
float newmoi = s->moi(s->data); float newmoi = s->moi(s->data);
moment-=moi; moment-=moi;
moment += newmoi; moment += newmoi;
if (moment < 0) moment = 0;
cpBodySetMoment(s->go->body, moment); cpBodySetMoment(s->go->body, moment);
} }

View file

@ -47,6 +47,8 @@ struct phys2d_circle {
struct phys2d_shape shape; struct phys2d_shape shape;
}; };
typedef struct phys2d_circle circle2d;
/* A convex polygon; defined as the convex hull around the given set of points */ /* A convex polygon; defined as the convex hull around the given set of points */
struct phys2d_poly { struct phys2d_poly {
HMM_Vec2 *points; HMM_Vec2 *points;
@ -66,6 +68,7 @@ struct phys2d_edge {
struct phys2d_circle *Make2DCircle(gameobject *go); struct phys2d_circle *Make2DCircle(gameobject *go);
void phys2d_circledel(struct phys2d_circle *c); void phys2d_circledel(struct phys2d_circle *c);
void circle2d_free(circle2d *c);
void phys2d_applycircle(struct phys2d_circle *circle); void phys2d_applycircle(struct phys2d_circle *circle);
void phys2d_dbgdrawcircle(struct phys2d_circle *circle); void phys2d_dbgdrawcircle(struct phys2d_circle *circle);
float phys2d_circle_moi(struct phys2d_circle *c); float phys2d_circle_moi(struct phys2d_circle *c);

View file

@ -546,8 +546,8 @@ void draw_box(HMM_Vec2 c, HMM_Vec2 wh, struct rgba color)
void draw_grid(float width, float span, struct rgba color) void draw_grid(float width, float span, struct rgba color)
{ {
HMM_Vec2 offset = (HMM_Vec2)cam_pos(); HMM_Vec2 offset = campos;
offset = HMM_MulV2F(offset, 1/cam_zoom()); offset = HMM_MulV2F(offset, 1/camzoom);
float ubo[4]; float ubo[4];
ubo[0] = offset.x; ubo[0] = offset.x;
@ -562,7 +562,7 @@ void draw_grid(float width, float span, struct rgba color)
fs_params_t pt; fs_params_t pt;
pt.thickness = (float)width; pt.thickness = (float)width;
pt.span = span/cam_zoom(); pt.span = span/camzoom;
memcpy(&pt.color, col, sizeof(float)*4); memcpy(&pt.color, col, sizeof(float)*4);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(ubo)); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(ubo));
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(pt)); sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(pt));

View file

@ -75,8 +75,8 @@ transform2d go2t(gameobject *go)
unsigned int editor_cat = 1<<31; unsigned int editor_cat = 1<<31;
void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go) { void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go) {
cpShapeSetFriction(shape, go->f); cpShapeSetFriction(shape, go->friction);
cpShapeSetElasticity(shape, go->e); cpShapeSetElasticity(shape, go->elasticity);
cpShapeSetCollisionType(shape, (cpCollisionType)go); cpShapeSetCollisionType(shape, (cpCollisionType)go);
cpShapeFilter filter; cpShapeFilter filter;
@ -105,6 +105,7 @@ void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
} }
void gameobject_apply(gameobject *go) { void gameobject_apply(gameobject *go) {
YughInfo("Applying gameobject %p", go);
cpBodySetType(go->body, go->phys); cpBodySetType(go->body, go->phys);
cpBodyEachShape(go->body, go_shape_apply, go); cpBodyEachShape(go->body, go_shape_apply, go);
@ -115,8 +116,6 @@ void gameobject_apply(gameobject *go) {
if (cpBodyGetMoment(go->body) <= 0.f) if (cpBodyGetMoment(go->body) <= 0.f)
cpBodySetMoment(go->body, 1.f); cpBodySetMoment(go->body, 1.f);
return;
} }
} }

View file

@ -32,8 +32,8 @@ struct gameobject {
HMM_Vec3 scale; /* local */ HMM_Vec3 scale; /* local */
int next; int next;
float mass; float mass;
float f; /* friction */ float friction;
float e; /* elasticity */ float elasticity;
float damping; float damping;
float timescale; float timescale;
float maxvelocity; float maxvelocity;

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,6 @@
#include "dsp.h" #include "dsp.h"
void ffi_load(); void ffi_load();
void ffi_stop();
JSValue vec22js(HMM_Vec2 v); JSValue vec22js(HMM_Vec2 v);
HMM_Vec2 js2vec2(JSValue v); HMM_Vec2 js2vec2(JSValue v);

View file

@ -26,6 +26,9 @@
#include "msf_gif.h" #include "msf_gif.h"
HMM_Vec2 campos = {0,0};
float camzoom = 1;
static struct { static struct {
sg_swapchain swap; sg_swapchain swap;
sg_pipeline pipe; sg_pipeline pipe;
@ -356,18 +359,10 @@ void render_init() {
} }
static cpBody *camera = NULL;
void set_cam_body(cpBody *body) { camera = body; }
cpVect cam_pos() { return camera ? cpBodyGetPosition(camera) : cpvzero; }
static float zoom = 1.f;
float cam_zoom() { return zoom; }
void add_zoom(float val) { zoom = val; }
HMM_Vec2 world2screen(HMM_Vec2 pos) HMM_Vec2 world2screen(HMM_Vec2 pos)
{ {
pos = HMM_SubV2(pos, HMM_V2(cam_pos().x, cam_pos().y)); pos = HMM_SubV2(pos, campos);
pos = HMM_ScaleV2(pos, 1.0/zoom); pos = HMM_ScaleV2(pos, 1.0/camzoom);
pos = HMM_AddV2(pos, HMM_ScaleV2(mainwin.size,0.5)); pos = HMM_AddV2(pos, HMM_ScaleV2(mainwin.size,0.5));
return pos; return pos;
} }
@ -376,8 +371,8 @@ HMM_Vec2 screen2world(HMM_Vec2 pos)
{ {
pos = HMM_ScaleV2(pos, 1/mainwin.dpi); pos = HMM_ScaleV2(pos, 1/mainwin.dpi);
pos = HMM_SubV2(pos, HMM_ScaleV2(mainwin.size, 0.5)); pos = HMM_SubV2(pos, HMM_ScaleV2(mainwin.size, 0.5));
pos = HMM_ScaleV2(pos, zoom); pos = HMM_ScaleV2(pos, camzoom);
pos = HMM_AddV2(pos, HMM_V2(cam_pos().x, cam_pos().y)); pos = HMM_AddV2(pos, campos);
return pos; return pos;
} }
@ -415,7 +410,7 @@ void full_3d_pass(struct window *window)
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(subo)); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(subo));
} }
void openglRender(struct window *window) { void openglRender(struct window *window, gameobject *cam, float zoom) {
sg_swapchain sch = sglue_swapchain(); sg_swapchain sch = sglue_swapchain();
sg_begin_pass(&(sg_pass){ sg_begin_pass(&(sg_pass){
.action = pass_action, .action = pass_action,
@ -450,13 +445,14 @@ void openglRender(struct window *window) {
} }
// 2D projection // 2D projection
cpVect pos = cam_pos(); campos = go_pos(cam);
camzoom = zoom;
projection = HMM_Orthographic_LH_NO( projection = HMM_Orthographic_LH_NO(
pos.x - zoom * usesize.x / 2, campos.x - camzoom * usesize.x / 2,
pos.x + zoom * usesize.x / 2, campos.x + camzoom * usesize.x / 2,
pos.y - zoom * usesize.y / 2, campos.y - camzoom * usesize.y / 2,
pos.y + zoom * usesize.y / 2, -10000.f, 10000.f); campos.y + camzoom * usesize.y / 2, -10000.f, 10000.f);
hudproj = HMM_Orthographic_LH_ZO(0, usesize.x, 0, usesize.y, -1.f, 1.f); hudproj = HMM_Orthographic_LH_ZO(0, usesize.x, 0, usesize.y, -1.f, 1.f);

View file

@ -14,6 +14,7 @@
#include "sokol/sokol_gfx.h" #include "sokol/sokol_gfx.h"
#include "HandmadeMath.h" #include "HandmadeMath.h"
#include "gameobject.h"
#define RGBA_MAX 255 #define RGBA_MAX 255
@ -52,17 +53,16 @@ enum RenderMode {
}; };
void render_init(); void render_init();
void openglRender(struct window *window); extern HMM_Vec2 campos;
extern float camzoom;
void openglRender(struct window *window, gameobject *cam, float zoom);
void opengl_rendermode(enum RenderMode r); void opengl_rendermode(enum RenderMode r);
void openglInit3d(struct window *window); void openglInit3d(struct window *window);
void openglRender3d(struct window *window, camera3d *camera); void openglRender3d(struct window *window, camera3d *camera);
void capture_screen(int x, int y, int w, int h, const char *path); void capture_screen(int x, int y, int w, int h, const char *path);
void set_cam_body(cpBody *body);
cpVect cam_pos();
float cam_zoom();
void add_zoom(float val);
HMM_Vec2 world2screen(HMM_Vec2 pos); HMM_Vec2 world2screen(HMM_Vec2 pos);
HMM_Vec2 screen2world(HMM_Vec2 pos); HMM_Vec2 screen2world(HMM_Vec2 pos);

View file

@ -29,9 +29,7 @@ void script_startup() {
void script_stop() void script_stop()
{ {
script_evalf("Event.notify('quit');");
script_evalf("prosperon.quit();"); script_evalf("prosperon.quit();");
ffi_stop();
#if LEAK #if LEAK
JS_FreeContext(js); JS_FreeContext(js);

View file

@ -207,8 +207,8 @@ void sprite_draw(struct sprite *sprite) {
if (!sprite->go) t = t2d_unit; if (!sprite->go) t = t2d_unit;
else t = go2t(sprite->go); else t = go2t(sprite->go);
t.pos.x += (cam_pos().x - (cam_pos().x/sprite->parallax)); t.pos.x += (campos.x - (campos.x/sprite->parallax));
t.pos.y += (cam_pos().y - (cam_pos().y/sprite->parallax)); t.pos.y += (campos.y - (campos.y/sprite->parallax));
HMM_Mat3 m = transform2d2mat(t); HMM_Mat3 m = transform2d2mat(t);
HMM_Mat3 sm = transform2d2mat(sprite2t(sprite)); HMM_Mat3 sm = transform2d2mat(sprite2t(sprite));
tex_draw(sprite->tex, HMM_MulM3(m,sm), sprite->frame, sprite->color, sprite->drawmode, (HMM_Vec2){0,0}, sprite->scale, sprite->emissive, sprite->parallax); tex_draw(sprite->tex, HMM_MulM3(m,sm), sprite->frame, sprite->color, sprite->drawmode, (HMM_Vec2){0,0}, sprite->scale, sprite->emissive, sprite->parallax);

View file

@ -201,6 +201,7 @@ int main(int argc, char **argv) {
signal(SIGABRT, seghandle); signal(SIGABRT, seghandle);
signal(SIGFPE, seghandle); signal(SIGFPE, seghandle);
#endif #endif
phys2d_init();
resources_init(); resources_init();
stm_setup(); /* time */ stm_setup(); /* time */
@ -237,7 +238,6 @@ void engine_start(JSValue start, JSValue procfn)
c_process_fn = procfn; c_process_fn = procfn;
sound_init(); sound_init();
phys2d_init();
start_desc.width = mainwin.size.x; start_desc.width = mainwin.size.x;
start_desc.height = mainwin.size.y; start_desc.height = mainwin.size.y;