Add guid; tags; physics point checking

This commit is contained in:
John Alanbrook 2024-04-03 00:44:08 -05:00
parent 3f73a808d8
commit 033b7c5109
14 changed files with 212 additions and 167 deletions

View file

@ -12,7 +12,7 @@ actor.spawn = function(script, config, callback){
padawan.padawans = [];
padawan.timers = [];
padawan.master = this;
Object.hide(padawan, "master","timers", "padawans");
Object.hide(padawan, "master", "timers", "padawans");
check_registers(padawan);
this.padawans.push(padawan);
return padawan;

View file

@ -1,10 +1,23 @@
this.phys = physics.kinematic;
this.dir_view2world = function(dir) { return dir.scale(this.realzoom()); };
this.view2world = function(pos) { return render.view2world(pos); };
this.world2view = function(pos) { return render.world2view(pos); };
this.view2world = function(pos) {
pos = pos.scale([window.rendersize.x/window.size.x, window.rendersize.y/window.size.y]);
pos = pos.sub(window.rendersize.scale(0.5));
pos = pos.scale(this.zoom);
pos = pos.add(this.pos);
return pos;
};
this.world2view = function(pos) {
pos = pos.sub(this.pos);
pos = pos.scale(1.0/this.zoom);
pos = pos.add(window.rendersize);
return pos;
};
this.realzoom = function() { return render.get_zoom(); };
this.screenright = function() { return this.pos.x + (window.rendersize.x/2); }
this.screenright = function() {
return this.view2world(window.size).x;
}
this.screenleft = function() { return this.pos.x - (window.rendersize.x/2); }
this.zoom = 1;

View file

@ -76,6 +76,7 @@ function json_from_whitelist(whitelist)
}
Object.mixin(os.sprite(true), {
loop: true,
toJSON:json_from_whitelist([
"path",
"pos",
@ -96,7 +97,7 @@ Object.mixin(os.sprite(true), {
self.del_anim = undefined;
self = undefined;
advance = undefined;
stop();
stop?.();
}
str ??= 0;
var playing = self.anim[str];
@ -112,8 +113,7 @@ Object.mixin(os.sprite(true), {
f = (f+1)%playing.frames.length;
if (f === 0) {
self.anim_done?.();
self.anim_done = undefined;
// if (!self.loop) { self.stop(); return; }
if (!self.loop) { self.stop(); return; }
}
stop = self.gameobject.delay(advance, playing.frames[f].time);
}
@ -149,6 +149,7 @@ Object.mixin(os.sprite(true), {
this.del_anim?.();
this.anim = undefined;
this.gameobject = undefined;
this.anim_done = undefined;
},
toString() { return "sprite"; },
move(d) { this.pos = this.pos.add(d); },
@ -461,14 +462,14 @@ polygon2d.inputs.f10 = function() {
polygon2d.inputs.f10.doc = "Sort all points to be CCW order.";
polygon2d.inputs['C-lm'] = function() {
this.points.push(this.gameobject.world2this(Mouse.worldpos()));
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(){};
polygon2d.inputs['C-M-lm'] = function() {
var idx = Math.grab_from_points(Mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
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);
};
@ -777,7 +778,7 @@ bucket.inputs['C-o'].doc = "Set spline to linear.";
bucket.inputs['C-M-lm'] = function() {
if (Spline.is_catmull(this.type)) {
var idx = Math.grab_from_points(Mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
var idx = Math.grab_from_points(input.mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
if (idx === -1) return;
} else {
@ -787,16 +788,16 @@ bucket.inputs['C-M-lm'] = function() {
};
bucket.inputs['C-M-lm'].doc = "Select the given point as the '0' of this spline.";
bucket.inputs['C-lm'] = function() { this.add_node(Mouse.worldpos()); }
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.";
bucket.inputs['C-M-lm'] = function() {
var idx = -1;
if (Spline.is_catmull(this.type))
idx = Math.grab_from_points(Mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
idx = Math.grab_from_points(input.mouse.worldpos(), this.points.map(p => this.gameobject.this2world(p)), 25);
else {
var nodes = Spline.bezier_nodes(this.points);
idx = Math.grab_from_points(Mouse.worldpos(), nodes.map(p => this.gameobject.this2world(p)), 25);
idx = Math.grab_from_points(input.mouse.worldpos(), nodes.map(p => this.gameobject.this2world(p)), 25);
idx *= 3;
}

View file

@ -22,12 +22,12 @@ debug.draw = function() {
if (this.draw_gizmos)
game.all_objects(function(x) {
if (!x.icon) return;
GUI.image(x.icon, window.world2screen(x.pos));
GUI.image(x.icon, game.camera.world2view(x.pos));
});
if (this.draw_names)
game.all_objects(function(x) {
render.text(x, window.world2screen(x.pos).add([0,32]), 1, Color.debug.names);
render.text(x, game.camera.view2screen(x.pos).add([0,32]), 1, Color.debug.names);
});
if (debug.gif.rec) {
@ -41,10 +41,10 @@ debug.draw = function() {
render.text(sim.playing() ? "PLAYING"
: sim.stepping() ?
"STEP" :
sim.paused() ?
"PAUSED; EDITING" :
"EDIT", [0, 0], 1);
"STEP" :
sim.paused() ?
"PAUSED; EDITING" :
"EDIT", [0, 0], 1);
}
function assert(op, str)

View file

@ -24,7 +24,7 @@ var editor = {
desktop: undefined, /* The editor desktop, where all editing objects live */
working_layer: 0,
get cursor() {
if (this.selectlist.length === 0 ) return Mouse.worldpos();
if (this.selectlist.length === 0 ) return input.mouse.worldpos();
return physics.com(this.selectlist.map(x => x.pos));
},
edit_mode: "basic",
@ -32,7 +32,7 @@ var editor = {
get_this() { return this.edit_level; },
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(input.mouse.worldpos());
return this.do_select(go);
},
@ -82,7 +82,7 @@ var editor = {
return function(go) { go.pos = go.pos.add(amt)};
},
step_amt() { return Keys.shift() ? 10 : 1; },
step_amt() { return input.keyboard.down("shift") ? 10 : 1; },
on_grid(pos) {
return pos.every(function(x) { return x % editor.grid_size === 0; });
@ -97,7 +97,7 @@ var editor = {
key_move(dir) {
if (!editor.grabselect) return;
if (Keys.ctrl())
if (input.keyboard.down('ctrl'))
this.selectlist.forEach(this.snapper(dir.scale(1.01), editor.grid_size));
else
this.selectlist.forEach(this.mover(dir.scale(this.step_amt())));
@ -154,7 +154,7 @@ var editor = {
},
input_num_pressed(num) {
if (Keys.ctrl()) {
if (input.keyboard.down('ctrl')) {
this.camera_recalls[num] = {
pos:this.camera.pos,
zoom:this.camera.zoom
@ -375,7 +375,7 @@ var editor = {
/* Draw selection box */
if (this.sel_start) {
var endpos = Mouse.worldpos();
var endpos = input.mouse.worldpos();
var c = [];
c[0] = (endpos[0] - this.sel_start[0]) / 2;
c[0] += this.sel_start[0];
@ -393,7 +393,7 @@ var editor = {
gui() {
/* Clean out killed objects */
this.selectlist = this.selectlist.filter(function(x) { return x.alive; });
render.text([0,0], window.world2screen([0,0]));
render.text([0,0], game.camera.world2view([0,0]));
render.text("WORKING LAYER: " + this.working_layer, [0,520]);
render.text("MODE: " + this.edit_mode, [0,500]);
@ -455,15 +455,15 @@ var editor = {
render.circle(x[1].screenpos(),10,Color.blue.alpha(0.3));
});
var mg = physics.pos_query(Mouse.worldpos(),10);
var mg = physics.pos_query(input.mouse.worldpos(),10);
if (mg) {
var p = mg.path_from(thiso);
render.text(p, Mouse.screenpos(),1,Color.teal);
render.text(p, input.mouse.screenpos(),1,Color.teal);
}
if (this.rotlist.length === 1)
render.text(Math.trunc(this.rotlist[0].obj.angle), Mouse.screenpos(), 1, Color.teal);
render.text(Math.trunc(this.rotlist[0].obj.angle), input.mouse.screenpos(), 1, Color.teal);
if (this.selectlist.length === 1) {
var i = 1;
@ -484,8 +484,8 @@ var editor = {
});
render.grid(1, editor.grid_size, Color.Editor.grid.alpha(0.3));
var startgrid = window.screen2world([-20,0]).map(function(x) { return Math.snap(x, editor.grid_size); });
var endgrid = window.screen2world([window.width, window.height]);
var startgrid = game.camera.view2world([-20,0]).map(function(x) { return Math.snap(x, editor.grid_size); });
var endgrid = game.camera.view2world([window.width, window.height]);
var w_step = Math.round(editor.ruler_mark_px/window.width * (endgrid.x-startgrid.x)/editor.grid_size)*editor.grid_size;
if (w_step === 0) w_step = editor.grid_size;
@ -494,12 +494,12 @@ var editor = {
if (h_step === 0) h_step = editor.grid_size;
while(startgrid[0] <= endgrid[0]) {
render.text(startgrid[0], [window.world2screen([startgrid[0], 0])[0],0]);
render.text(startgrid[0], [game.camera.world2view([startgrid[0], 0])[0],0]);
startgrid[0] += w_step;
}
while(startgrid[1] <= endgrid[1]) {
render.text(startgrid[1], [0, window.world2screen([0, startgrid[1]])[1]]);
render.text(startgrid[1], [0, game.camera.world2view([0, startgrid[1]])[1]]);
startgrid[1] += h_step;
}
@ -523,7 +523,7 @@ var editor = {
load(urstr) {
var obj = editor.edit_level.spawn(urstr);
obj.set_worldpos(Mouse.worldpos());
obj.set_worldpos(input.mouse.worldpos());
this.selectlist = [obj];
},
@ -604,7 +604,7 @@ var editor = {
editor.new_object = function()
{
var obj = editor.edit_level.spawn();
obj.set_worldpos(Mouse.worldpos());
obj.set_worldpos(input.mouse.worldpos());
this.selectlist = [obj];
return obj;
}
@ -650,7 +650,7 @@ editor.inputs.drop = function(str) {
return;
}
var mg = physics.pos_query(Mouse.worldpos(),10);
var mg = physics.pos_query(input.mouse.worldpos(),10);
if (!mg) return;
var img = mg.get_comp_by_name('sprite');
if (!img) return;
@ -794,7 +794,7 @@ editor.inputs['C-r'].doc = "Negate the selected's angle.";
editor.inputs.r = function() {
if (editor.sel_comp && 'angle' in editor.sel_comp) {
var relpos = Mouse.worldpos().sub(editor.sel_comp.gameobject.worldpos());
var relpos = input.mouse.worldpos().sub(editor.sel_comp.gameobject.worldpos());
editor.startoffset = Math.atan2(relpos.y, relpos.x);
editor.startrot = editor.sel_comp.angle;
@ -803,7 +803,7 @@ editor.inputs.r = function() {
editor.rotlist = [];
editor.selectlist.forEach(function(x) {
var relpos = Mouse.worldpos().sub(editor.cursor);
var relpos = input.mouse.worldpos().sub(editor.cursor);
editor.rotlist.push({
obj: x,
angle: x.angle,
@ -1016,11 +1016,11 @@ editor.inputs.f3 = function() {
this.openpanel(componentexplorer);
};
editor.inputs.lm = function() { editor.sel_start = Mouse.worldpos(); };
editor.inputs.lm = function() { editor.sel_start = input.mouse.worldpos(); };
editor.inputs.lm.doc = "Selection box.";
editor.inputs.lm.released = function() {
Mouse.normal();
input.mouse.normal();
editor.unselect();
if (!editor.sel_start) return;
@ -1033,11 +1033,11 @@ editor.inputs.lm.released = function() {
var selects = [];
/* TODO: selects somehow gets undefined objects in here */
if (Vector.equal(Mouse.worldpos(), editor.sel_start, 5)) {
if (Vector.equal(input.mouse.worldpos(), editor.sel_start, 5)) {
var sel = editor.try_select();
if (sel) selects.push(sel);
} else {
var box = bbox.frompoints([editor.sel_start, Mouse.worldpos()]);
var box = bbox.frompoints([editor.sel_start, input.mouse.worldpos()]);
physics.box_query(bbox.tocwh(box), function(entity) {
var obj = editor.do_select(entity);
@ -1051,7 +1051,7 @@ editor.inputs.lm.released = function() {
if (Object.empty(selects)) return;
if (Keys.shift()) {
if (input.keyboard.down('shift')) {
selects.forEach(function(x) {
this.selectlist.push_unique(x);
}, this);
@ -1059,7 +1059,7 @@ editor.inputs.lm.released = function() {
return;
}
if (Keys.ctrl()) {
if (input.keyboard.down('ctrl')) {
selects.forEach(function(x) {
delete this.selectlist[x.toString()];
}, this);
@ -1091,7 +1091,7 @@ editor.try_pick = function()
editor.grabselect = [];
if (editor.sel_comp && 'pick' in editor.sel_comp)
return editor.sel_comp.pick(Mouse.worldpos());
return editor.sel_comp.pick(input.mouse.worldpos());
return editor.try_select();
}
@ -1099,7 +1099,7 @@ editor.try_pick = function()
editor.inputs.mm = function() {
if (editor.brush_obj) {
editor.selectlist = editor.dup_objects([editor.brush_obj]);
editor.selectlist[0].pos = Mouse.worldpos();
editor.selectlist[0].pos = input.mouse.worldpos();
editor.grabselect = editor.selectlist[0];
return;
}
@ -1113,30 +1113,30 @@ editor.inputs['C-mm'] = editor.inputs.mm;
editor.inputs['C-M-lm'] = function()
{
var go = physics.pos_query(Mouse.worldpos());
var go = physics.pos_query(input.mouse.worldpos());
if (!go) return;
editor.edit_level = go.master;
}
editor.inputs['C-M-mm'] = function() {
editor.mousejoy = Mouse.screenpos();
editor.mousejoy = input.mouse.screenpos();
editor.joystart = editor.camera.pos;
};
editor.inputs['C-M-rm'] = function() {
editor.mousejoy = Mouse.screenpos();
editor.mousejoy = input.mouse.screenpos();
editor.z_start = editor.camera.zoom;
Mouse.disabled();
input.mouse.disabled();
};
editor.inputs.rm.released = function() {
editor.mousejoy = undefined;
editor.z_start = undefined;
Mouse.normal();
input.mouse.normal();
};
editor.inputs.mm.released = function () {
Mouse.normal();
input.mouse.normal();
this.grabselect = [];
editor.mousejoy = undefined;
editor.joystart = undefined;
@ -1157,7 +1157,7 @@ editor.inputs.mouse.move = function(pos, dpos)
x.sync();
});
var relpos = Mouse.worldpos().sub(editor.cursor);
var relpos = input.mouse.worldpos().sub(editor.cursor);
var dist = Vector.length(relpos);
editor.scalelist?.forEach(function(x) {
@ -1174,7 +1174,7 @@ editor.inputs.mouse.move = function(pos, dpos)
editor.rotlist?.forEach(function(x) {
var anglediff = Math.atan2(relpos.y, relpos.x) - x.rotoffset;
x.obj.angle = x.angle + Math.rad2turn(anglediff);
if (Keys.shift())
if (input.keyboard.down('shift'))
x.obj.angle = Math.nearest(x.obj.angle, (1/24));
if (x.pos)
x.obj.pos = x.pos.sub(x.offset).add(x.offset.rotate(anglediff));
@ -1192,7 +1192,7 @@ editor.inputs.mouse['C-scroll'] = function(scroll)
editor.camera.zoom += scroll.y/100;
}
editor.inputs['C-M-S-lm'] = function() { editor.selectlist[0].set_center(Mouse.worldpos()); };
editor.inputs['C-M-S-lm'] = function() { editor.selectlist[0].set_center(input.mouse.worldpos()); };
editor.inputs['C-M-S-lm'].doc = "Set world center to mouse position.";
editor.inputs.delete = function() {
@ -1229,7 +1229,7 @@ editor.inputs.g = function() {
if (editor.sel_comp) {
if ('pick' in editor.sel_comp) {
editor.grabselect = [editor.sel_comp.pick(Mouse.worldpos())];
editor.grabselect = [editor.sel_comp.pick(input.mouse.worldpos())];
return;
}
@ -1246,7 +1246,7 @@ editor.inputs.g = function() {
}
if (editor.sel_comp && 'pick' in editor.sel_comp) {
var o = editor.sel_comp.pick(Mouse.worldpos());
var o = editor.sel_comp.pick(input.mouse.worldpos());
if (o) editor.grabselect = [o];
return;
}
@ -1255,7 +1255,7 @@ editor.inputs.g = function() {
};
editor.inputs.g.doc = "Move selected objects.";
editor.inputs.g.released = function() { editor.grabselect = []; Mouse.normal(); };
editor.inputs.g.released = function() { editor.grabselect = []; input.mouse.normal(); };
editor.inputs.up = function() { this.key_move([0,1]); };
editor.inputs.up.rep = true;
@ -1302,13 +1302,13 @@ editor.inputs['M-g'] = function()
editor.inputs['M-g'].doc = "Move all.";
editor.inputs['C-lb'] = function() {
editor.grid_size -= Keys.shift() ? 10 : 1;
editor.grid_size -= input.keyboard.down('shift') ? 10 : 1;
if (editor.grid_size <= 0) editor.grid_size = 1;
};
editor.inputs['C-lb'].doc = "Decrease grid size. Hold shift to decrease it more.";
editor.inputs['C-lb'].rep = true;
editor.inputs['C-rb'] = function() { editor.grid_size += Keys.shift() ? 10 : 1; };
editor.inputs['C-rb'] = function() { editor.grid_size += input.keyboard.down('shift') ? 10 : 1; };
editor.inputs['C-rb'].doc = "Increase grid size. Hold shift to increase it more.";
editor.inputs['C-rb'].rep = true;
@ -1373,7 +1373,7 @@ compmode.inputs['C-x'] = function() {};
editor.scalelist = [];
editor.inputs.s = function() {
var scaleoffset = Vector.length(Mouse.worldpos().sub(editor.cursor));
var scaleoffset = Vector.length(input.mouse.worldpos().sub(editor.cursor));
editor.scalelist = [];
if (editor.sel_comp) {
@ -1580,7 +1580,7 @@ replpanel.inputs = Object.create(inputpanel.inputs);
replpanel.inputs.block = true;
replpanel.inputs.lm = function()
{
var mg = physics.pos_query(Mouse.worldpos());
var mg = physics.pos_query(input.mouse.worldpos());
if (!mg) return;
var p = mg.path_from(editor.get_this());
this.value = p;

View file

@ -254,7 +254,6 @@ var sim = {
}
var physlag = 0;
var timescale = 1;
var gggstart = game.engine_start;
game.engine_start = function(s) {
@ -288,8 +287,8 @@ function process()
while (physlag > phys_step) {
physlag -= phys_step;
prosperon.phys2d_step(phys_step*timescale);
prosperon.physupdate(phys_step*timescale);
prosperon.phys2d_step(phys_step*game.timescale);
prosperon.physupdate(phys_step*game.timescale);
}
if (!game.camera)
@ -314,20 +313,43 @@ function process()
game.timescale = 1;
var eachobj = function(obj,fn)
{
fn(obj);
for (var o in obj.objects)
eachobj(obj.objects[o],fn);
game.all_objects = function(fn) {
var eachobj = function(obj,fn)
{
fn(obj);
for (var o in obj.objects)
eachobj(obj.objects[o],fn);
}
eachobj(world,fn);
};
game.tags = {};
game.tag_add = function(tag, obj) {
game.tags[tag] ??= {};
game.tags[tag][obj.guid] = obj;
}
game.all_objects = function(fn) { eachobj(world,fn); };
game.tag_rm = function(tag, obj) {
delete game.tags[tag][obj.guid];
}
game.tag_clear_guid = function(guid)
{
for (var tag in game.tags)
delete game.tags[tag][guid];
}
game.objects_with_tag = function(tag)
{
if (!game.tags[tag]) return;
return Object.values(game.tags[tag]);
}
game.doc = {};
game.doc.object = "Returns the entity belonging to a given id.";
game.doc.pause = "Pause game simulation.";
game.doc.play = "Resume or start game simulation.";
game.doc.dt = "Current frame dt.";
game.doc.camera = "Current camera.";
game.texture = function(path)
@ -344,7 +366,6 @@ game.texture = function(path)
}
game.texture.cache = {};
prosperon.semver = {};
prosperon.semver.valid = function(v, range)
{
@ -519,17 +540,6 @@ window.modetypes = {
window.size = [640, 480];
window.screen2world = function(screenpos) {
if (game.camera)
return game.camera.view2world(screenpos);
return screenpos;
}
window.world2screen = function(worldpos) {
return game.camera.world2view(worldpos);
}
window.set_icon.doc = "Set the icon of the window using the PNG image at path.";
global.mixin("scripts/spline");

View file

@ -239,7 +239,7 @@ var gameobject = {
this.pos = x;
this.objects.forEach((o, i) => o.set_worldpos(this.this2world(poses[i])));
},
screenpos() { return window.world2screen(this.worldpos()); },
screenpos() { return game.camera.world2view(this.worldpos()); },
worldangle() { return this.angle; },
sworldangle(x) { this.angle = x; },
@ -254,10 +254,19 @@ var gameobject = {
*/
spawn(text, config, callback) {
var ent = os.make_gameobject();
ent.guid = prosperon.guid();
ent.setref(ent);
ent.components = {};
ent.objects = {};
ent.timers = [];
ent.reparent(this);
ent._ed = {
selectable: true,
dirty: false,
inst: false,
urdiff: {},
};
if (typeof text === 'object') // assume it's an ur
{
config = text.data;
@ -269,15 +278,6 @@ var gameobject = {
if (config)
Object.assign(ent, json.decode(io.slurp(config)));
ent.reparent(this);
ent._ed = {
selectable: true,
dirty: false,
inst: false,
urdiff: {},
};
ent.ur = text + "+" + config;
for (var [prop, p] of Object.entries(ent)) {
@ -321,6 +321,8 @@ var gameobject = {
}
}
if (ent.tag) game.tag_add(ent.tag, ent);
return ent;
},
@ -368,8 +370,8 @@ var gameobject = {
objects: {},
master: undefined,
this2screen(pos) { return window.world2screen(this.this2world(pos)); },
screen2this(pos) { return this.world2this(window.screen2world(pos)); },
this2screen(pos) { return game.camera.world2view(this.this2world(pos)); },
screen2this(pos) { return this.world2this(game.camera.view2world(pos)); },
in_air() { return this.in_air(); },
@ -544,6 +546,8 @@ var gameobject = {
this.clear();
if (typeof this.stop === 'function') this.stop();
game.tag_clear_guid(this.guid);
for (var i in this) {
if (typeof this[i] === 'object') delete this[i];
if (typeof this[i] === 'function') delete this[i];

View file

@ -69,7 +69,7 @@ GUI.controls.set_mum = function(mum)
}
GUI.controls.check_bb = function(mum)
{
if (bbox.pointin(mum.bb, Mouse.screenpos()))
if (bbox.pointin(mum.bb, input.mouse.screenpos()))
GUI.controls.set_mum(mum);
}
GUI.controls.inputs = {};

View file

@ -1,4 +1,4 @@
var keycodes = {
input.keycodes = {
259: "back",
258: "tab",
257: "enter",
@ -17,9 +17,9 @@ var keycodes = {
45: "minus",
};
var codekeys = {};
for (var code in keycodes)
codekeys[keycodes[code]] = code;
input.codekeys = {};
for (var code in input.keycodes)
input.codekeys[input.keycodes[code]] = code;
var mod = {
shift: 0,
@ -48,7 +48,7 @@ function keyname_extd(key)
return `kp${num}`;
}
if (keycodes[key]) return keycodes[key];
if (input.keycodes[key]) return input.keycodes[key];
if (key >= 32 && key <= 126) return String.fromCharCode(key).lc();
return undefined;
@ -120,32 +120,32 @@ prosperon.mousescroll = function(dx){
player[0].mouse_input(modstr() + "scroll", dx);
};
prosperon.mousedown = function(b){
player[0].raw_input(modstr() + Mouse.button[b], "pressed");
player[0].raw_input(modstr() + input.mouse.button[b], "pressed");
};
prosperon.mouseup = function(b){
player[0].raw_input(modstr() + Mouse.button[b], "released");
player[0].raw_input(modstr() + input.mouse.button[b], "released");
};
var Mouse = {
input.mouse = {
screenpos() { return mousepos.slice(); },
worldpos() { return window.screen2world(mousepos); },
worldpos() { return game.camera.view2world(mousepos); },
disabled() { input.mouse_mode(1); },
normal() { input.mouse_mode(0); },
mode(m) {
if (Mouse.custom[m])
input.cursor_img(Mouse.custom[m]);
if (input.mouse.custom[m])
input.cursor_img(input.mouse.custom[m]);
else
input.mouse_cursor(m);
},
set_custom_cursor(img, mode) {
mode ??= Mouse.cursor.default;
mode ??= input.mouse.cursor.default;
if (!img)
delete Mouse.custom[mode];
delete input.mouse.custom[mode];
else {
input.cursor_img(img);
Mouse.custom[mode] = img;
input.mouse.custom[mode] = img;
}
},
@ -170,17 +170,18 @@ var Mouse = {
},
};
Mouse.doc = {};
Mouse.doc.pos = "The screen position of the mouse.";
Mouse.doc.worldpos = "The position in the game world of the mouse.";
Mouse.disabled.doc = "Set the mouse to hidden. This locks it to the game and hides it, but still provides movement and click events.";
Mouse.normal.doc = "Set the mouse to show again after hiding.";
input.mouse.doc = {};
input.mouse.doc.pos = "The screen position of the mouse.";
input.mouse.doc.worldpos = "The position in the game world of the mouse.";
input.mouse.disabled.doc = "Set the mouse to hidden. This locks it to the game and hides it, but still provides movement and click events.";
input.mouse.normal.doc = "Set the mouse to show again after hiding.";
var Keys = {
down(code) {
return prosperon.keys[code];
},
};
input.keyboard = {};
input.keyboard.down = function(code) {
if (typeof code === 'number') return prosperon.keys[code];
if (typeof code === 'string') return prosperon.keys[keyname_extd(code)];
return undefined;
}
input.state2str = function(state) {
if (typeof state === 'string') return state;
@ -370,10 +371,5 @@ Player.doc.players = "A list of current players.";
var player = Player;
return {
Mouse,
Keys,
Player,
player,
keycodes,
codekeys
player
};

View file

@ -246,6 +246,7 @@ Cmdline.register_order("play", function(argv) {
global.mixin("scripts/sound.js");
global.app = actor.spawn("game.js");
if (project.icon) window.set_icon(game.texture(project.icon));
game.camera = world.spawn("scripts/camera2d");
});
}, "Play the game present in this folder.");

View file

@ -582,9 +582,9 @@ JSValue arb2js(cpArbiter *arb)
void phys_run_post(cpSpace *space, JSValue *fn, JSValue *hit)
{
JSValue hh = *hit;
script_call_sym(*fn, 1, &hh);
JS_FreeValue(js, hh);
script_call_sym(*fn, 1, hit);
JS_FreeValue(js, *hit);
JS_FreeValue(js, *fn);
}
/* TODO: Limitation, cannot handle multiple collision same frame */
@ -595,6 +595,7 @@ int script_phys_cb_begin(cpArbiter *arb, cpSpace *space, gameobject *go)
if (!JS_IsUndefined(go->cbs.begin) && cpSpaceAddPostStepCallback(space, phys_run_post, &go->cbs.begin, &go->cbs.bhit)) {
YughSpam("Added begin for %p", &go->cbs.begin);
JS_DupValue(js, go->cbs.begin);
go->cbs.bhit = arb2js(arb);
}

View file

@ -714,8 +714,6 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, make_texture, 1),
};
JSC_CCALL(render_normal, opengl_rendermode(LIT))
JSC_CCALL(render_wireframe, opengl_rendermode(WIREFRAME))
JSC_CCALL(render_grid, draw_grid(js2number(argv[0]), js2number(argv[1]), js2color(argv[2]));)
JSC_CCALL(render_point, draw_cppoint(js2vec2(argv[0]), js2number(argv[1]), js2color(argv[2])))
JSC_CCALL(render_circle, draw_circle(js2vec2(argv[0]), js2number(argv[1]), js2number(argv[2]), js2color(argv[3]), -1);)
@ -743,16 +741,10 @@ JSC_CCALL(render_end_pass,
sprite_flush();
)
JSC_SCALL(render_text_size, ret = bb2js(text_bb(str, js2number(argv[1]), js2number(argv[2]), 1)))
JSC_CCALL(render_world2screen, return vec22js(world2screen(js2vec2(argv[0]))))
JSC_CCALL(render_screen2world, return vec22js(screen2world(js2vec2(argv[0]))))
JSC_CCALL(render_set_camera, useproj = projection)
JSC_CCALL(render_set_window, useproj = hudproj)
static const JSCFunctionListEntry js_render_funcs[] = {
MIST_FUNC_DEF(render,world2screen,1),
MIST_FUNC_DEF(render,screen2world,1),
MIST_FUNC_DEF(render, normal, 0),
MIST_FUNC_DEF(render, wireframe, 0),
MIST_FUNC_DEF(render, grid, 3),
MIST_FUNC_DEF(render, point, 3),
MIST_FUNC_DEF(render, circle, 3),
@ -873,11 +865,21 @@ static const JSCFunctionListEntry js_input_funcs[] = {
JSC_CCALL(prosperon_emitters_step, emitters_step(js2number(argv[0])))
JSC_CCALL(prosperon_phys2d_step, phys2d_update(js2number(argv[0])))
JSC_CCALL(prosperon_window_render, openglRender(&mainwin, js2gameobject(argv[0]), js2number(argv[1])))
JSC_CCALL(prosperon_guid,
uint8_t bytes[16];
for (int i = 0; i < 16; i++) bytes[i] = rand()%256;
char uuid[37];
snprintf(uuid, 37, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]);
return str2js(uuid);
)
static const JSCFunctionListEntry js_prosperon_funcs[] = {
MIST_FUNC_DEF(prosperon, emitters_step, 1),
MIST_FUNC_DEF(prosperon, phys2d_step, 1),
MIST_FUNC_DEF(prosperon, window_render, 0)
MIST_FUNC_DEF(prosperon, window_render, 0),
MIST_FUNC_DEF(prosperon, guid, 0),
};
JSC_CCALL(time_now,
@ -1085,18 +1087,50 @@ static void ray_query_fn(cpShape *shape, float t, cpVect n, float a, JSValue *cb
number2js(a)
};
script_call_sym(*cb, 3, argv);
for (int i = 0; i < 3; i++)
JS_FreeValue(js, argv[i]);
for (int i = 0; i < 3; i++) JS_FreeValue(js, argv[i]);
}
JSC_CCALL(physics_ray_query,
cpSpaceSegmentQuery(space, js2vec2(argv[0]).cp, js2vec2(argv[1]).cp, js2number(argv[2]), allfilter, ray_query_fn, &argv[3]);
);
static void point_query_fn(cpShape *shape, float dist, cpVect point, JSValue *cb)
{
JSValue argv[3] = {
JS_DupValue(js, shape2go(shape)->ref),
vec22js((HMM_Vec2)point),
number2js(dist)
};
script_call_sym(*cb, 3, argv);
for (int i = 0; i < 3; i++) JS_FreeValue(js, argv[i]);
}
JSC_CCALL(physics_point_query,
cpSpacePointQuery(space, js2vec2(argv[0]).cp, js2number(argv[1]), allfilter, point_query_fn, &argv[2]);
);
JSValue pointinfo2js(cpPointQueryInfo info)
{
JSValue o = JS_NewObject(js);
JS_SetPropertyStr(js, o, "distance", number2js(info.distance));
JS_SetPropertyStr(js, o, "point", vec22js((HMM_Vec2)info.point));
JS_SetPropertyStr(js, o, "entity", JS_DupValue(js, shape2go(info.shape)->ref));
return o;
}
JSC_CCALL(physics_point_query_nearest,
cpPointQueryInfo info;
cpShape *sh = cpSpacePointQueryNearest(space, js2vec2(argv[0]).cp, js2number(argv[1]), allfilter, &info);
if (!sh) return JS_UNDEFINED;
return pointinfo2js(info);
)
static const JSCFunctionListEntry js_physics_funcs[] = {
MIST_FUNC_DEF(physics, sgscale, 2),
MIST_FUNC_DEF(physics, set_cat_mask, 2),
MIST_FUNC_DEF(physics, pos_query, 2),
MIST_FUNC_DEF(physics, point_query, 3),
MIST_FUNC_DEF(physics, point_query_nearest, 3),
MIST_FUNC_DEF(physics, ray_query, 2),
MIST_FUNC_DEF(physics, box_query, 2),
MIST_FUNC_DEF(physics, shape_query, 1),
@ -1200,7 +1234,13 @@ static const JSCFunctionListEntry js_window_funcs[] = {
MIST_FUNC_DEF(window, set_icon, 1)
};
JSC_GETSET_BODY(pos, Position, cvec2)
JSValue js_gameobject_set_pos(JSContext *js, JSValue this, JSValue val) {
gameobject *go = js2gameobject(this);
cpBodySetPosition(go->body, js2vec2(val).cp);
if (go->phys == CP_BODY_TYPE_STATIC)
cpSpaceReindexShapesForBody(space, go->body);
}
JSValue js_gameobject_get_pos(JSContext *js, JSValue this) { return vec22js((HMM_Vec2)cpBodyGetPosition(js2gameobject(this)->body)); }
JSValue js_gameobject_set_angle (JSContext *js, JSValue this, JSValue val) { cpBodySetAngle(js2gameobject(this)->body, HMM_TurnToRad*js2number(val)); }
JSValue js_gameobject_get_angle (JSContext *js, JSValue this) { return number2js(HMM_RadToTurn*cpBodyGetAngle(js2gameobject(this)->body)); }
JSC_GETSET_BODY(velocity, Velocity, cvec2)

View file

@ -121,18 +121,13 @@ void capture_screen(int x, int y, int w, int h, const char *path)
#include "HandmadeMath.h"
int renderMode = LIT;
struct rgba editorClearColor = {35,60,92,255};
void opengl_rendermode(enum RenderMode r) {
renderMode = r;
}
sg_pass_action pass_action = {0};
static struct {
sg_pass_action pass_action;
sg_pass pass;
sg_pipeline pipe;
sg_shader shader;
@ -283,23 +278,6 @@ void render_init() {
});
}
HMM_Vec2 world2screen(HMM_Vec2 pos)
{
pos = HMM_SubV2(pos, campos);
pos = HMM_ScaleV2(pos, 1.0/camzoom);
pos = HMM_AddV2(pos, HMM_ScaleV2(mainwin.size,0.5));
return pos;
}
HMM_Vec2 screen2world(HMM_Vec2 pos)
{
pos = HMM_ScaleV2(pos, 1/mainwin.dpi);
pos = HMM_SubV2(pos, HMM_ScaleV2(mainwin.size, 0.5));
pos = HMM_ScaleV2(pos, camzoom);
pos = HMM_AddV2(pos, campos);
return pos;
}
HMM_Mat4 projection = {0.f};
HMM_Mat4 hudproj = {0.f};
HMM_Mat4 useproj = {0};

View file

@ -85,8 +85,9 @@ int sprite_sort(sprite **sa, sprite **sb)
if (!goa && !gob) return 0;
if (!goa) return -1;
if (!gob) return 1;
if (goa->drawlayer == gob->drawlayer) return 0;
if (goa->drawlayer > gob->drawlayer) return 1;
if (gob->drawlayer > goa->drawlayer) return -1;
if (*sa > *sb) return 1;
return -1;
}