diff options
| author | schererleander <leander@schererleander.de> | 2026-03-10 02:58:58 +0100 |
|---|---|---|
| committer | schererleander <leander@schererleander.de> | 2026-03-10 02:58:58 +0100 |
| commit | e32c1eeed3427832b40d1e9f43a17dbec8cb56ae (patch) | |
| tree | c0857fa0435f41004ca7132c60430ccbf2904ce4 /src | |
| parent | d7855a2b93be4aa1008643e54249cb739986869e (diff) | |
feat(fairy): implement fairy with wandering logic
Diffstat (limited to 'src')
| -rw-r--r-- | src/fairy.c | 51 | ||||
| -rw-r--r-- | src/main.c | 69 |
2 files changed, 80 insertions, 40 deletions
diff --git a/src/fairy.c b/src/fairy.c new file mode 100644 index 0000000..6e9c6cc --- /dev/null +++ b/src/fairy.c @@ -0,0 +1,51 @@ +#include "raylib.h" +#include "raymath.h" +#include <math.h> + +#include "fairy.h" +#include "globals.h" + +#define FAIRY_WAND_RADIUS 20 +#define FAIRY_STAY_MIN 1 +#define FAIRY_STAY_MAX 3 +#define FAIRY_SMOOTHNESS 0.25f + +#define FAIRY_BOB_SPEED 4 +#define FAIRY_BOB_HEIGHT 5 + +void UpdateFairy(Fairy *fairy, Vector2 playerWorldPosiion) { + float deltaTime = GetFrameTime(); + + fairy->wandTimer -= deltaTime; + if (fairy->wandTimer <= 0) { + fairy->targetOffset = + (Vector2){GetRandomValue(-FAIRY_WAND_RADIUS, FAIRY_WAND_RADIUS), + GetRandomValue(-FAIRY_WAND_RADIUS, FAIRY_WAND_RADIUS)}; + fairy->wandTimer = GetRandomValue(FAIRY_STAY_MIN, FAIRY_STAY_MAX); + } + + fairy->targetWorld = Vector2Add(playerWorldPosiion, fairy->targetOffset); + + fairy->position = Vector2Lerp(fairy->position, fairy->targetWorld, + FAIRY_SMOOTHNESS * deltaTime); +} + +void DrawFairy(Fairy *fairy) { + float bob = sin(GetTime() * FAIRY_BOB_SPEED) * FAIRY_BOB_HEIGHT; + int x = (int)fairy->position.x; + int y = (int)(fairy->position.y + bob); + + if (debugMode) { + DrawCircleV(fairy->targetWorld, 1, RED); + DrawCircleV(fairy->position, 1, GREEN); + } + + // Outer cross glow + DrawRectangle(x, y - 3, 1, 7, (Color){140, 180, 255, 40}); + DrawRectangle(x - 3, y, 7, 1, (Color){140, 180, 255, 40}); + // Mid cross + DrawRectangle(x, y - 1, 1, 3, (Color){190, 215, 255, 120}); + DrawRectangle(x - 1, y, 3, 1, (Color){190, 215, 255, 120}); + // Bright core pixel + DrawRectangle(x, y, 1, 1, (Color){255, 255, 255, 255}); +} @@ -1,11 +1,12 @@ // src/main.c #include "raylib.h" #define RAYTMX_IMPLEMENTATION -#include "game.h" -#include "player.h" -#include "map_manager.h" #include "entity.h" +#include "fairy.h" +#include "game.h" #include "globals.h" +#include "map_manager.h" +#include "player.h" bool debugMode = false; @@ -15,49 +16,34 @@ int main(void) { GameScreen currentScreen = SCREEN_TITLE; - MapManager mapMgr = LoadGameMap("assets/maps/debug.tmx"); - + MapManager mapMgr = LoadGameMap("assets/maps/debug.tmx"); + EntityManager entityMgr = InitEntityManager(100); if (mapMgr.map) { SpawnEntitiesFromMap(&entityMgr, mapMgr.map); } - + RaytmxExternalTileset elfTS = LoadTSX("assets/tilesets/elf.tsx"); - Player player = { - .position = { 200, 200}, - .speed = 120.0f, - .bounds = { 204, 204, 12, 12 }, - .tileset = elfTS.tileset, - .currentFrame = 0, - .frameTime = 0.0f, - .state = 0, // idle - .facingRight = true - }; + Player player = {.position = {200, 200}, + .speed = 120.0f, + .bounds = {204, 204, 12, 12}, + .tileset = elfTS.tileset, + .currentFrame = 0, + .frameTime = 0.0f, + .state = 0, // idle + .facingRight = true}; + + Fairy fairy = {.position = player.position, .targetOffset = {0}}; - Camera2D camera = { 0 }; + Camera2D camera = {0}; camera.offset.x = (float)SCREEN_WIDTH / 2.0f; camera.offset.y = (float)SCREEN_HEIGHT / 2.0f; camera.target = player.position; camera.zoom = 4.0f; while (!WindowShouldClose()) { - if (IsKeyPressed(KEY_B)) debugMode = !debugMode; - if (IsKeyPressed(KEY_R)) { - // Reload map and entities - UnloadGameMap(&mapMgr); - UnloadEntityManager(&entityMgr); - - mapMgr = LoadGameMap("assets/maps/debug.tmx"); - entityMgr = InitEntityManager(100); - if (mapMgr.map) { - SpawnEntitiesFromMap(&entityMgr, mapMgr.map); - } - - // Reset player position - player.position = (Vector2){ 200, 200 }; - player.bounds = (Rectangle){ 204, 204, 12, 12 }; - } - + if (IsKeyPressed(KEY_B)) + debugMode = !debugMode; switch (currentScreen) { case SCREEN_TITLE: if (IsKeyPressed(KEY_ENTER)) @@ -66,9 +52,10 @@ int main(void) { case SCREEN_PLAYING: if (IsKeyDown(KEY_ESCAPE)) currentScreen = SCREEN_PAUSED; - UpdatePlayer(&player, &mapMgr); + UpdatePlayer(&player, &mapMgr); + UpdateFairy(&fairy, player.position); UpdateEntities(&entityMgr, &player, &mapMgr); - camera.target = player.position; + camera.target = player.position; break; case SCREEN_PAUSED: if (IsKeyDown(KEY_ESCAPE)) @@ -82,7 +69,7 @@ int main(void) { // --- DRAW --- BeginDrawing(); - + switch (currentScreen) { case SCREEN_TITLE: ClearBackground(BLACK); @@ -98,10 +85,12 @@ int main(void) { { DrawMap(&mapMgr); DrawEntities(&entityMgr, mapMgr.map); - DrawPlayer(&player); + DrawPlayer(&player); + DrawFairy(&fairy); } EndMode2D(); - if (debugMode) DrawFPS(10, 10); + if (debugMode) + DrawFPS(10, 10); break; case SCREEN_GAME_OVER: ClearBackground(BLACK); @@ -112,7 +101,7 @@ int main(void) { EndDrawing(); } - UnloadGameMap(&mapMgr); + UnloadGameMap(&mapMgr); UnloadEntityManager(&entityMgr); UnloadTexture(player.tileset.image.texture); CloseWindow(); |
