1gps/06-spaghetti-vs-bolognese/main.c

168 lines
5.4 KiB
C

#include <stdio.h>
#include "raylib.h"
#include "raymath.h"
#define ROPE_LEN 20
#define ROPE_WIDTH 10
#define NB_ROPE 50
Vector2 ropes[NB_ROPE];
Vector2 forces[NB_ROPE];
#define ENEMIE_WIDTH 25
#define NB_ENEMIE 10
Vector2 enemies[NB_ENEMIE];
int points = -NB_ENEMIE;
Vector2 window = {1920, 1080};
int main()
{
SetRandomSeed(69);
InitWindow(window.x, window.y, "SPAGHETTI VS BOLOGNESE");
SetWindowState(FLAG_FULLSCREEN_MODE|FLAG_WINDOW_RESIZABLE);
HideCursor();
SetTargetFPS(60);
for (int i = 0; i < NB_ROPE; i++) {
ropes[i] = (Vector2) {window.x/2, window.y/2};
}
while (!WindowShouldClose()) {
if (IsWindowResized()) {
window.x = GetScreenWidth();
window.y = GetScreenHeight();
}
static int is_space = 0;
if (IsKeyPressed(KEY_SPACE)) {
is_space = !is_space;
}
BeginDrawing();
{
ClearBackground(GRAY);
if (GetTime() < 5) {
int size = 75;
const char* info = "Soak your spaghetti in Bolognese sauce !";
DrawText(
info,
window.x / 2 - MeasureText(info, size) / 2,
window.y / 2 - size,
size, GOLD
);
const char* mode = "Press space to change mode";
DrawText(
mode,
window.x / 2 - MeasureText(mode, size) / 2,
window.y / 2,
size, SKYBLUE
);
}
if (points > (NB_ROPE-1)*10) {
ShowCursor();
static int off = 0;
off++;
DrawCircleV(ropes[0], ROPE_WIDTH/2, ColorFromHSV(off%360, 1, 1));
for (int i = 1; i < NB_ROPE; i++) {
Color c = ColorFromHSV((off+i*3)%360, 1, 1);
DrawCircleV(ropes[i], ROPE_WIDTH/2, c);
DrawLineEx(ropes[i-1], ropes[i], ROPE_WIDTH, c);
}
int size = 75;
DrawText("YOU WON!", window.x/2-MeasureText("YOU WON!", size)/2, window.y/2-size/2, size, GOLD);
EndDrawing();
continue;
}
ropes[0] = GetMousePosition();
DrawCircleV(ropes[0], ROPE_WIDTH/2, points > 0 ? RED : YELLOW);
for (int i = 1; i < NB_ROPE; i++) {
Vector2 old = ropes[i];
if (!is_space)
forces[i].y += 9.8*69*GetFrameTime();
ropes[i] = Vector2Add(ropes[i], forces[i]);
float dist = Vector2Distance(ropes[i-1], ropes[i]);
if (!dist) dist = ROPE_LEN;
ropes[i] = Vector2Lerp(ropes[i-1], ropes[i], ROPE_LEN/dist);
Vector2 snap = Vector2Subtract(old, ropes[i]);
snap = Vector2Negate(snap);
snap = Vector2Scale(snap, GetFrameTime()*37);
forces[i] = snap;
Color color = YELLOW;
if (i*10 < points) color = RED;
DrawCircleV(ropes[i], ROPE_WIDTH/2, color);
DrawLineEx(ropes[i-1], ropes[i], ROPE_WIDTH, color);
for (int y = 0; y < NB_ENEMIE; y++) {
if (CheckCollisionCircles(enemies[y], ENEMIE_WIDTH, ropes[i], ROPE_WIDTH/2)) {
points++;
enemies[y].x = -500;
enemies[y].y = -500;
}
}
}
for (int i = 0; i < NB_ENEMIE; i++) {
if (!CheckCollisionCircleRec(enemies[i], 50, (Rectangle){0,0,window.x,window.y})) {
int side = GetRandomValue(0, 3);
float pour = (float)GetRandomValue(0, 100)/100;
switch (side) {
case 0: // left
enemies[i].x = -ENEMIE_WIDTH;
enemies[i].y = pour*window.y;
break;
case 1: // top
enemies[i].x = pour*window.x;
enemies[i].y = -ENEMIE_WIDTH;
break;
case 2: // right
enemies[i].x = window.x+ENEMIE_WIDTH;
enemies[i].y = pour*window.y;
break;
case 3: // bottom
enemies[i].x = pour*window.x;
enemies[i].y = window.y+ENEMIE_WIDTH;
break;
}
continue;
}
enemies[i].x += (i+50)*GetFrameTime() * (i%2 ? -i/5-1 : i/3+1);
enemies[i].y += (i+50)*GetFrameTime() * (i%3 ? i/2+1 : -i/2-1);
DrawCircleV(enemies[i], ENEMIE_WIDTH, RED);
}
int size = 30;
int marg = 5;
DrawText(" Mode: ", 0, marg, size, ORANGE);
if (is_space) {
DrawText("SPACE", MeasureText(" Mode: ", size), marg, size, DARKBLUE);
} else {
DrawText("GRAVITY", MeasureText(" Mode: ", size), marg, size, BROWN);
}
DrawText(" Points: ", 0, size+marg, size, ORANGE);
DrawText(TextFormat("%d / %d", points, 10*NB_ROPE), MeasureText(" Points: ", size), size+marg, size, GOLD);
}
EndDrawing();
}
}