diff options
author | BoredGuy <osome3717@gmail.com> | 2025-07-29 11:50:57 +0300 |
---|---|---|
committer | BoredGuy <osome3717@gmail.com> | 2025-07-29 11:50:57 +0300 |
commit | 815aec62f8ae3a403e913559d5fe6138c8825007 (patch) | |
tree | 3041d4b8a843c05a4da02e66d5e2f63e1e713b72 | |
parent | 9e1627c229d8d094c7b55751d82db9d3579a16e1 (diff) |
Added background entity and asset system
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | include/assets.h | 6 | ||||
-rw-r--r-- | include/background.h | 7 | ||||
-rw-r--r-- | include/game.h | 20 | ||||
-rw-r--r-- | src/assets.c | 67 | ||||
-rw-r--r-- | src/background.c | 30 | ||||
-rw-r--r-- | src/game.c | 71 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/player.c | 6 |
9 files changed, 200 insertions, 20 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a1560e9..c8989c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,10 +12,14 @@ add_executable(game "include/constants.h" "include/physics.h" "include/player.h" + "include/assets.h" + "include/background.h" "src/game.c" "src/main.c" "src/player.c" + "src/assets.c" + "src/background.c" ) target_include_directories(game PRIVATE "include") @@ -31,4 +35,4 @@ endif() if (MSVC) target_link_libraries(game winmm) -endif()
\ No newline at end of file +endif() diff --git a/include/assets.h b/include/assets.h new file mode 100644 index 0000000..e2d76b7 --- /dev/null +++ b/include/assets.h @@ -0,0 +1,6 @@ +#pragma once + +#include <raylib.h> + +void LoadAssets(); +Texture2D GetTexture(const char* name); diff --git a/include/background.h b/include/background.h new file mode 100644 index 0000000..104db7c --- /dev/null +++ b/include/background.h @@ -0,0 +1,7 @@ +#pragma once + +#include "game.h" +#include "assets.h" + +void AddBackground(const char* backgroundTexture); +void UpdateBackground(Entity* background, float deltaTime); diff --git a/include/game.h b/include/game.h index 64da8e7..1039ad5 100644 --- a/include/game.h +++ b/include/game.h @@ -1,6 +1,7 @@ #pragma once #include <raylib.h> +#include <stdbool.h> #include <stdint.h> #include "constants.h" @@ -11,9 +12,15 @@ typedef enum EntityType { Player_Entity, - Wall_Entity + Wall_Entity, + Background_Entity } EntityType; +typedef enum DrawLayer { + Background_Layer = 0, + Foreground_Layer = 1 +} DrawLayer; + typedef struct Entity { int id; EntityType type; @@ -29,6 +36,11 @@ typedef struct Entity { int numHurtBoxes; Rectangle hurtBoxes[MAX_AREA_COUNT]; + //Graphics Information + Texture2D texture; + DrawLayer drawLayer; + Rectangle destRect; //Relative to the players position + #ifdef BEATEMUP_DEBUG //Debug information Color physicsColliderColor; @@ -42,6 +54,10 @@ typedef struct Game { Texture2D background; float backgroundPosition; + #ifdef BEATEMUP_DEBUG + //Debug information + bool enableDebugOverlay; + #endif } Game; void AddEntity(Entity* e); @@ -49,4 +65,4 @@ void AddWall(float xpos, float ypos, float width, float height); void InitGame(); void UpdateGame(float deltaTime); -void DrawGame();
\ No newline at end of file +void DrawGame(); diff --git a/src/assets.c b/src/assets.c new file mode 100644 index 0000000..8edfde6 --- /dev/null +++ b/src/assets.c @@ -0,0 +1,67 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include "assets.h" + +typedef enum AssetType { + Texture_Asset +} AssetType; + +typedef struct Asset { + AssetType type; + const char* name; + const char* filePath; + + Texture2D texture; +} Asset; + +Asset assets[] = { + { + .type = Texture_Asset, + .name = "bar-background", + .filePath = "assets/art/backgrounds/bar-background.png" + }, + { + .type = Texture_Asset, + .name = "rails", + .filePath = "assets/art/backgrounds/rails.png" + }, +}; + +#define ASSET_COUNT (sizeof(assets) / sizeof(Asset)) + +void LoadAssets() { + + for (size_t i = 0; i < ASSET_COUNT; i++) { + Asset* c = &assets[i]; + + switch (c->type) { + case Texture_Asset: + c->texture = LoadTexture(c->filePath); + break; + } + } +} + +Asset* GetMatchingAssetWithType(const char* targetName, AssetType targetType) { + for (size_t i = 0; i < ASSET_COUNT; i++) { + Asset* c = &assets[i]; + + if (strcmp(targetName, c->name) == 0 && c->type == targetType) + return c; + } + + return NULL; +} + +Texture2D GetTexture(const char* name) { + Asset* textureAsset = GetMatchingAssetWithType(name, Texture_Asset); + + if (textureAsset == NULL) { + fprintf(stderr, "Failed to load texture with name: %s, exitting!\n", name); + exit(EXIT_FAILURE); + } + + return textureAsset->texture; +} diff --git a/src/background.c b/src/background.c new file mode 100644 index 0000000..39e3c1e --- /dev/null +++ b/src/background.c @@ -0,0 +1,30 @@ +#include "background.h" +#include "constants.h" +#include <raymath.h> + +void AddBackground(const char* backgroundTextureName) { + Entity e = {0}; + e.type = Background_Entity; + + e.flags |= ENTITY_VISIBLE; + e.drawLayer = Background_Layer; + + e.position = (Vector2) {0.0f, 0.0f}; + Texture2D backgroundTexture = GetTexture(backgroundTextureName); + + const float backgroundSizeScale = (float)WINDOW_HEIGHT / backgroundTexture.height; + Vector2 backgroundBounds = + Vector2Scale((Vector2) {backgroundTexture.width, backgroundTexture.height}, backgroundSizeScale); + + e.destRect = (Rectangle) { + .width = backgroundBounds.x, + .height = backgroundBounds.y + }; + e.texture = backgroundTexture; + + AddEntity(&e); +} + +void UpdateBackground(Entity* background, float deltaTime) { + background->position.x -= 600 * deltaTime; +} @@ -1,8 +1,11 @@ #include <raylib.h> #include <string.h> #include "game.h" +#include "assets.h" +#include "stdio.h" #include "player.h" +#include "background.h" Game game; @@ -14,8 +17,10 @@ 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 ShouldDrawEntity(const Entity* e, DrawLayer layerDrawing) { + return EntityAllocated(e) + && (e->flags & ENTITY_VISIBLE) + && (layerDrawing == e->drawLayer); } static inline bool SameEntity(const Entity* a, const Entity* b) { @@ -26,7 +31,7 @@ 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) + 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; @@ -40,6 +45,15 @@ static inline Rectangle GetPhysicsColliderGlobal(const Entity* e) { return physicsColliderGlobal; } +static inline Rectangle GetDrawDestinationRectGlobal(const Entity* e) { + Rectangle destRectGlobal = e->destRect; + + destRectGlobal.x += e->position.x; + destRectGlobal.y += e->position.y; + + return destRectGlobal; +} + void MoveAndSlide(Entity* e, float deltaTime) { Vector2 velocity = e->velocity; Rectangle physicsCollider = GetPhysicsColliderGlobal(e); @@ -97,6 +111,7 @@ void AddEntity(Entity* e) { void InitGame() { game.paused = false; + LoadAssets(); memset(game.entities, 0, sizeof(game.entities)); } @@ -106,6 +121,10 @@ void UpdateEntity(Entity* e, float deltaTime) { case Player_Entity: UpdatePlayer(e, deltaTime); break; + + case Background_Entity: + UpdateBackground(e, deltaTime); + break; default: break; @@ -113,7 +132,11 @@ void UpdateEntity(Entity* e, float deltaTime) { } void UpdateGame(float deltaTime) { - (void)deltaTime; + #ifdef BEATEMUP_DEBUG + if (IsKeyPressed(KEY_D) && IsKeyDown(KEY_ENTER)) { + game.enableDebugOverlay = !game.enableDebugOverlay; + } + #endif for (int i = 0; i < MAX_ENTITY_COUNT; i++) { Entity* e = &game.entities[i]; @@ -125,34 +148,56 @@ void UpdateGame(float deltaTime) { #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 +void DefaultDrawEntity(const Entity* e) { + Rectangle srcRect = {0, 0, e->texture.width, e->texture.height}; + Vector2 origin = {0.0f, 0.0f}; + float rotation = 0.0f; + Rectangle destRect = GetDrawDestinationRectGlobal(e); + + DrawTexturePro(e->texture, srcRect, destRect, origin, rotation, WHITE); +} + void DrawEntity(const Entity* e) { + switch (e->type) { + + default: + DefaultDrawEntity(e); + } } void DrawGame() { BeginDrawing(); ClearBackground(RAYWHITE); - for (int i = 0; i < MAX_ENTITY_COUNT; i++) { - Entity* e = &game.entities[i]; + for (DrawLayer layer = Background_Layer; layer <= Foreground_Layer; layer++) { + for (int j = 0; j < MAX_ENTITY_COUNT; j++) { + Entity* currentEntity = &game.entities[j]; - #ifdef BEATEMUP_DEBUG - DebugHighlights(e); - #endif + if (ShouldDrawEntity(currentEntity, layer)) + DrawEntity(currentEntity); + } + } - if (ShouldDrawEntity(e)) - DrawEntity(e); + #ifdef BEATEMUP_DEBUG + for (int i = 0; i < MAX_ENTITY_COUNT; i++) { + if (game.enableDebugOverlay) + DebugHighlights(&game.entities[i]); } + #endif EndDrawing(); } void AddWall(float xpos, float ypos, float width, float height) { - Entity wall; + Entity wall = {0}; wall.type = Wall_Entity; wall.flags |= ENTITY_PHYSICS_ACTIVE; @@ -165,4 +210,4 @@ void AddWall(float xpos, float ypos, float width, float height) { #endif AddEntity(&wall); -}
\ No newline at end of file +} @@ -3,6 +3,7 @@ #include "constants.h" #include "game.h" #include "player.h" +#include "background.h" int main() { SetConfigFlags(FLAG_VSYNC_HINT); //Always better than fixed FPS imo @@ -11,7 +12,11 @@ int main() { InitGame(); AddPlayer(0.0, 0.0); + AddWall(200, 100, 10000, 100); + AddWall(200, 400, 10000, 100); + + AddBackground("bar-background"); while(!WindowShouldClose()) { UpdateGame(GetFrameTime()); @@ -21,4 +26,4 @@ int main() { CloseWindow(); return 0; -}
\ No newline at end of file +} diff --git a/src/player.c b/src/player.c index d65b873..c8e3f7d 100644 --- a/src/player.c +++ b/src/player.c @@ -27,11 +27,11 @@ void UpdatePlayer(Entity* player, float deltaTime) { } void AddPlayer(float xpos, float ypos) { - Entity player; + Entity player = {0}; player.type = Player_Entity; player.position = (Vector2) {xpos, ypos}; - player.flags |= (ENTITY_PHYSICS_ACTIVE | ENTITY_VISIBLE); + player.flags |= (ENTITY_PHYSICS_ACTIVE); player.physicsCollider = (Rectangle) {0, 0, 100, 100}; @@ -40,4 +40,4 @@ void AddPlayer(float xpos, float ypos) { #endif AddEntity(&player); -}
\ No newline at end of file +} |