Properly kill gameobjects, sprites, physics shapes

This commit is contained in:
John Alanbrook 2023-01-13 14:05:36 +00:00
parent e0b7d6459d
commit d2cbc61164
10 changed files with 116 additions and 81 deletions

View file

@ -41,10 +41,12 @@ void phys2d_shape_apply(struct phys2d_shape *shape)
cpShapeSetElasticity(shape->shape, id2go(shape->go)->e);
}
void init_phys2dshape(struct phys2d_shape *shape, int go)
void init_phys2dshape(struct phys2d_shape *shape, int go, void *data)
{
shape->go = go;
cpShapeSetCollisionType(shape->shape, id2go(go));
shape->data = data;
cpShapeSetCollisionType(shape->shape, go);
cpShapeSetUserData(shape->shape, shape);
phys2d_shape_apply(shape);
}
@ -62,7 +64,8 @@ struct phys2d_circle *Make2DCircle(int go)
new->offset[1] = 0.f;
new->shape.shape = cpSpaceAddShape(space, cpCircleShapeNew(id2go(go)->body, new->radius, cpvzero));
init_phys2dshape(&new->shape, go);
new->shape.debugdraw = phys2d_dbgdrawcircle;
init_phys2dshape(&new->shape, go, new);
return new;
}
@ -82,7 +85,6 @@ void circle_gui(struct phys2d_circle *circle)
void phys2d_dbgdrawcpcirc(cpCircleShape *c)
{
YughInfo("DRAW CIRCLE");
cpVect pos = cpBodyGetPosition(cpShapeGetBody(c));
cpVect offset = cpCircleShapeGetOffset(c);
float radius = cpCircleShapeGetRadius(c);
@ -93,7 +95,6 @@ void phys2d_dbgdrawcpcirc(cpCircleShape *c)
void phys2d_dbgdrawcircle(struct phys2d_circle *circle)
{
YughInfo("Drawing a circle");
phys2d_dbgdrawcpcirc((cpCircleShape *)circle->shape.shape);
cpVect p = cpBodyGetPosition(cpShapeGetBody(circle->shape.shape));
@ -118,7 +119,8 @@ struct phys2d_segment *Make2DSegment(int go)
new->b[1] = 0.f;
new->shape.shape = cpSpaceAddShape(space, cpSegmentShapeNew(id2go(go)->body, cpvzero, cpvzero, new->thickness));
init_phys2dshape(&new->shape, go);
new->shape.debugdraw = phys2d_dbgdrawseg;
init_phys2dshape(&new->shape, go, new);
return new;
}
@ -150,7 +152,8 @@ struct phys2d_box *Make2DBox(int go)
new->offset[1] = 0.f;
new->shape.shape = cpSpaceAddShape(space, cpBoxShapeNew(id2go(go)->body, new->w, new->h, new->r));
init_phys2dshape(&new->shape, go);
new->shape.debugdraw = phys2d_dbgdrawbox;
init_phys2dshape(&new->shape, go, new);
phys2d_applybox(new);
return new;
@ -182,7 +185,8 @@ struct phys2d_poly *Make2DPoly(int go)
cpTransform T = { 0 };
new->shape.shape = cpSpaceAddShape(space, cpPolyShapeNew(id2go(go)->body, 0, NULL, T, new->radius));
init_phys2dshape(&new->shape, go);
init_phys2dshape(&new->shape, go, new);
new->shape.debugdraw = phys2d_dbgdrawpoly;
phys2d_applypoly(new);
return new;
@ -453,16 +457,15 @@ void register_collide(void *sym) {
}
static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data) {
struct gameobject *go = data;
cpBody *body1;
cpBody *body2;
cpArbiterGetBodies(arb, &body1, &body2);
struct gameobject *g2 = cpBodyGetUserData(body2);
int g1 = cpBodyGetUserData(body1);
int g2 = cpBodyGetUserData(body2);
duk_push_heapptr(duk, go->cbs.begin.fn);
duk_push_heapptr(duk, go->cbs.begin.obj);
duk_push_heapptr(duk, id2go(g1)->cbs.begin.fn);
duk_push_heapptr(duk, id2go(g1)->cbs.begin.obj);
int obj = duk_push_object(duk);
@ -492,10 +495,9 @@ static void s7_phys_cb_separate(cpArbiter *Arb, cpSpace *space, void *data) {
}
void phys2d_add_handler_type(int cmd, int go, struct callee c) {
/*
cpCollisionHandler *handler = cpSpaceAddWildcardHandler(space, go);
handler->userData = id2go(go);
handler->userData = go;
switch (cmd) {
case 0:
@ -514,5 +516,5 @@ void phys2d_add_handler_type(int cmd, int go, struct callee c) {
//go->cbs->separate = cb;
break;
}
*/
}

View file

@ -4,7 +4,6 @@
#include <chipmunk/chipmunk.h>
#include "script.h"
extern cpBody *ballBody;
extern float phys2d_gravity;
extern int physOn;
extern cpSpace *space;
@ -12,6 +11,8 @@ extern cpSpace *space;
struct phys2d_shape {
cpShape *shape;
int go;
void *data;
void (*debugdraw)(void *data);
};
struct phys2d_circle {

View file

@ -100,7 +100,7 @@ duk_ret_t duk_cmd(duk_context *duk) {
break;
case 10:
remove_pawn(duk_get_heapptr(duk, 1));
break;
case 11:
@ -145,7 +145,7 @@ duk_ret_t duk_register_collide(duk_context *duk) {
struct callee c = {fn, obj};
YughInfo("Registering ...");
phys2d_add_handler_type(0, get_gameobject_from_id(go), c);
phys2d_add_handler_type(0, go, c);
return 0;
}
@ -310,7 +310,7 @@ duk_ret_t duk_sprite(duk_context *duk) {
int id = duk_to_int(duk, 1);
switch (cmd) {
case 0:
case 0: break;
}
}
@ -326,7 +326,6 @@ duk_ret_t duk_make_sprite(duk_context *duk) {
sp->pos[0] = pos.x;
sp->pos[1] = pos.y;
duk_push_int(duk, sprite);
return 1;
}

View file

@ -15,7 +15,7 @@
#include "stb_ds.h"
struct gameobject *gameobjects = NULL;
struct gameobject *first = NULL;
static int first = -1;
const int nameBuf[MAXNAME] = { 0 };
const int prefabNameBuf[MAXNAME] = { 0 };
@ -66,46 +66,66 @@ int MakeGameobject()
struct gameobject go = {
.scale = 1.f,
.bodytype = CP_BODY_TYPE_STATIC,
.mass = 1.f
.mass = 1.f,
.next = -1
};
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f));
struct gameobject *tar;
int retid;
if (!first) {
if (first<0) {
arrput(gameobjects, go);
tar = &arrlast(gameobjects);
retid = arrlen(gameobjects)-1;
tar->id = retid;
retid = arrlast(gameobjects).id = arrlen(gameobjects)-1;
} else {
retid = first->id;
struct gameobject *next = first->next;
YughInfo("Created in slot %d.", retid);
tar = first;
*first = go;
first->id = retid;
first = next;
retid = first;
first = id2go(first)->next;
*id2go(retid) = go;
}
cpBodySetUserData(go.body, tar);
YughInfo("Made game object with ID ===== %d", retid);
cpBodySetUserData(go.body, retid);
return retid;
}
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
struct phys2d_shape *s = cpShapeGetUserData(shape);
free(s->data);
cpSpaceRemoveShape(space, shape);
}
/* Really more of a "mark for deletion" ... */
void gameobject_delete(int id)
{
YughInfo("Deleting gameobject with id %d.", id);
struct gameobject *go = id2go(id);
cpSpaceRemoveBody(space, go->body);
go->next = first;
first = go;
id2go(id)->next = first;
first = id;
}
YughInfo("Did it to %d.", first->id);
void gameobject_clean(int id) {
if (id < 0) {
YughError("Tried to clean ID %d.", id);
return;
}
struct gameobject *go = id2go(id);
cpBodyEachShape(go->body, rm_body_shapes, NULL);
cpSpaceRemoveBody(space, go->body);
go->body = NULL;
}
static int last_cleaned = -1;
void gameobjects_cleanup() {
if (first < 0) {
last_cleaned = first;
return;
}
int clean = first;
while (clean != last_cleaned) {
gameobject_clean(clean);
clean = id2go(clean)->next;
}
last_cleaned = first;
}
void gameobject_save(struct gameobject *go, FILE * file)
@ -330,17 +350,19 @@ void object_gui(struct gameobject *go)
*/
}
void body_draw_shapes_dbg(cpBody *body, cpShape *shape, void *data) {
struct phys2d_shape *s = cpShapeGetUserData(shape);
s->debugdraw(s->data);
}
void gameobject_draw_debugs() {
/*
YughInfo("DRAWING DEBUG");
for (int i = 0; i < arrlen(gameobjects); i++) {
YughInfo("Drawing this many ... %d", arrlen(gameobjects[i].components));
for (int j = 0; j < arrlen(gameobjects[i].components); j++) {
struct component *c = &gameobjects[i].components[j];
comp_draw_debug(c);
if (!gameobjects[i].body) continue;
cpBodyEachShape(gameobjects[i].body, body_draw_shapes_dbg, NULL);
}
}
*/
}

View file

@ -24,10 +24,8 @@ struct editor {
};
struct gameobject {
union {
cpBodyType bodytype;
struct gameobject *next;
};
int next;
float scale;
float mass;
float f; /* friction */
@ -44,6 +42,7 @@ extern struct gameobject *gameobjects;
int MakeGameobject();
void gameobject_apply(struct gameobject *go);
void gameobject_delete(int id);
void gameobjects_cleanup();
void toggleprefab(struct gameobject *go);
struct gameobject *get_gameobject_from_id(int id);

View file

@ -23,7 +23,15 @@ static void **pawns = NULL;
void set_pawn(void *pawn) {
arrput(pawns, pawn);
YughInfo("Now controling %d pawns.", arrlen(pawns));
}
void remove_pawn(void *pawn) {
for (int i = 0; i < arrlen(pawns); i++) {
if (pawns[i] == pawn) {
pawns[i] = NULL;
return;
}
}
}
static void cursor_pos_cb(GLFWwindow *w, double xpos, double ypos)
@ -48,9 +56,14 @@ void input_init()
}
void call_input_signal(char *signal) {
for (int i = 0; i < arrlen(pawns); i++)
for (int i = arrlen(pawns)-1; i >= 0; i--) {
if (pawns[i] == NULL) arrdel(pawns, i);
}
for (int i = 0; i < arrlen(pawns); i++) {
script_eval_w_env(signal, pawns[i]);
}
}
const char *keyname_extd(int key, int scancode) {
char keybuf[50];

View file

@ -31,5 +31,6 @@ struct inputaction
};
void set_pawn(void *pawn);
void remove_pawn(void *pawn);
#endif

View file

@ -14,41 +14,43 @@
struct TextureOptions TEX_SPRITE = { 1, 0, 0 };
struct sprite *sprites;
struct sprite *first;
static struct sprite *sprites;
static int first = -1;
static uint32_t VBO;
int make_sprite(int go)
{
YughInfo("Making sprite with gameobject %d", go);
struct sprite sprite = {
.color = {1.f, 1.f, 1.f},
.size = {1.f, 1.f},
.tex = texture_loadfromfile("ph.png"),
.go = go,
.next = NULL };
.next = -1 };
int ret;
if (!first) {
YughInfo("Making a brand new sprite.");
if (first<0) {
arrput(sprites, sprite);
arrlast(sprites).id = arrlen(sprites)-1;
return arrlen(sprites)-1;
} else {
YughInfo("Reusing a sprite slot.");
int slot = first->id;
struct sprite *next = first->next;
*first = sprite;
first->id = slot;
first = next;
int slot = first;
first = id2sprite(first)->next;
*id2sprite(slot) = sprite;
return slot;
}
}
void sprite_delete(int id)
{
struct sprite *sp = id2sprite(id);
sp->go = -1;
sp->next = first;
first = id;
}
struct sprite *id2sprite(int id) {
return &sprites[id];
}
@ -72,13 +74,7 @@ void sprite_io(struct sprite *sprite, FILE *f, int read)
}
}
void sprite_delete(int id)
{
struct sprite *sp = id2sprite(id);
sp->go = -1;
sp->next = first;
first = sp;
}
void sprite_draw_all()
{

View file

@ -19,7 +19,7 @@ struct sprite {
int id;
struct TexAnimation anim;
struct Texture *tex;
struct sprite *next;
int next;
};
int make_sprite(int go);

View file

@ -199,6 +199,8 @@ int main(int argc, char **args) {
window_renderall();
}
gameobjects_cleanup();
}
return 0;