le ju sans map-ulp

This commit is contained in:
nemo 2025-06-03 09:27:07 +02:00
commit f5d6ef1d2a
16 changed files with 9792 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
dorianocacasorus
dorianocacasorus-linux
dorianocacasorus-windows.exe
dorianocacasorus.zip
bakery
assets/*.h

30
Makefile Normal file
View File

@ -0,0 +1,30 @@
BIN=dorianocacasorus
all:
gcc -Wall -Wextra -ggdb main.c -o $(BIN) -Ilib -Llib/ -lraylib -lm
run: all
./$(BIN)
release: bake
gcc -Wall -Wextra -O3 -ggdb -DRELEASE main.c -o $(BIN)-linux -Ilib -Llib/ -lraylib -lm
x86_64-w64-mingw32-gcc -Wall -Wextra -O3 -DRELEASE main.c -o $(BIN)-windows -Ilib -Llib -lwindows-raylib -lgdi32 -lwinmm
dist: clear release
mkdir $(BIN)
cp $(BIN)-linux $(BIN)-windows.exe $(BIN)
zip $(BIN) $(BIN)/*
rm -r $(BIN)/
clear:
rm -fr $(BIN) $(BIN)-linux $(BIN)-windows.exe bakery assets/*.h $(BIN).zip
bakery: bakery.c
gcc -Wall -Wextra -O3 bakery.c -o bakery -lm
bake: bakery
./bakery assets/fond.png assets/fond.h menufond
./bakery assets/bittersweet.mp3 assets/bittersweet.h musique
./bakery assets/Keyboard_Space.png assets/Keyboard_Space.h tuto_space
./bakery assets/Keyboard_Arrows.png assets/Keyboard_Arrows.h tuto_key
./bakery assets/raccon-delicieu.png assets/raccon-delicieu.h raccoon

BIN
assets/Keyboard_Arrows.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

BIN
assets/Keyboard_Space.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

BIN
assets/bittersweet.mp3 Normal file

Binary file not shown.

BIN
assets/fond.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

BIN
assets/raccon-delicieu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 KiB

93
bakery.c Normal file
View File

@ -0,0 +1,93 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
typedef struct File {
unsigned char* data;
int len;
} File;
int file_exist(const char* filename) {
return access(filename, F_OK) == 0;
}
File read_entire_file(const char* filename)
{
FILE *f = fopen(filename, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
unsigned char *string = malloc(fsize);
fread(string, fsize, 1, f);
fclose(f);
return (File) {
.len = fsize,
.data = string,
};
}
void file_free(File file)
{
free(file.data);
}
void write_entire_file(const char* filename, File file)
{
FILE *f = fopen(filename, "w");
fwrite(file.data, file.len, 1, f);
fclose(f);
}
// TODO: str -> format, ... | vsnprintf
int file_append(File file, int at, const char* format, ...)
{
int len = strlen(format);
memcpy(&file.data[at], format, len);
return len;
}
int main(int argc, const char *argv[])
{
if (argc != 4) {
printf("ERR: missing argument.\n");
printf("usage: %s <input asset> <output header file> <variable name>\n", argv[0]);
return 1;
}
const char *input = argv[1];
const char *output = argv[2];
const char *name = argv[3];
if (!file_exist(input)) {
printf("ERR: input file '%s' do not exist.\n", input);
return 1;
}
File asset = read_entire_file(input);
File header;
header.len = asset.len*6 /*0xFF, */ + asset.len/20*5 /*\n */ + 200 /*header+footer+banane*/ + strlen(name)*2;
header.data = malloc(header.len);
int cursor = 0;
// TODO: refacto ce truc de con la
// cursor += file_append(header, cursor, "static const int %s_size = %d;\n", name, asset.len);
cursor += snprintf((char*)header.data+cursor, header.len-cursor, "static const int %s_size = %d;\n", name, asset.len);
cursor += snprintf((char*)header.data+cursor, header.len-cursor, "static const unsigned char %s_data[%d] = {", name, asset.len);
int i;
for (i = 0; i < asset.len; i++) {
if (!(i%20)) cursor += snprintf((char*)header.data+cursor, header.len-cursor, "\n ");
cursor += snprintf((char*)header.data+cursor, header.len-cursor, "0x%02X, ", asset.data[i]);
}
cursor += snprintf((char*)header.data+cursor, header.len-cursor, "\n};\n");
header.len = cursor;
write_entire_file(output, header);
return 0;
}

BIN
lib/libraylib.a Normal file

Binary file not shown.

BIN
lib/libwindows-raylib.a Normal file

Binary file not shown.

1662
lib/raylib.h Normal file

File diff suppressed because it is too large Load Diff

2190
lib/raymath.h Normal file

File diff suppressed because it is too large Load Diff

4859
lib/rlgl.h Normal file

File diff suppressed because it is too large Load Diff

632
main.c Normal file
View File

@ -0,0 +1,632 @@
#include <stdio.h>
#include <string.h>
#include "raylib.h"
typedef struct Vec2i {
int x, y;
} Vec2i;
int vec2i_equals(Vec2i v1, Vec2i v2)
{
return v1.x == v2.x && v1.y == v2.y;
}
#include "maps.h"
#include "winfun.c"
typedef struct Shot {
int up, down, left, right;
} Shot;
#ifdef RELEASE
Vector2 window = {1920, 1080};
#else
Vector2 window = {600, 600};
#endif
#ifdef RELEASE
int in_menu = 1;
#else
int in_menu = 0;
#endif
int door_open = 0;
float level_finished = 0;
float alarme_sonne = 0;
float player_dead = 0;
float shoot_cooldown = 0;
float end_time_game = 0;
float begin_play_time = 0;
Texture tex_fond;
Texture tex_tuto_key;
Texture tex_tuto_space;
void draw_menu(void)
{
BeginDrawing();
ClearBackground(BLUE);
DrawTexturePro(tex_fond, (Rectangle){0,0,tex_fond.width,tex_fond.height}, (Rectangle){0,0,window.x,window.y}, (Vector2){0,0}, 0, WHITE);
const char *title = "DORIANOCACASORUS";
int size = 50;
int width = MeasureText(title, size);
DrawText(title, window.x/2-width/2, window.y/2-size/2, size, GOLD);
Vector2 mouse = GetMousePosition();
Rectangle button = {
.x = window.x/2-250,
.y = window.y*0.6,
.width = 500,
.height = 100,
};
Color button_color = GRAY;
if (CheckCollisionPointRec(mouse, button)) {
button_color = LIGHTGRAY;
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
in_menu = 0;
begin_play_time = GetTime();
#ifdef RELEASE
HideCursor();
DisableCursor();
#endif
}
}
DrawRectangleRec(button, button_color);
DrawText("PLAY", window.x/2-MeasureText("PLAY", size)/2, window.y*0.6+size/2, size, WHITE);
EndDrawing();
}
void draw_win(void)
{
BeginDrawing();
ClearBackground(DARKBLUE);
const char *title = "Étage réussie";
int size = 75;
int width = MeasureText(title, size);
DrawText(title, window.x/2-width/2, window.y/2-size/2, size, GOLD);
EndDrawing();
}
void draw_alarme_lose(void)
{
BeginDrawing();
ClearBackground(DARKBLUE);
const char *title = "L'alarme sonne";
int size = 75;
int width = MeasureText(title, size);
DrawText(title, window.x/2-width/2, window.y/2-size/2, size, VIOLET);
EndDrawing();
}
void draw_lose(void)
{
BeginDrawing();
ClearBackground(DARKBLUE);
const char *title = "Un guarde ta attraper";
int size = 75;
int width = MeasureText(title, size);
DrawText(title, window.x/2-width/2, window.y/2-size/2, size, RED);
EndDrawing();
}
void draw_end(void)
{
BeginDrawing();
ClearBackground(DARKBLUE);
const char *title = "GG ta finit le ju";
int size = 75;
int width = MeasureText(title, size);
DrawText(title, window.x/2-width/2, window.y/2-size/2, size, GOLD);
if (end_time_game < 0.1) end_time_game = GetTime()-begin_play_time;
title = TextFormat("temps: %d", (int)(end_time_game));
size = 50;
width = MeasureText(title, size);
DrawText(title, window.x/2-width/2, window.y/2+size, size, GOLD);
EndDrawing();
}
void draw_tuto(void)
{
int scale = 7;
int y_offset = 32;
int key_frame = 4;
Vec2i key_size = {32, 20};
int key_offset = ((int)(GetTime()*5)%key_frame)*key_size.x;
int space_frame = 2;
Vec2i space_size = {28, 13};
int space_offset = ((int)(GetTime()*5)%space_frame)*space_size.x;
DrawTexturePro(
tex_tuto_key,
(Rectangle) {key_offset, 0, key_size.x, key_size.y},
(Rectangle) {
window.x/2 - space_size.x*scale/2 - key_size.x*(scale+1)/2,
y_offset,
key_size.x*scale,
key_size.y*scale
},
(Vector2) {0, 0},
0, WHITE
);
DrawTexturePro(
tex_tuto_space,
(Rectangle) {space_offset, 0, space_size.x, space_size.y},
(Rectangle) {
window.x/2 - space_size.x*scale/2 + key_size.x*(scale+1)/2,
y_offset + key_size.y*scale - space_size.y*scale,
space_size.x*scale,
space_size.y*scale
},
(Vector2) {0, 0},
0, WHITE
);
}
Vec2i find_player(Map map, Vec2i map_size)
{
for (int x=0; x<map_size.x; x++) {
for (int y=0; y<map_size.y; y++) {
if (map[y][x] == 'S') {
return (Vec2i){x, y};
}
}
}
return (Vec2i){0, 0};
}
void load_map(Map *map, Vec2i *map_size, int etage)
{
door_open = 0;
*map_size = map_sizes[etage];
memcpy(map, maps[etage], (map_size->x)*(map_size->y)*sizeof(char)*2 /*jsp pk il faut 2*/);
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (guard.start.x == guard.end.x && guard.start.y == guard.end.y) {
guards[etage][g].dead = 1;
continue;
}
if (guard.start.x == guard.end.x && guard.start.y < guard.end .y) guards[etage][g].dir = BAS;
if (guard.start.x == guard.end.x && guard.start.y > guard.end .y) guards[etage][g].dir = HAUT;
if (guard.start.x < guard.end.x && guard.start.y == guard.end .y) guards[etage][g].dir = DROITE;
if (guard.start.x > guard.end.x && guard.start.y == guard.end .y) guards[etage][g].dir = GAUCHE;
guards[etage][g].pos = guard.start;
guards[etage][g].dead = 0;
}
}
int update_player_move(Map map, Vec2i map_size)
{
Vec2i old_pos = find_player(map, map_size);
Vec2i new_pos = old_pos;
if (IsKeyPressed(KEY_LEFT)) new_pos.x--;
if (IsKeyPressed(KEY_RIGHT)) new_pos.x++;
if (IsKeyPressed(KEY_DOWN)) new_pos.y++;
if (IsKeyPressed(KEY_UP)) new_pos.y--;
if (
new_pos.x < 0 ||
new_pos.y < 0 ||
new_pos.x >= map_size.x ||
new_pos.y >= map_size.y
) return 0;
if (door_open && map[new_pos.y][new_pos.x] == 'P') {
level_finished = 1.2;
etage++;
}
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (!guard.dead && vec2i_equals(guard.pos, new_pos)) return 0;
}
if (map[new_pos.y][new_pos.x] == ' ') {
map[new_pos.y][new_pos.x] = 'S';
map[old_pos.y][old_pos.x] = ' ';
return 1;
}
return 0;
}
void update_guard_pos(void)
{
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard *guard = &guards[etage][g];
if (guard->dead) continue;
switch (guard->dir) {
case HAUT: guard->pos.y--; break;
case BAS: guard->pos.y++; break;
case GAUCHE: guard->pos.x--; break;
case DROITE: guard->pos.x++; break;
}
if (vec2i_equals(guard->pos, guard->start) || vec2i_equals(guard->pos, guard->end)) {
switch (guard->dir) {
case HAUT: guard->dir = BAS; break;
case BAS: guard->dir = HAUT; break;
case GAUCHE: guard->dir = DROITE; break;
case DROITE: guard->dir = GAUCHE; break;
}
}
}
}
void check_player_dead(Map map, Vec2i map_size)
{
Vec2i player = find_player(map, map_size);
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (!guard.dead && vec2i_equals(player, guard.pos)) {
player_dead = 1.2;
return;
}
}
for (int x=player.x; x<map_size.x; x++) {
if (map[player.y][x] != ' ' && map[player.y][x] != 'S') break;
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (!guard.dead && guard.dir != DROITE && vec2i_equals((Vec2i){x, player.y}, guard.pos)) {
player_dead = 1.2;
return;
}
}
}
for (int x=player.x; x>=0; x--) {
if (map[player.y][x] != ' ' && map[player.y][x] != 'S') break;
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (!guard.dead && guard.dir != GAUCHE && vec2i_equals((Vec2i){x, player.y}, guard.pos)) {
player_dead = 1.2;
return;
}
}
}
for (int y=player.y; y<map_size.y; y++) {
if (map[y][player.x] != ' ' && map[y][player.x] != 'S') break;
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (!guard.dead && guard.dir != BAS && vec2i_equals((Vec2i){player.x, y}, guard.pos)) {
player_dead = 1.2;
return;
}
}
}
for (int y=player.y; y>=0; y--) {
if (map[y][player.x] != ' ' && map[y][player.x] != 'S') break;
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (!guard.dead && guard.dir != HAUT && vec2i_equals((Vec2i){player.x, y}, guard.pos)) {
player_dead = 1.2;
return;
}
}
}
}
int kill(Map map, Vec2i pos)
{
int killed = 1;
switch (map[pos.y][pos.x]) {
case 'G':
map[pos.y][pos.x] = ' ';
break;
case 'O':
map[pos.y][pos.x] = ' ';
break;
case 'B':
map[pos.y][pos.x] = ' ';
door_open = 1;
break;
case 'A':
map[pos.y][pos.x] = ' ';
alarme_sonne = 1.2;
shoot_cooldown = 0;
break;
default:
killed = 0;
break;
}
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (!guard.dead && vec2i_equals(pos, guard.pos)) {
guards[etage][g].dead = 1;
return 1;
}
}
return killed;
}
Shot shoot(Map map, Vec2i map_size, Vec2i from)
{
Shot shot;
int up = from.y;
for (; up>0 && map[up-1][from.x] != 'M'; up--)
if (kill(map, (Vec2i){from.x, up-1})) break;
shot.up = up;
int down = from.y;
for (; down<map_size.y-1 && map[down+1][from.x] != 'M'; down++)
if (kill(map, (Vec2i){from.x, down+1})) break;
shot.down = down;
int left = from.x;
for (; left>0 && map[from.y][left-1] != 'M'; left--)
if (kill(map, (Vec2i){left-1, from.y})) break;
shot.left = left;
int right = from.x;
for (; right<map_size.x-1 && map[from.y][right+1] != 'M'; right++)
if (kill(map, (Vec2i){right+1, from.y})) break;
shot.right = right;
return shot;
}
int main(void)
{
#ifdef RELEASE
SetTraceLogLevel(LOG_FATAL);
#endif
SetRandomSeed(69);
InitWindow(window.x, window.y, "DIRANOCACASORUS");
#ifdef RELEASE
SetWindowState(FLAG_FULLSCREEN_MODE);
#else
SetWindowState(FLAG_WINDOW_RESIZABLE);
#endif
SetTargetFPS(60);
#ifdef RELEASE
#include "assets/fond.h"
Image img_fond = LoadImageFromMemory(".png", menufond_data, menufond_size);
tex_fond = LoadTextureFromImage(img_fond);
#else
tex_fond = LoadTexture("assets/fond.png");
#endif
InitAudioDevice();
#ifdef RELEASE
#include "assets/bittersweet.h"
Wave wave_musique = LoadWaveFromMemory(".mp3", musique_data, musique_size);
Sound musique = LoadSoundFromWave(wave_musique);
#else
Sound musique = LoadSound("assets/bittersweet.mp3");
#endif
PlaySound(musique);
Vec2i map_size;
Map map;
load_map(&map, &map_size, etage);
#ifdef RELEASE
#include "assets/Keyboard_Arrows.h"
Image img_tuto_key = LoadImageFromMemory(".png", tuto_key_data, tuto_key_size);
tex_tuto_key = LoadTextureFromImage(img_tuto_key);
#include "assets/Keyboard_Space.h"
Image img_tuto_space = LoadImageFromMemory(".png", tuto_space_data, tuto_space_size);
tex_tuto_space = LoadTextureFromImage(img_tuto_space);
#else
tex_tuto_key = LoadTexture("assets/Keyboard_Arrows.png");
tex_tuto_space = LoadTexture("assets/Keyboard_Space.png");
#endif
while (!WindowShouldClose()) {
if (IsWindowResized()) {
window.x = GetScreenWidth();
window.y = GetScreenHeight();
}
if (!IsSoundPlaying(musique)) PlaySound(musique);
if (in_menu) {
draw_menu();
continue;
}
if (alarme_sonne > 0) {
alarme_sonne -= GetFrameTime();
load_map(&map, &map_size, etage); // NOTE: memcpy pendant 1.2s mais flemme
draw_alarme_lose();
continue;
}
if (player_dead > 0) {
player_dead -= GetFrameTime();
load_map(&map, &map_size, etage); // NOTE: memcpy pendant 1.2s mais flemme
draw_lose();
continue;
}
Vec2i player_pos = find_player(map, map_size);
static Shot shot;
if (IsKeyPressed(KEY_SPACE)) {
shoot_cooldown = 0.12;
shot = shoot(map, map_size, player_pos);
update_guard_pos();
}
check_player_dead(map, map_size);
if (shoot_cooldown > 0) {
shoot_cooldown -= GetFrameTime();
}
if (shoot_cooldown <= 0) {
int moved = update_player_move(map, map_size);
if (moved) {
update_guard_pos();
}
}
if (level_finished > 0) {
level_finished -= GetFrameTime();
load_map(&map, &map_size, etage); // NOTE: memcpy pendant 1.2s mais flemme
draw_win();
continue;
}
if (level_finished > -2.7 && etage >= NB_ETAGE_TOTAL) {
level_finished -= GetFrameTime();
draw_end();
continue;
}
if (etage >= NB_ETAGE_TOTAL) {
win_fun();
continue;
}
BeginDrawing();
ClearBackground(DARKBLUE);
if (etage == 0) {
draw_tuto();
}
int mult = 50;
int size = 50;
Vec2i offset;
offset.x = window.x/2 - map_size.x*size/2;
offset.y = window.y/2 - map_size.y*size/2;
for (int x=0; x<map_size.x; x++) {
for (int y=0; y<map_size.y; y++) {
int is_danger = 0;
for (int g=0; g<MAX_GUARD_ETAGE; g++) {
Guard guard = guards[etage][g];
if (guard.dead) continue;
Vec2i pos = {x,y};
if (vec2i_equals(pos, guard.pos)) goto skip;
if (vec2i_equals(pos, guard.start) && !vec2i_equals(pos, guard.start)) goto skip;
if (vec2i_equals(pos, guard.end) && !vec2i_equals(pos, guard.end)) goto skip;
if (pos.x == guard.pos.x) {
if (pos.y > guard.pos.y && guard.dir == HAUT) continue;
if (pos.y < guard.pos.y && guard.dir == BAS) continue;
int min = pos.y < guard.pos.y ? pos.y : guard.pos.y;
int max = pos.y > guard.pos.y ? pos.y : guard.pos.y;
int walled = 0;
for (int i=min; i<max; i++) {
if (map[i][x] == 'M' || map[i][x] == 'O' || map[i][x] == 'A') {
walled = 1;
break;
}
}
if (!walled) is_danger = 1;
}
else if (pos.y == guard.pos.y) {
if (pos.x > guard.pos.x && guard.dir == GAUCHE) continue;
if (pos.x < guard.pos.x && guard.dir == DROITE) continue;
int min = pos.x < guard.pos.x ? pos.x : guard.pos.x;
int max = pos.x > guard.pos.x ? pos.x : guard.pos.x;
int walled = 0;
for (int i=min; i<max; i++) {
if (map[y][i] == 'M' || map[y][i] == 'O' || map[y][i] == 'A') {
walled = 1;
break;
}
}
if (!walled) is_danger = 1;
}
}
switch (map[y][x]) {
case 'M':
DrawText("M", offset.x+x*mult, offset.y+y*mult, size, GOLD);
break;
case 'O':
DrawText("O", offset.x+x*mult, offset.y+y*mult, size, YELLOW);
break;
case 'P':
if (!door_open) DrawText("P", offset.x+x*mult, offset.y+y*mult, size, BLACK);
else DrawText("E", offset.x+x*mult, offset.y+y*mult, size, LIME);
break;
case 'B':
DrawText("B", offset.x+x*mult, offset.y+y*mult, size, WHITE);
break;
case 'S':
DrawText("S", offset.x+x*mult, offset.y+y*mult, size, GREEN);
break;
case 'G':
DrawText("G", offset.x+x*mult, offset.y+y*mult, size, RED);
break;
case 'A':
DrawText("A", offset.x+x*mult, offset.y+y*mult, size, VIOLET);
break;
default:
DrawText("-", offset.x+x*mult, offset.y+y*mult, size, is_danger?RED:WHITE);
break;
}
skip:
}
}
for (int i = 0; i < MAX_GUARD_ETAGE; i++) {
Guard guard = guards[etage][i];
if (guard.dead) continue;
DrawText("G", offset.x+guard.pos.x*mult, offset.y+guard.pos.y*mult, size, RED);
int to_end = 0;
switch (guard.dir) {
case HAUT: to_end = guard.pos.y <= guard.end.y; break;
case BAS: to_end = guard.pos.y > guard.end.y; break;
case GAUCHE: to_end = guard.pos.x <= guard.end.x; break;
case DROITE: to_end = guard.pos.x > guard.end.x; break;
}
if (!vec2i_equals(guard.pos, guard.start) && !vec2i_equals(guard.start, player_pos))
DrawText("+", offset.x+guard.start.x*mult, offset.y+guard.start.y*mult, size, !to_end?RED:ORANGE);
if (!vec2i_equals(guard.pos, guard.end) && !vec2i_equals(guard.end, player_pos))
DrawText("+", offset.x+guard.end.x*mult, offset.y+guard.end.y*mult, size, to_end?RED:ORANGE);
}
if (shoot_cooldown > 0) {
int up = shot.up;
int down = shot.down;
int left = shot.left;
int rigth = shot.right;
if (up != player_pos.y) for (int i=player_pos.y-1; i>=up; i--) DrawText("@", offset.x+player_pos.x*mult, offset.y+i*mult, size, ORANGE);
if (down != player_pos.y) for (int i=player_pos.y+1; i<=down; i++) DrawText("@", offset.x+player_pos.x*mult, offset.y+i*mult, size, ORANGE);
if (left != player_pos.x) for (int i=player_pos.x-1; i>=left; i--) DrawText("@", offset.x+i*mult, offset.y+player_pos.y*mult, size, ORANGE);
if (rigth != player_pos.x) for (int i=player_pos.x+1; i<=rigth; i++) DrawText("@", offset.x+i*mult, offset.y+player_pos.y*mult, size, ORANGE);
}
DrawText(TextFormat("Étage %d/%d", etage+1, NB_ETAGE_TOTAL), 10, 10, size/2, RAYWHITE);
DrawText(TextFormat("Timer: %d", (int)(GetTime()-begin_play_time)), 10, 20+size/2, size/2, RAYWHITE);
EndDrawing();
}
}

179
maps.h Normal file
View File

@ -0,0 +1,179 @@
#ifdef RELEASE
int etage = 0;
#else
int etage = 8;
#endif
#define MAP_SIZE_MAX 15
typedef char Map[MAP_SIZE_MAX][MAP_SIZE_MAX];
#define NB_ETAGE_TOTAL 10
Vec2i map_sizes[NB_ETAGE_TOTAL] = {
[0] = {9, 9},
[1] = {9, 9},
[2] = {9, 9},
[3] = {9, 9},
[4] = {9, 9},
[5] = {9, 9},
[6] = {9, 9},
[7] = {9, 9},
[8] = {9, 9},
[9] = {9, 9},
};
Map maps[NB_ETAGE_TOTAL] = {
[0] = {
{' ','P',' ',' ','M',' ',' ','B',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[1] = {
{' ','P',' ',' ',' ',' ',' ','B',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[2] = {
{'M','P',' ',' ','M',' ',' ','B',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[3] = {
{'M','P',' ',' ','M',' ',' ','B',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[4] = {
{'M','P',' ',' ','M',' ',' ','B',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[5] = {
{'M','P',' ',' ','M',' ',' ','B',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[6] = {
{'M','P',' ',' ','M',' ',' ','B',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ',' ',' ',' ',' ',' '},
{'M',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[7] = {
{'M','P',' ',' ','M',' ',' ','B',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ',' ',' ',' ',' ',' '},
{'M',' ',' ',' ',' ',' ',' ',' ',' '},
{'M',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','S',' ',' ',' ',' '},
},
[8] = {
{'M','P',' ',' ','M',' ',' ','B',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ',' ',' ','M',' ',' ',' ',' '},
{'M',' ','G',' ','M',' ','A',' ',' '},
{'M','O','O','O','O','O','O','O','O'},
{'M',' ',' ',' ',' ',' ',' ',' ',' '},
{'M',' ',' ',' ',' ',' ',' ',' ',' '},
{'M',' ',' ',' ','S',' ',' ',' ',' '},
},
[9] = {
{'M','P',' ',' ','O',' ',' ','B',' '},
{'M','M',' ',' ','M',' ',' ',' ',' '},
{'M','M',' ',' ','M',' ',' ',' ',' '},
{'M','M',' ',' ','M',' ',' ',' ',' '},
{'M','M',' ',' ','M',' ',' ',' ',' '},
{'M','M',' ',' ',' ',' ',' ',' ',' '},
{'M','M',' ',' ',' ',' ',' ',' ',' '},
{'M','M',' ',' ',' ',' ',' ',' ',' '},
{'M','M',' ',' ','S',' ',' ',' ',' '},
},
};
// M: mur
// O: mur cassable
// S: joueur
// B: boutton pour ouvrir la porte
// P: porte fermer
// E: porte ouverte
// A: alarme
// G: guarde qui bouge pas
typedef enum Direction {
HAUT, BAS, GAUCHE, DROITE,
} Direction;
typedef struct Guard {
const Vec2i start, end;
Vec2i pos;
Direction dir;
int dead;
} Guard;
#define MAX_GUARD_ETAGE 15
typedef Guard Guards[MAX_GUARD_ETAGE];
Guards guards[NB_ETAGE_TOTAL] = {
[1] = {
{.start = {1,1}, .end = {1,5}},
{.start = {7,2}, .end = {7,6}},
},
[2] = {
{.start = {2,0}, .end = {2,5}},
{.start = {3,1}, .end = {3,6}},
},
[7] = {
{.start = {3,2}, .end = {3,7}},
},
[8] = {
{.start = {1,1}, .end = {1,4}},
{.start = {7,2}, .end = {7,4}},
},
[9] = {
{.start = {3,6}, .end = {7,6}},
},
};

141
winfun.c Normal file
View File

@ -0,0 +1,141 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define NOB_REALLOC realloc
#define NOB_ASSERT assert
// Initial capacity of a dynamic array
#define NOB_DA_INIT_CAP 256
// Append an item to a dynamic array
#define nob_da_append(da, item) \
do { \
if ((da)->count >= (da)->capacity) { \
(da)->capacity = (da)->capacity == 0 ? NOB_DA_INIT_CAP : (da)->capacity*2; \
(da)->items = NOB_REALLOC((da)->items, (da)->capacity*sizeof(*(da)->items)); \
NOB_ASSERT((da)->items != NULL && "Buy more RAM lol"); \
} \
\
(da)->items[(da)->count++] = (item); \
} while (0)
#include "raylib.h"
#include "raymath.h"
#define PLAYER_SPEED 1000
#define REAL_FPS 30
#define TARGET_FPS 480
#define TARGET_DT (1.0/TARGET_FPS)
#define GRAVITY 1000.0f
#define COLLISION_DAMPING 0.8
typedef struct {
Vector2 *items;
size_t count;
size_t capacity;
} Vector2s;
typedef struct {
Color *items;
size_t count;
size_t capacity;
} Colors;
Texture tex_rac;
int win_fun()
{
SetWindowState(FLAG_WINDOW_RESIZABLE);
#ifdef RELEASE
ShowCursor();
EnableCursor();
#endif
#ifdef RELEASE
SetWindowSize(690, 690);
#else
SetWindowSize(1600, 900);
#endif
SetTargetFPS(REAL_FPS);
Vector2s positions = {0};
Vector2s velocities = {0};
Colors colors = {0};
#ifdef RELEASE
#include "assets/raccon-delicieu.h"
Image img_rac = LoadImageFromMemory(".png", raccoon_data, raccoon_size);
tex_rac = LoadTextureFromImage(img_rac);
#else
tex_rac = LoadTexture("assets/raccon-delicieu.png");
#endif
Vector2 prev_winpos = GetWindowPosition();
while (!WindowShouldClose()) {
Vector2 winpos = GetWindowPosition();
Vector2 dwinpos = Vector2Subtract(winpos, prev_winpos);
float w = GetScreenWidth();
float h = GetScreenHeight();
float real_dt = GetFrameTime();
float radius = 40.0f;
BeginDrawing();
ClearBackground(GetColor(0x181818FF));
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
nob_da_append(&positions, GetMousePosition());
float angle = DEG2RAD*GetRandomValue(0, 360);
Vector2 dir = {500*cosf(angle), 500*sinf(angle)};
nob_da_append(&velocities, dir);
nob_da_append(&colors, ColorFromHSV(GetRandomValue(0, 360), 1, 1));
}
for (float t = 0.0; t < real_dt; t += TARGET_DT) {
for (size_t i = 0; i < positions.count; ++i) {
float f = t/real_dt;
positions.items[i] = Vector2Subtract(positions.items[i], Vector2Scale(dwinpos, TARGET_DT/real_dt));
velocities.items[i].y += GRAVITY*TARGET_DT;
float nx = positions.items[i].x + velocities.items[i].x*TARGET_DT;
if (nx - radius <= 0) {
positions.items[i].x = radius;
velocities.items[i].x *= -COLLISION_DAMPING;
velocities.items[i].x += dwinpos.x*TARGET_DT/real_dt*300;
} else if (nx + radius >= w) {
positions.items[i].x = w - radius;
velocities.items[i].x *= -COLLISION_DAMPING;
velocities.items[i].x += dwinpos.x*TARGET_DT/real_dt*300;
} else {
positions.items[i].x = nx;
}
float ny = positions.items[i].y + velocities.items[i].y*TARGET_DT;
if (ny - radius <= 0) {
positions.items[i].y = radius;
velocities.items[i].y *= -COLLISION_DAMPING;
velocities.items[i].y += dwinpos.y*TARGET_DT/real_dt*300;
} else if (ny + radius >= h) {
positions.items[i].y = h - radius;
velocities.items[i].y *= -COLLISION_DAMPING;
velocities.items[i].y += dwinpos.y*TARGET_DT/real_dt*300;
} else {
positions.items[i].y = ny;
}
// DrawRing(positions.items[i], radius*0.8, radius, 0, 360, 100, ColorAlpha(colors.items[i], f));
DrawTexturePro(
tex_rac,
(Rectangle) {0, 0, tex_rac.width, tex_rac.height},
(Rectangle) {positions.items[i].x-radius, positions.items[i].y-radius, radius*2, radius*2},
(Vector2) {0, 0},
0.0f,
ColorAlpha(colors.items[i], f)
);
}
}
EndDrawing();
prev_winpos = winpos;
}
CloseWindow();
return 0;
}