big refactor: i see i need header files
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
#include <engine.h>
|
||||
|
||||
#include "appTypes.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
RenderGame(app);
|
||||
}break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CleanupApp(App *app){
|
||||
CleanupMenu(&app->menu);
|
||||
CleanupGame(app);
|
||||
CleanupFont(&app->font);
|
||||
CleanUpConfig(&app->config);
|
||||
}
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
const ShaderAsset shaderAssets[SHADER_COUNT] = {
|
||||
{"shaders/postfx.fs"}};
|
||||
|
||||
|
||||
|
||||
const SoundtrackAsset soundtrackAssets[SOUNDTRACK_COUNT] = {
|
||||
{"assets/sea.mp3"}};
|
||||
|
||||
|
||||
void InitGame(App *app)
|
||||
{
|
||||
GameState *g = &app->game;
|
||||
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(app->window.width, app->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(App *app)
|
||||
{
|
||||
GameState *g = &app->game;
|
||||
if(!app->state.gameStarted){
|
||||
app->state.gameStarted = true;
|
||||
}
|
||||
|
||||
if (GetFPS() <= 60)
|
||||
{
|
||||
SetTargetFPS(0);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ESCAPE))
|
||||
{
|
||||
app->state.currentView = MENU;
|
||||
}
|
||||
|
||||
if (WindowShouldClose() && !IsKeyPressed(KEY_ESCAPE))
|
||||
{
|
||||
app->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], app->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(App *app)
|
||||
{
|
||||
GameState *g = &app->game;
|
||||
RenderFloor(&g->floor);
|
||||
RenderPlayer(&g->player);
|
||||
RenderBirds(&g->birds);
|
||||
RenderIslands(&g->islands);
|
||||
}
|
||||
|
||||
void RenderGame(App *app)
|
||||
{
|
||||
GameState *g = &app->game;
|
||||
|
||||
BeginTextureMode(g->target);
|
||||
ClearBackground(BLACK);
|
||||
BeginMode2D(g->camera);
|
||||
RenderComponents(app);
|
||||
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 (app->flags.showFPS)
|
||||
{
|
||||
DrawFPS(10, 10);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
void CleanupGame(App *app)
|
||||
{
|
||||
GameState *g = &app->game;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
const TextureAsset playerTextureAssets[PLAYER_TEX_COUNT] = {
|
||||
{"assets/ship_start.png", 16.0f, 16.0f, 0.0f}
|
||||
};
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
|
||||
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}};
|
||||
|
||||
|
||||
const SoundtrackAsset menuSoundtrackAssets[MENU_SOUNDTRACK_COUNT] = {
|
||||
{"assets/merrygoround.wav"}};
|
||||
|
||||
|
||||
const SoundAsset menuSoundAssets[MENU_SOUND_COUNT] = {
|
||||
{"assets/button_hover.wav"},
|
||||
{"assets/button_click.wav"}};
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "appTypes.h"
|
||||
|
||||
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){
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "engine.h"
|
||||
|
||||
void UpdateAnimation(Animation *animation, float deltaTime) {
|
||||
animation->animTimer += deltaTime;
|
||||
float frameTime = 1.0f / animation->framesSpeed;
|
||||
|
||||
if (animation->animTimer < frameTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
animation->animTimer -= frameTime;
|
||||
animation->currentFrame++;
|
||||
|
||||
if (animation->currentFrame >= animation->maxFrame) {
|
||||
animation->currentFrame = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "engine.h"
|
||||
|
||||
Array* CreateArray(unsigned int initCapacity)
|
||||
{
|
||||
Array* array = malloc(sizeof(Array));
|
||||
if (!array) return NULL;
|
||||
|
||||
array->elements = malloc(sizeof(void* ) * initCapacity);
|
||||
if (!array->elements) {
|
||||
free(array);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
array->count = 0;
|
||||
array->capacity = initCapacity;
|
||||
return array;
|
||||
}
|
||||
|
||||
int AddElementToArray(Array* array, void* element)
|
||||
{
|
||||
if(array->count >= array->capacity) {
|
||||
unsigned int newCapacity = array->capacity * 2;
|
||||
void** newElements = realloc(array->elements, sizeof(void*) * newCapacity);
|
||||
if (!newElements) return 0;
|
||||
|
||||
array->elements = newElements;
|
||||
array->capacity = newCapacity;
|
||||
}
|
||||
array->elements[array->count++] = element;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// NORMAL REMOVE
|
||||
// int RemoveElementFromArray(Array* array, unsigned int index){
|
||||
// if (index >= array->count) return 0;
|
||||
|
||||
// for (unsigned int i = index; i < array->count - 1; i++) {
|
||||
// array->elements[i] = array->elements[i + 1];
|
||||
// }
|
||||
|
||||
// array->count--;
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// SWAP AND POP REMOVE
|
||||
int RemoveElementFromArray(Array* array, unsigned int index)
|
||||
{
|
||||
if (index >= array->count) return 0;
|
||||
|
||||
array->elements[index] = array->elements[array->count - 1];
|
||||
|
||||
array->count--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* GetRandomElementFromArray(Array* array)
|
||||
{
|
||||
if (array == NULL || array->elements == NULL || array->count == 0) {
|
||||
return NULL;
|
||||
}
|
||||
int randomIndex = GetRandomValue(0, (int)array->count-1);
|
||||
return &array->elements[randomIndex];
|
||||
}
|
||||
|
||||
void UpdateArray(Array* array, void (*updateFunc)(void*))
|
||||
{
|
||||
if (!array || !updateFunc) return;
|
||||
for (unsigned int i = 0; i < array->count; i++) {
|
||||
updateFunc(array->elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderArray(Array* array, void (*renderFunc)(void*))
|
||||
{
|
||||
if (!array || !renderFunc) return;
|
||||
for (unsigned int i = 0; i < array->count; i++) {
|
||||
renderFunc(array->elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void FreeArray(Array** array)
|
||||
{
|
||||
if (!array || !*array) return;
|
||||
|
||||
free((*array)->elements);
|
||||
(*array)->elements = NULL;
|
||||
|
||||
free(*array);
|
||||
*array = NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "engine.h"
|
||||
|
||||
Camera2D CreateCamera(Vector2 playerPosition, float initZoom){
|
||||
int windowWidth = GetScreenWidth();
|
||||
int windowHeight = GetScreenHeight();
|
||||
return (Camera2D){
|
||||
.offset = (Vector2){windowWidth / 2.0f, windowHeight / 2.0f},
|
||||
.target = playerPosition,
|
||||
.rotation = 0.0f,
|
||||
.zoom = initZoom
|
||||
};
|
||||
}
|
||||
|
||||
void UpdateCameraTarget(Camera2D *camera, Vector2 *position, const float smoothness){
|
||||
camera->target = Vector2Lerp(camera->target, *position, smoothness * GetFrameTime());
|
||||
}
|
||||
|
||||
void UpdateCameraZoom(Camera2D *camera, const float *scaleFactor, const float *minZoom, const float *maxZoom){
|
||||
float targetZoom = Clamp(camera->zoom * *scaleFactor, *minZoom, *maxZoom);
|
||||
camera->zoom = Lerp(camera->zoom, targetZoom, 0.1f);
|
||||
}
|
||||
|
||||
void UpdateCamera2D(Camera2D* camera, Vector2* position, Mouse* mouse){
|
||||
UpdateCameraTarget(camera, position, 5.0f);
|
||||
UpdateCameraZoom(camera, &mouse->scaleFactor, &mouse->minZoom, &mouse->maxZoom);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#define RINI_IMPLEMENTATION
|
||||
#define RINI_VALUE_DELIMITER '='
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
void InitConfig(Config *config, const char* path) {
|
||||
config->rini = rini_load_config(path);
|
||||
if (config->rini.count == 0) {
|
||||
printf("Warning: Loaded config has no entries. Path: %s\n", config->path);
|
||||
}
|
||||
}
|
||||
|
||||
int GetConfigInt(Config *config, const char *key) {
|
||||
return rini_get_config_value_fallback(config->rini, key, 0);
|
||||
}
|
||||
|
||||
int GetConfigIntOrDefault(Config *config, const char *key, int default_value) {
|
||||
return rini_get_config_value_fallback(config->rini, key, default_value);
|
||||
}
|
||||
|
||||
const char* GetConfigString(Config *config, const char *key) {
|
||||
return rini_get_config_value_text(config->rini, key);
|
||||
}
|
||||
|
||||
const char* GetConfigStringOrDefault(Config *config, const char *key, const char *default_value) {
|
||||
return rini_get_config_value_text_fallback(config->rini, key, default_value);
|
||||
}
|
||||
|
||||
const char* GetConfigDescription(Config *config, const char *key) {
|
||||
return rini_get_config_value_description(config->rini, key);
|
||||
}
|
||||
|
||||
int SetConfigInt(Config *config, const char *key, int value, const char *desc) {
|
||||
return rini_set_config_value(&config->rini, key, value, desc);
|
||||
}
|
||||
|
||||
int SetConfigString(Config *config, const char *key, const char *text, const char *desc) {
|
||||
return rini_set_config_value_text(&config->rini, key, text, desc);
|
||||
}
|
||||
|
||||
int SetConfigDescription(Config *config, const char *key, const char *desc) {
|
||||
return rini_set_config_value_description(&config->rini, key, desc);
|
||||
}
|
||||
|
||||
int AddCommentLine(Config *config, const char *comment) {
|
||||
return rini_set_config_comment_line(&config->rini, comment);
|
||||
}
|
||||
|
||||
void SaveConfig(Config *config) {
|
||||
rini_save_config(config->rini, config->path);
|
||||
}
|
||||
|
||||
void CleanUpConfig(Config *config) {
|
||||
rini_unload_config(&config->rini);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "engine.h"
|
||||
|
||||
void InitFont(Font *font, const char* path){
|
||||
*font = LoadFont(path);
|
||||
SetTextureFilter(font->texture, TEXTURE_FILTER_POINT);
|
||||
}
|
||||
|
||||
void CleanupFont(Font *font){
|
||||
UnloadFont(*font);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "engine.h"
|
||||
|
||||
ImageButton CreateImageButton(ButtonState state, Texture2D *texture, const TextureAsset *asset, Vector2 *source, Vector2 *clicked, Vector2 *hover, Rectangle *destRec){
|
||||
return (ImageButton){
|
||||
.sprite = {
|
||||
.texture = *texture,
|
||||
.sourceRec = (Rectangle){ source->x, source->y, asset->frameWidth, asset->frameHeight},
|
||||
.destRec = *destRec,
|
||||
.frameSize = (Vector2){asset->frameWidth, asset->frameHeight},
|
||||
.origin = (Vector2){0.0f, 0.0f},
|
||||
.rotation = 0.0f,
|
||||
.color = WHITE
|
||||
},
|
||||
.notClicked = (Vector2){source->x, source->y},
|
||||
.hover = *hover,
|
||||
.clicked = *clicked
|
||||
};
|
||||
}
|
||||
|
||||
ImageElement CreateImageElement(Texture2D *texture, const TextureAsset *asset, Vector2 *source, Rectangle *destRec){
|
||||
return (ImageElement){
|
||||
.sprite = {
|
||||
.texture = *texture,
|
||||
.sourceRec = (Rectangle){ source->x, source->y, asset->frameWidth, asset->frameHeight},
|
||||
.destRec = *destRec,
|
||||
.frameSize = (Vector2){asset->frameWidth, asset->frameHeight},
|
||||
.origin = (Vector2){0.0f, 0.0f},
|
||||
.rotation = 0.0f,
|
||||
.color = WHITE
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int isImageButtonClicked(ImageButton *b, Sound soundHover, Sound soundClick){
|
||||
if (CheckCollisionPointRec(GetMousePosition(), b->sprite.destRec)) {
|
||||
|
||||
if (!b->isHovered) {
|
||||
PlaySound(soundHover);
|
||||
b->isHovered = true;
|
||||
UpdateSpriteSourceRec(&b->sprite, &b->hover);
|
||||
}
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)){
|
||||
if (!b->isClicked) {
|
||||
PlaySound(soundClick);
|
||||
b->isClicked = true;
|
||||
UpdateSpriteSourceRec(&b->sprite, &b->clicked);
|
||||
}
|
||||
}
|
||||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
b->isClicked = false;
|
||||
b->isHovered = false;
|
||||
UpdateSpriteSourceRec(&b->sprite, &b->notClicked);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
UpdateSpriteSourceRec(&b->sprite, &b->notClicked);
|
||||
b->isClicked = false;
|
||||
b->isHovered = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void renderImageButton(ImageButton *b) {
|
||||
RenderSprite(&b->sprite);
|
||||
}
|
||||
|
||||
void renderImageElement(ImageElement *e){
|
||||
RenderSprite(&e->sprite);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
Button initButton(char *text, Vector2 dimensions, Vector2 position)
|
||||
{
|
||||
Button b;
|
||||
|
||||
b.rec = (Rectangle){position.x - dimensions.x / 2, position.y - dimensions.y / 2, dimensions.x, dimensions.y};
|
||||
b.text = text;
|
||||
return b;
|
||||
}
|
||||
|
||||
int isButtonClicked(Button *b)
|
||||
{
|
||||
return (CheckCollisionPointRec(GetMousePosition(), b->rec) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON));
|
||||
}
|
||||
|
||||
void renderButton(Button *b)
|
||||
{
|
||||
GuiButton(b->rec, b->text);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "engine.h"
|
||||
|
||||
Mouse CreateMouse(float zoomSpeed, float minZoom, float maxZoom, Texture2D *texture){
|
||||
HideCursor();
|
||||
return (Mouse){
|
||||
.zoomSpeed = zoomSpeed,
|
||||
.minZoom = minZoom,
|
||||
.maxZoom = maxZoom,
|
||||
.cursorTexture = *texture
|
||||
};
|
||||
}
|
||||
|
||||
void UpdateMouseScreen(Mouse *mouse){
|
||||
mouse->screenPosition = GetMousePosition();
|
||||
|
||||
}
|
||||
|
||||
void UpdateMouse(Mouse *mouse, Camera2D *camera) {
|
||||
|
||||
Vector2 pos = GetMousePosition();
|
||||
mouse->screenPosition = pos;
|
||||
mouse->worldPosition = GetScreenToWorld2D(pos, *camera);
|
||||
mouse->leftButton = IsMouseButtonDown(MOUSE_LEFT_BUTTON);
|
||||
mouse->rightButton = IsMouseButtonDown(MOUSE_RIGHT_BUTTON);
|
||||
|
||||
mouse->wheelMove = GetMouseWheelMove();
|
||||
if (mouse->wheelMove != 0) {
|
||||
float zoomFactor = 1.0f + (mouse->zoomSpeed * fabsf(mouse->wheelMove));
|
||||
mouse->scaleFactor = (mouse->wheelMove < 0) ? (1.0f / zoomFactor) : zoomFactor;
|
||||
} else {
|
||||
mouse->scaleFactor = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 GetDirectionVector(void){
|
||||
Vector2 vector = {.x = 0.0f, .y = 0.0f};
|
||||
if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)){vector.x += 1.0f; }
|
||||
if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)){ vector.x -= 1.0f; }
|
||||
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)){ vector.y -= 1.0f; }
|
||||
if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)){ vector.y += 1.0f; }
|
||||
if (Vector2Length(vector) > 0.0f) {vector = Vector2Normalize(vector); }
|
||||
return vector;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#include "engine.h"
|
||||
|
||||
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 = (Object* )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 || objects->data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return &objects->data[GetRandomValue(0, (int)objects->count-1)];
|
||||
}
|
||||
|
||||
void AddObjectToArray(ObjectArray *objects, const Object *prototype, Vector2 position) {
|
||||
Object *newData = (Object* )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--;
|
||||
}
|
||||
}
|
||||
objects->data = (Object*)realloc(objects->data, objects->count * sizeof(Object));
|
||||
|
||||
}
|
||||
|
||||
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--;
|
||||
}
|
||||
}
|
||||
objects->data = (Object*)realloc(objects->data, objects->count * sizeof(Object));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "engine.h"
|
||||
|
||||
void UpdatePhysicsDirection(Vector2 *direction, Vector2 vector)
|
||||
{
|
||||
*direction = Vector2Normalize(vector);
|
||||
}
|
||||
|
||||
void UpdatePhysicsVelocity(Vector2 *velocity, Vector2 *direction, float *speed)
|
||||
{
|
||||
*velocity = Vector2Scale(*direction, *speed * GetFrameTime());
|
||||
}
|
||||
|
||||
void UpdatePhysicsPosition(Vector2 *position, Vector2 *velocity)
|
||||
{
|
||||
*position = Vector2Add(*position, *velocity);
|
||||
}
|
||||
|
||||
void UpdatePhysicsSpeed(float *speed, float *newSpeed)
|
||||
{
|
||||
*speed = *newSpeed;
|
||||
}
|
||||
|
||||
void UpdatePhysics(Physics *physics, Vector2 direction)
|
||||
{
|
||||
UpdatePhysicsDirection(&physics->direction, direction);
|
||||
UpdatePhysicsVelocity(&physics->velocity, &physics->direction, &physics->speed);
|
||||
UpdatePhysicsPosition(&physics->position, &physics->velocity);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "engine.h"
|
||||
|
||||
PostProcessing CreatePostFX(const char* shaderPath){
|
||||
PostProcessing postFX = {0};
|
||||
postFX.shader = LoadShader(NULL, shaderPath);
|
||||
|
||||
if (postFX.shader.id == 0) {
|
||||
TraceLog(LOG_ERROR, "Failed to load shader: %s", shaderPath);
|
||||
return postFX;
|
||||
}
|
||||
|
||||
postFX.strength = 0.0f;
|
||||
postFX.resolutionLoc = GetShaderLocation(postFX.shader, "resolution");
|
||||
postFX.strengthLoc = GetShaderLocation(postFX.shader, "strength");
|
||||
Vector2 resolution = { (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||
SetShaderValue(postFX.shader, postFX.resolutionLoc, &resolution, SHADER_UNIFORM_VEC2);
|
||||
return postFX;
|
||||
}
|
||||
|
||||
void UpdatePostFX(PostProcessing *postFX){
|
||||
if (postFX->shader.id == 0) return;
|
||||
SetShaderValue(postFX->shader, postFX->strengthLoc, &postFX->strength, SHADER_UNIFORM_FLOAT);
|
||||
Vector2 resolution = { (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||
SetShaderValue(postFX->shader, postFX->resolutionLoc, &resolution, SHADER_UNIFORM_VEC2);
|
||||
}
|
||||
|
||||
void RenderPostFX(PostProcessing *postFX, RenderTexture2D *target){
|
||||
BeginShaderMode(postFX->shader);
|
||||
DrawTextureRec(target->texture, (Rectangle){ 0, 0, target->texture.width, -target->texture.height }, (Vector2){ 0, 0 }, WHITE);
|
||||
EndShaderMode();
|
||||
}
|
||||
|
||||
void UnloadPostFX(PostProcessing *postFX){
|
||||
if (postFX->shader.id == 0) return;
|
||||
UnloadShader(postFX->shader);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "engine.h"
|
||||
|
||||
Soundtrack LoadSoundtrack(const char* musicPath){
|
||||
Soundtrack soundtrack = {
|
||||
.music = LoadMusicStream(musicPath),
|
||||
.playing = false,
|
||||
.paused = false
|
||||
};
|
||||
PlayMusicStream(soundtrack.music);
|
||||
return soundtrack;
|
||||
}
|
||||
|
||||
void UpdateSoundtrack(Soundtrack *soundtrack, bool playing){
|
||||
|
||||
if (playing && !soundtrack->playing){
|
||||
ResumeMusicStream(soundtrack->music);
|
||||
soundtrack->paused = false;
|
||||
} else if (!playing && soundtrack->playing){
|
||||
PauseMusicStream(soundtrack->music);
|
||||
soundtrack->paused = true;
|
||||
}
|
||||
|
||||
soundtrack->playing = playing;
|
||||
|
||||
if (soundtrack->playing) {
|
||||
UpdateMusicStream(soundtrack->music);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "engine.h"
|
||||
|
||||
|
||||
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 UpdateSpriteRotation(Sprite *sprite, Vector2 *vector)
|
||||
{
|
||||
if (Vector2Length(*vector) <= 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float targetRotation = (float)atan2(vector->y, vector->x) * (180.0f / PI) + 90.0f;
|
||||
sprite->rotation = Lerp(sprite->rotation, targetRotation, 0.1f);
|
||||
}
|
||||
|
||||
void RenderSprite(const Sprite *sprite)
|
||||
{
|
||||
DrawTexturePro(
|
||||
sprite->texture,
|
||||
sprite->sourceRec,
|
||||
sprite->destRec,
|
||||
sprite->origin,
|
||||
sprite->rotation,
|
||||
sprite->color);
|
||||
}
|
||||
|
||||
void PrintSprite(const Sprite *sprite)
|
||||
{
|
||||
printf("Sprite:\n");
|
||||
printf(" Sprite.texture: id = %d\n", sprite->texture.id);
|
||||
printf(" Sprite.sourceRec: x = %f, y = %f, width = %f, height = %f\n", sprite->sourceRec.x, sprite->sourceRec.y, sprite->sourceRec.width, sprite->sourceRec.height);
|
||||
printf(" Sprite.destRec: x = %f, y = %f, width = %f, height = %f\n", sprite->destRec.x, sprite->destRec.y, sprite->destRec.width, sprite->destRec.height);
|
||||
printf(" Sprite.frameSize: x = %f, y = %f\n", sprite->frameSize.x, sprite->frameSize.y);
|
||||
printf(" Sprite.origin: x = %f, y = %f\n", sprite->origin.x, sprite->origin.y);
|
||||
printf(" Sprite.rotation: %f\n", sprite->rotation);
|
||||
printf(" Sprite.color: r = %d, g = %d, b = %d, a = %d\n", sprite->color.r, sprite->color.g, sprite->color.b, sprite->color.a);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "engine.h"
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
+1
-2
@@ -1,5 +1,4 @@
|
||||
#include <raylib.h>
|
||||
#include "app.h"
|
||||
#include "appTypes.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user