JacksEscape/physics_move.c

98 lines
2.8 KiB
C
Raw Permalink Normal View History

2024-02-29 16:51:46 +08:00
2024-03-05 11:40:42 +08:00
#include "physics.h"
#include "entity.h"
#include "types.h"
2024-02-29 16:51:46 +08:00
#include "util/tree.h"
#include <stdlib.h>
2024-03-04 17:04:05 +08:00
#include <stdio.h>
2024-02-29 16:51:46 +08:00
static inline double dabs(double x) {
return x < 0 ? -x : x;
}
2024-03-01 17:09:24 +08:00
static inline void call_hithandler(Entity *me, Entity *other, Vec2 triedDelta, void *data) {
2024-03-01 14:37:59 +08:00
if (me->hitbox->onHit)
2024-03-01 17:09:24 +08:00
me->hitbox->onHit(me, other, triedDelta, data);
2024-03-01 14:37:59 +08:00
}
2024-03-05 10:42:17 +08:00
static inline void call_hitby(Entity *me, Entity *other, Vec2 triedDelta, void *data) {
if (me->hitbox->onHitBy)
me->hitbox->onHitBy(me, other, triedDelta, data);
}
2024-03-01 14:37:59 +08:00
2024-02-29 16:51:46 +08:00
void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime) {
double delta = e->position->velocity.x * duration_Seconds(deltaTime);
2024-03-01 13:29:29 +08:00
Box2 mybox = physics_HitboxAbsolute(e->hitbox);
2024-02-29 16:51:46 +08:00
if (dabs(delta) < EPS)
return;
for (tree_Node *i = tree_FirstNode(sys->hit);
i != NULL;
i = tree_Node_Next(i)) {
2024-03-01 13:29:29 +08:00
Component_Hitbox *tohit_comp = *((Component_Hitbox **)i->data);
Box2 tohit = physics_HitboxAbsolute(tohit_comp);
if (!tohit_comp->fixed)
2024-02-29 16:51:46 +08:00
continue;
2024-03-01 13:29:29 +08:00
if (box2_Intersects(tohit, box2_OffsetX(mybox, delta), NULL)) {
2024-03-01 17:09:24 +08:00
call_hithandler(e, tohit_comp->super, vec2(delta, 0), e->hitbox->onHitData);
2024-03-05 10:42:17 +08:00
call_hitby(tohit_comp->super, e, vec2(delta, 0), tohit_comp->onHitData);
2024-02-29 16:51:46 +08:00
if (delta > 0) {
// Moves right, hits left edge
2024-03-01 13:29:29 +08:00
double maxdelta = tohit.lefttop.x - mybox.lefttop.x - mybox.size.x;
2024-02-29 16:51:46 +08:00
delta = maxdelta - EPS;
} else {
// Moves left, hits right edge
2024-03-01 13:29:29 +08:00
double maxdelta = tohit.lefttop.x - mybox.lefttop.x + tohit.size.x;
2024-02-29 16:51:46 +08:00
delta = maxdelta + EPS;
}
2024-03-04 16:13:43 +08:00
e->position->velocity.x = 0;
2024-02-29 16:51:46 +08:00
}
if (dabs(delta) < EPS)
break;
}
if (dabs(delta) > EPS)
e->position->position.x += delta;
}
void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime) {
double delta = e->position->velocity.y * duration_Seconds(deltaTime);
2024-03-01 13:29:29 +08:00
Box2 mybox = physics_HitboxAbsolute(e->hitbox);
2024-02-29 16:51:46 +08:00
if (dabs(delta) < EPS)
return;
for (tree_Node *i = tree_FirstNode(sys->hit);
i != NULL;
i = tree_Node_Next(i)) {
2024-03-01 13:29:29 +08:00
Component_Hitbox *tohit_comp = *((Component_Hitbox **)i->data);
Box2 tohit = physics_HitboxAbsolute(tohit_comp);
if (!tohit_comp->fixed)
2024-02-29 16:51:46 +08:00
continue;
2024-03-01 13:29:29 +08:00
if (box2_Intersects(tohit, box2_OffsetY(mybox, delta), NULL)) {
2024-03-04 13:34:30 +08:00
call_hithandler(e, tohit_comp->super, vec2(0, delta), e->hitbox->onHitData);
2024-03-05 10:42:17 +08:00
call_hitby(tohit_comp->super, e, vec2(0, delta), tohit_comp->onHitData);
2024-02-29 16:51:46 +08:00
if (delta > 0) {
// Moves down, hits top edge
2024-03-01 13:29:29 +08:00
double maxdelta = tohit.lefttop.y - mybox.lefttop.y - mybox.size.y;
2024-02-29 16:51:46 +08:00
delta = maxdelta - EPS;
} else {
// Moves up, hits bottom edge
2024-03-01 13:29:29 +08:00
double maxdelta = tohit.lefttop.y - mybox.lefttop.y + tohit.size.y;
2024-02-29 16:51:46 +08:00
delta = maxdelta + EPS;
}
2024-03-04 16:13:43 +08:00
e->position->velocity.y = 0;
2024-02-29 16:51:46 +08:00
}
if (dabs(delta) < EPS)
break;
}
if (dabs(delta) > EPS)
e->position->position.y += delta;
}