big refactor
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
COMPILER = clang
|
COMPILER = clang
|
||||||
C_FLAGS = -std=c99 -g -Wall -Werror -Wpedantic -Wconversion -Wshadow -Wstrict-prototypes -fsanitize=address,undefined -O0
|
C_FLAGS = -std=c99 -g -Wall -Werror -Wpedantic -Wconversion -Wshadow -Wstrict-prototypes -fsanitize=address,undefined -O0 -Iinclude
|
||||||
|
SUPPRESSED_FLAGS = -Wno-conversion -Wno-sign-conversion -Wno-unused-variable -Wno-unused-but-set-variable
|
||||||
RAYLIB_FLAGS = $(shell pkg-config --libs --cflags raylib)
|
RAYLIB_FLAGS = $(shell pkg-config --libs --cflags raylib)
|
||||||
SRC = scripts/main.c
|
SRC = src/main.c
|
||||||
TARGET = bin/game
|
TARGET = bin/game
|
||||||
|
|
||||||
build: $(TARGET)
|
build: $(TARGET)
|
||||||
$(TARGET): $(SRC)
|
$(TARGET): $(SRC)
|
||||||
$(COMPILER) $(FLAGS) $(RAYLIB_FLAGS) $(SRC) -o $(TARGET)
|
$(COMPILER) $(C_FLAGS) $(RAYLIB_FLAGS) $(SRC) -o $(TARGET) $(SUPPRESSED_FLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGET)
|
rm -f $(TARGET)
|
||||||
|
|||||||
Binary file not shown.
@@ -1,15 +0,0 @@
|
|||||||
#ifndef CAMERA_H
|
|
||||||
#define CAMERA_H
|
|
||||||
#include <raymath.h>
|
|
||||||
#include "input.h"
|
|
||||||
|
|
||||||
void UpdateCamera2DTarget(Camera2D *camera, Vector2 *position, const float smoothness){
|
|
||||||
camera->target = Vector2Lerp(camera->target, *position, smoothness * GetFrameTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateCamera2DZoom(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CAMERA_H
|
|
||||||
-230
@@ -1,230 +0,0 @@
|
|||||||
#include <raylib.h>
|
|
||||||
#include "sprite.h"
|
|
||||||
#include "animation.h"
|
|
||||||
#include "tilesprite.h"
|
|
||||||
#include "vector.h"
|
|
||||||
#include "object.h"
|
|
||||||
#include "physics.h"
|
|
||||||
#include "camera.h"
|
|
||||||
#include "input.h"
|
|
||||||
|
|
||||||
// Structs
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Sprite sprite;
|
|
||||||
Animation animation;
|
|
||||||
Physics physics;
|
|
||||||
} Player;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Sprite sprite;
|
|
||||||
Animation animation;
|
|
||||||
Physics physics;
|
|
||||||
Object target;
|
|
||||||
Object hive;
|
|
||||||
int flowerCount;
|
|
||||||
} Bee;
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
// Load
|
|
||||||
InitWindow(1280, 720, "The Last Hive");
|
|
||||||
|
|
||||||
InitAudioDevice();
|
|
||||||
Music music = LoadMusicStream("assets/beez.mp3");
|
|
||||||
PlayMusicStream(music);
|
|
||||||
|
|
||||||
Texture2D flowerTexture = LoadTexture("assets/flower.png");
|
|
||||||
Texture2D beeTexture = LoadTexture("assets/character_bee.png");
|
|
||||||
Texture2D floorTexture = LoadTexture("assets/grass.png");
|
|
||||||
Texture2D hiveTexture = LoadTexture("assets/hive.png");
|
|
||||||
|
|
||||||
TileSprite floor = {
|
|
||||||
.sprite = {
|
|
||||||
.texture = floorTexture,
|
|
||||||
.frameSize = {16.0f,16.0f},
|
|
||||||
.sourceRec = { 0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.destRec = {0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.origin = {8.0f, 8.0f},
|
|
||||||
.rotation = 0.0f,
|
|
||||||
.color = WHITE
|
|
||||||
},
|
|
||||||
.bounds = {0.0f,0.0f,0.0f,0.0f}
|
|
||||||
};
|
|
||||||
|
|
||||||
Object hive = {
|
|
||||||
.sprite = {
|
|
||||||
.texture = hiveTexture,
|
|
||||||
.frameSize = {32.0f,32.0f},
|
|
||||||
.sourceRec = {0.0f, 0.0f, 32.0f, 32.0f},
|
|
||||||
.destRec = {0.0f, 0.0f, 32.0f, 32.0f},
|
|
||||||
.origin = {16.0f, 16.0f},
|
|
||||||
.rotation = 0.0f,
|
|
||||||
.color = WHITE
|
|
||||||
},
|
|
||||||
.position = (Vector2){0.0f,0.0f}
|
|
||||||
};
|
|
||||||
|
|
||||||
ObjectArray flowers = CreateObjectArray(&(Object){
|
|
||||||
.sprite = {
|
|
||||||
.texture = flowerTexture,
|
|
||||||
.frameSize = {16.0f, 16.0f},
|
|
||||||
.sourceRec = {0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.destRec = {0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.origin = {8.0f, 8.0f},
|
|
||||||
.rotation = 45.0f,
|
|
||||||
.color = WHITE
|
|
||||||
},
|
|
||||||
.position = {0.0f, 0.0f}
|
|
||||||
}, 10);
|
|
||||||
if (!flowers.data) {
|
|
||||||
printf("Memory allocation failed.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
Rectangle flowerField = {-50.0f, -50.0f, 100.0f, 100.0f};
|
|
||||||
SetRandomPositionForObjectArray(&flowers, flowerField);
|
|
||||||
|
|
||||||
Player player = {
|
|
||||||
.sprite = {
|
|
||||||
.texture = beeTexture,
|
|
||||||
.frameSize = {16.0f, 16.0f},
|
|
||||||
.sourceRec = {0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.destRec = {0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.origin = {8.0f, 8.0f},
|
|
||||||
.rotation = 0.0f,
|
|
||||||
.color = WHITE
|
|
||||||
},
|
|
||||||
.animation = {
|
|
||||||
.currentFrame = 0,
|
|
||||||
.maxFrame = 4,
|
|
||||||
.framesCounter = 0,
|
|
||||||
.framesSpeed = 10,
|
|
||||||
.animTimer = 0.0f
|
|
||||||
},
|
|
||||||
.physics = {
|
|
||||||
.position = hive.position,
|
|
||||||
.direction = (Vector2){0.0f,0.0f},
|
|
||||||
.speed = 50.0f
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Bee bee1 = {
|
|
||||||
.sprite = {
|
|
||||||
.texture = beeTexture,
|
|
||||||
.frameSize = {16.0f, 16.0f},
|
|
||||||
.sourceRec = {0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.destRec = {0.0f, 0.0f, 16.0f, 16.0f},
|
|
||||||
.origin = {8.0f, 8.0f},
|
|
||||||
.rotation = 0.0f,
|
|
||||||
.color = WHITE
|
|
||||||
},
|
|
||||||
.animation = {
|
|
||||||
.currentFrame = 0,
|
|
||||||
.maxFrame = 4,
|
|
||||||
.framesCounter = 0,
|
|
||||||
.framesSpeed = 10,
|
|
||||||
.animTimer = 0.0f
|
|
||||||
},
|
|
||||||
.physics = {
|
|
||||||
.position = hive.position,
|
|
||||||
.direction = (Vector2){0.0f,0.0f},
|
|
||||||
.speed = 10.0f
|
|
||||||
},
|
|
||||||
.target = *GetRandomObject(&flowers),
|
|
||||||
.hive = hive
|
|
||||||
};
|
|
||||||
|
|
||||||
Camera2D camera = {
|
|
||||||
.offset = (Vector2){GetScreenWidth() / 2.0f, GetScreenHeight() / 2.0f},
|
|
||||||
.target = player.physics.position,
|
|
||||||
.rotation = 0.0f,
|
|
||||||
.zoom = 10.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
Mouse mouse = {
|
|
||||||
.zoomSpeed = 0.10f,
|
|
||||||
.minZoom = 5.0f,
|
|
||||||
.maxZoom = 10.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update & Render
|
|
||||||
while (!WindowShouldClose())
|
|
||||||
{
|
|
||||||
// Update
|
|
||||||
UpdateMusicStream(music);
|
|
||||||
|
|
||||||
UpdateTileSpriteBounds(&floor, &camera);
|
|
||||||
|
|
||||||
UpdateMouse(&mouse, &camera);
|
|
||||||
|
|
||||||
if (mouse.leftButton) {
|
|
||||||
AddObjectToArray(&flowers, flowers.prototype, mouse.worldPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateVectorOnInput(&player.physics.direction);
|
|
||||||
Move(&player.physics.position, &player.physics.direction, &player.physics.speed);
|
|
||||||
UpdateSpriteRotation(&player.sprite, &player.physics.direction);
|
|
||||||
UpdateSpriteDestRec(&player.sprite, &player.physics.position);
|
|
||||||
UpdateAnimation(&player.animation, GetFrameTime());
|
|
||||||
UpdateSpriteSourceRec(&player.sprite, &(Vector2){player.sprite.frameSize.x, player.sprite.frameSize.x * player.animation.currentFrame});
|
|
||||||
|
|
||||||
const float tolerance = 1.0f;
|
|
||||||
|
|
||||||
if (bee1.flowerCount < 4){
|
|
||||||
if (fabs(bee1.physics.position.x - bee1.target.position.x) < tolerance &&
|
|
||||||
fabs(bee1.physics.position.y - bee1.target.position.y) < tolerance) {
|
|
||||||
bee1.target = *GetRandomObject(&flowers);
|
|
||||||
bee1.flowerCount++;
|
|
||||||
} else {
|
|
||||||
Move(&bee1.physics.position, &bee1.physics.direction, &bee1.physics.speed);
|
|
||||||
UpdateSpriteRotation(&bee1.sprite, &bee1.physics.direction);
|
|
||||||
bee1.physics.direction = GetDirectionToObject(&bee1.target, bee1.physics.position);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bee1.target = hive;
|
|
||||||
if (fabs(bee1.physics.position.x - bee1.target.position.x) < tolerance &&
|
|
||||||
fabs(bee1.physics.position.y - bee1.target.position.y) < tolerance) {
|
|
||||||
bee1.physics.speed = 0.0f;
|
|
||||||
} else {
|
|
||||||
Move(&bee1.physics.position, &bee1.physics.direction, &bee1.physics.speed);
|
|
||||||
UpdateSpriteRotation(&bee1.sprite, &bee1.physics.direction);
|
|
||||||
bee1.physics.direction = GetDirectionToObject(&bee1.target, bee1.physics.position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSpriteDestRec(&bee1.sprite, &bee1.physics.position);
|
|
||||||
UpdateAnimation(&bee1.animation, GetFrameTime());
|
|
||||||
UpdateSpriteSourceRec(&bee1.sprite, &(Vector2){bee1.sprite.frameSize.x, bee1.sprite.frameSize.x * bee1.animation.currentFrame});
|
|
||||||
|
|
||||||
UpdateCamera2DTarget(&camera, &player.physics.position, 5.0f);
|
|
||||||
|
|
||||||
if (mouse.wheelMove != 0)
|
|
||||||
{
|
|
||||||
UpdateCamera2DZoom(&camera, &mouse.scaleFactor, &mouse.minZoom, &mouse.maxZoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render
|
|
||||||
BeginDrawing();
|
|
||||||
ClearBackground(BLACK);
|
|
||||||
BeginMode2D(camera);
|
|
||||||
RenderTileSprite(&floor);
|
|
||||||
RenderSprite(&hive.sprite);
|
|
||||||
RenderObjectArray(&flowers);
|
|
||||||
RenderSprite(&bee1.sprite);
|
|
||||||
RenderSprite(&player.sprite);
|
|
||||||
EndMode2D();
|
|
||||||
DrawFPS(10,10);
|
|
||||||
EndDrawing();
|
|
||||||
}
|
|
||||||
// Unload
|
|
||||||
UnloadTexture(floorTexture);
|
|
||||||
UnloadTexture(hiveTexture);
|
|
||||||
UnloadTexture(flowerTexture);
|
|
||||||
UnloadTexture(beeTexture);
|
|
||||||
UnloadMusicStream(music);
|
|
||||||
free(flowers.data);
|
|
||||||
// Close
|
|
||||||
CloseAudioDevice();
|
|
||||||
CloseWindow();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#ifndef PHYSICS_H
|
|
||||||
#define PHYSICS_H
|
|
||||||
#include <raylib.h>
|
|
||||||
#include <raymath.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Vector2 position;
|
|
||||||
Vector2 direction;
|
|
||||||
float speed;
|
|
||||||
} Physics;
|
|
||||||
|
|
||||||
Vector2 GetVelocity(Vector2 *direction, float *speed){
|
|
||||||
return Vector2Scale(*direction, *speed * GetFrameTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Move(Vector2 *position, Vector2 *direction, float *speed) {
|
|
||||||
*position = Vector2Add(*position, GetVelocity(direction, speed));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PHYSICS_H
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#ifndef TILESPRITE_H
|
|
||||||
#define TILESPRITE_H
|
|
||||||
#include <raylib.h>
|
|
||||||
#include "sprite.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Sprite sprite;
|
|
||||||
Rectangle bounds;
|
|
||||||
} TileSprite;
|
|
||||||
|
|
||||||
void UpdateTileSpriteBounds(TileSprite *tileSprite, const Camera2D *camera){
|
|
||||||
tileSprite->bounds.x = (int)((camera->target.x - (GetScreenWidth() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.x) - 1;
|
|
||||||
tileSprite->bounds.width = (int)((camera->target.x + (GetScreenWidth() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.x) + 1;
|
|
||||||
tileSprite->bounds.y = (int)((camera->target.y - (GetScreenHeight() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.y) - 1;
|
|
||||||
tileSprite->bounds.height = (int)((camera->target.y + (GetScreenHeight() / 2.0f / camera->zoom)) / tileSprite->sprite.frameSize.y) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderTileSprite(TileSprite *tileSprite){
|
|
||||||
for (float y = tileSprite->bounds.y; y <= tileSprite->bounds.height; y++)
|
|
||||||
{
|
|
||||||
for (float x = tileSprite->bounds.x; x <= tileSprite->bounds.width; x++)
|
|
||||||
{
|
|
||||||
Vector2 tilePosition = {x * tileSprite->sprite.frameSize.x, y * tileSprite->sprite.frameSize.y};
|
|
||||||
UpdateSpriteDestRec(&tileSprite->sprite, &tilePosition);
|
|
||||||
RenderSprite(&tileSprite->sprite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //TILESPRITE_H
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
uniform float strength;
|
||||||
|
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 uv = fragTexCoord;
|
||||||
|
vec2 position = uv - vec2(0.5);
|
||||||
|
float dist = length(position) * 2.0;
|
||||||
|
float vignette = 1.0 - strength * dist * dist;
|
||||||
|
vignette = clamp(vignette, 0.0, 1.0);
|
||||||
|
vec4 color = texture(texture0, uv);
|
||||||
|
finalColor = vec4(color.rgb * vignette, color.a);
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef ANIMSPRITE_H
|
#ifndef ANIMATION_H
|
||||||
#define ANIMSPRITE_H
|
#define ANIMATION_H
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int currentFrame;
|
int currentFrame;
|
||||||
@@ -25,4 +25,4 @@ void UpdateAnimation(Animation *animation, float deltaTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ANIMSPRITE_H
|
#endif // ANIMATION_H
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
Camera2D CreateCamera(int screenWidth, int screenHeight, Vector2 playerPosition, float initZoom){
|
||||||
|
return (Camera2D){
|
||||||
|
.offset = (Vector2){screenWidth / 2.0f, screenHeight / 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CAMERA_H
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef GUI_H
|
||||||
|
#define GUI_H
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "../include/raygui.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Rectangle rec;
|
||||||
|
const char *text;
|
||||||
|
} Button;
|
||||||
|
|
||||||
|
void initButton(Button *b, const char *text, int buttonWidth, int buttonHeight, int buttonPosX, int buttonPosY)
|
||||||
|
{
|
||||||
|
b->rec = (Rectangle){buttonPosX - buttonWidth / 2, buttonPosY - buttonHeight / 2, buttonWidth, buttonHeight};
|
||||||
|
b->text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isButtonClicked(Button *b)
|
||||||
|
{
|
||||||
|
return (CheckCollisionPointRec(GetMousePosition(), b->rec) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON));
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderButton(Button *b)
|
||||||
|
{
|
||||||
|
GuiButton(b->rec, b->text);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GUI_H
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#ifndef INPUT_H
|
#ifndef INPUT_H
|
||||||
#define INPUT_H
|
#define INPUT_H
|
||||||
#include <raymath.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Vector2 worldPosition;
|
Vector2 worldPosition;
|
||||||
@@ -13,6 +12,14 @@ typedef struct {
|
|||||||
bool rightButton;
|
bool rightButton;
|
||||||
} Mouse;
|
} Mouse;
|
||||||
|
|
||||||
|
Mouse CreateMouse(float zoomSpeed, float minZoom, float maxZoom){
|
||||||
|
return (Mouse){
|
||||||
|
.zoomSpeed = zoomSpeed,
|
||||||
|
.minZoom = minZoom,
|
||||||
|
.maxZoom = maxZoom
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateMouse(Mouse *mouse, Camera2D *camera) {
|
void UpdateMouse(Mouse *mouse, Camera2D *camera) {
|
||||||
mouse->worldPosition = GetScreenToWorld2D(GetMousePosition(), *camera);
|
mouse->worldPosition = GetScreenToWorld2D(GetMousePosition(), *camera);
|
||||||
mouse->leftButton = IsMouseButtonDown(MOUSE_LEFT_BUTTON);
|
mouse->leftButton = IsMouseButtonDown(MOUSE_LEFT_BUTTON);
|
||||||
@@ -28,13 +35,14 @@ void UpdateMouse(Mouse *mouse, Camera2D *camera) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateVectorOnInput(Vector2 *vector){
|
Vector2 GetDirectionVector(void){
|
||||||
*vector = (Vector2){0.0f, 0.0f};
|
Vector2 vector = {.x = 0.0f, .y = 0.0f};
|
||||||
if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)){ vector->x += 1.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_LEFT) || IsKeyDown(KEY_A)){ vector.x -= 1.0f; }
|
||||||
if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)){ vector->y += 1.0f; }
|
if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)){ vector.y += 1.0f; }
|
||||||
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)){ vector->y -= 1.0f; }
|
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)){ vector.y -= 1.0f; }
|
||||||
if (Vector2Length(*vector) > 0.0f) { *vector = Vector2Normalize(*vector); }
|
if (Vector2Length(vector) > 0.0f) {vector = Vector2Normalize(vector); }
|
||||||
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //INPUT_H
|
#endif //INPUT_H
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef MUSICMANAGER_H
|
||||||
|
#define MUSICMANAGER_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Music music;
|
||||||
|
bool playing;
|
||||||
|
} MyMusic;
|
||||||
|
|
||||||
|
MyMusic CreateMusic(char* musicPath){
|
||||||
|
MyMusic music = {
|
||||||
|
.music = LoadMusicStream(musicPath),
|
||||||
|
.playing = 0
|
||||||
|
};
|
||||||
|
PlayMusicStream(music.music);
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateMusic(MyMusic* music){
|
||||||
|
UpdateMusicStream(music->music);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MUSICMANAGER_H
|
||||||
|
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
#ifndef OBJECT_H
|
#ifndef OBJECT_H
|
||||||
#define OBJECT_H
|
#define OBJECT_H
|
||||||
#include <raylib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <raymath.h>
|
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
@@ -22,13 +18,13 @@ typedef struct {
|
|||||||
ObjectArray CreateObjectArray(const Object *prototype, const size_t count) {
|
ObjectArray CreateObjectArray(const Object *prototype, const size_t count) {
|
||||||
ObjectArray objects = {0};
|
ObjectArray objects = {0};
|
||||||
|
|
||||||
if (count <= 0) {
|
if (count == 0) {
|
||||||
printf("Objects size must be greater than 0.\n");
|
printf("Objects size must be greater than 0.\n");
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.count = count;
|
objects.count = count;
|
||||||
objects.data = malloc(count * sizeof(Object));
|
objects.data = (Object* )malloc(count * sizeof(Object));
|
||||||
|
|
||||||
if (!objects.data) {
|
if (!objects.data) {
|
||||||
printf("Memory allocation of objects failed.\n");
|
printf("Memory allocation of objects failed.\n");
|
||||||
@@ -45,14 +41,14 @@ ObjectArray CreateObjectArray(const Object *prototype, const size_t count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object* GetRandomObject(ObjectArray *objects){
|
Object* GetRandomObject(ObjectArray *objects){
|
||||||
if (objects->count == 0) {
|
if (objects->count == 0 || objects->data == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return &objects->data[GetRandomValue(0, (int)objects->count-1)];
|
return &objects->data[GetRandomValue(0, (int)objects->count-1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddObjectToArray(ObjectArray *objects, const Object *prototype, Vector2 position) {
|
void AddObjectToArray(ObjectArray *objects, const Object *prototype, Vector2 position) {
|
||||||
Object *newData = realloc(objects->data, (objects->count + 1) * sizeof(Object));
|
Object *newData = (Object* )realloc(objects->data, (objects->count + 1) * sizeof(Object));
|
||||||
if (newData) {
|
if (newData) {
|
||||||
objects->data = newData;
|
objects->data = newData;
|
||||||
objects->data[objects->count] = *prototype;
|
objects->data[objects->count] = *prototype;
|
||||||
@@ -100,6 +96,8 @@ void SwapAndPopObjectsArrayOnRecCollision(ObjectArray *objects, const Rectangle
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
objects->data = (Object*)realloc(objects->data, objects->count * sizeof(Object));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapAndPopObjectsArrayOnPointCollision(ObjectArray *objects, const Vector2 point){
|
void SwapAndPopObjectsArrayOnPointCollision(ObjectArray *objects, const Vector2 point){
|
||||||
@@ -115,6 +113,7 @@ void SwapAndPopObjectsArrayOnPointCollision(ObjectArray *objects, const Vector2
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
objects->data = (Object*)realloc(objects->data, objects->count * sizeof(Object));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 GetDirectionToObject(Object *object, Vector2 position){
|
Vector2 GetDirectionToObject(Object *object, Vector2 position){
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef PHYSICS_H
|
||||||
|
#define PHYSICS_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Vector2 position;
|
||||||
|
Vector2 direction;
|
||||||
|
Vector2 velocity;
|
||||||
|
float speed;
|
||||||
|
} Physics;
|
||||||
|
|
||||||
|
void UpdatePhysicsDirection(Vector2 *direction, Vector2 vector){
|
||||||
|
*direction = 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 target){
|
||||||
|
UpdatePhysicsDirection(&physics->direction, target);
|
||||||
|
UpdatePhysicsVelocity(&physics->velocity, &physics->direction, &physics->speed);
|
||||||
|
UpdatePhysicsPosition(&physics->position, &physics->velocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PHYSICS_H
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef SCREEN_H
|
||||||
|
#define SCREEN_H
|
||||||
|
|
||||||
|
typedef enum Screen {
|
||||||
|
LOGO = 0,
|
||||||
|
MENU,
|
||||||
|
GAMEPLAY
|
||||||
|
} Screen;
|
||||||
|
|
||||||
|
#endif // SCREEN_H
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef SETTINGS_H
|
||||||
|
#define SETTINGS_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int screenWidth;
|
||||||
|
int screenHeight;
|
||||||
|
const char* name;
|
||||||
|
} Settings;
|
||||||
|
|
||||||
|
#endif // SETTINGS_H
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef SHADER_H
|
||||||
|
#define SHADER_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Shader shader;
|
||||||
|
int resolutionLoc;
|
||||||
|
int strengthLoc;
|
||||||
|
float strength;
|
||||||
|
} VignetteShader;
|
||||||
|
|
||||||
|
VignetteShader CreateShader(const char* shaderPath, float strength){
|
||||||
|
VignetteShader vignetteShader = {0};
|
||||||
|
vignetteShader.shader = LoadShader(NULL, shaderPath);
|
||||||
|
|
||||||
|
if (vignetteShader.shader.id == 0) {
|
||||||
|
TraceLog(LOG_ERROR, "Failed to load shader: %s", shaderPath);
|
||||||
|
return vignetteShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
vignetteShader.strength = strength;
|
||||||
|
vignetteShader.resolutionLoc = GetShaderLocation(vignetteShader.shader, "resolution");
|
||||||
|
vignetteShader.strengthLoc = GetShaderLocation(vignetteShader.shader, "strength");
|
||||||
|
Vector2 resolution = { (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||||
|
SetShaderValue(vignetteShader.shader, vignetteShader.resolutionLoc, &resolution, SHADER_UNIFORM_VEC2);
|
||||||
|
return vignetteShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateShader(VignetteShader* vignetteShader){
|
||||||
|
if (vignetteShader->shader.id == 0) return;
|
||||||
|
SetShaderValue(vignetteShader->shader, vignetteShader->strengthLoc, &vignetteShader->strength, SHADER_UNIFORM_FLOAT);
|
||||||
|
Vector2 resolution = { (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||||
|
SetShaderValue(vignetteShader->shader, vignetteShader->resolutionLoc, &resolution, SHADER_UNIFORM_VEC2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadVignetteShader(VignetteShader* vignetteShader){
|
||||||
|
if (vignetteShader->shader.id == 0) return;
|
||||||
|
UnloadShader(vignetteShader->shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SHADER_H
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
#ifndef SPRITE_H
|
#ifndef SPRITE_H
|
||||||
#define SPRITE_H
|
#define SPRITE_H
|
||||||
#include <raylib.h>
|
|
||||||
#include <raymath.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Texture2D texture;
|
Texture2D texture;
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
#ifndef VECTOR_H
|
#ifndef VECTOR_H
|
||||||
#define VECTOR_H
|
#define VECTOR_H
|
||||||
#include <raylib.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <raymath.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Vector2 *data;
|
Vector2 *data;
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
- Naturschuetzer in einem Brachland
|
||||||
|
- Jahreszeiten -> mehrere Generationen von Bienenstaemmen
|
||||||
|
- Kasten sauber machen
|
||||||
|
|
||||||
|
- 1. Samen saehen
|
||||||
|
- 2. Zuckerwasser aufstellen
|
||||||
|
- 3. Kaesten aufstellen
|
||||||
|
- 4. Baueme pflanzen
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef BEE_H
|
||||||
|
#define BEE_H
|
||||||
|
#include "../engine/sprite.h"
|
||||||
|
#include "../engine/animation.h"
|
||||||
|
#include "../engine/physics.h"
|
||||||
|
#include "../engine/object.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Sprite sprite;
|
||||||
|
Animation animation;
|
||||||
|
Physics physics;
|
||||||
|
Object target;
|
||||||
|
Object hive;
|
||||||
|
int flowerCount;
|
||||||
|
} Bee;
|
||||||
|
|
||||||
|
Bee CreateBee(Texture2D texture, float frameWidth, int maxFrame, int framesSpeed, Vector2 position, float speed, ObjectArray* target, Object* base){
|
||||||
|
return (Bee){
|
||||||
|
.sprite = {
|
||||||
|
.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 = 0.0f,
|
||||||
|
.color = WHITE
|
||||||
|
},
|
||||||
|
.animation = {
|
||||||
|
.currentFrame = 0,
|
||||||
|
.maxFrame = maxFrame,
|
||||||
|
.framesCounter = 0,
|
||||||
|
.framesSpeed = framesSpeed,
|
||||||
|
.animTimer = 0.0f
|
||||||
|
},
|
||||||
|
.physics = {
|
||||||
|
.position = position,
|
||||||
|
.direction = (Vector2){0.0f,0.0f},
|
||||||
|
.speed = speed
|
||||||
|
},
|
||||||
|
.target = *GetRandomObject(target),
|
||||||
|
.hive = *base
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateBee(Bee* bee, ObjectArray* flowers, Object hive){
|
||||||
|
const float tolerance = 1.0f;
|
||||||
|
|
||||||
|
if (bee->flowerCount < 4){
|
||||||
|
if (fabs(bee->physics.position.x - bee->target.position.x) < tolerance &&
|
||||||
|
fabs(bee->physics.position.y - bee->target.position.y) < tolerance) {
|
||||||
|
bee->target = *GetRandomObject(flowers);
|
||||||
|
bee->flowerCount++;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bee->target = hive;
|
||||||
|
if (fabs(bee->physics.position.x - bee->target.position.x) < tolerance &&
|
||||||
|
fabs(bee->physics.position.y - bee->target.position.y) < tolerance) {
|
||||||
|
bee->physics.speed = 0.0f;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdatePhysics(&bee->physics, GetDirectionToObject(&bee->target, bee->physics.position));
|
||||||
|
UpdateSpriteRotation(&bee->sprite, &bee->physics.direction);
|
||||||
|
UpdateSpriteDestRec(&bee->sprite, &bee->physics.position);
|
||||||
|
UpdateAnimation(&bee->animation, GetFrameTime());
|
||||||
|
UpdateSpriteSourceRec(&bee->sprite, &(Vector2){bee->sprite.frameSize.x, bee->sprite.frameSize.x * bee->animation.currentFrame});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BEE_H
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef Floor_H
|
||||||
|
#define Floor_H
|
||||||
|
#include "../engine/sprite.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Sprite sprite;
|
||||||
|
Rectangle bounds;
|
||||||
|
} Floor;
|
||||||
|
|
||||||
|
Floor CreateFloor(Texture2D texture, float textureWidth){
|
||||||
|
return (Floor){
|
||||||
|
.sprite = {
|
||||||
|
.texture = texture,
|
||||||
|
.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.0f,0.0f,0.0f,0.0f}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderFloor(Floor *Floor){
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //Floor_H
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef FLOWERS_H
|
||||||
|
#define FLOWERS_H
|
||||||
|
|
||||||
|
#include "../engine/object.h"
|
||||||
|
|
||||||
|
ObjectArray CreateFlowers(Texture2D texture,float frameWidth, float rotation, float fieldSize) {
|
||||||
|
ObjectArray flowers = CreateObjectArray(&(Object){
|
||||||
|
.sprite = {
|
||||||
|
.texture = texture,
|
||||||
|
.sourceRec = {0.0f, 0.0f, frameWidth, frameWidth},
|
||||||
|
.destRec = {0.0f, 0.0f, frameWidth, frameWidth},
|
||||||
|
.origin = {frameWidth / 2, frameWidth / 2},
|
||||||
|
.rotation = rotation,
|
||||||
|
.color = WHITE
|
||||||
|
},
|
||||||
|
.position = {0.0f, 0.0f}
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
if (!flowers.data) {
|
||||||
|
printf("Memory allocation failed.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetRandomPositionForObjectArray(&flowers, (Rectangle){-fieldSize, -fieldSize, fieldSize * 2, fieldSize * 2});
|
||||||
|
|
||||||
|
return flowers;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FLOWERS_H
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
#include "../engine/object.h"
|
||||||
|
#include "../engine/camera.h"
|
||||||
|
#include "../engine/input.h"
|
||||||
|
#include "../engine/shader.h"
|
||||||
|
#include "../engine/musicmanager.h"
|
||||||
|
#include "floor.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "bee.h"
|
||||||
|
#include "hive.h"
|
||||||
|
#include "flowers.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VignetteShader vignetteShader;
|
||||||
|
MyMusic ambient;
|
||||||
|
RenderTexture2D target;
|
||||||
|
Texture2D flowerTexture, beeTexture, floorTexture, hiveTexture;
|
||||||
|
Floor floor;
|
||||||
|
Object hive;
|
||||||
|
ObjectArray flowers;
|
||||||
|
Player player;
|
||||||
|
Bee bee1;
|
||||||
|
Camera2D camera;
|
||||||
|
Mouse mouse;
|
||||||
|
} GameState;
|
||||||
|
|
||||||
|
void initGame(GameState* g){
|
||||||
|
InitAudioDevice();
|
||||||
|
|
||||||
|
g->vignetteShader = CreateShader("shaders/vignette.fs", 0.3f);
|
||||||
|
|
||||||
|
g->ambient = CreateMusic("assets/beez.mp3");
|
||||||
|
|
||||||
|
g->target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
|
g->flowerTexture = LoadTexture("assets/flower.png");
|
||||||
|
g->beeTexture = LoadTexture("assets/character_bee.png");
|
||||||
|
g->floorTexture = LoadTexture("assets/grass.png");
|
||||||
|
g->hiveTexture = LoadTexture("assets/hive.png");
|
||||||
|
|
||||||
|
g->floor = CreateFloor(g->floorTexture, 16.0f);
|
||||||
|
g->flowers = CreateFlowers(g->flowerTexture, 16.0f, 45.0f, 50.0f);
|
||||||
|
g->hive = CreateHive(g->hiveTexture, 32.0f);
|
||||||
|
g->player = CreatePlayer(g->beeTexture, 16.0f, 4, 10, g->hive.position, 50.0f);
|
||||||
|
g->bee1 = CreateBee(g->beeTexture, 16.0f, 4, 10, g->hive.position, 10.0f, &g->flowers, &g->hive);
|
||||||
|
|
||||||
|
g->camera = CreateCamera(GetScreenWidth(), GetScreenHeight(), g->player.physics.position, 10.0f);
|
||||||
|
g->mouse = CreateMouse(0.10f, 5.0f, 10.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateGame(GameState* g){
|
||||||
|
UpdateShader(&g->vignetteShader);
|
||||||
|
UpdateMusic(&g->ambient);
|
||||||
|
UpdateMouse(&g->mouse, &g->camera);
|
||||||
|
UpdateCamera2D(&g->camera, &g->player.physics.position, &g->mouse);
|
||||||
|
UpdateFloor(&g->floor, &g->camera);
|
||||||
|
UpdatePlayer(&g->player);
|
||||||
|
UpdateBee(&g->bee1, &g->flowers, g->hive);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderGame(GameState* g){
|
||||||
|
BeginTextureMode(g->target);
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
BeginMode2D(g->camera);
|
||||||
|
RenderFloor(&g->floor);
|
||||||
|
RenderSprite(&g->hive.sprite);
|
||||||
|
RenderObjectArray(&g->flowers);
|
||||||
|
RenderSprite(&g->bee1.sprite);
|
||||||
|
RenderSprite(&g->player.sprite);
|
||||||
|
EndMode2D();
|
||||||
|
EndTextureMode();
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
BeginShaderMode(g->vignetteShader.shader);
|
||||||
|
DrawTextureRec(g->target.texture, (Rectangle){ 0, 0, g->target.texture.width, -g->target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
||||||
|
EndShaderMode();
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanupGame(GameState* g){
|
||||||
|
UnloadVignetteShader(&g->vignetteShader);
|
||||||
|
UnloadRenderTexture(g->target);
|
||||||
|
UnloadTexture(g->floorTexture);
|
||||||
|
UnloadTexture(g->hiveTexture);
|
||||||
|
UnloadTexture(g->flowerTexture);
|
||||||
|
UnloadTexture(g->beeTexture);
|
||||||
|
UnloadMusicStream(g->ambient.music);
|
||||||
|
free(g->flowers.data);
|
||||||
|
CloseAudioDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GAME_H
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef HIVE_H
|
||||||
|
#define HIVE_H
|
||||||
|
#include "../engine/object.h"
|
||||||
|
|
||||||
|
Object CreateHive(Texture2D texture, float frameWidth){
|
||||||
|
return (Object) {
|
||||||
|
.sprite = {
|
||||||
|
.texture = texture,
|
||||||
|
.sourceRec = (Rectangle){0.0f, 0.0f, frameWidth, frameWidth},
|
||||||
|
.destRec = (Rectangle){0.0f, 0.0f, frameWidth, frameWidth},
|
||||||
|
.origin = (Vector2){frameWidth / 2, frameWidth / 2},
|
||||||
|
.rotation = 0.0f,
|
||||||
|
.color = WHITE,
|
||||||
|
},
|
||||||
|
.position = (Vector2){0.0f, 0.0f}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HIVE_H
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
#ifndef LOGO_H
|
||||||
|
#define LOGO_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, Screen *currentScreen) {
|
||||||
|
l->frameCounter++; // Increment the frame counter each frame
|
||||||
|
|
||||||
|
if (l->state == 0) { // State 0: Small box blinking for 120 frames (2 seconds at 60 FPS)
|
||||||
|
if (l->frameCounter >= 120) {
|
||||||
|
l->state = 1;
|
||||||
|
l->frameCounter = 0; // Reset frame counter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (l->state == 1) { // State 1: Top and left bars growing
|
||||||
|
l->topSideRecWidth += 4;
|
||||||
|
l->leftSideRecHeight += 4;
|
||||||
|
|
||||||
|
if (l->topSideRecWidth >= 256) {
|
||||||
|
l->state = 2;
|
||||||
|
l->frameCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (l->state == 2) { // State 2: Bottom and right bars growing
|
||||||
|
l->bottomSideRecWidth += 4;
|
||||||
|
l->rightSideRecHeight += 4;
|
||||||
|
|
||||||
|
if (l->bottomSideRecWidth >= 256) {
|
||||||
|
l->state = 3;
|
||||||
|
l->frameCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (l->state == 3) { // State 3: Letters appearing
|
||||||
|
if (l->frameCounter % 12 == 0) { // Every 12 frames, one more letter appears
|
||||||
|
l->lettersCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->lettersCount >= 10) { // Fade out animation
|
||||||
|
l->alpha -= 0.02f;
|
||||||
|
if (l->alpha <= 0.0f) {
|
||||||
|
l->alpha = 0.0f;
|
||||||
|
l->state = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (l->state == 4) { // State 4: Transition to GAMEPLAY
|
||||||
|
SetTargetFPS(0);
|
||||||
|
*currentScreen = MENU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderLogo(const LogoState *l) {
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
if (l->state == 0) { // Small box blinking
|
||||||
|
if ((l->frameCounter / 15) % 2 == 0) { // Blink every 15 frames
|
||||||
|
DrawRectangle(l->positionX, l->positionY, 16, 16, BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (l->state == 1) { // Top and left bars growing
|
||||||
|
DrawRectangle(l->positionX, l->positionY, l->topSideRecWidth, 16, BLACK);
|
||||||
|
DrawRectangle(l->positionX, l->positionY, 16, l->leftSideRecHeight, BLACK);
|
||||||
|
}
|
||||||
|
else if (l->state == 2) { // Bottom and right bars growing
|
||||||
|
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) { // Letters appearing
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LOGO_H
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef MENU_H
|
||||||
|
#define MENU_H
|
||||||
|
|
||||||
|
#include "../engine/gui.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Button startButton;
|
||||||
|
} MenuState;
|
||||||
|
|
||||||
|
void initMenu(MenuState *t){
|
||||||
|
initButton(&t->startButton, "Start Game", GetScreenWidth() / 10, GetScreenHeight() / 20, GetScreenWidth() / 2, GetScreenHeight() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateMenu(MenuState *t, Screen *currentScreen){
|
||||||
|
if (isButtonClicked(&t->startButton)) {
|
||||||
|
*currentScreen = GAMEPLAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderMenu(MenuState *t){
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
renderButton(&t->startButton);
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MENU_H
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef PLAYER_H
|
||||||
|
#define PLAYER_H
|
||||||
|
#include "../engine/sprite.h"
|
||||||
|
#include "../engine/animation.h"
|
||||||
|
#include "../engine/physics.h"
|
||||||
|
#include "../engine/input.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Sprite sprite;
|
||||||
|
Animation animation;
|
||||||
|
Physics physics;
|
||||||
|
} Player;
|
||||||
|
|
||||||
|
Player CreatePlayer(Texture2D texture, float frameWidth, int maxFrame, int framesSpeed, Vector2 startPosition, float speed){
|
||||||
|
return (Player){
|
||||||
|
.sprite = {
|
||||||
|
.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 = 0.0f,
|
||||||
|
.color = WHITE
|
||||||
|
},
|
||||||
|
.animation = {
|
||||||
|
.currentFrame = 0,
|
||||||
|
.maxFrame = maxFrame,
|
||||||
|
.framesCounter = 0,
|
||||||
|
.framesSpeed = framesSpeed,
|
||||||
|
.animTimer = 0.0f
|
||||||
|
},
|
||||||
|
.physics = {
|
||||||
|
.position = startPosition,
|
||||||
|
.direction = (Vector2){0.0f,0.0f},
|
||||||
|
.speed = speed
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdatePlayer(Player* player){
|
||||||
|
UpdatePhysics(&player->physics, GetDirectionVector());
|
||||||
|
UpdateSpriteRotation(&player->sprite, &player->physics.direction);
|
||||||
|
UpdateSpriteDestRec(&player->sprite, &player->physics.position);
|
||||||
|
UpdateAnimation(&player->animation, GetFrameTime());
|
||||||
|
UpdateSpriteSourceRec(&player->sprite, &(Vector2){player->sprite.frameSize.x, player->sprite.frameSize.x * player->animation.currentFrame});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PLAYER_H
|
||||||
File diff suppressed because it is too large
Load Diff
+55
@@ -0,0 +1,55 @@
|
|||||||
|
#include <raylib.h>
|
||||||
|
#include <raymath.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "engine/screen.h"
|
||||||
|
#include "engine/settings.h"
|
||||||
|
#include "game/logo.h"
|
||||||
|
#include "game/menu.h"
|
||||||
|
#include "game/game.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
Settings settings = {
|
||||||
|
.name = "The Last Hive",
|
||||||
|
.screenWidth = 1280,
|
||||||
|
.screenHeight = 720
|
||||||
|
};
|
||||||
|
|
||||||
|
InitWindow(settings.screenWidth, settings.screenHeight, settings.name);
|
||||||
|
|
||||||
|
Screen currentScreen = LOGO;
|
||||||
|
LogoState logo;
|
||||||
|
GameState game;
|
||||||
|
MenuState menu;
|
||||||
|
|
||||||
|
initLogo(&logo);
|
||||||
|
initMenu(&menu);
|
||||||
|
initGame(&game);
|
||||||
|
|
||||||
|
while (!WindowShouldClose())
|
||||||
|
{
|
||||||
|
switch (currentScreen)
|
||||||
|
{
|
||||||
|
case LOGO:
|
||||||
|
{
|
||||||
|
updateLogo(&logo,¤tScreen);
|
||||||
|
renderLogo(&logo);
|
||||||
|
}break;
|
||||||
|
case MENU:
|
||||||
|
{
|
||||||
|
updateMenu(&menu, ¤tScreen);
|
||||||
|
renderMenu(&menu);
|
||||||
|
}break;
|
||||||
|
case GAMEPLAY:
|
||||||
|
{
|
||||||
|
updateGame(&game);
|
||||||
|
renderGame(&game);
|
||||||
|
}break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cleanupGame(&game);
|
||||||
|
CloseWindow();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user