diff --git a/src/main.c b/src/main.c index 98d64f90e26ab7f33456b4131dfb1834203604ad..7f236cb8af9220813b07e1e1937b58fbceff86d1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,14 +1,13 @@ #include "raylib.h" #include "snake.h" #include "food.h" -#include "game.h" +#include "obstacle.h" #include <stdlib.h> #include <time.h> #include <stdio.h> typedef enum { MENU, PLAYING, GAME_OVER } GameState; -// Modified FlashScreen to work with main loop void HandleFlashEffect(int *flashFrames, Color *flashColor) { if (*flashFrames > 0) { BeginDrawing(); @@ -18,38 +17,54 @@ void HandleFlashEffect(int *flashFrames, Color *flashColor) { } } +void ResetGame(Snake *snake, Food *food, Obstacle obstacles[], int *score, GameState *state) { + InitSnake(snake); + SpawnFood(food); + InitObstacles(obstacles, MAX_OBSTACLES); + *score = 0; + *state = PLAYING; + + // Spawn initial obstacles + for (int i = 0; i < 5; i++) { // Start with 5 obstacles + SpawnObstacle(obstacles, MAX_OBSTACLES, snake, food); + } +} + int main(void) { InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Snake Game"); SetTargetFPS(10); // Game state management GameState gameState = MENU; - bool startGame = false; int flashFrames = 0; Color flashColor = BLANK; + int score = 0; + int level = 1; // Game components srand(time(NULL)); Snake snake; Food food; + Obstacle obstacles[MAX_OBSTACLES]; + InitSnake(&snake); SpawnFood(&food); - int score = 0; + InitObstacles(obstacles, MAX_OBSTACLES); while (!WindowShouldClose()) { // Handle flash effect first if (flashFrames > 0) { HandleFlashEffect(&flashFrames, &flashColor); - continue; // Skip other logic during flash + continue; } // State machine switch (gameState) { case MENU: if (IsKeyPressed(KEY_ENTER)) { - gameState = PLAYING; + ResetGame(&snake, &food, obstacles, &score, &gameState); flashColor = PURPLE; - flashFrames = 1; // Short green flash when starting + flashFrames = 1; } break; @@ -64,10 +79,16 @@ int main(void) { SpawnFood(&food); flashColor = YELLOW; flashFrames = 1; + + // Every 5 points, add a new obstacle + if (score % 5 == 0) { + SpawnObstacle(obstacles, MAX_OBSTACLES, &snake, &food); + level++; + } } - // Game over check - if (CheckCollision(&snake)) { + // Collision checks + if (CheckCollision(&snake) || CheckObstacleCollision(&snake, obstacles, MAX_OBSTACLES)) { gameState = GAME_OVER; flashColor = RED; flashFrames = 2; @@ -76,8 +97,7 @@ int main(void) { case GAME_OVER: if (IsKeyPressed(KEY_ENTER)) { - ResetGame(&snake, &food, &score, &gameState); - gameState = PLAYING; + ResetGame(&snake, &food, obstacles, &score, &gameState); flashColor = GREEN; flashFrames = 5; } @@ -106,15 +126,20 @@ int main(void) { DrawRectangle(food.position.x * CELL_SIZE, food.position.y * CELL_SIZE, CELL_SIZE, CELL_SIZE, BLUE); + + // Draw obstacles + DrawObstacles(obstacles, MAX_OBSTACLES); - // Draw score - DrawText(TextFormat("Scoreee: %d", score), 10, 10, 20, DARKGRAY); + // Draw score and level + DrawText(TextFormat("Score: %d", score), 10, 10, 20, DARKGRAY); + DrawText(TextFormat("Level: %d", level), 10, 40, 20, DARKGRAY); break; case GAME_OVER: DrawText("GAME OVER!", SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT/2 - 40, 40, RED); - DrawText(TextFormat("Scoreee: %d", score), SCREEN_WIDTH/2 - 60, SCREEN_HEIGHT/2 + 20, 30, DARKGRAY); - DrawText("Press ENTER to yeniden", SCREEN_WIDTH/2 - 140, SCREEN_HEIGHT/2 + 70, 20, GRAY); + DrawText(TextFormat("Score: %d", score), SCREEN_WIDTH/2 - 60, SCREEN_HEIGHT/2 + 20, 30, DARKGRAY); + DrawText(TextFormat("Level: %d", level), SCREEN_WIDTH/2 - 60, SCREEN_HEIGHT/2 + 60, 30, DARKGRAY); + DrawText("Press ENTER to restart", SCREEN_WIDTH/2 - 140, SCREEN_HEIGHT/2 + 110, 20, GRAY); break; } diff --git a/src/obstacle.c b/src/obstacle.c new file mode 100644 index 0000000000000000000000000000000000000000..d09aa0dada85347465093a93bfc69b2338a993e1 --- /dev/null +++ b/src/obstacle.c @@ -0,0 +1,77 @@ +#include "obstacle.h" +#include <stdlib.h> + +void InitObstacles(Obstacle obstacles[], int count) { + for (int i = 0; i < count; i++) { + obstacles[i].active = false; + } +} + +void SpawnObstacle(Obstacle obstacles[], int count, const Snake *snake, const Food *food) { + for (int i = 0; i < count; i++) { + if (!obstacles[i].active) { + Vector2 newPos; + bool validPosition = false; + + // Keep trying until we find a valid position + while (!validPosition) { + validPosition = true; + newPos = (Vector2){ + rand() % (SCREEN_WIDTH / CELL_SIZE), + rand() % (SCREEN_HEIGHT / CELL_SIZE) + }; + + // Check if position overlaps with snake + for (int j = 0; j < snake->length; j++) { + if (newPos.x == snake->segments[j].x && newPos.y == snake->segments[j].y) { + validPosition = false; + break; + } + } + + // Check if position overlaps with food + if (newPos.x == food->position.x && newPos.y == food->position.y) { + validPosition = false; + } + + // Check if position overlaps with other obstacles + for (int j = 0; j < count; j++) { + if (obstacles[j].active && + newPos.x == obstacles[j].position.x && + newPos.y == obstacles[j].position.y) { + validPosition = false; + break; + } + } + } + + obstacles[i].position = newPos; + obstacles[i].active = true; + break; + } + } +} + +void DrawObstacles(const Obstacle obstacles[], int count) { + for (int i = 0; i < count; i++) { + if (obstacles[i].active) { + DrawRectangle( + obstacles[i].position.x * CELL_SIZE, + obstacles[i].position.y * CELL_SIZE, + CELL_SIZE, CELL_SIZE, OBSTACLE_COLOR + ); + } + } +} + +bool CheckObstacleCollision(const Snake *snake, const Obstacle obstacles[], int count) { + Vector2 head = snake->segments[0]; + for (int i = 0; i < count; i++) { + if (obstacles[i].active && + head.x == obstacles[i].position.x && + head.y == obstacles[i].position.y) { + return true; + } + } + return false; +} \ No newline at end of file diff --git a/src/obstacle.h b/src/obstacle.h new file mode 100644 index 0000000000000000000000000000000000000000..d25d24fc93d124e698e690e6d4d8f0d0c58d30ea --- /dev/null +++ b/src/obstacle.h @@ -0,0 +1,19 @@ +#ifndef OBSTACLE_H +#define OBSTACLE_H + +#include "raylib.h" + +#define MAX_OBSTACLES 20 +#define OBSTACLE_COLOR RED + +typedef struct { + Vector2 position; + bool active; +} Obstacle; + +void InitObstacles(Obstacle obstacles[], int count); +void SpawnObstacle(Obstacle obstacles[], int count, const Snake *snake, const Food *food); +void DrawObstacles(const Obstacle obstacles[], int count); +bool CheckObstacleCollision(const Snake *snake, const Obstacle obstacles[], int count); + +#endif \ No newline at end of file