big refactor: i see i need header files

This commit is contained in:
huaqo-games
2025-11-02 11:23:26 +01:00
parent 297a835780
commit c1a2448126
38 changed files with 582 additions and 560 deletions
-78
View File
@@ -1,78 +0,0 @@
#ifndef APP_H
#define APP_H
#include <engine.h>
#include "appState.h"
#include "appSettings.h"
#include "appColors.h"
#include "appLogo.h"
#include "appMenu.h"
#include "appGame.h"
typedef struct {
Config config;
State state;
Flags flags;
Window window;
Font font;
LogoState logo;
MenuState menu;
GameState game;
} App;
void ConfigApp(App* app){
InitConfig(&app->config, "config/config.ini");
app->state.currentView = GetConfigInt(&app->config, "startView");
app->flags.showFPS = GetConfigInt(&app->config, "showFPS");
app->flags.soundtrackOn = GetConfigInt(&app->config, "soundtrackOn");
app->window.title = GetConfigString(&app->config, "window_title");
app->window.width = GetConfigInt(&app->config, "window_width");
app->window.height = GetConfigInt(&app->config, "window_height");
}
void InitApp(App *app){
InitFont(&app->font, "assets/font.fnt");
InitLogo(&app->logo);
InitMenu(&app->menu);
InitGame(&app->game,&app->window);
}
void UpdateApp(App *app){
app->state.running = true;
app->state.gameStarted = false;
while (app->state.running)
{
switch (app->state.currentView)
{
case LOGO:
{
UpdateLogo(&app->logo, &app->state.currentView, &app->state.running);
RenderLogo(&app->logo, &app->flags);
}break;
case MENU:
{
UpdateMenu(&app->menu, &app->state, &app->flags);
RenderMenu(&app->menu, &app->font, app->window.title, &app->flags);
}break;
case GAMEPLAY:
{
UpdateGame(&app->game, &app->state, &app->flags);
RenderGame(&app->game, &app->state, &app->flags);
}break;
default: break;
}
}
}
void CleanupApp(App *app){
CleanupMenu(&app->menu);
CleanupGame(&app->game);
CleanupFont(&app->font);
CleanUpConfig(&app->config);
}
#endif //APP_H
-7
View File
@@ -1,7 +0,0 @@
#ifndef APPCOLORS_H
#define APPCOLORS_H
#define TEXT_COLOR_DARK (Color){ 182, 137, 98, 255}
#define TEXT_COLOR_LIGHT (Color){ 243, 229, 194, 255}
#endif // APPCOLORS_H
-138
View File
@@ -1,138 +0,0 @@
#ifndef APPGAME_H
#define APPGAME_H
#include "appGameFloor.h"
#include "appGamePlayer.h"
#include "appGameBirds.h"
#include "appGameIslands.h"
#include "appGameAssets.h"
typedef struct
{
Assets assets;
PostProcessing postFX[SHADER_COUNT];
Soundtrack soundtracks[SOUNDTRACK_COUNT];
RenderTexture2D target;
Floor floor;
Player player;
Birds birds;
Islands islands;
Camera2D camera;
Mouse mouse;
Image image;
} GameState;
void InitGame(GameState *g, Window *window)
{
g->assets = (Assets){
.shaderAssets = shaderAssets,
.soundtrackAssets = soundtrackAssets
};
for (int i = 0; i < SHADER_COUNT; i++)
{
g->postFX[i] = CreatePostFX(g->assets.shaderAssets[i].path);
}
for (int i = 0; i < SOUNDTRACK_COUNT; i++)
{
g->soundtracks[i] = LoadSoundtrack(g->assets.soundtrackAssets[i].path);
}
g->target = LoadRenderTexture(window->width, window->height);
g->player = CreatePlayer();
g->birds = CreateBirds();
g->islands = CreateIslands();
g->floor = CreateFloor();
g->camera = CreateCamera(g->player.physics.position, 10.0f);
Texture2D mouseTexture = LoadTexture("assets/mouse.png");
g->mouse = CreateMouse(0.10f, 5.0f, 10.0f, &mouseTexture);
}
void UpdateGame(GameState *g, State *state, Flags *flags)
{
if(!state->gameStarted){
state->gameStarted = true;
}
if (GetFPS() <= 60)
{
SetTargetFPS(0);
}
if (IsKeyPressed(KEY_ESCAPE))
{
state->currentView = MENU;
}
if (WindowShouldClose() && !IsKeyPressed(KEY_ESCAPE))
{
state->running = false;
}
for (int i = 0; i < SHADER_COUNT; i++)
{
UpdatePostFX(&g->postFX[i]);
}
for (int i = 0; i < SOUNDTRACK_COUNT; i++)
{
UpdateSoundtrack(&g->soundtracks[i], flags->soundtrackOn);
}
UpdateMouse(&g->mouse, &g->camera);
UpdateCamera2D(&g->camera, &g->player.physics.position, &g->mouse);
UpdateFloor(&g->floor, &g->camera);
UpdatePlayer(&g->player);
UpdateBirds(&g->birds);
UpdateIslands(&g->islands);
}
void RenderComponents(GameState *g)
{
RenderFloor(&g->floor);
RenderPlayer(&g->player);
RenderBirds(&g->birds);
RenderIslands(&g->islands);
}
void RenderGame(GameState *g, const State *appState, Flags *flags)
{
BeginTextureMode(g->target);
ClearBackground(BLACK);
BeginMode2D(g->camera);
RenderComponents(g);
EndMode2D();
DrawTextureRec(g->mouse.cursorTexture, (Rectangle){0, 0, g->mouse.cursorTexture.width, g->mouse.cursorTexture.height}, (Vector2){g->mouse.screenPosition.x, g->mouse.screenPosition.y}, WHITE);
EndTextureMode();
BeginDrawing();
ClearBackground(BLACK);
for (int i = 0; i < SHADER_COUNT; i++)
{
RenderPostFX(&g->postFX[i], &g->target);
}
if (flags->showFPS)
{
DrawFPS(10, 10);
}
EndDrawing();
}
void CleanupGame(GameState *g)
{
for (int i = 0; i < SHADER_COUNT; i++)
{
UnloadPostFX(&g->postFX[i]);
}
for (int i = 0; i < SOUNDTRACK_COUNT; i++)
{
UnloadMusicStream(g->soundtracks[i].music);
}
UnloadRenderTexture(g->target);
}
#endif // APPGAME_H
-25
View File
@@ -1,25 +0,0 @@
#ifndef APPGAMEASSETS_H
#define APPGAMEASSETS_H
typedef enum
{
POST_FX,
SHADER_COUNT
} ShaderID;
const ShaderAsset shaderAssets[SHADER_COUNT] = {
{"shaders/postfx.fs"}};
typedef enum
{
BEE_AMBIENT,
SOUNDTRACK_COUNT
} SoundtrackID;
const SoundtrackAsset soundtrackAssets[SOUNDTRACK_COUNT] = {
{"assets/sea.mp3"}};
#endif // APPGAMEASSETS_H
-71
View File
@@ -1,71 +0,0 @@
#ifndef APPGAMEBIRDS_H
#define APPGAMEBIRDS_H
typedef struct {
Sprite sprite;
Animation animation;
Physics physics;
} Birds;
typedef enum
{
FLYING,
BIRDS_TEX_COUNT
} birdsTextureID;
const TextureAsset birdsTextureAssets[BIRDS_TEX_COUNT] = {
{"assets/birds.png", 16.0f, 16.0f, 45.0f}
};
Birds CreateBirds(void){
TextureAsset flyingAsset = birdsTextureAssets[FLYING];
Texture2D texture = LoadTexture(flyingAsset.path);
float frameWidth = flyingAsset.frameWidth;
float rotation = flyingAsset.rotation;
Sprite birdSprite = {
.texture = texture,
.frameSize = {frameWidth, frameWidth},
.sourceRec = {0.0f, 0.0f, frameWidth, frameWidth},
.destRec = {GetScreenWidth()/2, 0.0f, frameWidth, frameWidth},
.origin = {frameWidth / 2, frameWidth / 2},
.rotation = rotation,
.color = WHITE
};
Animation birdsAnimation = {
.state = 1,
.currentFrame = 0,
.maxFrame = 2,
.framesCounter = 0,
.framesSpeed = 2.0f,
.animTimer = 0.0f
};
Physics birdsPhysics = {
.position = (Vector2){-100.0f, 0.0f},
.direction = (Vector2){0.0f, 0.0f},
.speed = 10.0f
};
return (Birds){
.sprite = birdSprite,
.animation = birdsAnimation,
.physics = birdsPhysics
};
}
void UpdateBirds(Birds *birds){
UpdatePhysics(&birds->physics, (Vector2){1.0f,0.0f});
UpdateSpriteDestRec(&birds->sprite, &birds->physics.position);
UpdateAnimation(&birds->animation, GetFrameTime());
UpdateSpriteSourceRec(&birds->sprite, &(Vector2){birds->sprite.frameSize.x * birds->animation.currentFrame, birds->sprite.frameSize.y});
}
void RenderBirds(Birds *birds){
RenderSprite(&birds->sprite);
}
#endif // APPGAMEBIRDS_H
-102
View File
@@ -1,102 +0,0 @@
#ifndef APPGAMEFloor_H
#define APPGAMEFloor_H
typedef struct
{
Sprite sprite;
Rectangle bounds;
Shader shader;
float time;
} Floor;
Floor CreateFloor(void)
{
Texture2D base = LoadTexture("assets/water_base.png");
Texture2D caustic = LoadTexture("assets/water_caustics.png");
Texture2D causticHighlight = LoadTexture("assets/water_caustics_highlights.png");
Texture2D noise = LoadTexture("assets/water_noise.png");
Texture2D cloud = LoadTexture("assets/water_cloudnoise.png");
Texture2D voronoise = LoadTexture("assets/water_voronoise.png");
float textureWidth = 64.0f;
Floor floor = {
.sprite = {
.texture = base,
.frameSize = {textureWidth, textureWidth},
.sourceRec = {0.0f, 0.0f, textureWidth, textureWidth},
.destRec = {0.0f, 0.0f, textureWidth, textureWidth},
.origin = {textureWidth / 2, textureWidth / 2},
.rotation = 0.0f,
.color = WHITE},
.bounds = {0},
.shader = LoadShader("shaders/water.vs", "shaders/water.fs"),
.time = 0.0f
};
float worldTileSize = 128.0f;
float textureSize = 32.0f;
floor.sprite.frameSize = (Vector2){worldTileSize, worldTileSize};
floor.sprite.sourceRec = (Rectangle){0, 0, textureSize, textureSize};
floor.sprite.destRec = (Rectangle){0, 0, worldTileSize, worldTileSize};
floor.sprite.origin = (Vector2){0, 0};
SetShaderValueTexture(floor.shader, GetShaderLocation(floor.shader, "causticTexture"), caustic);
SetShaderValueTexture(floor.shader, GetShaderLocation(floor.shader, "causticHighlightTexture"), causticHighlight);
SetShaderValueTexture(floor.shader, GetShaderLocation(floor.shader, "causticNoiseTexture"), noise);
SetShaderValueTexture(floor.shader, GetShaderLocation(floor.shader, "causticFadeNoiseTexture"), cloud);
SetShaderValueTexture(floor.shader, GetShaderLocation(floor.shader, "specularNoiseTexture"), voronoise);
SetShaderValueTexture(floor.shader, GetShaderLocation(floor.shader, "specularMovementLeftNoiseTexture"), voronoise);
SetShaderValueTexture(floor.shader, GetShaderLocation(floor.shader, "specularMovementRightNoiseTexture"), cloud);
float aspect = (float)GetScreenHeight() / (float)GetScreenWidth();
float pixelization = 2048.0f;
int aspectLoc = GetShaderLocation(floor.shader, "aspectRatio");
int pixelLoc = GetShaderLocation(floor.shader, "pixelization");
SetShaderValue(floor.shader, aspectLoc, &aspect, SHADER_UNIFORM_FLOAT);
SetShaderValue(floor.shader, pixelLoc, &pixelization, SHADER_UNIFORM_FLOAT);
floor.sprite.texture = base;
return floor;
}
void UpdateFloor(Floor *floor, const Camera2D *camera)
{
floor->bounds.x = (int)((camera->target.x - (GetScreenWidth() / 2.0f / camera->zoom)) / floor->sprite.frameSize.x) - 1;
floor->bounds.width = (int)((camera->target.x + (GetScreenWidth() / 2.0f / camera->zoom)) / floor->sprite.frameSize.x) + 1;
floor->bounds.y = (int)((camera->target.y - (GetScreenHeight() / 2.0f / camera->zoom)) / floor->sprite.frameSize.y) - 1;
floor->bounds.height = (int)((camera->target.y + (GetScreenHeight() / 2.0f / camera->zoom)) / floor->sprite.frameSize.y) + 1;
floor->time += GetFrameTime();
int timeLoc = GetShaderLocation(floor->shader, "time");
SetShaderValue(floor->shader, timeLoc, &floor->time, SHADER_UNIFORM_FLOAT);
}
void RenderFloor(Floor *floor)
{
BeginShaderMode(floor->shader);
for (int y = (int)floor->bounds.y; y <= (int)floor->bounds.height; y++)
{
for (int x = (int)floor->bounds.x; x <= (int)floor->bounds.width; x++)
{
Vector2 floorPosition = {x * floor->sprite.frameSize.x, y * floor->sprite.frameSize.y};
UpdateSpriteDestRec(&floor->sprite, &floorPosition);
RenderSprite(&floor->sprite);
}
}
EndShaderMode();
}
void UnloadFloor(Floor *floor)
{
UnloadShader(floor->shader);
}
#endif // APPGAMEFLOOR_H
-62
View File
@@ -1,62 +0,0 @@
#ifndef APPGAMEISLANDS_H
#define APPGAMEISLANDS_H
typedef struct {
Sprite sprite;
Animation animation;
Physics physics;
} Islands;
typedef enum
{
ISLAND,
ISLANDS_TEX_COUNT
} islandsTextureID;
const TextureAsset islandsTextureAssets[ISLANDS_TEX_COUNT] = {
{"assets/island.png", 16.0f, 16.0f, 0.0f}
};
Islands CreateIslands(void){
TextureAsset islandAsset = islandsTextureAssets[ISLAND];
Texture2D texture = LoadTexture(islandAsset.path);
float frameWidth = islandAsset.frameWidth;
float rotation = islandAsset.rotation;
Sprite islandSprite = {
.texture = texture,
.frameSize = {frameWidth, frameWidth},
.sourceRec = {0.0f, 0.0f, frameWidth, frameWidth},
.destRec = {GetScreenWidth()/2, 0.0f, frameWidth, frameWidth},
.origin = {frameWidth / 2, frameWidth / 2},
.rotation = rotation,
.color = WHITE
};
Physics islandPhysics = {
.position = (Vector2){-100.0f, 0.0f},
.direction = (Vector2){0.0f, 0.0f},
.speed = 10.0f
};
return (Islands){
.sprite = islandSprite,
.physics = islandPhysics
};
}
void UpdateIslands(Islands *islands){
UpdatePhysics(&islands->physics, (Vector2){0.0f,0.0f});
UpdateSpriteDestRec(&islands->sprite, &islands->physics.position);
UpdateAnimation(&islands->animation, GetFrameTime());
UpdateSpriteSourceRec(&islands->sprite, &(Vector2){islands->sprite.frameSize.x * islands->animation.currentFrame, islands->sprite.frameSize.y});
}
void RenderIslands(Islands *islands){
RenderSprite(&islands->sprite);
}
#endif // APPGAMEISLANDS_H
-145
View File
@@ -1,145 +0,0 @@
#ifndef APPGAMEPLAYER_H
#define APPGAMEPLAYER_H
typedef enum
{
START_SHIP,
PLAYER_TEX_COUNT
} playerTextureID;
const TextureAsset playerTextureAssets[PLAYER_TEX_COUNT] = {
{"assets/ship_start.png", 16.0f, 16.0f, 0.0f}
};
typedef enum {
ANCHOR,
SLOW_AHEAD,
FAST_AHEAD,
SPEED_COUNT
} playerSpeedID;
float playerSpeeds[SPEED_COUNT] = {
0.0f,
5.0f,
10.0f
};
playerSpeedID GetPlayerSpeedID(float speed) {
for (int i = 0; i < SPEED_COUNT; i++) {
if (playerSpeeds[i] == speed) {
return (playerSpeedID)i;
}
}
return ANCHOR;
}
typedef struct
{
Sprite sprite;
Animation animation;
Physics physics;
float rotation;
} Player;
Player CreatePlayer(void)
{
TextureAsset startShipAsset = playerTextureAssets[START_SHIP];
Texture2D texture = LoadTexture(startShipAsset.path);
float frameWidth = startShipAsset.frameWidth;
float rotation = startShipAsset.rotation;
Sprite playerSprite = {
.texture = texture,
.frameSize = {frameWidth, frameWidth},
.sourceRec = {0.0f, 0.0f, frameWidth, frameWidth},
.destRec = {0.0f, 0.0f, frameWidth, frameWidth},
.origin = {frameWidth / 2, frameWidth / 2},
.rotation = rotation,
.color = WHITE
};
Animation playerAnimation = {
.state = 1,
.currentFrame = 0,
.maxFrame = 3,
.framesCounter = 0,
.framesSpeed = 0.0f,
.animTimer = 0.0f
};
Physics playerPhysics = {
.position = (Vector2){0.0f,0.0f},
.direction = (Vector2){0.0f, 0.0f},
.speed = playerSpeeds[ANCHOR]
};
return (Player){
.sprite = playerSprite,
.animation = playerAnimation,
.physics = playerPhysics,
.rotation = rotation
};
}
void UpdatePlayer(Player *player)
{
if(IsKeyPressed(KEY_W) || IsKeyPressed(KEY_UP)){
if(player->physics.speed < playerSpeeds[FAST_AHEAD]){
if(player->physics.speed < playerSpeeds[SLOW_AHEAD]){
player->physics.speed = playerSpeeds[SLOW_AHEAD];
}
else {
player->physics.speed = playerSpeeds[FAST_AHEAD];
}
}
}
if(IsKeyPressed(KEY_S) || IsKeyPressed(KEY_DOWN)){
if(player->physics.speed > playerSpeeds[ANCHOR]){
if(player->physics.speed > playerSpeeds[SLOW_AHEAD]){
player->physics.speed = playerSpeeds[SLOW_AHEAD];
}
else {
player->physics.speed = playerSpeeds[ANCHOR];
}
}
}
player->sprite.sourceRec.x = 16.0f * GetPlayerSpeedID(player->physics.speed);
float rotationSpeed = 50.0f;
if (player->physics.speed > playerSpeeds[ANCHOR]){
if (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT)) {
player->rotation -= rotationSpeed * GetFrameTime();
}
if (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT)) {
player->rotation += rotationSpeed * GetFrameTime();
}
}
player->sprite.rotation = player->rotation;
float rad = (player->rotation - 90.0f) * (PI / 180.0f);
Vector2 dir = { cosf(rad), sinf(rad) };
UpdatePhysics(&player->physics, dir);
UpdateSpriteDestRec(&player->sprite, &player->physics.position);
}
void RenderPlayer(Player *player){
RenderSprite(&player->sprite);
}
#endif // APPGAMEPLAYER_H
-117
View File
@@ -1,117 +0,0 @@
#ifndef APPLOGO_H
#define APPLOGO_H
typedef struct {
int frameCounter;
int positionX;
int positionY;
int lettersCount;
int topSideRecWidth;
int leftSideRecHeight;
int bottomSideRecWidth;
int rightSideRecHeight;
int state;
float alpha;
} LogoState;
void InitLogo(LogoState *l) {
SetTargetFPS(60);
l->frameCounter = 0;
l->positionX = GetScreenWidth() / 2 - 128;
l->positionY = GetScreenHeight() / 2 - 128;
l->lettersCount = 0;
l->topSideRecWidth = 16;
l->leftSideRecHeight = 16;
l->bottomSideRecWidth = 16;
l->rightSideRecHeight = 16;
l->state = 0;
l->alpha = 1.0f;
}
void UpdateLogo(LogoState *l, View *currentView, bool *running) {
if (WindowShouldClose() && !IsKeyPressed(KEY_ESCAPE)) {
*running = false;
}
l->frameCounter++;
if (l->state == 0) {
if (l->frameCounter >= 120) {
l->state = 1;
l->frameCounter = 0;
}
}
else if (l->state == 1) {
l->topSideRecWidth += 4;
l->leftSideRecHeight += 4;
if (l->topSideRecWidth >= 256) {
l->state = 2;
l->frameCounter = 0;
}
}
else if (l->state == 2) {
l->bottomSideRecWidth += 4;
l->rightSideRecHeight += 4;
if (l->bottomSideRecWidth >= 256) {
l->state = 3;
l->frameCounter = 0;
}
}
else if (l->state == 3) {
if (l->frameCounter % 12 == 0) {
l->lettersCount++;
}
if (l->lettersCount >= 10) {
l->alpha -= 0.02f;
if (l->alpha <= 0.0f) {
l->alpha = 0.0f;
l->state = 4;
}
}
}
else if (l->state == 4) {
*currentView = MENU;
}
}
void RenderLogo(const LogoState *l, Flags *flags) {
BeginDrawing();
ClearBackground(RAYWHITE);
if (l->state == 0) {
if ((l->frameCounter / 15) % 2 == 0) {
DrawRectangle(l->positionX, l->positionY, 16, 16, BLACK);
}
}
else if (l->state == 1) {
DrawRectangle(l->positionX, l->positionY, l->topSideRecWidth, 16, BLACK);
DrawRectangle(l->positionX, l->positionY, 16, l->leftSideRecHeight, BLACK);
}
else if (l->state == 2) {
DrawRectangle(l->positionX, l->positionY, l->topSideRecWidth, 16, BLACK);
DrawRectangle(l->positionX, l->positionY, 16, l->leftSideRecHeight, BLACK);
DrawRectangle(l->positionX + 240, l->positionY, 16, l->rightSideRecHeight, BLACK);
DrawRectangle(l->positionX, l->positionY + 240, l->bottomSideRecWidth, 16, BLACK);
}
else if (l->state == 3) {
DrawRectangle(l->positionX, l->positionY, l->topSideRecWidth, 16, Fade(BLACK, l->alpha));
DrawRectangle(l->positionX, l->positionY + 16, 16, l->leftSideRecHeight - 32, Fade(BLACK, l->alpha));
DrawRectangle(l->positionX + 240, l->positionY + 16, 16, l->rightSideRecHeight - 32, Fade(BLACK, l->alpha));
DrawRectangle(l->positionX, l->positionY + 240, l->bottomSideRecWidth, 16, Fade(BLACK, l->alpha));
DrawRectangle(GetScreenWidth() / 2 - 112, GetScreenHeight() / 2 - 112, 224, 224, Fade(RAYWHITE, l->alpha));
DrawText(TextSubtext("raylib", 0, l->lettersCount), GetScreenWidth() / 2 - 44, GetScreenHeight() / 2 + 48, 50, Fade(BLACK, l->alpha));
}
if (flags->showFPS){
DrawFPS(10, 10);
}
EndDrawing();
}
#endif // APPLOGO_H
-62
View File
@@ -1,62 +0,0 @@
#ifndef APPMENU_H
#define APPMENU_H
#include <appMenuView.h>
#include <appMenuSettings.h>
#include <appMenuMain.h>
typedef struct
{
MenuView menuView;
MenuMain menuMain;
MenuSettings menuSettings;
} MenuState;
void InitMenu(MenuState *m)
{
m->menuView = MAIN;
InitMenuSettings(&m->menuSettings);
InitMenuMain(&m->menuMain);
}
void UpdateMenu(MenuState *m, State *state, Flags *flags)
{
switch (m->menuView)
{
case MAIN:
{
UpdateMenuMain(&m->menuMain, state, flags, &m->menuView);
}break;
case SETTINGS:
{
UpdateMenuSettings(&m->menuSettings, &m->menuView, flags);
}break;
default: break;
}
}
void RenderMenu(MenuState *m, Font *font, const char *title, Flags *flags)
{
switch (m->menuView)
{
case MAIN:
{
RenderMenuMain(&m->menuMain, font, title, flags);
}break;
case SETTINGS:
{
RenderMenuSettings(&m->menuSettings, flags);
}
default: break;
}
}
void CleanupMenu(MenuState *m)
{
CleanupMenuMain(&m->menuMain);
}
#endif // APPMENU_H
-43
View File
@@ -1,43 +0,0 @@
#ifndef APPMENUASSETS_H
#define APPMENUASSETS_H
typedef enum
{
MENU_CURSOR_TEX,
MENU_BIG_BUTTONS_TEX,
MENU_BOARD_TEX,
MENU_CLOUD_BACKGROUND,
MENU_CLOUD_MIDGROUND,
MENU_CLOUD_FOREGROUND,
MENU_TEX_COUNT
} MenuTextureID;
const TextureAsset menuTextureAssets[MENU_TEX_COUNT] = {
{"assets/mouse.png", 16.0f, 16.0f, 0.0f},
{"assets/buttons.png", 288.0f/3, 96.0f/3, 0.0f},
{"assets/menu_board.png", 128.0f, 144.0f, 0.0f},
{"assets/cloud_background.png", 576.0f, 324.0f, 0.0f},
{"assets/cloud_midground.png", 576.0f, 324.0f, 0.0f},
{"assets/cloud_foreground.png", 576.0f, 324.0f, 0.0f}};
typedef enum
{
MENU_MUSIC,
MENU_SOUNDTRACK_COUNT
} MenuSoundtrackID;
const SoundtrackAsset menuSoundtrackAssets[MENU_SOUNDTRACK_COUNT] = {
{"assets/merrygoround.wav"}};
typedef enum
{
HOVER_SOUND,
CLICK_SOUND,
MENU_SOUND_COUNT
} MenuSoundID;
const SoundAsset menuSoundAssets[MENU_SOUND_COUNT] = {
{"assets/button_hover.wav"},
{"assets/button_click.wav"}};
#endif // APPMENUASSETS_H
-211
View File
@@ -1,211 +0,0 @@
#ifndef APPMENUMAIN_H
#define APPMENUMAIN_H
#include "appMenuAssets.h"
#include "appMenuView.h"
#include "appMenuMainBackground.h"
typedef struct {
Assets assets;
Mouse mouse;
Texture2D textures[MENU_TEX_COUNT];
Sound sounds[MENU_SOUND_COUNT];
Soundtrack soundtracks[MENU_SOUNDTRACK_COUNT];
ImageElement board;
ImageButton playButton;
ImageButton quitButton;
ImageButton settingsButton;
int menuScale;
Background background;
Background midground;
Background foreground;
} MenuMain;
void InitMenuMain(MenuMain *m){
m->assets = (Assets){
.textureAssets = menuTextureAssets,
.soundAssets = menuSoundAssets,
.soundtrackAssets = menuSoundtrackAssets};
for (int i = 0; i < MENU_TEX_COUNT; i++)
{
m->textures[i] = LoadTexture(m->assets.textureAssets[i].path);
}
for (int i = 0; i < MENU_SOUND_COUNT; i++)
{
m->sounds[i] = LoadSound(m->assets.soundAssets[i].path);
}
for (int i = 0; i < MENU_SOUNDTRACK_COUNT; i++)
{
m->soundtracks[i] = LoadSoundtrack(m->assets.soundtrackAssets[i].path);
}
InitBackground(0.1f, &m->background, &m->textures[MENU_CLOUD_BACKGROUND], &m->assets.textureAssets[MENU_CLOUD_BACKGROUND]);
InitBackground(0.2f, &m->midground, &m->textures[MENU_CLOUD_MIDGROUND], &m->assets.textureAssets[MENU_CLOUD_MIDGROUND]);
InitBackground(0.3f, &m->foreground, &m->textures[MENU_CLOUD_FOREGROUND], &m->assets.textureAssets[MENU_CLOUD_FOREGROUND]);
m->mouse = CreateMouse(0.10f, 5.0f, 10.0f, &m->textures[MENU_CURSOR_TEX]);
m->menuScale = 4;
int windowWidth = GetScreenWidth();
int windowHeight = GetScreenHeight();
Vector2 windowCenter = {windowWidth / 2, windowHeight / 2};
int boardWidth = windowWidth / m->menuScale * 2.5f;
float boardScaleFactor = (float)boardWidth / m->assets.textureAssets[MENU_BOARD_TEX].frameWidth;
int boardHeight = (int)(m->assets.textureAssets[MENU_BOARD_TEX].frameHeight * boardScaleFactor);
Vector2 boardSource = {128.0f, 0.0f};
Rectangle boardDestRec = {
.x = windowCenter.x - (boardWidth / 2),
.y = windowCenter.y - (boardHeight / 2),
.width = boardWidth,
.height = boardHeight};
m->board = CreateImageElement(&m->textures[MENU_BOARD_TEX], &m->assets.textureAssets[MENU_BOARD_TEX], &boardSource, &boardDestRec);
int buttonWidth = windowWidth / m->menuScale;
float buttonScaleFactor = (float)buttonWidth / m->assets.textureAssets[MENU_BIG_BUTTONS_TEX].frameWidth;
int buttonHeight = (int)(m->assets.textureAssets[MENU_BIG_BUTTONS_TEX].frameHeight * buttonScaleFactor);
int buttonSpacing = buttonHeight;
//Button texture dimensions
float menuButtonWidth = m->assets.textureAssets[MENU_BIG_BUTTONS_TEX].frameWidth;
float menuButtonHeight = m->assets.textureAssets[MENU_BIG_BUTTONS_TEX].frameHeight;
//Quit Button
Vector2 quitButtonNotPressed = {0.0f, 0.0f};
Vector2 quitButtonHover = {menuButtonWidth, 0.0f};
Vector2 quitButtonPressed = {menuButtonWidth * 2, 0.0f};
Rectangle quitButtonDestRec = {
.x = windowCenter.x - (buttonWidth / 2),
.y = windowCenter.y - (buttonHeight / 2) + buttonSpacing,
.width = buttonWidth,
.height = buttonHeight
};
m->quitButton = CreateImageButton(NOT_CLICKED, &m->textures[MENU_BIG_BUTTONS_TEX], &m->assets.textureAssets[MENU_BIG_BUTTONS_TEX], &quitButtonNotPressed, &quitButtonPressed, &quitButtonHover, &quitButtonDestRec);
//Play Button
Vector2 playButtonNotPressed = {0.0f, menuButtonHeight};
Vector2 playButtonHover = {menuButtonWidth, menuButtonHeight};
Vector2 playButtonPressed = {menuButtonWidth * 2, menuButtonHeight};
Rectangle playButtonDestRec = {
.x = windowCenter.x - (buttonWidth / 2),
.y = windowCenter.y - (buttonHeight / 2),
.width = buttonWidth,
.height = buttonHeight
};
m->playButton = CreateImageButton(NOT_CLICKED, &m->textures[MENU_BIG_BUTTONS_TEX], &m->assets.textureAssets[MENU_BIG_BUTTONS_TEX], &playButtonNotPressed, &playButtonPressed, &playButtonHover, &playButtonDestRec);
//Settings Button
Vector2 settingsButtonNotPressed = {0.0f, menuButtonHeight * 2};
Vector2 settingsButtonHover = {menuButtonWidth, menuButtonHeight * 2};
Vector2 settingsButtonPressed = {menuButtonWidth * 2, menuButtonHeight * 2};
Rectangle settingsButtonDestRec = {
.x = windowCenter.x - (buttonWidth / 2),
.y = windowCenter.y - (buttonHeight / 2) + buttonSpacing * 2,
.width = buttonWidth,
.height = buttonHeight
};
m->settingsButton = CreateImageButton(NOT_CLICKED, &m->textures[MENU_BIG_BUTTONS_TEX], &m->assets.textureAssets[MENU_BIG_BUTTONS_TEX], &settingsButtonNotPressed, &settingsButtonPressed, &settingsButtonHover, &settingsButtonDestRec);
}
void UpdateMenuMain(MenuMain *m, State *state, Flags *flags, MenuView *menuView){
for (int i = 0; i < MENU_SOUNDTRACK_COUNT; i++)
{
UpdateSoundtrack(&m->soundtracks[i], flags->soundtrackOn);
}
if (GetFPS() >= 60)
{
SetTargetFPS(60);
}
if (isImageButtonClicked(&m->playButton, m->sounds[HOVER_SOUND], m->sounds[CLICK_SOUND]))
{
state->running = true;
state->currentView = GAMEPLAY;
}
if (IsKeyPressed(KEY_ESCAPE) && state->gameStarted)
{
state->currentView = GAMEPLAY;
}
if (isImageButtonClicked(&m->settingsButton, m->sounds[HOVER_SOUND], m->sounds[CLICK_SOUND]))
{
*menuView = SETTINGS;
}
if (isImageButtonClicked(&m->quitButton, m->sounds[HOVER_SOUND], m->sounds[CLICK_SOUND]) || (WindowShouldClose() && !IsKeyPressed(KEY_ESCAPE)))
{
state->running = false;
}
UpdateBackground(&m->background);
UpdateBackground(&m->midground);
UpdateBackground(&m->foreground);
UpdateMouseScreen(&m->mouse);
}
void RenderMenuMain(MenuMain *m, Font *font, const char *title, Flags *flags){
BeginDrawing();
ClearBackground(WHITE);
RenderBackground(&m->background);
RenderBackground(&m->midground);
RenderBackground(&m->foreground);
renderImageElement(&m->board);
renderImageButton(&m->playButton);
renderImageButton(&m->quitButton);
renderImageButton(&m->settingsButton);
int textWidth = MeasureText(title, font->baseSize);
DrawTextEx(*font, title, (Vector2){GetScreenWidth() / 2 - textWidth / 2, textWidth / 4}, (float)font->baseSize, 2, WHITE);
DrawTexturePro(
m->mouse.cursorTexture,
(Rectangle){0, 0, m->mouse.cursorTexture.width, m->mouse.cursorTexture.height},
(Rectangle){m->mouse.screenPosition.x, m->mouse.screenPosition.y, m->mouse.cursorTexture.width, m->mouse.cursorTexture.height},
(Vector2){0.0f, 0.0f},
0.0f,
WHITE);
if (flags->showFPS)
{
DrawFPS(10, 10);
}
EndDrawing();
}
void CleanupMenuMain(MenuMain *m){
for (int i = 0; i < MENU_SOUND_COUNT; i++)
{
UnloadSound(m->sounds[i]);
}
for (int i = 0; i < MENU_TEX_COUNT; i++)
{
if (m->textures[i].id > 0)
{
UnloadTexture(m->textures[i]);
}
}
for (int i = 0; i < MENU_SOUNDTRACK_COUNT; i++)
{
UnloadMusicStream(m->soundtracks[i].music);
}
}
#endif //APPMENUMAIN_H
-68
View File
@@ -1,68 +0,0 @@
#ifndef APPMENUMAINBACKGROUND_H
#define APPMENUMAINBACKGROUND_H
typedef struct {
Sprite sprite;
float scrolling;
float scale;
float scrollSpeed;
Vector2 pos;
} Background;
void InitBackground(float scrollSpeed, Background *bg, Texture2D *texture, const TextureAsset *backgroundAsset){
bg->scrolling = 0.0f;
bg->scrollSpeed = scrollSpeed;
bg->scale = 1.0f;
bg->sprite = (Sprite){
.texture = *texture,
.sourceRec = (Rectangle){0.0f,0.0f,backgroundAsset->frameWidth, backgroundAsset->frameHeight},
.destRec = (Rectangle){0.0f,0.0f,(float)GetScreenWidth(),(float)GetScreenHeight()},
.origin = (Vector2){0.0f,0.0f},
.rotation = 0.0f,
.color = WHITE
};
}
void UpdateBackground(Background *bg){
bg->scrolling -= bg->scrollSpeed;
if (bg->scrolling <= -bg->sprite.texture.width * bg->scale) {
bg->scrolling = 0;
}
bg->pos = (Vector2){ bg->scrolling, 0.0f };
UpdateSpriteDestRec(&bg->sprite, &bg->pos);
}
void RenderBackground(Background *bg){
Sprite temp0 = bg->sprite;
float newX0 = bg->sprite.destRec.x + bg->sprite.texture.width * bg->scale * 2;
Vector2 newPos0 = {newX0, bg->sprite.destRec.y};
UpdateSpriteDestRec(&temp0, &newPos0);
RenderSprite(&temp0);
Sprite temp = bg->sprite;
float newX = bg->sprite.destRec.x + bg->sprite.texture.width * bg->scale;
Vector2 newPos = {newX, bg->sprite.destRec.y};
UpdateSpriteDestRec(&temp, &newPos);
RenderSprite(&temp);
RenderSprite(&bg->sprite);
Sprite temp2 = bg->sprite;
float newX2 = bg->sprite.destRec.x - bg->sprite.texture.width * bg->scale;
Vector2 newPos2 = {newX2, bg->sprite.destRec.y};
UpdateSpriteDestRec(&temp2, &newPos2);
RenderSprite(&temp2);
Sprite temp3 = bg->sprite;
float newX3 = bg->sprite.destRec.x - bg->sprite.texture.width * bg->scale * 2;
Vector2 newPos3 = {newX3, bg->sprite.destRec.y};
UpdateSpriteDestRec(&temp3, &newPos3);
RenderSprite(&temp3);
}
#endif // APPMENUMAINBACKGROUND_H
-68
View File
@@ -1,68 +0,0 @@
#ifndef APPMENUSETTINGS_H
#define APPMENUSETTINGS_H
typedef struct
{
Button showFPS;
Button soundtrackOn;
} MenuSettings;
void InitMenuSettings(MenuSettings *s)
{
int windowWidth = GetScreenWidth();
int windowHeight = GetScreenHeight();
Vector2 windowCenter = {windowWidth / 2, windowHeight / 2};
Vector2 standardButtonDimensions = {100, 50};
int standardSpacing = standardButtonDimensions.y / 2;
Vector2 button1Pos = {windowCenter.x, windowCenter.y};
Vector2 button2Pos = {windowCenter.x, windowCenter.y + standardButtonDimensions.y + standardSpacing};
s->showFPS = initButton("showFPS", standardButtonDimensions, button1Pos);
s->soundtrackOn = initButton("soundtrackOn", standardButtonDimensions, button2Pos);
}
void UpdateMenuSettings(MenuSettings *s, MenuView *menuView,Flags *flags)
{
ShowCursor();
if(isButtonClicked(&s->showFPS)){
flags->showFPS = !flags->showFPS;
}
if(isButtonClicked(&s->soundtrackOn)){
flags->soundtrackOn = !flags->soundtrackOn;
}
if (IsKeyPressed(KEY_ESCAPE)){
*menuView = MAIN;
}
}
void RenderMenuSettings(MenuSettings *s, Flags *flags)
{
BeginDrawing();
ClearBackground(BLACK);
renderButton(&s->showFPS);
if (flags->showFPS){
DrawFPS(10,10);
}
renderButton(&s->soundtrackOn);
EndDrawing();
}
void ClenupMenuSettings(MenuSettings *s){
}
#endif // APPMENUSETTINGS_H
-10
View File
@@ -1,10 +0,0 @@
#ifndef APPMENUVIEW_H
#define APPMENUVIEW_H
typedef enum MenuView {
MAIN = 0,
SETTINGS = 1
} MenuView;
#endif // MENUVIEW_H
-9
View File
@@ -1,9 +0,0 @@
#ifndef APPSETTINGS_H
#define APPSETTINGS_H
typedef struct {
bool showFPS;
bool soundtrackOn;
} Flags;
#endif // APPSETTINGS_H
-16
View File
@@ -1,16 +0,0 @@
#ifndef APPSTATE_H
#define APPSTATE_H
typedef enum View {
LOGO = 0,
MENU = 1,
GAMEPLAY = 2
} View;
typedef struct {
View currentView;
bool running;
bool gameStarted;
} State;
#endif // APPSTATE_H
+257
View File
@@ -0,0 +1,257 @@
#ifndef APPTYPES_H
#define APPTYPES_H
//INCLUDES//
#include <raylib.h>
#include <engine.h>
//DEFINES//
#define TEXT_COLOR_DARK (Color){ 182, 137, 98, 255}
#define TEXT_COLOR_LIGHT (Color){ 243, 229, 194, 255}
//ENUMS//
typedef enum
{
MENU_CURSOR_TEX,
MENU_BIG_BUTTONS_TEX,
MENU_BOARD_TEX,
MENU_CLOUD_BACKGROUND,
MENU_CLOUD_MIDGROUND,
MENU_CLOUD_FOREGROUND,
MENU_TEX_COUNT
} MenuTextureID;
typedef enum
{
MENU_MUSIC,
MENU_SOUNDTRACK_COUNT
} MenuSoundtrackID;
typedef enum
{
HOVER_SOUND,
CLICK_SOUND,
MENU_SOUND_COUNT
} MenuSoundID;
typedef enum MenuView {
MAIN = 0,
SETTINGS = 1
} MenuView;
typedef enum
{
START_SHIP,
PLAYER_TEX_COUNT
} playerTextureID;
typedef enum {
ANCHOR,
SLOW_AHEAD,
FAST_AHEAD,
SPEED_COUNT
} playerSpeedID;
typedef enum
{
FLYING,
BIRDS_TEX_COUNT
} birdsTextureID;
typedef enum
{
ISLAND,
ISLANDS_TEX_COUNT
} islandsTextureID;
typedef enum
{
POST_FX,
SHADER_COUNT
} ShaderID;
typedef enum
{
BEE_AMBIENT,
SOUNDTRACK_COUNT
} SoundtrackID;
typedef enum View {
LOGO = 0,
MENU = 1,
GAMEPLAY = 2
} View;
//STRUCTS//
typedef struct {
int frameCounter;
int positionX;
int positionY;
int lettersCount;
int topSideRecWidth;
int leftSideRecHeight;
int bottomSideRecWidth;
int rightSideRecHeight;
int state;
float alpha;
} LogoState;
typedef struct {
Sprite sprite;
float scrolling;
float scale;
float scrollSpeed;
Vector2 pos;
} Background;
typedef struct {
Assets assets;
Mouse mouse;
Texture2D textures[MENU_TEX_COUNT];
Sound sounds[MENU_SOUND_COUNT];
Soundtrack soundtracks[MENU_SOUNDTRACK_COUNT];
ImageElement board;
ImageButton playButton;
ImageButton quitButton;
ImageButton settingsButton;
int menuScale;
Background background;
Background midground;
Background foreground;
} MenuMain;
typedef struct
{
Button showFPS;
Button soundtrackOn;
} MenuSettings;
typedef struct
{
MenuView menuView;
MenuMain menuMain;
MenuSettings menuSettings;
} MenuState;
typedef struct
{
Sprite sprite;
Rectangle bounds;
Shader shader;
float time;
} Floor;
typedef struct
{
Sprite sprite;
Animation animation;
Physics physics;
float rotation;
} Player;
typedef struct {
Sprite sprite;
Animation animation;
Physics physics;
} Birds;
typedef struct {
Sprite sprite;
Animation animation;
Physics physics;
} Islands;
typedef struct
{
Assets assets;
PostProcessing postFX[SHADER_COUNT];
Soundtrack soundtracks[SOUNDTRACK_COUNT];
RenderTexture2D target;
Floor floor;
Player player;
Birds birds;
Islands islands;
Camera2D camera;
Mouse mouse;
Image image;
} GameState;
typedef struct {
View currentView;
bool running;
bool gameStarted;
} State;
typedef struct {
bool showFPS;
bool soundtrackOn;
} Flags;
typedef struct {
Config config;
State state;
Flags flags;
Window window;
Font font;
LogoState logo;
MenuState menu;
GameState game;
} App;
//FUNCTIONS//
void InitLogo(LogoState *l);
void UpdateLogo(LogoState *l, View *currentView, bool *running);
void RenderLogo(const LogoState *l, Flags *flags);
void InitBackground(float scrollSpeed, Background *bg, Texture2D *texture, const TextureAsset *backgroundAsset);
void UpdateBackground(Background *bg);
void RenderBackground(Background *bg);
void InitMenuMain(MenuMain *m);
void UpdateMenuMain(MenuMain *m, State *state, Flags *flags, MenuView *menuView);
void RenderMenuMain(MenuMain *m, Font *font, const char *title, Flags *flags);
void CleanupMenuMain(MenuMain *m);
void InitMenuSettings(MenuSettings *s);
void UpdateMenuSettings(MenuSettings *s, MenuView *menuView, Flags *flags);
void RenderMenuSettings(MenuSettings *s, Flags *flags);
void CleanupMenuSettings(MenuSettings *s);
void InitMenu(MenuState *m);
void UpdateMenu(MenuState *m, State *state, Flags *flags);
void RenderMenu(MenuState *m, Font *font, const char *title, Flags *flags);
void CleanupMenu(MenuState *m);
Floor CreateFloor(void);
void UpdateFloor(Floor *floor, const Camera2D *camera);
void RenderFloor(Floor *floor);
void UnloadFloor(Floor *floor);
playerSpeedID GetPlayerSpeedID(float speed);
Player CreatePlayer(void);
void UpdatePlayer(Player *player);
void RenderPlayer(Player *player);
Birds CreateBirds(void);
void UpdateBirds(Birds *birds);
void RenderBirds(Birds *birds);
Islands CreateIslands(void);
void UpdateIslands(Islands *islands);
void RenderIslands(Islands *islands);
void InitGame(App *app);
void UpdateGame(App *app);
void RenderComponents(App *app);
void RenderGame(App *app);
void CleanupGame(App *app);
void ConfigApp(App *app);
void InitApp(App *app);
void UpdateApp(App *app);
void CleanupApp(App *app);
#endif //APPTYPES_H
+232
View File
@@ -0,0 +1,232 @@
#ifndef ENGINE_H
#define ENGINE_H
#include <raylib.h>
#include <raymath.h>
#include <raygui.h>
#include <rini.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <math.h>
typedef struct
{
Texture2D texture;
Rectangle sourceRec;
Rectangle destRec;
Vector2 frameSize;
Vector2 origin;
float rotation;
Color color;
} Sprite;
typedef struct {
int state;
int currentFrame;
int maxFrame;
int framesCounter;
int framesSpeed;
float animTimer;
} Animation;
typedef struct {
void** elements;
unsigned int count;
unsigned int capacity;
} Array;
typedef struct {
const char* path;
float frameWidth;
float frameHeight;
float rotation;
} TextureAsset;
typedef struct {
const char* path;
} ShaderAsset;
typedef struct {
const char* path;
} SoundtrackAsset;
typedef struct {
const char* path;
} SoundAsset;
typedef struct {
const TextureAsset *textureAssets;
const ShaderAsset *shaderAssets;
const SoundtrackAsset *soundtrackAssets;
const SoundAsset *soundAssets;
} Assets;
typedef struct {
char *path;
rini_config rini;
} Config;
typedef enum {
NOT_CLICKED,
HOVER,
CLICKED
} ButtonState;
typedef struct
{
Sprite sprite;
Vector2 notClicked;
Vector2 hover;
Vector2 clicked;
bool isHovered;
bool isClicked;
} ImageButton;
typedef struct
{
Sprite sprite;
} ImageElement;
typedef struct
{
Rectangle rec;
char *text;
} Button;
typedef struct {
Vector2 screenPosition;
Vector2 worldPosition;
float zoomSpeed;
float minZoom;
float maxZoom;
float scaleFactor;
float wheelMove;
bool leftButton;
bool rightButton;
Texture2D cursorTexture;
} Mouse;
typedef struct {
Sprite sprite;
Vector2 position;
} Object;
typedef struct {
Object *data;
const Object *prototype;
size_t count;
} ObjectArray;
typedef struct
{
Vector2 position;
Vector2 direction;
Vector2 velocity;
float speed;
} Physics;
typedef struct {
Shader shader;
int resolutionLoc;
int strengthLoc;
float strength;
} PostProcessing;
typedef struct {
Music music;
bool playing;
bool paused;
} Soundtrack;
typedef struct {
Vector2 *data;
size_t count;
} Vector2Array;
typedef struct {
int width;
int height;
const char* title;
} Window;
void UpdateAnimation(Animation *animation, float deltaTime);
Array* CreateArray(unsigned int initCapacity);
int AddElementToArray(Array* array, void* element);
int RemoveElementFromArray(Array* array, unsigned int index);
void* GetRandomElementFromArray(Array* array);
void UpdateArray(Array* array, void (*updateFunc)(void*));
void RenderArray(Array* array, void (*renderFunc)(void*));
void FreeArray(Array** array);
Camera2D CreateCamera(Vector2 playerPosition, float initZoom);
void UpdateCameraTarget(Camera2D *camera, Vector2 *position, const float smoothness);
void UpdateCameraZoom(Camera2D *camera, const float *scaleFactor, const float *minZoom, const float *maxZoom);
void UpdateCamera2D(Camera2D* camera, Vector2* position, Mouse* mouse);
void InitConfig(Config *config, const char* path);
int GetConfigInt(Config *config, const char *key);
int GetConfigIntOrDefault(Config *config, const char *key, int default_value);
const char* GetConfigString(Config *config, const char *key);
const char* GetConfigStringOrDefault(Config *config, const char *key, const char *default_value);
const char* GetConfigDescription(Config *config, const char *key);
int SetConfigInt(Config *config, const char *key, int value, const char *desc);
int SetConfigString(Config *config, const char *key, const char *text, const char *desc);
int SetConfigDescription(Config *config, const char *key, const char *desc);
int AddCommentLine(Config *config, const char *comment);
void SaveConfig(Config *config);
void CleanUpConfig(Config *config);
void InitFont(Font *font, const char* path);
void CleanupFont(Font *font);
ImageButton CreateImageButton(ButtonState state, Texture2D *texture, const TextureAsset *asset, Vector2 *source, Vector2 *clicked, Vector2 *hover, Rectangle *destRec);
ImageElement CreateImageElement(Texture2D *texture, const TextureAsset *asset, Vector2 *source, Rectangle *destRec);
int isImageButtonClicked(ImageButton *b, Sound soundHover, Sound soundClick);
void renderImageButton(ImageButton *b);
void renderImageElement(ImageElement *e);
Button initButton(char *text, Vector2 dimensions, Vector2 position);
int isButtonClicked(Button *b);
void renderButton(Button *b);
Mouse CreateMouse(float zoomSpeed, float minZoom, float maxZoom, Texture2D *texture);
void UpdateMouseScreen(Mouse *mouse);
void UpdateMouse(Mouse *mouse, Camera2D *camera);
Vector2 GetDirectionVector(void);
ObjectArray CreateObjectArray(const Object *prototype, const size_t count);
Object* GetRandomObject(ObjectArray *objects);
void AddObjectToArray(ObjectArray *objects, const Object *prototype, Vector2 position);
void SetPositionForObjectArray(ObjectArray *objects, const Vector2Array *positions);
void SetRandomPositionForObjectArray(ObjectArray *objects, const Rectangle bounds);
void SwapAndPopObjectsArrayOnRecCollision(ObjectArray *objects, const Rectangle rec);
void SwapAndPopObjectsArrayOnPointCollision(ObjectArray *objects, const Vector2 point);
void RenderObjectArray(const ObjectArray *objects);
void UpdatePhysicsDirection(Vector2 *direction, Vector2 vector);
void UpdatePhysicsVelocity(Vector2 *velocity, Vector2 *direction, float *speed);
void UpdatePhysicsPosition(Vector2 *position, Vector2 *velocity);
void UpdatePhysicsSpeed(float *speed, float *newSpeed);
void UpdatePhysics(Physics *physics, Vector2 direction);
PostProcessing CreatePostFX(const char* shaderPath);
void UpdatePostFX(PostProcessing *postFX);
void RenderPostFX(PostProcessing *postFX, RenderTexture2D *target);
void UnloadPostFX(PostProcessing *postFX);
Soundtrack LoadSoundtrack(const char* musicPath);
void UpdateSoundtrack(Soundtrack *soundtrack, bool playing);
void UpdateSpriteSourceRec(Sprite *sprite, const Vector2 *vector);
void UpdateSpriteDestRec(Sprite *sprite, const Vector2 *vector);
void UpdateSpriteRotation(Sprite *sprite, Vector2 *vector);
void RenderSprite(const Sprite *sprite);
void PrintSprite(const Sprite *sprite);
bool IsVectorZero(Vector2 v);
Vector2 GetRandomVector(const Rectangle bounds);
#endif //ENGINE_H