stability

This commit is contained in:
John Alanbrook 2023-05-29 15:47:30 +00:00
parent 591f48c703
commit 9cb53b04af
16 changed files with 248 additions and 159 deletions

View file

@ -50,44 +50,3 @@ be rendered: is it a sprite, is it a texture, does it have mipmaps,
etc. Textures are all file based, and are only accessed through the etc. Textures are all file based, and are only accessed through the
explicit path to their associated image file. explicit path to their associated image file.
.Scripting
Levels and objects have certain functions you can use that will be
called at particular times during the course of the game running.
setup
Called once, when the object is created.
start
Called once when the gameplay is simulating.
update(dt)
Called once per frame, while the game is simulating
physupdate(dt)
Called once per physics step
stop
Called when the object is destroyed, either by being killed or otherwise.
.Collider functions
Colliders get special functions to help with collision handling.
collide(hit)
Called when an object collides with the object this function is on.
"hit" object
normal - A vector in the direction the hit happened
hit - Object ID of colliding object
sensor - True if the colliding object is a sensor
velocity - A vector of the velocity of the collision
.Draw functions
draw()
Called during lower rendering
gui()
Called for screen space over the top rendering
debug()
Called during a debug phase; Will not be called when debug draw is off

View file

@ -1,3 +1,46 @@
# Yugine Scripting # Yugine Scripting
Scripting is done with mruby. MAY CHANGE. Scripting is done with JS.
Load up objects with functions that are called back at specific times.
Levels and objects have certain functions you can use that will be
called at particular times during the course of the game running.
setup
Called once, when the object is created.
start
Called once when the gameplay is simulating.
update(dt)
Called once per frame, while the game is simulating
physupdate(dt)
Called once per physics step
stop
Called when the object is destroyed, either by being killed or otherwise.
.Collider functions
Colliders get special functions to help with collision handling.
collide(hit)
Called when an object collides with the object this function is on.
"hit" object
normal - A vector in the direction the hit happened
hit - Object ID of colliding object
sensor - True if the colliding object is a sensor
velocity - A vector of the velocity of the collision
.Draw functions
draw()
Called during lower rendering
gui()
Called for screen space over the top rendering
debug()
Called during a debug phase; Will not be called when debug draw is off

View file

@ -164,6 +164,8 @@ void phys2d_init()
{ {
space = cpSpaceNew(); space = cpSpaceNew();
cpSpaceSetSleepTimeThreshold(space, 1); cpSpaceSetSleepTimeThreshold(space, 1);
cpSpaceSetCollisionSlop(space, 0.01);
cpSpaceSetCollisionBias(space, cpfpow(1.0-0.5, 165.f));
} }
void phys2d_set_gravity(cpVect v) { void phys2d_set_gravity(cpVect v) {
@ -613,6 +615,7 @@ void duk_call_phys_cb(cpVect norm, struct callee c, int hit, cpArbiter *arb) {
JS_SetPropertyStr(js, obj, "sensor", JS_NewBool(js, cpShapeGetSensor(shape2))); JS_SetPropertyStr(js, obj, "sensor", JS_NewBool(js, cpShapeGetSensor(shape2)));
JS_SetPropertyStr(js, obj, "velocity", vec2js(cpArbiterGetSurfaceVelocity(arb))); JS_SetPropertyStr(js, obj, "velocity", vec2js(cpArbiterGetSurfaceVelocity(arb)));
JS_SetPropertyStr(js, obj, "pos", vec2js(cpArbiterGetPointA(arb, 0))); JS_SetPropertyStr(js, obj, "pos", vec2js(cpArbiterGetPointA(arb, 0)));
JS_SetPropertyStr(js,obj,"depth", num2js(cpArbiterGetDepth(arb,0)));
JS_SetPropertyStr(js, obj, "id", JS_NewInt32(js,hit)); JS_SetPropertyStr(js, obj, "id", JS_NewInt32(js,hit));
JS_SetPropertyStr(js,obj,"obj", JS_DupValue(js,id2go(hit)->ref)); JS_SetPropertyStr(js,obj,"obj", JS_DupValue(js,id2go(hit)->ref));

View file

@ -81,7 +81,6 @@ static struct circle_vertex circle_b[v_amt];
void debug_flush() void debug_flush()
{ {
if (poly_c != 0) { if (poly_c != 0) {
sg_apply_pipeline(poly_pipe); sg_apply_pipeline(poly_pipe);
sg_apply_bindings(&poly_bind); sg_apply_bindings(&poly_bind);
@ -136,7 +135,6 @@ void debug_flush()
sg_draw(0,4,circle_count); sg_draw(0,4,circle_count);
circle_count = 0; circle_count = 0;
} }
} }
static sg_shader_uniform_block_desc projection_ubo = { static sg_shader_uniform_block_desc projection_ubo = {
@ -586,7 +584,7 @@ void draw_poly(cpVect *points, int n, struct rgba color)
/* Find polygon mesh */ /* Find polygon mesh */
int tric = n - 2; int tric = n - 2;
if (n < 1) return; if (tric < 1) return;
uint32_t tridxs[tric*3]; uint32_t tridxs[tric*3];

View file

@ -899,7 +899,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
return JS_NULL; return JS_NULL;
case 83: case 83:
draw_edge(js2cpvec2arr(argv[1]), 2, js2color(argv[2]), 1, 0, 0, js2color(argv[2]), 10); draw_edge(js2cpvec2arr(argv[1]), js_arrlen(argv[1]), js2color(argv[2]), js2number(argv[3]), 0, 0, js2color(argv[2]), 10);
return JS_NULL; return JS_NULL;
case 84: case 84:
@ -1021,6 +1021,14 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 115: case 115:
draw_circle(js2vec2(argv[1]), js2number(argv[2]), js2number(argv[2]), js2color(argv[3]), -1); draw_circle(js2vec2(argv[1]), js2number(argv[2]), js2number(argv[2]), js2color(argv[3]), -1);
break; break;
case 116:
return str2js(tex_get_path(js2sprite(argv[1])->tex));
case 117:
str = JS_ToCString(js, argv[1]);
ret = JS_NewInt64(js, script_runfile(str));
break;
} }
if (str) if (str)

View file

@ -53,8 +53,10 @@ void script_init() {
num_cache[i] = int2js(i); num_cache[i] = int2js(i);
} }
void script_run(const char *script) { void script_run(const char *script, const char *file) {
JS_FreeValue(js, JS_Eval(js, script, strlen(script), "script", JS_EVAL_FLAGS)); JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAGS);
js_print_exception(obj);
JS_FreeValue(js,obj);
} }
void compile_script(const char *file) { void compile_script(const char *file) {
@ -91,9 +93,11 @@ int js_print_exception(JSValue v) {
#ifdef DBG #ifdef DBG
if (JS_IsException(v)) { if (JS_IsException(v)) {
JSValue exception = JS_GetException(js); JSValue exception = JS_GetException(js);
/* TODO: Does it need freed if null? */ /* TODO: Does it need freed if null? */
if (JS_IsNull(exception)) if (JS_IsNull(exception))
return 0; return 0;
JSValue val = JS_GetPropertyStr(js, exception, "stack"); JSValue val = JS_GetPropertyStr(js, exception, "stack");
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name")); const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message")); const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
@ -112,17 +116,27 @@ int js_print_exception(JSValue v) {
return 0; return 0;
} }
int script_dofile(const char *file) { int script_dofile(const char *file) {
YughInfo("Doing script %s", file);
const char *script = slurp_text(file); const char *script = slurp_text(file);
if (!script) { if (!script) {
YughError("Can't find file %s.", file); YughError("Can't find file %s.", file);
return 0; return 0;
} }
JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAGS); script_run(script,file);
js_print_exception(obj); free(script);
JS_FreeValue(js, obj); return file_mod_secs(file);
}
int script_runfile(const char *file)
{
const char *script = slurp_text(file);
int bufsize = strlen(script)+50;
char scriptbuffer[bufsize];
snprintf(scriptbuffer,bufsize, "(function(){%s})()", script);
script_run(scriptbuffer,file);
free(script);
return file_mod_secs(file); return file_mod_secs(file);
} }

View file

@ -18,8 +18,9 @@ extern JSValue num_cache[100];
void js_stacktrace(); void js_stacktrace();
void script_startup(); void script_startup();
void script_init(); void script_init();
void script_run(const char *script); void script_run(const char *script, const char *file);
int script_dofile(const char *file); int script_dofile(const char *file);
int script_runfile(const char *file);
void script_update(double dt); void script_update(double dt);
void script_draw(); void script_draw();

View file

@ -19,7 +19,6 @@ static int first = -1;
static sg_pipeline pip_sprite; static sg_pipeline pip_sprite;
static sg_bindings bind_sprite; static sg_bindings bind_sprite;
static int sprite_c = 0;
int make_sprite(int go) { int make_sprite(int go) {
struct sprite sprite = { struct sprite sprite = {

View file

@ -156,7 +156,7 @@ char *tex_get_path(struct Texture *tex) {
} }
} }
return NULL; return "";
} }
struct Texture *texture_loadfromfile(const char *path) { struct Texture *texture_loadfromfile(const char *path) {

View file

@ -61,8 +61,8 @@ struct TextureOptions {
/* Represents an actual texture on the GPU */ /* Represents an actual texture on the GPU */
struct Texture { struct Texture {
sg_image id; /* ID reference for the GPU memory location of the texture */ sg_image id; /* ID reference for the GPU memory location of the texture */
int width; uint16_t width;
int height; uint16_t height;
unsigned char *data; unsigned char *data;
struct TextureOptions opts; struct TextureOptions opts;
struct TexAnim anim; struct TexAnim anim;

View file

@ -73,6 +73,7 @@ void timer_remove(int id) {
struct timer *t = id2timer(id); struct timer *t = id2timer(id);
if (t->owndata) free(t->data); if (t->owndata) free(t->data);
t->next = first; t->next = first;
t->on = 0;
first = id; first = id;
} }

View file

@ -42,8 +42,8 @@ double physlag = 0;
double updatelag = 0; double updatelag = 0;
double renderMS = 1 / 165.f; double renderMS = 1 / 165.f;
double physMS = 1 / 240.f; double physMS = 1 / 165.f;
double updateMS = 1 / 60.f; double updateMS = 1 / 165.f;
static int ed = 1; static int ed = 1;
static int sim_play = 0; static int sim_play = 0;
@ -234,14 +234,14 @@ int main(int argc, char **args) {
timer_update(elapsed * timescale); timer_update(elapsed * timescale);
physlag += elapsed; physlag += elapsed;
call_updates(elapsed * timescale); call_updates(elapsed * timescale);
while (physlag >= physMS) { // while (physlag >= physMS) {
phys_step = 1; phys_step = 1;
physlag -= physMS; physlag -= physMS;
phys2d_update(physMS * timescale); phys2d_update(physMS * timescale);
call_physics(physMS * timescale); call_physics(physMS * timescale);
if (sim_play == SIM_STEP) sim_pause(); if (sim_play == SIM_STEP) sim_pause();
phys_step = 0; phys_step = 0;
} // }
} }
renderlag += elapsed; renderlag += elapsed;

View file

@ -33,17 +33,13 @@ var sprite = clone(component, {
angle: 0, angle: 0,
rect: {s0:0, s1: 1, t0: 0, t1: 1}, rect: {s0:0, s1: 1, t0: 0, t1: 1},
input_kp7_pressed() { this.pos = [-1,0]; }, get dimensions() { return cmd(64,this.path); },
input_kp6_pressed() { this.pos = [0,-0.5]; }, set dimensions(x) {},
input_kp5_pressed() { this.pos = [-0.5,-0.5]; },
input_kp4_pressed() { this.pos = [-1,-0.5]; },
input_kp3_pressed() { this.pos = [0, -1]; },
input_kp2_pressed() { this.pos = [-0.5,-1]; },
input_kp1_pressed() { this.pos = [-1,-1]; },
make(go) { make(go) {
var old = this; var sprite = Object.create(this);
var sprite = clone(this, { sprite.id = make_sprite(go,this.path,this.pos);
complete_assign(sprite, {
get enabled() { return cmd(114,this.id); }, get enabled() { return cmd(114,this.id); },
set enabled(x) { cmd(20,this.id,x); }, set enabled(x) { cmd(20,this.id,x); },
set color(x) { cmd(96,this.id,x); }, set color(x) { cmd(96,this.id,x); },
@ -51,10 +47,9 @@ var sprite = clone(component, {
set pos(x) { cmd(37,this.id,x); }, set pos(x) { cmd(37,this.id,x); },
set layer(x) { cmd(60, this.id, x); }, set layer(x) { cmd(60, this.id, x); },
get layer() { return this.gameobject.draw_layer; }, get layer() { return this.gameobject.draw_layer; },
set path(x) { cmd(12,this.id,x,this.rect); },
get boundingbox() { get boundingbox() {
var dim = cmd(64,this.path); var dim = this.dimensions;
dim = dim.scale(this.gameobject.scale); dim = dim.scale(this.gameobject.scale);
var realpos = this.pos.copy(); var realpos = this.pos.copy();
realpos.x = realpos.x * dim.x + (dim.x/2); realpos.x = realpos.x * dim.x + (dim.x/2);
@ -62,21 +57,25 @@ var sprite = clone(component, {
return cwh2bb(realpos,dim); return cwh2bb(realpos,dim);
}, },
sync() {
if (this.path)
cmd(12,this.id,this.path,this.rect);
},
kill() { cmd(9,this.id); }, kill() { cmd(9,this.id); },
}); });
sprite = new Proxy(sprite, sync_proxy);
sprite.obscure('boundingbox'); sprite.obscure('boundingbox');
var id = make_sprite(go,old.path,old.pos);
Object.defineProperty(sprite, 'id', {value:id});
Object.assign(sprite, this);
return sprite; return sprite;
}, },
input_kp7_pressed() { this.pos = [-1,0]; },
input_kp6_pressed() { this.pos = [0,-0.5]; },
input_kp5_pressed() { this.pos = [-0.5,-0.5]; },
input_kp4_pressed() { this.pos = [-1,-0.5]; },
input_kp3_pressed() { this.pos = [0, -1]; },
input_kp2_pressed() { this.pos = [-0.5,-1]; },
input_kp1_pressed() { this.pos = [-1,-1]; },
}); });
/* Container to play sprites and anim2ds */ /* Container to play sprites and anim2ds */
@ -100,10 +99,39 @@ var char2d = clone(sprite, {
}, },
make(go) { make(go) {
var char = clone(this); var char = clone(this, {
get enabled() { return cmd(114,this.id); },
set enabled(x) { cmd(20,this.id,x); },
set color(x) { cmd(96,this.id,x); },
get pos() { return cmd(111, this.id); },
set pos(x) { cmd(37,this.id,x); },
set layer(x) { cmd(60, this.id, x); },
get layer() { return this.gameobject.draw_layer; },
get boundingbox() {
var dim = cmd(64,this.path);
dim = dim.scale(this.gameobject.scale);
dim.x *= 1/6;
var realpos = [0,0];
// var realpos = this.pos.slice();
// realpos.x = realpos.x * dim.x + (dim.x/2);
// realpos.y = realpos.y * dim.y + (dim.y/2);
return cwh2bb(realpos,dim);
},
sync() {
if (this.path)
cmd(12,this.id,this.path,this.rect);
},
kill() { cmd(9,this.id); },
});
char.curplaying = char.anims.array()[0]; char.curplaying = char.anims.array()[0];
char.obscure('curplaying'); char.obscure('curplaying');
Object.defineProperty(char, 'id', {value:make_sprite(go,char.curplaying.path,this.pos)}); char.id = make_sprite(go, char.curplaying.path, this.pos);
char.obscure('id'); char.obscure('id');
char.frame = 0; char.frame = 0;
char.timer = timer.make(char.advance.bind(char), 1/char.curplaying.fps); char.timer = timer.make(char.advance.bind(char), 1/char.curplaying.fps);
@ -254,11 +282,12 @@ var polygon2d = clone(collider2d, {
complete_assign(poly, this.make_fns); complete_assign(poly, this.make_fns);
complete_assign(poly, { complete_assign(poly, {
get boundingbox() { get boundingbox() {
return points2bb(this.points.map(x => x.scale(this.gameobject.scale))); return points2bb(this.spoints);
}, },
sync() { cmd_poly2d(0, this.id, this.spoints); } sync() { cmd_poly2d(0, this.id, this.spoints); }
}); });
poly.obscure('boundingbox'); poly.obscure('boundingbox');
poly.defn('points', this.points.copy()); poly.defn('points', this.points.copy());
@ -268,6 +297,8 @@ var polygon2d = clone(collider2d, {
Object.defineProperty(poly, 'id', {enumerable:false}); Object.defineProperty(poly, 'id', {enumerable:false});
Object.defineProperty(poly, 'shape', {enumerable:false}); Object.defineProperty(poly, 'shape', {enumerable:false});
poly.sync();
return poly; return poly;
}, },
@ -278,7 +309,6 @@ var polygon2d = clone(collider2d, {
this.points = sortpointsccw(this.points); this.points = sortpointsccw(this.points);
}, },
input_b_pressed() { input_b_pressed() {
if (!Keys.ctrl()) return; if (!Keys.ctrl()) return;

View file

@ -55,7 +55,8 @@ var Debug = {
register_debug(fn,obj); register_debug(fn,obj);
}, },
line(points, color, type) { line(points, color, type, thickness) {
thickness ??= 1;
if (!type) if (!type)
type = 0; type = 0;
@ -64,7 +65,7 @@ var Debug = {
switch (type) { switch (type) {
case 0: case 0:
cmd(83, points, color); cmd(83, points, color, thickness);
} }
}, },
}; };

View file

@ -1,8 +1,5 @@
var files = {}; var files = {};
function load(file) { function load(file) {
if (typeof Log !== 'undefined')
Log.warn(`doing ${file}`);
var modtime = cmd(0, file); var modtime = cmd(0, file);
if (modtime === 0) { if (modtime === 0) {
@ -12,6 +9,17 @@ function load(file) {
files[file] = modtime; files[file] = modtime;
} }
function run(file)
{
var modtime = cmd(117,file);
if (modtime === 0) {
Log.stack();
return false;
}
files[file] = modtime;
}
load("scripts/base.js"); load("scripts/base.js");
var Log = { var Log = {
@ -167,6 +175,16 @@ var Yugine = {
}; };
var timer = { var timer = {
guardfn(fn) {
if (typeof fn === 'function')
fn();
else {
Log.warn("TIMER TRYING TO EXECUTE WIHTOUT!!!");
Log.warn(this);
this.kill();
}
},
make(fn, secs,obj,loop) { make(fn, secs,obj,loop) {
if (secs === 0) { if (secs === 0) {
fn.call(obj); fn.call(obj);
@ -174,7 +192,7 @@ var timer = {
} }
var t = clone(this); var t = clone(this);
t.id = make_timer(fn, secs, obj); t.id = make_timer(this.guardfn.bind(t,fn), secs, obj);
return t; return t;
}, },
@ -484,6 +502,7 @@ var Register = {
nk_guis: [], nk_guis: [],
nk_gui() { nk_gui() {
this.nk_guis.forEach(x => x[0].call(x[1])); this.nk_guis.forEach(x => x[0].call(x[1]));
}, },
@ -514,12 +533,13 @@ var Register = {
}, },
unregister_obj(obj) { unregister_obj(obj) {
// Log.warn(`Unregister ${JSON.stringify(obj)}`);
this.updates = this.updates.filter(x => x[1] !== obj); this.updates = this.updates.filter(x => x[1] !== obj);
this.guis = this.guis.filter(x => x[1] !== obj); this.guis = this.guis.filter(x => x[1] !== obj);
this.nk_guis = this.nk_guis.filter(x => x[1] !== obj); this.nk_guis = this.nk_guis.filter(x => x[1] !== obj);
this.debugs = this.debugs.filter(x => x[1] !== obj); this.debugs = this.debugs.filter(x => x[1] !== obj);
this.physupdates = this.physupdates.filter(x => x[1] !== obj); this.physupdates = this.physupdates.filter(x => x[1] !== obj);
this.draws = this.draws.filter(x => x[1] !== obj);
Player.players.forEach(x => x.uncontrol(obj)); Player.players.forEach(x => x.uncontrol(obj));
}, },
@ -538,7 +558,6 @@ var Register = {
}, },
}; };
Register.unregister_obj(null);
register(0, Register.update, Register); register(0, Register.update, Register);
register(1, Register.physupdate, Register); register(1, Register.physupdate, Register);
register(2, Register.gui, Register); register(2, Register.gui, Register);
@ -568,7 +587,7 @@ function register_debug(fn, obj) {
}; };
function unregister_gui(fn, obj) { function unregister_gui(fn, obj) {
Register.guis = Register.guis.filter(x => x[0] !== fn && x[1] !== obj); Register.guis = Register.guis.filter(x => x[0] !== fn || x[1] !== obj);
}; };
function register_nk_gui(fn, obj) { function register_nk_gui(fn, obj) {
@ -608,7 +627,7 @@ var Signal = {
register_collide(3,fn,obj,go.body); register_collide(3,fn,obj,go.body);
}, },
clear_obj(obj) { clera_obj(obj) {
this.signals.filter(function(x) { return x[1] !== obj; }); this.signals.filter(function(x) { return x[1] !== obj; });
}, },
}; };
@ -635,6 +654,7 @@ function reloadfiles() {
load("scripts/debug.js"); load("scripts/debug.js");
/*
function Color(from) { function Color(from) {
var color = Object.create(Array); var color = Object.create(Array);
Object.defineProperty(color, 'r', setelem(0)); Object.defineProperty(color, 'r', setelem(0));
@ -647,6 +667,7 @@ function Color(from) {
return color; return color;
}; };
*/
load("scripts/components.js"); load("scripts/components.js");
@ -1266,15 +1287,7 @@ function grab_from_points(pos, points, slop) {
}; };
var gameobject = { var gameobject = {
get scale() { return this._scale; }, scale: 1.0,
set scale(x) {
this._scale = Math.max(0,x);
if (this.body > -1)
cmd(36, this.body, this._scale);
this.sync();
},
_scale: 1.0,
save: true, save: true,
@ -1427,11 +1440,11 @@ var gameobject = {
this.instances.forEach(function(x) { x.sync(); }); this.instances.forEach(function(x) { x.sync(); });
}, },
pulse(vec) { pulse(vec) { /* apply impulse */
set_body(4, this.body, vec); set_body(4, this.body, vec);
}, },
push(vec) { push(vec) { /* apply force */
set_body(12,this.body,vec); set_body(12,this.body,vec);
}, },
@ -1477,6 +1490,18 @@ var gameobject = {
return bb ? bb : cwh2bb([0,0], [0,0]); return bb ? bb : cwh2bb([0,0], [0,0]);
}, },
set width(x) {},
get width() {
var bb = this.boundingbox;
Log.warn(bb);
return bb.r - bb.l;
},
set height(x) {},
get height() {
var bb = this.boundingbox;
return bb.t-bb.b;
},
stop() {}, stop() {},
kill() { kill() {
@ -1490,7 +1515,7 @@ var gameobject = {
this.uncontrol(); this.uncontrol();
this.instances.remove(this); this.instances.remove(this);
Register.unregister_obj(this); Register.unregister_obj(this);
Signal.clear_obj(this); // Signal.clear_obj(this);
this.body = -1; this.body = -1;
for (var key in this.components) { for (var key in this.components) {
@ -1538,6 +1563,30 @@ var gameobject = {
world2this(pos) { return cmd(70, this.body, pos); }, world2this(pos) { return cmd(70, this.body, pos); },
this2world(pos) { return cmd(71, this.body,pos); }, this2world(pos) { return cmd(71, this.body,pos); },
check_registers(obj) {
Register.unregister_obj(this);
if (typeof obj.update === 'function')
register_update(obj.update, obj);
if (typeof obj.physupdate === 'function')
register_physupdate(obj.physupdate, obj);
if (typeof obj.collide === 'function')
obj.register_hit(obj.collide, obj);
if (typeof obj.separate === 'function')
obj.register_separate(obj.separate, obj);
if (typeof obj.draw === 'function')
register_draw(obj.draw,obj);
obj.components.forEach(function(x) {
if (typeof x.collide === 'function')
register_collide(1, x.collide, x, obj.body, x.shape);
});
},
make(props, level) { make(props, level) {
level ??= World; level ??= World;
var obj = Object.create(this); var obj = Object.create(this);
@ -1600,25 +1649,7 @@ var gameobject = {
} }
}; };
if (typeof obj.update === 'function') obj.check_registers(obj);
register_update(obj.update, obj);
if (typeof obj.physupdate === 'function')
register_physupdate(obj.physupdate, obj);
if (typeof obj.collide === 'function')
obj.register_hit(obj.collide, obj);
if (typeof obj.separate === 'function')
obj.register_separate(obj.separate, obj);
if (typeof obj.draw === 'function')
register_draw(obj.draw,obj);
obj.components.forEach(function(x) {
if (typeof x.collide === 'function')
register_collide(1, x.collide, x, obj.body, x.shape);
});
if ('begin' in obj) obj.begin(); if ('begin' in obj) obj.begin();
@ -1641,11 +1672,8 @@ var gameobject = {
} }
var locks = ['visible', 'body', 'controlled', 'selectable', 'save', 'velocity', 'angularvelocity', 'alive', 'boundingbox', 'name', 'scale', 'angle', 'properties', 'moi', 'relpos', 'relangle', 'up', 'down', 'right', 'left', 'bodytype', 'gizmo', 'pos']; var locks = ['height', 'width', 'visible', 'body', 'controlled', 'selectable', 'save', 'velocity', 'angularvelocity', 'alive', 'boundingbox', 'name', 'scale', 'angle', 'properties', 'moi', 'relpos', 'relangle', 'up', 'down', 'right', 'left', 'bodytype', 'gizmo', 'pos'];
locks.forEach(function(x) { locks.forEach(x => gameobject.obscure(x));
Object.defineProperty(gameobject, x, {enumerable:false});
});
/* Load configs */ /* Load configs */
function load_configs(file) { function load_configs(file) {
var configs = JSON.parse(IO.slurp(file)); var configs = JSON.parse(IO.slurp(file));
@ -1790,3 +1818,5 @@ for (var key in prototypes) {
} }
function save_gameobjects_as_prototypes() { slurpwrite(JSON.stringify(gameobjects,null,2), "proto.json"); }; function save_gameobjects_as_prototypes() { slurpwrite(JSON.stringify(gameobjects,null,2), "proto.json"); };
let Gamestate = {};

View file

@ -3,3 +3,5 @@ if (load("game.js") === false) {
quit(); quit();
} }
sim_start();