tinyswords/boids_game.c

103 lines
3.1 KiB
C

#include <stdlib.h>
#include "include/raylib.h"
#include "include/raymath.h"
#include "boids_game.h"
#include "lib.h"
#define SCREEN_WIDTH 1300
#define SCREEN_HEIGHT 1080
#define NUM_BOIDS 16
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;
GameState *init() {
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};
}
return state;
}
void finalize(GameState *state) {
(void)state;
}
void reload(GameState *state) {
(void)state;
}
void unload(GameState *state) {
(void)state;
}
void step(GameState *state) {
// 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 < 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 < 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();
}