129 lines
3.7 KiB
C
129 lines
3.7 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "include/raylib.h"
|
|
#include "include/raymath.h"
|
|
#include "boids_game.h"
|
|
#include "lib.h"
|
|
|
|
#define SCREEN_WIDTH 1300
|
|
#define SCREEN_HEIGHT 1080
|
|
|
|
typedef struct Boid {
|
|
Point position;
|
|
Vector2 acceleration;
|
|
Vector2 velocity;
|
|
} Boid;
|
|
|
|
typedef struct GameState {
|
|
Boid *boids;
|
|
PointOption target_pos;
|
|
int num_boids;
|
|
float max_speed;
|
|
float max_force;
|
|
} GameState;
|
|
|
|
static GameState *init() {
|
|
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Boids");
|
|
|
|
SetTargetFPS(60);
|
|
|
|
GameState *state = malloc(sizeof(struct GameApi));
|
|
state->num_boids = 16;
|
|
state->max_speed = 5.0f;
|
|
state->max_force = 0.05;
|
|
Boid *boids = malloc(state->num_boids * sizeof(Boid));
|
|
state->boids = boids;
|
|
for (int i = 0; i < state->num_boids; i++) {
|
|
Boid *boid = &boids[i];
|
|
int rand_x = GetRandomValue(0, SCREEN_WIDTH);
|
|
int rand_y = GetRandomValue(0, SCREEN_HEIGHT);
|
|
boid->position = (Vector2){rand_x, rand_y};
|
|
int rand_vx = GetRandomValue(0, 100);
|
|
int rand_vy = GetRandomValue(0, 100);
|
|
boid->velocity = (Vector2){rand_vx * 0.01f - 0.5f, rand_vy * 0.01f - 0.5f};
|
|
// boid->velocity = Vector2Scale(boid->velocity, 10.0f);
|
|
// int rand_ax = GetRandomValue(0, 100);
|
|
// int rand_ay = GetRandomValue(0, 100);
|
|
// boid->velocity = (Vector2){rand_ax * 0.01f - 0.5f, rand_ay * 0.01f - 0.5f};
|
|
boid->acceleration = (Vector2){0};
|
|
}
|
|
|
|
printf("Initialized Game\n");
|
|
return state;
|
|
}
|
|
|
|
static void finalize(GameState *state) {
|
|
free(state->boids);
|
|
CloseWindow();
|
|
}
|
|
|
|
static void reload(GameState *state) {
|
|
(void)state;
|
|
state->max_speed = 5.0f;
|
|
state->max_force = 0.1;
|
|
printf("Reloaded Game\n");
|
|
}
|
|
|
|
static void unload(GameState *state) {
|
|
(void)state;
|
|
}
|
|
|
|
static int step(GameState *state) {
|
|
if (WindowShouldClose()) {
|
|
return 1;
|
|
}
|
|
|
|
int return_int = 0;
|
|
if (IsKeyPressed(KEY_SPACE)) {
|
|
return_int = 2;
|
|
}
|
|
// Process Input
|
|
if (IsMouseButtonPressed(0)) {
|
|
Vector2 mouse_pos = GetMousePosition();
|
|
state->target_pos = (PointOption){.tag = SOME, .some.point = mouse_pos};
|
|
}
|
|
|
|
// Update
|
|
for (int i = 0; i < state->num_boids; i++) {
|
|
Boid *boid = &state->boids[i];
|
|
if (state->target_pos.tag == SOME) {
|
|
Vector2 desired = Vector2Subtract(state->target_pos.some.point, boid->position);
|
|
desired = Vector2Normalize(desired);
|
|
desired = Vector2Scale(desired, state->max_speed);
|
|
Vector2 steer = Vector2Subtract(desired, boid->velocity);
|
|
steer = Vector2ClampValue(steer, 0.0f, state->max_force);
|
|
boid->acceleration = Vector2Add(boid->acceleration, steer);
|
|
}
|
|
boid->velocity = Vector2Add(boid->velocity, boid->acceleration);
|
|
boid->velocity = Vector2ClampValue(boid->velocity, 0.0f, state->max_speed);
|
|
boid->position = Vector2Add(boid->position, boid->velocity);
|
|
}
|
|
|
|
|
|
// Update
|
|
BeginDrawing();
|
|
{
|
|
ClearBackground(RAYWHITE);
|
|
// You can draw a triangle but you'd need to rotate all 3 vectors, and I don't
|
|
// want to get distracted with that
|
|
// DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, GREEN);
|
|
// DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, GREEN);
|
|
for (int i = 0; i < state->num_boids; i++) {
|
|
Boid *boid = &state->boids[i];
|
|
DrawCircle(boid->position.x, boid->position.y, 27, BLACK);
|
|
DrawCircle(boid->position.x, boid->position.y, 20, GREEN);
|
|
}
|
|
|
|
}
|
|
EndDrawing();
|
|
return return_int;
|
|
}
|
|
|
|
const struct GameApi GAME_API = {
|
|
.init = init,
|
|
.reload = reload,
|
|
.step = step,
|
|
.unload = unload,
|
|
.finalize = finalize
|
|
};
|