2025-06-03 09:27:07 +02:00
|
|
|
#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
|
2025-06-07 13:17:02 +02:00
|
|
|
Vector2 window = {900, 800};
|
2025-06-03 09:27:07 +02:00
|
|
|
#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];
|
2025-06-05 14:42:49 +02:00
|
|
|
memcpy(map, maps[etage], MAP_SIZE_MAX*MAP_SIZE_MAX);
|
2025-06-03 09:27:07 +02:00
|
|
|
|
|
|
|
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;
|
2025-06-10 23:19:47 +02:00
|
|
|
case 'P': case 'E':
|
|
|
|
killed = 1;
|
|
|
|
break;
|
2025-06-03 09:27:07 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2025-06-07 13:17:02 +02:00
|
|
|
if (alarme_sonne > 0 && etage < NB_ETAGE_TOTAL) {
|
2025-06-03 09:27:07 +02:00
|
|
|
alarme_sonne -= GetFrameTime();
|
|
|
|
load_map(&map, &map_size, etage); // NOTE: memcpy pendant 1.2s mais flemme
|
|
|
|
draw_alarme_lose();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2025-06-07 13:17:02 +02:00
|
|
|
if (player_dead > 0 && etage < NB_ETAGE_TOTAL) {
|
2025-06-03 09:27:07 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2025-06-03 12:47:41 +02:00
|
|
|
if (IsKeyDown(KEY_LEFT_SHIFT) && IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_E)) etage = NB_ETAGE_TOTAL + 69;
|
|
|
|
|
2025-06-03 09:27:07 +02:00
|
|
|
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++) {
|
2025-06-10 23:19:47 +02:00
|
|
|
if (map[i][x] != ' ') {
|
2025-06-03 09:27:07 +02:00
|
|
|
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++) {
|
2025-06-10 23:19:47 +02:00
|
|
|
if (map[y][i] != ' ') {
|
2025-06-03 09:27:07 +02:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|