summaryrefslogtreecommitdiff
path: root/src/physics.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/physics.c')
-rw-r--r--src/physics.c76
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