From 97702f11ea016ca2e395f71f03c3fc3a2ee929ca Mon Sep 17 00:00:00 2001 From: esquizo Date: Sun, 17 May 2026 12:02:56 -0300 Subject: adicionado libphysics --- libphysics/tick.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 libphysics/tick.c (limited to 'libphysics/tick.c') diff --git a/libphysics/tick.c b/libphysics/tick.c new file mode 100644 index 0000000..c6399ab --- /dev/null +++ b/libphysics/tick.c @@ -0,0 +1,138 @@ +#include +#include +#include + +#include "dat.h" + +#define PHX_TICK_TIME (1.0 / 480.0) + +static void tick(void); +static void mapcollision(Body *); +static void bodycollision(Body *); + +#define TILE_SIZE 16 + +void +phxtick(float delta) +{ + static float time; + + time += delta; + if(time >= PHX_TICK_TIME > 0) { + while(time >= PHX_TICK_TIME) { + tick(); + time -= PHX_TICK_TIME; + } + for(int i = 0; i < phxbodypoolsize; i++) { + Body *b = phxbodypool + i; + if(!b->active) + continue; + + b->accel[0] = 0.0; + b->accel[1] = 0.0; + } + } +} + +void +tick(void) +{ + for(int i = 0; i < phxbodypoolsize; i++) { + Body *b = phxbodypool + i; + if(!b->active) + continue; + + vec2_add_scaled(b->vel, b->vel, b->accel, PHX_TICK_TIME); + } + + for(int i = 0; i < phxbodypoolsize; i++) { + Body *b = phxbodypool + i; + if(!b->active) + continue; + + mapcollision(b); + bodycollision(b); + } + + for(int i = 0; i < phxbodypoolsize; i++) { + Body *b = phxbodypool + i; + if(!b->active) + continue; + + vec2_add_scaled(b->pos, b->pos, b->vel, PHX_TICK_TIME); + } +} + +void +mapcollision(Body *a) +{ + int minx, miny, maxx, maxy; + + minx = ((int)(a->pos[0] - a->size[0]) / TILE_SIZE) * TILE_SIZE; + maxx = ((int)(a->pos[0] + a->size[0]) / TILE_SIZE) * TILE_SIZE; + miny = ((int)(a->pos[1] - a->size[1]) / TILE_SIZE) * TILE_SIZE; + maxy = ((int)(a->pos[1] + a->size[1]) / TILE_SIZE) * TILE_SIZE; + + for(int y = miny; y <= maxy + TILE_SIZE; y += TILE_SIZE) + for(int x = minx; x <= maxx + TILE_SIZE; x += TILE_SIZE) { + int tilex = x / (2 * TILE_SIZE); + int tiley = y / (2 * TILE_SIZE); + + if(tilex < 0 || tilex >= phxmapwidth) + continue; + if(tiley < 0 || tiley >= phxmapheight) + continue; + + if(!phxmapbuffer[tilex + tiley * phxmapwidth]) + continue; + + Body b = { + .pos = { + tilex * TILE_SIZE * 2.0, + tiley * TILE_SIZE * 2.0, + }, + .size = { TILE_SIZE, TILE_SIZE }, + }; + + if(phxaabbcheck(a, &b)) { + float p[2], n[2]; + phxaabbresolv(a, &b, p, n); + + vec2_sub(a->pos, a->pos, p); + + if(p[0] != 0.0) { + a->vel[0] = 0; + } else { + a->vel[1] = 0; + } + } + } +} + +void +bodycollision(Body *a) +{ + CollisionEvent event; + for(Body *b = a + 1; b < (a + phxbodypoolsize); b++) { + if(!b->active) + continue; + + if(phxaabbcheck(a, b)) { + float p[2], n[2], rvel[2], j; + phxaabbresolv(a, b, p, n); + + vec2_sub(rvel, a->vel, b->vel); + j = vec2_dot(rvel, n); + + vec2_sub_scaled(a->vel, a->vel, n, 0.5); + vec2_sub_scaled(b->vel, b->vel, n, -0.5); + + vec2_sub_scaled(a->pos, a->pos, p, 0.5); + vec2_sub_scaled(b->pos, b->pos, p, -0.5); + + event.body1 = a; + event.body2 = b; + phxenqevent(&event); + } + } +} -- cgit v1.2.3