diff options
Diffstat (limited to 'src/physics.c')
-rw-r--r-- | src/physics.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/physics.c b/src/physics.c new file mode 100644 index 0000000..6567dc4 --- /dev/null +++ b/src/physics.c @@ -0,0 +1,76 @@ +#include "physics.h" +#include "game.h" + +extern Game game; + +static inline bool PhysicsEnabled(const Entity* e) { + return EntityAllocated(e) && (e->flags & ENTITY_PHYSICS_ACTIVE); +} + +static inline bool IsColliding(const Rectangle* a, const Rectangle* b) { + bool collisionX = (a->x <= b->x && a->x + a->width > b->x) + || (b->x <= a->x && b->x + b->width > a->x); + + bool collisionY = (a->y <= b->y && a->y + a->height > b->y) + || (b->y <= a->y && b->y + b->height > a->y); + + return collisionX && collisionY; +} + +static inline Rectangle GetPhysicsColliderGlobal(const Entity* e) { + Rectangle physicsColliderGlobal = e->physicsCollider; + physicsColliderGlobal.x += e->position.x; + physicsColliderGlobal.y += e->position.y; + + return physicsColliderGlobal; +} + +void MoveAndSlide(Entity* e, float deltaTime) { + Vector2 velocity = e->velocity; + Rectangle physicsCollider = GetPhysicsColliderGlobal(e); + + physicsCollider.x += e->velocity.x * deltaTime; + for (int i = 0; i < MAX_ENTITY_COUNT; i++) { + Entity* c = &game.entities[i]; + + if(!PhysicsEnabled(c) || SameEntity(c, e)) continue; + Rectangle otherCollider = GetPhysicsColliderGlobal(c); + + if(IsColliding(&physicsCollider, &otherCollider)) { + if (velocity.x > 0) { + physicsCollider.x = otherCollider.x - physicsCollider.width; + } else { + physicsCollider.x = otherCollider.x + otherCollider.width; + } + } + } + + physicsCollider.y += e->velocity.y * deltaTime; + for (int i = 0; i < MAX_ENTITY_COUNT; i++) { + Entity* c = &game.entities[i]; + + if(!PhysicsEnabled(c) || SameEntity(c, e)) continue; + Rectangle otherCollider = GetPhysicsColliderGlobal(c); + + if(IsColliding(&physicsCollider, &otherCollider)) { + if (velocity.y > 0) { + physicsCollider.y = otherCollider.y - physicsCollider.height; + } else { + physicsCollider.y = otherCollider.y + otherCollider.height; + } + } + } + + e->position.x = physicsCollider.x; + e->position.y = physicsCollider.y; +} + +#ifdef BEATEMUP_DEBUG +void DebugHighlights(const Entity* e) { + if (!PhysicsEnabled(e)) + return; + + Rectangle dstRect = GetPhysicsColliderGlobal(e); + DrawRectangle(dstRect.x, dstRect.y, dstRect.width, dstRect.height, e->physicsColliderColor); +} +#endif |