diff --git a/bin/game b/bin/game index e384799..7d8148c 100755 Binary files a/bin/game and b/bin/game differ diff --git a/bin/game.dSYM/Contents/Resources/DWARF/game b/bin/game.dSYM/Contents/Resources/DWARF/game index 7a7edf6..9cc3b93 100644 Binary files a/bin/game.dSYM/Contents/Resources/DWARF/game and b/bin/game.dSYM/Contents/Resources/DWARF/game differ diff --git a/scripts/animsprite.h b/scripts/animsprite.h new file mode 100644 index 0000000..f66f1a3 --- /dev/null +++ b/scripts/animsprite.h @@ -0,0 +1,41 @@ +#ifndef ANIMSPRITE_H +#define ANIMSPRITE_H +#include +#include "sprite.h" + +typedef struct { + Sprite sprite; + int currentFrame; + int maxFrame; + int framesCounter; + int framesSpeed; + float animTimer; + bool isVertical; +} AnimSprite; + +void UpdateAnimSprite(AnimSprite *animSprite) { + animSprite->animTimer += GetFrameTime(); + float frameTime = 1.0f / animSprite->framesSpeed; + + if (animSprite->animTimer < frameTime) { + return; + } + + animSprite->animTimer -= frameTime; + animSprite->currentFrame++; + + if (animSprite->currentFrame >= animSprite->maxFrame) { + animSprite->currentFrame = 0; + } + + Vector2 newFramePos = { + .x = animSprite->isVertical ? animSprite->sprite.sourceRec.x + : animSprite->currentFrame * animSprite->sprite.frameSize.x, + .y = animSprite->isVertical ? animSprite->currentFrame * animSprite->sprite.frameSize.y + : animSprite->sprite.sourceRec.y + }; + + UpdateSpriteSourceRec(&animSprite->sprite, &newFramePos); +} + +#endif // ANIMSPRITE_H diff --git a/scripts/main.c b/scripts/main.c index 49a6ce6..614d79f 100644 --- a/scripts/main.c +++ b/scripts/main.c @@ -7,125 +7,45 @@ // BeginDrawing(), EndDrawing(), ClearBackground(), // Camera2D, BeginMode2D(), EndMode2D() #include // Vector2Length(), Vector2Normalize(), Vector2Add(), Vector2Scale(), Lerp() -#include // rand(), srand() +#include // rand(), srand(), malloc() #include // time() #include // memcpy() -#include +#include "sprite.h" +#include "animsprite.h" +#include "tilesprite.h" +#include "vector.h" +#include "object.h" // Structs -typedef struct { - Vector2 *data; - size_t count; -} Vector2Array; - -typedef struct { - Texture2D texture; // Texture for the sprite - Rectangle sourceRec; // Source rectangle for the texture - Rectangle destRec; // Destination rectangle for the texture - Vector2 frameSize; // Size of the frame in the texture - Vector2 origin; // Origin point for rotation and positioning - float rotation; // Rotation angle - Color color; -} Sprite; - -typedef struct { - Sprite sprite; - Rectangle bounds; -} TileSprite; - -typedef struct { - Sprite sprite; // Base sprite for rendering - int currentFrame; // Current animation frame - int maxFrame; // Total number of frames - int framesCounter; // Counter to control frame speed - int framesSpeed; // Speed of the animation (frames per second) - float animTimer; - bool isVertical; // Whether the animation frames are arranged vertically -} AnimSprite; - -typedef struct { - Sprite sprite; - Vector2 position; -} Object; - -typedef struct { - Object *data; - const Object *prototype; - size_t count; -} ObjectArray; - typedef struct { AnimSprite animSprite; Vector2 position; Vector2 direction; float velocity; -} Entity; +} Player; typedef struct { - Entity entity; + AnimSprite animSprite; + Vector2 position; + Vector2 direction; + float velocity; Object targetFlower; Object hive; } Bee; // Pure functions -bool IsVectorZero(Vector2 v) { - float epsilon = 0.01f; - return (fabs(v.x) < epsilon && fabs(v.y) < epsilon); -} -float GetRandomFloat(const float min, const float max){ - return min + (float)rand() / (float)(RAND_MAX / (max - min)); -} - -Vector2 GetRandomVector(const Rectangle bounds){ - return (Vector2){ - GetRandomFloat(bounds.x, bounds.x + bounds.width), - GetRandomFloat(bounds.y, bounds.y + bounds.height) - }; -} - -ObjectArray CreateObjectArray(const Object *prototype, const size_t count) { - ObjectArray objects = {0}; - - if (count <= 0) { - printf("Objects size must be greater than 0.\n"); - return objects; +void Move(Vector2 *position, Vector2 *direction, float *velocity, float *rotation) { + if(Vector2Length(*direction) <= 0.0f){ + return; } - - objects.count = count; - objects.data = malloc(count * sizeof(Object)); - - if (!objects.data) { - printf("Memory allocation of objects failed.\n"); - return objects; - } - - objects.prototype = prototype; - - for (int i = 0; i < count; i++) { - objects.data[i].position = prototype->position; - objects.data[i].sprite = prototype->sprite; - } - return objects; + float targetRotation = (float)atan2(direction->y, direction->x) * (180.0f / PI) + 90.0f; + *rotation = Lerp(*rotation, targetRotation, 0.1f); + *position = Vector2Add(*position, Vector2Scale(*direction, *velocity * GetFrameTime())); } -void AddObjectToArray(ObjectArray *objects, const Object *prototype, Vector2 position) { - Object *newData = realloc(objects->data, (objects->count + 1) * sizeof(Object)); - if (newData) { - objects->data = newData; - objects->data[objects->count] = *prototype; - objects->data[objects->count].position = position; - objects->data[objects->count].sprite.destRec.x = position.x; - objects->data[objects->count].sprite.destRec.y = position.y; - objects->count++; - } else { - printf("Memory allocation failed while adding an object.\n"); - } -} - - // Mutator Functions void GetDirectionFromInput(Vector2 *direction){ @@ -137,160 +57,8 @@ void GetDirectionFromInput(Vector2 *direction){ if (Vector2Length(*direction) > 0.0f) { *direction = Vector2Normalize(*direction); } } -Object* GetRandomObject(ObjectArray *objects){ - if (objects->count == 0) { - return NULL; - } - return &objects->data[GetRandomValue(0, (int)objects->count-1)]; -} - -Vector2 GetDirectionToObject(Object *object, Vector2 position){ - return Vector2Normalize(Vector2Subtract(object->position, position)); -} - -void SetPositionOnDirectionAndVelocity(const Vector2 *direction, const float *velocity, Vector2 *position) { - *position = Vector2Add(*position, Vector2Scale(*direction, *velocity * GetFrameTime())); -} - -void SetDestRecOnPosition(const Vector2 *position, Sprite *sprite){ - Rectangle newDestRec = { - position->x, - position->y, - sprite->frameSize.x, - sprite->frameSize.y - }; - sprite->destRec = newDestRec; -} - -void SetAnimSpriteOnFrameTime(AnimSprite *animSprite) { - animSprite->animTimer += GetFrameTime(); - float frameTime = 1.0f / animSprite->framesSpeed; - - if (animSprite->animTimer < frameTime) { - return; - } - - animSprite->animTimer -= frameTime; - animSprite->currentFrame++; - - if (animSprite->currentFrame >= animSprite->maxFrame) { - animSprite->currentFrame = 0; - } - - if (animSprite->isVertical) { - animSprite->sprite.sourceRec.y = animSprite->currentFrame * animSprite->sprite.frameSize.y; - } else { - animSprite->sprite.sourceRec.x = animSprite->currentFrame * animSprite->sprite.frameSize.x; - } -} - -void SetRotationOnDirection(const Vector2 *direction, float *rotationDegree){ - if(Vector2Length(*direction) <= 0.0f){ - return; - } - float targetRotationDegree = (float)atan2(direction->y, direction->x) * (180.0f / PI) + 90.0f; - *rotationDegree = Lerp(*rotationDegree, targetRotationDegree, 0.1f); -} - -void SetPositionForObjectArray(ObjectArray *objects, const Vector2Array *positions) { - if (positions->count != objects->count) { - printf("Warning: Position array size (%zu) does not match ObjectArray size (%zu)\n", positions->count, objects->count); - return; - } - - for (size_t i = 0; i < objects->count; i++) { - objects->data[i].position = positions->data[i]; - objects->data[i].sprite.destRec.x = positions->data[i].x; - objects->data[i].sprite.destRec.y = positions->data[i].y; - } -} - -void SetRandomPositionForObjectArray(ObjectArray *objects, const Rectangle bounds){ - srand((unsigned int)time(NULL)); - for (int i = 0; i < objects->count; i++) { - Vector2 position = GetRandomVector(bounds); - objects->data[i].position = position; - objects->data[i].sprite.destRec.x = position.x; - objects->data[i].sprite.destRec.y = position.y; - } -} - -void UpdatePlayer(Entity *player) { - GetDirectionFromInput(&player->direction); - SetRotationOnDirection(&player->direction, &player->animSprite.sprite.rotation); - SetPositionOnDirectionAndVelocity(&player->direction, &player->velocity, &player->position); - SetDestRecOnPosition(&player->position, &player->animSprite.sprite); - SetAnimSpriteOnFrameTime(&player->animSprite); -} - -void UpdateTileSprite(TileSprite *tileSprite, const Camera2D *camera){ - tileSprite->bounds.x = (int)((camera->target.x - (GetScreenWidth() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.x) - 1; - tileSprite->bounds.width = (int)((camera->target.x + (GetScreenWidth() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.x) + 1; - tileSprite->bounds.y = (int)((camera->target.y - (GetScreenHeight() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.y) - 1; - tileSprite->bounds.height = (int)((camera->target.y + (GetScreenHeight() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.y) + 1; -} - -void UpdateCamera2D(Camera2D *camera, const Entity *player, const float smoothness){ - camera->target = Vector2Lerp(camera->target, player->position, smoothness * GetFrameTime()); -} - -void SwapAndPopObjectsArrayOnRecCollision(ObjectArray *objects, const Rectangle rec){ - for (int i = 0; i < objects->count; i++){ - - if (CheckCollisionRecs(rec, objects->data[i].sprite.destRec)){ - if (objects->count == 1) { - objects->count = 0; - break; - } - objects->data[i] = objects->data[objects->count - 1]; - objects->count--; - i--; - } - } -} - -void SwapAndPopObjectsArrayOnPointCollision(ObjectArray *objects, const Vector2 point){ - for (int i = 0; i < objects->count; i++){ - - if (CheckCollisionPointRec(point, objects->data[i].sprite.destRec)){ - if (objects->count == 1) { - objects->count = 0; - break; - } - objects->data[i] = objects->data[objects->count - 1]; - objects->count--; - i--; - } - } -} - -void RenderSprite(const Sprite *sprite){ - DrawTexturePro( - sprite->texture, - sprite->sourceRec, - sprite->destRec, - sprite->origin, - sprite->rotation, - sprite->color - ); -} - -void RenderTileSprite(TileSprite *tileSprite){ - for (float y = tileSprite->bounds.y; y <= tileSprite->bounds.height; y++) - { - for (float x = tileSprite->bounds.x; x <= tileSprite->bounds.width; x++) - { - Vector2 tilePosition = {x * tileSprite->sprite.frameSize.x, y * tileSprite->sprite.frameSize.y}; - SetDestRecOnPosition(&tilePosition, &tileSprite->sprite); - RenderSprite(&tileSprite->sprite); - } - } -} - -void RenderObjectArray(const ObjectArray *objects){ - for (int i = 0; i < objects->count; i++){ - RenderSprite(&objects->data[i].sprite); - } +void UpdateCamera2DTarget(Camera2D *camera, Vector2 *position, const float smoothness){ + camera->target = Vector2Lerp(camera->target, *position, smoothness * GetFrameTime()); } // Main @@ -339,14 +107,14 @@ int main(void) .color = WHITE }, .position = {0.0f, 0.0f} - }, 1); + }, 300); if (!flowers.data) { printf("Memory allocation failed.\n"); exit(1); } Rectangle flowerField = {-50.0f, -50.0f, 100.0f, 100.0f}; SetRandomPositionForObjectArray(&flowers, flowerField); - Entity player = { + Player player = { .animSprite = { .sprite = { .texture = LoadTexture("assets/character_bee.png"), @@ -368,30 +136,27 @@ int main(void) .direction = (Vector2){0.0f,0.0f}, .velocity = 50.0f }; - Bee bee1 = { - .entity = { - .animSprite = { - .sprite = { - .texture = LoadTexture("assets/character_bee.png"), - .frameSize = {16.0f, 16.0f}, - .sourceRec = {0.0f, 0.0f, 16.0f, 16.0f}, - .destRec = {0.0f, 0.0f, 16.0f, 16.0f}, - .origin = {8.0f, 8.0f}, - .rotation = 0.0f, - .color = WHITE - }, - .currentFrame = 0, - .maxFrame = 4, - .framesCounter = 0, - .framesSpeed = 10, - .isVertical = true, - .animTimer = 0.0f + .animSprite = { + .sprite = { + .texture = LoadTexture("assets/character_bee.png"), + .frameSize = {16.0f, 16.0f}, + .sourceRec = {0.0f, 0.0f, 16.0f, 16.0f}, + .destRec = {0.0f, 0.0f, 16.0f, 16.0f}, + .origin = {8.0f, 8.0f}, + .rotation = 0.0f, + .color = WHITE }, - .position = hive.position, - .direction = (Vector2){0.0f,0.0f}, - .velocity = 5.0f + .currentFrame = 0, + .maxFrame = 4, + .framesCounter = 0, + .framesSpeed = 10, + .isVertical = true, + .animTimer = 0.0f }, + .position = hive.position, + .direction = (Vector2){0.0f,0.0f}, + .velocity = 5.0f, .targetFlower = *GetRandomObject(&flowers), .hive = hive }; @@ -401,7 +166,6 @@ int main(void) .rotation = 0.0f, .zoom = 10.0f }; - float followSmoothness = 5.0f; // Update & Render while (!WindowShouldClose()) @@ -413,24 +177,27 @@ int main(void) } UpdateMusicStream(music); - UpdateTileSprite(&floor, &camera); - UpdatePlayer(&player); + UpdateTileSpriteBounds(&floor, &camera); + + GetDirectionFromInput(&player.direction); + Move(&player.position, &player.direction, &player.velocity, &player.animSprite.sprite.rotation); + UpdateSpriteDestRec(&player.animSprite.sprite, &player.position); + UpdateAnimSprite(&player.animSprite); const float tolerance = 1.0f; // Adjust as needed - if (fabs(bee1.entity.position.x - bee1.targetFlower.position.x) < tolerance && - fabs(bee1.entity.position.y - bee1.targetFlower.position.y) < tolerance) { - bee1.entity.velocity = 0.0f; + if (fabs(bee1.position.x - bee1.targetFlower.position.x) < tolerance && + fabs(bee1.position.y - bee1.targetFlower.position.y) < tolerance) { + bee1.velocity = 0.0f; } else { - SetPositionOnDirectionAndVelocity(&bee1.entity.direction, &bee1.entity.velocity, &bee1.entity.position); - bee1.entity.direction = GetDirectionToObject(&bee1.targetFlower, bee1.entity.position); + Move(&bee1.position, &bee1.direction, &bee1.velocity, &bee1.animSprite.sprite.rotation); + bee1.direction = GetDirectionToObject(&bee1.targetFlower, bee1.position); } - SetRotationOnDirection(&bee1.entity.direction, &bee1.entity.animSprite.sprite.rotation); - SetDestRecOnPosition(&bee1.entity.position, &bee1.entity.animSprite.sprite); - SetAnimSpriteOnFrameTime(&bee1.entity.animSprite); + UpdateSpriteDestRec(&bee1.animSprite.sprite, &bee1.position); + UpdateAnimSprite(&bee1.animSprite); - UpdateCamera2D(&camera, &player, followSmoothness); + UpdateCamera2DTarget(&camera, &player.position, 5.0f); float wheel = GetMouseWheelMove(); if (wheel != 0) @@ -449,8 +216,8 @@ int main(void) RenderTileSprite(&floor); RenderSprite(&hive.sprite); RenderObjectArray(&flowers); - RenderSprite(&bee1.entity.animSprite.sprite); - // RenderSprite(&player.animSprite.sprite); + RenderSprite(&bee1.animSprite.sprite); + RenderSprite(&player.animSprite.sprite); EndMode2D(); DrawFPS(10,10); EndDrawing(); @@ -459,7 +226,7 @@ int main(void) UnloadTexture(floor.sprite.texture); UnloadTexture(hive.sprite.texture); UnloadTexture(flower); - UnloadTexture(bee1.entity.animSprite.sprite.texture); + UnloadTexture(bee1.animSprite.sprite.texture); UnloadTexture(player.animSprite.sprite.texture); UnloadMusicStream(music); free(flowers.data); diff --git a/scripts/main_crossplattform.cpp b/scripts/main_crossplattform.cpp deleted file mode 100644 index 20d73ac..0000000 --- a/scripts/main_crossplattform.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "raylib.h" -#include "Game.h" - -#ifdef PLATFORM_WEB - #include -#endif - -Game game; - -void UpdateDrawFrame() { - game.update(); - game.render(); -} - -int main() { - InitWindow(1280, 720, "Lazy Bee"); - SetTargetFPS(60); - game.init(); -#ifdef PLATFORM_WEB - emscripten_set_main_loop(UpdateDrawFrame, 0, 1); -#else - while (!WindowShouldClose()) { game.update(); game.render(); } -#endif - game.close(); - return 0; -} diff --git a/scripts/object.c b/scripts/object.c deleted file mode 100644 index e69de29..0000000 diff --git a/scripts/object.h b/scripts/object.h new file mode 100644 index 0000000..22c7b4a --- /dev/null +++ b/scripts/object.h @@ -0,0 +1,128 @@ +#ifndef OBJECT_H +#define OBJECT_H +#include // Vector2, Rectangle, Color, GetRandomValue(), CheckCollisionRecs(), CheckCollisionPointRec() +#include // printf() +#include // malloc(), realloc() +#include "sprite.h" // Sprite +#include "vector.h" + +typedef struct { + Sprite sprite; + Vector2 position; +} Object; + +typedef struct { + Object *data; + const Object *prototype; + size_t count; +} ObjectArray; + +ObjectArray CreateObjectArray(const Object *prototype, const size_t count) { + ObjectArray objects = {0}; + + if (count <= 0) { + printf("Objects size must be greater than 0.\n"); + return objects; + } + + objects.count = count; + objects.data = malloc(count * sizeof(Object)); + + if (!objects.data) { + printf("Memory allocation of objects failed.\n"); + return objects; + } + + objects.prototype = prototype; + + for (int i = 0; i < count; i++) { + objects.data[i].position = prototype->position; + objects.data[i].sprite = prototype->sprite; + } + return objects; +} + +Object* GetRandomObject(ObjectArray *objects){ + if (objects->count == 0) { + return NULL; + } + return &objects->data[GetRandomValue(0, (int)objects->count-1)]; +} + +void AddObjectToArray(ObjectArray *objects, const Object *prototype, Vector2 position) { + Object *newData = realloc(objects->data, (objects->count + 1) * sizeof(Object)); + if (newData) { + objects->data = newData; + objects->data[objects->count] = *prototype; + objects->data[objects->count].position = position; + objects->data[objects->count].sprite.destRec.x = position.x; + objects->data[objects->count].sprite.destRec.y = position.y; + objects->count++; + } else { + printf("Memory allocation failed while adding an object.\n"); + } +} + +void SetPositionForObjectArray(ObjectArray *objects, const Vector2Array *positions) { + if (positions->count != objects->count) { + printf("Warning: Position array size (%zu) does not match ObjectArray size (%zu)\n", positions->count, objects->count); + return; + } + + for (size_t i = 0; i < objects->count; i++) { + objects->data[i].position = positions->data[i]; + objects->data[i].sprite.destRec.x = positions->data[i].x; + objects->data[i].sprite.destRec.y = positions->data[i].y; + } +} + +void SetRandomPositionForObjectArray(ObjectArray *objects, const Rectangle bounds){ + for (int i = 0; i < objects->count; i++) { + Vector2 position = GetRandomVector(bounds); + objects->data[i].position = position; + objects->data[i].sprite.destRec.x = position.x; + objects->data[i].sprite.destRec.y = position.y; + } +} + +void SwapAndPopObjectsArrayOnRecCollision(ObjectArray *objects, const Rectangle rec){ + for (int i = 0; i < objects->count; i++){ + + if (CheckCollisionRecs(rec, objects->data[i].sprite.destRec)){ + if (objects->count == 1) { + objects->count = 0; + break; + } + objects->data[i] = objects->data[objects->count - 1]; + objects->count--; + i--; + } + } +} + +void SwapAndPopObjectsArrayOnPointCollision(ObjectArray *objects, const Vector2 point){ + for (int i = 0; i < objects->count; i++){ + + if (CheckCollisionPointRec(point, objects->data[i].sprite.destRec)){ + if (objects->count == 1) { + objects->count = 0; + break; + } + objects->data[i] = objects->data[objects->count - 1]; + objects->count--; + i--; + } + } +} + +Vector2 GetDirectionToObject(Object *object, Vector2 position){ + return Vector2Normalize(Vector2Subtract(object->position, position)); +} + +void RenderObjectArray(const ObjectArray *objects){ + for (int i = 0; i < objects->count; i++){ + RenderSprite(&objects->data[i].sprite); + } +} + +#endif // OBJECT_H diff --git a/scripts/sprite.h b/scripts/sprite.h new file mode 100644 index 0000000..a416c09 --- /dev/null +++ b/scripts/sprite.h @@ -0,0 +1,36 @@ +#ifndef SPRITE_H +#define SPRITE_H +#include + +typedef struct { + Texture2D texture; + Rectangle sourceRec; + Rectangle destRec; + Vector2 frameSize; + Vector2 origin; + float rotation; + Color color; +} Sprite; + +void UpdateSpriteSourceRec(Sprite *sprite, const Vector2 *vector){ + sprite->sourceRec.x = vector->x; + sprite->sourceRec.y = vector->y; +} + +void UpdateSpriteDestRec(Sprite *sprite, const Vector2 *vector){ + sprite->destRec.x = vector->x; + sprite->destRec.y = vector->y; +} + +void RenderSprite(const Sprite *sprite){ + DrawTexturePro( + sprite->texture, + sprite->sourceRec, + sprite->destRec, + sprite->origin, + sprite->rotation, + sprite->color + ); +} + +#endif // SPRITE_H diff --git a/scripts/tilesprite.h b/scripts/tilesprite.h new file mode 100644 index 0000000..82bc32c --- /dev/null +++ b/scripts/tilesprite.h @@ -0,0 +1,30 @@ +#ifndef TILESPRITE_H +#define TILESPRITE_H +#include +#include "sprite.h" + +typedef struct { + Sprite sprite; + Rectangle bounds; +} TileSprite; + +void UpdateTileSpriteBounds(TileSprite *tileSprite, const Camera2D *camera){ + tileSprite->bounds.x = (int)((camera->target.x - (GetScreenWidth() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.x) - 1; + tileSprite->bounds.width = (int)((camera->target.x + (GetScreenWidth() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.x) + 1; + tileSprite->bounds.y = (int)((camera->target.y - (GetScreenHeight() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.y) - 1; + tileSprite->bounds.height = (int)((camera->target.y + (GetScreenHeight() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.y) + 1; +} + +void RenderTileSprite(TileSprite *tileSprite){ + for (float y = tileSprite->bounds.y; y <= tileSprite->bounds.height; y++) + { + for (float x = tileSprite->bounds.x; x <= tileSprite->bounds.width; x++) + { + Vector2 tilePosition = {x * tileSprite->sprite.frameSize.x, y * tileSprite->sprite.frameSize.y}; + UpdateSpriteDestRec(&tileSprite->sprite, &tilePosition); + RenderSprite(&tileSprite->sprite); + } + } +} + +#endif //TILESPRITE_H diff --git a/scripts/vector.h b/scripts/vector.h new file mode 100644 index 0000000..12d9d99 --- /dev/null +++ b/scripts/vector.h @@ -0,0 +1,22 @@ +#ifndef VECTOR_H +#define VECTOR_H +#include + +typedef struct { + Vector2 *data; + size_t count; +} Vector2Array; + +bool IsVectorZero(Vector2 v) { + float epsilon = 0.01f; + return (fabs(v.x) < epsilon && fabs(v.y) < epsilon); +} + +Vector2 GetRandomVector(const Rectangle bounds) { + return (Vector2){ + bounds.x + (float)GetRandomValue(0, 10000) / 10000.0f * bounds.width, + bounds.y + (float)GetRandomValue(0, 10000) / 10000.0f * bounds.height + }; +} + +#endif // VECTOR_H