#include #include #include "game.h" #include "player.h" Game game; static inline bool EntityAllocated(const Entity* e) { return (e->flags & ENTITY_ALLOCATED); } static inline bool PhysicsEnabled(const Entity* e) { return EntityAllocated(e) && (e->flags & ENTITY_PHYSICS_ACTIVE); } static inline bool ShouldDrawEntity(const Entity* e) { return EntityAllocated(e) && (e->flags & ENTITY_VISIBLE); } static inline bool SameEntity(const Entity* a, const Entity* b) { return a->id == b->id; } 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->height) || (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; } void AddEntity(Entity* e) { static int nextId = 0; e->id = nextId++; e->flags |= ENTITY_ALLOCATED; for(int i = 0; i < MAX_ENTITY_COUNT; i++) { if (!EntityAllocated(&game.entities[i])) { game.entities[i] = *e; break; } } } void InitGame() { game.paused = false; memset(game.entities, 0, sizeof(game.entities)); } void UpdateEntity(Entity* e, float deltaTime) { switch (e->type) { case Player_Entity: UpdatePlayer(e, deltaTime); break; default: break; } } void UpdateGame(float deltaTime) { (void)deltaTime; for (int i = 0; i < MAX_ENTITY_COUNT; i++) { Entity* e = &game.entities[i]; if (EntityAllocated(e)) UpdateEntity(e, deltaTime); } } #ifdef BEATEMUP_DEBUG void DebugHighlights(const Entity* e) { Rectangle dstRect = GetPhysicsColliderGlobal(e); DrawRectangle(dstRect.x, dstRect.y, dstRect.width, dstRect.height, e->physicsColliderColor); } #endif void DrawEntity(const Entity* e) { } void DrawGame() { BeginDrawing(); ClearBackground(RAYWHITE); for (int i = 0; i < MAX_ENTITY_COUNT; i++) { Entity* e = &game.entities[i]; #ifdef BEATEMUP_DEBUG DebugHighlights(e); #endif if (ShouldDrawEntity(e)) DrawEntity(e); } EndDrawing(); } void AddWall(float xpos, float ypos, float width, float height) { Entity wall; wall.type = Wall_Entity; wall.flags |= ENTITY_PHYSICS_ACTIVE; wall.position = (Vector2) {xpos, ypos}; wall.physicsCollider = (Rectangle) {0, 0, width, height}; #ifdef BEATEMUP_DEBUG wall.physicsColliderColor = BLUE; #endif AddEntity(&wall); }