work
This commit is contained in:
parent
bea5b326cf
commit
d3cb9278a9
|
@ -32,6 +32,24 @@ associated script file can access.
|
||||||
While playing ...
|
While playing ...
|
||||||
* F7 Stop
|
* F7 Stop
|
||||||
|
|
||||||
|
.Level model
|
||||||
|
The game world is made up of objects. Levels are collections of
|
||||||
|
objects. The topmost level is called "World". Objects are spawned into
|
||||||
|
a specific level. If none are explicitly given, objects are spawned
|
||||||
|
into World. Objects in turn are made up of components - sprites,
|
||||||
|
colliders, and so on. Accessing an object might go like this:
|
||||||
|
|
||||||
|
World.level1.enemy1.sprite.path = "brick.png";
|
||||||
|
|
||||||
|
To set the image of enemy1 in level 1's sprite.
|
||||||
|
|
||||||
|
.Textures & images
|
||||||
|
A sprite is a display of a specific texture in the game world. The
|
||||||
|
underlying texture has values associated with it, like how it should
|
||||||
|
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
|
||||||
|
explicit path to their associated image file.
|
||||||
|
|
||||||
.Scripting
|
.Scripting
|
||||||
|
|
||||||
Levels and objects have certain functions you can use that will be
|
Levels and objects have certain functions you can use that will be
|
||||||
|
|
|
@ -41,8 +41,8 @@ void set_cat_mask(int cat, unsigned int mask)
|
||||||
void color2float(struct color color, float *fcolor)
|
void color2float(struct color color, float *fcolor)
|
||||||
{
|
{
|
||||||
fcolor[0] = (float)color.r/255;
|
fcolor[0] = (float)color.r/255;
|
||||||
fcolor[1] = (float)color.b/255;
|
fcolor[1] = (float)color.g/255;
|
||||||
fcolor[2] = (float)color.g/255;
|
fcolor[2] = (float)color.b/255;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct color float2color(float *fcolor)
|
struct color float2color(float *fcolor)
|
||||||
|
|
|
@ -65,6 +65,11 @@ double js2number(JSValue v)
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int js2bool(JSValue v)
|
||||||
|
{
|
||||||
|
return JS_ToBool(js,v);
|
||||||
|
}
|
||||||
|
|
||||||
JSValue float2js(double g)
|
JSValue float2js(double g)
|
||||||
{
|
{
|
||||||
return JS_NewFloat64(js,g);
|
return JS_NewFloat64(js,g);
|
||||||
|
@ -931,6 +936,23 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
|
|
||||||
case 93:
|
case 93:
|
||||||
ret = int2js(logLevel);
|
ret = int2js(logLevel);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 94:
|
||||||
|
str = JS_ToCString(js,argv[1]);
|
||||||
|
texture_pullfromfile(str)->opts.mips = js2bool(argv[2]);
|
||||||
|
texture_sync(str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 95:
|
||||||
|
str = JS_ToCString(js,argv[1]);
|
||||||
|
texture_pullfromfile(str)->opts.sprite = js2bool(argv[2]);
|
||||||
|
texture_sync(str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 96:
|
||||||
|
color2float(js2color(argv[2]), id2sprite(js2int(argv[1]))->color);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str)
|
if (str)
|
||||||
|
@ -1237,7 +1259,6 @@ JSValue duk_make_sprite(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
JS_FreeCString(js,path);
|
JS_FreeCString(js,path);
|
||||||
|
|
||||||
return JS_NewInt64(js, sprite);
|
return JS_NewInt64(js, sprite);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make anim from texture */
|
/* Make anim from texture */
|
||||||
|
|
|
@ -189,6 +189,7 @@ void joystick_cb(int jid, int event)
|
||||||
|
|
||||||
JSValue jsgamepadstr[15];
|
JSValue jsgamepadstr[15];
|
||||||
JSValue jsaxesstr[4];
|
JSValue jsaxesstr[4];
|
||||||
|
JSValue jsaxis;
|
||||||
|
|
||||||
void input_init()
|
void input_init()
|
||||||
{
|
{
|
||||||
|
@ -205,10 +206,11 @@ void input_init()
|
||||||
for (int b = 0; b < 15; b++)
|
for (int b = 0; b < 15; b++)
|
||||||
jsgamepadstr[b] = str2js(gamepad2str(b));
|
jsgamepadstr[b] = str2js(gamepad2str(b));
|
||||||
|
|
||||||
jsaxesstr[0] = str2js("axis_ljoy");
|
jsaxesstr[0] = str2js("ljoy");
|
||||||
jsaxesstr[1] = str2js("axis_rjoy");
|
jsaxesstr[1] = str2js("rjoy");
|
||||||
jsaxesstr[2] = str2js("axis_ltrigger");
|
jsaxesstr[2] = str2js("ltrigger");
|
||||||
jsaxesstr[3] = str2js("axis_rtrigger");
|
jsaxesstr[3] = str2js("rtrigger");
|
||||||
|
jsaxis = str2js("axis");
|
||||||
|
|
||||||
/* Grab all joysticks initially present */
|
/* Grab all joysticks initially present */
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
|
@ -397,7 +399,7 @@ void input_poll(double wait)
|
||||||
GLFWgamepadstate state;
|
GLFWgamepadstate state;
|
||||||
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
||||||
|
|
||||||
JSValue argv[3];
|
JSValue argv[4];
|
||||||
argv[0] = num_cache[joysticks[i].id];
|
argv[0] = num_cache[joysticks[i].id];
|
||||||
for (int b = 0; b < 15; b++) {
|
for (int b = 0; b < 15; b++) {
|
||||||
argv[1] = jsgamepadstr[b];
|
argv[1] = jsgamepadstr[b];
|
||||||
|
@ -417,30 +419,37 @@ void input_poll(double wait)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argv[2] = jsaxis;
|
||||||
|
|
||||||
|
float deadzone = 0.05;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
state.axes[i] = fabs(state.axes[i]) > deadzone ? state.axes[i] : 0;
|
||||||
|
|
||||||
argv[1] = jsaxesstr[0];
|
argv[1] = jsaxesstr[0];
|
||||||
cpVect v;
|
cpVect v;
|
||||||
v.x = state.axes[0];
|
v.x = state.axes[0];
|
||||||
v.y = -state.axes[1];
|
v.y = -state.axes[1];
|
||||||
argv[2] = vec2js(v);
|
argv[3] = vec2js(v);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,4,argv);
|
||||||
JS_FreeValue(js, argv[2]);
|
JS_FreeValue(js, argv[3]);
|
||||||
|
|
||||||
argv[1] = jsaxesstr[1];
|
argv[1] = jsaxesstr[1];
|
||||||
v.x = state.axes[2];
|
v.x = state.axes[2];
|
||||||
v.y = -state.axes[3];
|
v.y = -state.axes[3];
|
||||||
argv[2] = vec2js(v);
|
argv[3] = vec2js(v);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,4,argv);
|
||||||
JS_FreeValue(js, argv[2]);
|
JS_FreeValue(js, argv[3]);
|
||||||
|
|
||||||
argv[1] = jsaxesstr[2];
|
argv[1] = jsaxesstr[2];
|
||||||
argv[2] = num2js((state.axes[4]+1)/2);
|
argv[3] = num2js((state.axes[4]+1)/2);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,4,argv);
|
||||||
JS_FreeValue(js, argv[2]);
|
JS_FreeValue(js, argv[3]);
|
||||||
|
|
||||||
argv[1] = jsaxesstr[3];
|
argv[1] = jsaxesstr[3];
|
||||||
argv[2] = num2js((state.axes[5]+1)/2);
|
argv[3] = num2js((state.axes[5]+1)/2);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,4,argv);
|
||||||
JS_FreeValue(js, argv[2]);
|
JS_FreeValue(js, argv[3]);
|
||||||
|
|
||||||
joysticks[i].state = state;
|
joysticks[i].state = state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ void sprite_initialize()
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], float offset[2], struct glrect r) {
|
void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], float offset[2], struct glrect r, mfloat_t color[3]) {
|
||||||
mfloat_t model[16] = { 0.f };
|
mfloat_t model[16] = { 0.f };
|
||||||
mfloat_t r_model[16] = { 0.f };
|
mfloat_t r_model[16] = { 0.f };
|
||||||
mfloat_t s_model[16] = { 0.f };
|
mfloat_t s_model[16] = { 0.f };
|
||||||
|
@ -142,9 +142,8 @@ void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], flo
|
||||||
|
|
||||||
mat4_translate_vec2(model, pos);
|
mat4_translate_vec2(model, pos);
|
||||||
|
|
||||||
float white[3] = { 1.f, 1.f, 1.f };
|
|
||||||
shader_setmat4(spriteShader, "model", model);
|
shader_setmat4(spriteShader, "model", model);
|
||||||
shader_setvec3(spriteShader, "spriteColor", white);
|
shader_setvec3(spriteShader, "spriteColor", color);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->id);
|
glBindTexture(GL_TEXTURE_2D, tex->id);
|
||||||
|
@ -173,7 +172,7 @@ void sprite_draw(struct sprite *sprite)
|
||||||
cpVect cpos = cpBodyGetPosition(go->body);
|
cpVect cpos = cpBodyGetPosition(go->body);
|
||||||
float pos[2] = {cpos.x, cpos.y};
|
float pos[2] = {cpos.x, cpos.y};
|
||||||
float size[2] = { sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy };
|
float size[2] = { sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy };
|
||||||
tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, sprite->frame);
|
tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, sprite->frame, sprite->color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +189,8 @@ void gui_draw_img(const char *img, float x, float y) {
|
||||||
float pos[2] = {x, y};
|
float pos[2] = {x, y};
|
||||||
float size[2] = {1.f, 1.f};
|
float size[2] = {1.f, 1.f};
|
||||||
float offset[2] = { 0.f, 0.f };
|
float offset[2] = { 0.f, 0.f };
|
||||||
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex));
|
float white[3] = {1.f,1.f,1.f};
|
||||||
|
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex), white);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_setframe(struct sprite *sprite, struct glrect *frame)
|
void sprite_setframe(struct sprite *sprite, struct glrect *frame)
|
||||||
|
|
|
@ -34,24 +34,11 @@ struct Texture *texture_pullfromfile(const char *path)
|
||||||
|
|
||||||
YughInfo("Loading texture %s.", path);
|
YughInfo("Loading texture %s.", path);
|
||||||
struct Texture *tex = calloc(1, sizeof(*tex));
|
struct Texture *tex = calloc(1, sizeof(*tex));
|
||||||
|
tex->opts.sprite = 1;
|
||||||
/* Find texture's asset; otherwise load default asset */
|
tex->opts.mips = 0;
|
||||||
JSON_Value *rv = json_parse_file("texture.asset");
|
|
||||||
JSON_Object *ro = json_value_get_object(rv);
|
|
||||||
tex->opts.sprite = json_object_get_boolean(ro, "sprite");
|
|
||||||
tex->opts.mips = json_object_get_boolean(ro, "mips");
|
|
||||||
json_value_free(rv);
|
|
||||||
|
|
||||||
tex->opts.gamma = 0;
|
tex->opts.gamma = 0;
|
||||||
|
|
||||||
|
|
||||||
tex->anim.ms = 2;
|
|
||||||
tex->anim.tex = tex;
|
|
||||||
texanim_fromframes(&tex->anim, 2);
|
|
||||||
tex->anim.loop = 1;
|
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
|
@ -89,12 +76,22 @@ struct Texture *texture_pullfromfile(const char *path)
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
if (tex->opts.sprite) {
|
if (tex->opts.sprite) {
|
||||||
|
if (tex->opts.mips) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||||
|
} else {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (tex->opts.mips) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
} else {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
@ -107,6 +104,36 @@ struct Texture *texture_pullfromfile(const char *path)
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void texture_sync(const char *path)
|
||||||
|
{
|
||||||
|
struct Texture *tex = texture_pullfromfile(path);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex->id);
|
||||||
|
if (tex->opts.mips)
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
if (tex->opts.sprite) {
|
||||||
|
if (tex->opts.mips) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||||
|
} else {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tex->opts.mips) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
} else {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
char *tex_get_path(struct Texture *tex) {
|
char *tex_get_path(struct Texture *tex) {
|
||||||
for (int i = 0; i < shlen(texhash); i++) {
|
for (int i = 0; i < shlen(texhash); i++) {
|
||||||
if (tex == texhash[i].value) {
|
if (tex == texhash[i].value) {
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct Texture {
|
||||||
|
|
||||||
struct Texture *texture_pullfromfile(const char *path); // Create texture from image
|
struct Texture *texture_pullfromfile(const char *path); // Create texture from image
|
||||||
struct Texture *texture_loadfromfile(const char *path); // Create texture & load to gpu
|
struct Texture *texture_loadfromfile(const char *path); // Create texture & load to gpu
|
||||||
|
void texture_sync(const char *path);
|
||||||
struct Texture *str2tex(const char *path);
|
struct Texture *str2tex(const char *path);
|
||||||
void tex_gpu_reload(struct Texture *tex); // gpu_free then gpu_load
|
void tex_gpu_reload(struct Texture *tex); // gpu_free then gpu_load
|
||||||
void tex_gpu_free(struct Texture *tex); // Remove texture data from gpu
|
void tex_gpu_free(struct Texture *tex); // Remove texture data from gpu
|
||||||
|
|
|
@ -105,6 +105,10 @@ var sprite = clone(component, {
|
||||||
cmd(37, this.id, this.pos);
|
cmd(37, this.id, this.pos);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set color(x) {
|
||||||
|
cmd(96, this.id, x);
|
||||||
|
},
|
||||||
|
|
||||||
load_img(img) {
|
load_img(img) {
|
||||||
cmd(12, this.id, img, this.rect);
|
cmd(12, this.id, img, this.rect);
|
||||||
},
|
},
|
||||||
|
@ -679,3 +683,35 @@ var circle2d = clone(collider2d, {
|
||||||
this.coll_sync();
|
this.coll_sync();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* ASSETS */
|
||||||
|
|
||||||
|
var Texture = {
|
||||||
|
mipmaps(path, x) {
|
||||||
|
cmd(94, path, x);
|
||||||
|
},
|
||||||
|
|
||||||
|
sprite(path, x) {
|
||||||
|
cmd(95, path, x);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var Resources = {
|
||||||
|
load(path) {
|
||||||
|
if (path in this)
|
||||||
|
return this[path];
|
||||||
|
|
||||||
|
var src = {};
|
||||||
|
this[path] = src;
|
||||||
|
src.path = path;
|
||||||
|
|
||||||
|
if (!IO.exists(`${path}.asset`))
|
||||||
|
return this[path];
|
||||||
|
|
||||||
|
var data = JSON.parse(IO.slurp(`${path}.asset`));
|
||||||
|
Object.assign(src,data);
|
||||||
|
return this[path];
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -420,7 +420,7 @@ var Action = {
|
||||||
var Player = {
|
var Player = {
|
||||||
players: [],
|
players: [],
|
||||||
input(fn, ...args) {
|
input(fn, ...args) {
|
||||||
this.pawns.forEach(x => { if (fn in x) x[fn](...args); });
|
this.pawns.forEach(x => x[fn]?.(...args));
|
||||||
},
|
},
|
||||||
|
|
||||||
control(pawn) {
|
control(pawn) {
|
||||||
|
@ -440,6 +440,7 @@ for (var i = 0; i < 4; i++) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function state2str(state) {
|
function state2str(state) {
|
||||||
|
if (typeof state === 'string') return state;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 0:
|
case 0:
|
||||||
return "down";
|
return "down";
|
||||||
|
@ -723,6 +724,7 @@ var Game = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var Level = {
|
var Level = {
|
||||||
levels: [],
|
levels: [],
|
||||||
objects: [],
|
objects: [],
|
||||||
|
@ -922,6 +924,8 @@ var Level = {
|
||||||
newobj.defn('level', this);
|
newobj.defn('level', this);
|
||||||
this.objects.push(newobj);
|
this.objects.push(newobj);
|
||||||
Game.register_obj(newobj);
|
Game.register_obj(newobj);
|
||||||
|
newobj.setup?.();
|
||||||
|
newobj.start?.();
|
||||||
return newobj;
|
return newobj;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1185,9 +1189,11 @@ var Level = {
|
||||||
get left() {
|
get left() {
|
||||||
return [-1,0].rotate(Math.deg2rad(this.angle));
|
return [-1,0].rotate(Math.deg2rad(this.angle));
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var World = Level.create();
|
||||||
|
World.name = "World";
|
||||||
|
|
||||||
var gameobjects = {};
|
var gameobjects = {};
|
||||||
|
|
||||||
/* Returns the index of the smallest element in array, defined by a function that returns a number */
|
/* Returns the index of the smallest element in array, defined by a function that returns a number */
|
||||||
|
@ -1211,7 +1217,13 @@ function grab_from_points(pos, points, slop) {
|
||||||
|
|
||||||
var gameobject = {
|
var gameobject = {
|
||||||
get scale() { return this._scale; },
|
get scale() { return this._scale; },
|
||||||
set scale(x) { this._scale = Math.max(0,x); if (this.body > -1) cmd(36, this.body, this._scale); this.sync(); },
|
set scale(x) {
|
||||||
|
this._scale = Math.max(0,x);
|
||||||
|
if (this.body > -1)
|
||||||
|
cmd(36, this.body, this._scale);
|
||||||
|
|
||||||
|
this.sync();
|
||||||
|
},
|
||||||
_scale: 1.0,
|
_scale: 1.0,
|
||||||
|
|
||||||
save: true,
|
save: true,
|
||||||
|
@ -1310,6 +1322,26 @@ var gameobject = {
|
||||||
body: -1,
|
body: -1,
|
||||||
controlled: false,
|
controlled: false,
|
||||||
|
|
||||||
|
get properties() {
|
||||||
|
var keys = [];
|
||||||
|
for (var key of Object.keys(this)) {
|
||||||
|
if (key.startsWith("_"))
|
||||||
|
keys.push(key.substring(1));
|
||||||
|
else
|
||||||
|
keys.push(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
},
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
var obj = {};
|
||||||
|
for (var key of this.properties)
|
||||||
|
obj[key] = this[key];
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
set_center(pos) {
|
set_center(pos) {
|
||||||
var change = pos.sub(this.pos);
|
var change = pos.sub(this.pos);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
|
@ -1515,6 +1547,7 @@ var gameobject = {
|
||||||
this2world(pos) { return cmd(71, this.body,pos); },
|
this2world(pos) { return cmd(71, this.body,pos); },
|
||||||
|
|
||||||
make(props, level) {
|
make(props, level) {
|
||||||
|
level ??= World;
|
||||||
var obj = Object.create(this);
|
var obj = Object.create(this);
|
||||||
this.instances.push(obj);
|
this.instances.push(obj);
|
||||||
obj.toString = function() {
|
obj.toString = function() {
|
||||||
|
@ -1584,39 +1617,11 @@ var gameobject = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var locks = ['draw_layer', 'friction','elasticity', 'visible', 'body', 'flipx', 'flipy', 'scale', 'controlled', 'selectable', 'save', 'velocity', 'angularvelocity', 'alive', 'boundingbox', 'name'];
|
var locks = ['draw_layer', 'friction','elasticity', 'visible', 'body', 'flipx', 'flipy', '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(function(x) {
|
||||||
Object.defineProperty(gameobject, x, {enumerable:false});
|
Object.defineProperty(gameobject, x, {enumerable:false});
|
||||||
});
|
});
|
||||||
|
|
||||||
function private_non_enumerable(obj) {
|
|
||||||
for (var key in obj) {
|
|
||||||
if (key.startsWith('_'))
|
|
||||||
Object.defineProperty(obj, key, {enumerable:false});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function add_sync_prop(obj, prop, syncfn) {
|
|
||||||
var hidden = "_"+prop;
|
|
||||||
Log.info(hidden);
|
|
||||||
Object.defineProperty(obj, hidden, {
|
|
||||||
value: null,
|
|
||||||
writable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(obj, prop, {
|
|
||||||
get: function() { return obj[hidden]; },
|
|
||||||
set: function(x) {
|
|
||||||
obj[hidden] = x;
|
|
||||||
syncfn(obj[hidden]);
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 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));
|
||||||
|
@ -1761,5 +1766,3 @@ 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"); };
|
||||||
|
|
||||||
Resources = {};
|
|
||||||
|
|
Loading…
Reference in a new issue