snek time
This commit is contained in:
228
snake/snek.c
Normal file
228
snake/snek.c
Normal file
@@ -0,0 +1,228 @@
|
||||
#include <raylib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* typedef struct map_t { */
|
||||
|
||||
/* } Map; */
|
||||
|
||||
const int screenHeight = 800;
|
||||
const int screenWidth = 800;
|
||||
int fps = 60;
|
||||
int rows = 10;
|
||||
int cols = 10;
|
||||
int size;
|
||||
int food_x;
|
||||
int food_y;
|
||||
int score = 0;
|
||||
char score_text[16] = "0";
|
||||
|
||||
typedef enum directions {
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
RIGHT
|
||||
} Direction;
|
||||
|
||||
typedef struct snake_body {
|
||||
int x;
|
||||
int y;
|
||||
} SnakeBody;
|
||||
|
||||
typedef struct snake_t {
|
||||
SnakeBody *body;
|
||||
int max_length;
|
||||
int length;
|
||||
int direction;
|
||||
int frame_duration;
|
||||
bool alive;
|
||||
} Snake;
|
||||
|
||||
Snake make_snake(int max_len, int speed){
|
||||
Snake snek;
|
||||
if (max_len < 3){
|
||||
snek.alive = false;
|
||||
snek.length = 0;
|
||||
return snek;
|
||||
}
|
||||
|
||||
snek.body = (SnakeBody*) calloc(max_len, sizeof(SnakeBody));
|
||||
snek.max_length = max_len;
|
||||
snek.length = 3;
|
||||
snek.body[0].x = GetRandomValue(0, cols - 1);
|
||||
snek.body[0].y = GetRandomValue(0, rows - 1);
|
||||
snek.frame_duration = fps / speed;
|
||||
snek.direction = snek.body[0].x < cols / 2 ? RIGHT : LEFT;
|
||||
snek.alive = true;
|
||||
snek.body[1] = snek.body[2] = snek.body[0];
|
||||
snek.body[1].x += snek.direction == LEFT ? 1 : -1;
|
||||
snek.body[2].x += snek.direction == LEFT ? 2 : -2;
|
||||
return snek;
|
||||
}
|
||||
|
||||
void free_snake(Snake* s){
|
||||
free(s->body);
|
||||
}
|
||||
|
||||
void grow_snake(Snake* s){
|
||||
int i = s->length;
|
||||
if (i < s->max_length){
|
||||
s->body[i] = (SnakeBody) {
|
||||
2 * s->body[i - 1].x - s->body[i - 2].x,
|
||||
2 * s->body[i - 1].y - s->body[i - 2].y
|
||||
};
|
||||
|
||||
s->length++;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_snake(Snake* s){
|
||||
for (int i = 0; i < s->length; i++){
|
||||
DrawRectangle(size * s->body[i].x, size * s->body[i].y, size, size, BLACK);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
bool collides_with_snake(Snake* s, int x, int y){
|
||||
for (int i = 0; i < s->length; i++){
|
||||
if (s->body[i].x == x && s->body[i].y == y){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void place_food(Snake* s){
|
||||
do {
|
||||
food_x = GetRandomValue(0, cols - 1);
|
||||
food_y = GetRandomValue(0, rows - 1);
|
||||
} while (collides_with_snake(s, food_x, food_y));
|
||||
}
|
||||
|
||||
void move_snake(Snake* s){
|
||||
SnakeBody temp1 = s->body[0];
|
||||
SnakeBody temp2;
|
||||
switch (s->direction){
|
||||
case LEFT:
|
||||
s->body[0].x--;
|
||||
if (s->body[0].x < 0 || s->body[0].x >= cols){
|
||||
s->alive = false;
|
||||
}
|
||||
break;
|
||||
case RIGHT:
|
||||
s->body[0].x++;
|
||||
if (s->body[0].x < 0 || s->body[0].x >= cols){
|
||||
s->alive = false;
|
||||
}
|
||||
break;
|
||||
case UP:
|
||||
s->body[0].y--;
|
||||
if (s->body[0].y < 0 || s->body[0].y >= rows){
|
||||
s->alive = false;
|
||||
}
|
||||
break;
|
||||
case DOWN:
|
||||
s->body[0].y++;
|
||||
if (s->body[0].x < 0 || s->body[0].y >= rows){
|
||||
s->alive = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (int i = 1; i < s->length; i++){
|
||||
if (s->body[0].x == s->body[i].x &&
|
||||
s->body[0].y == s->body[i].y){
|
||||
s->alive = false;
|
||||
break;
|
||||
}
|
||||
temp2 = s->body[i];
|
||||
s->body[i] = temp1;
|
||||
temp1 = temp2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* int frame = 0; */
|
||||
void update_snake(Snake* s){
|
||||
static int frame = 0;
|
||||
if (frame++ > s->frame_duration){
|
||||
move_snake(s);
|
||||
frame = 0;
|
||||
}
|
||||
int key;
|
||||
while ((key = GetKeyPressed()) != 0){
|
||||
switch (key){
|
||||
case KEY_W:
|
||||
s->direction = UP;
|
||||
break;
|
||||
case KEY_A:
|
||||
s->direction = LEFT;
|
||||
break;
|
||||
case KEY_S:
|
||||
s->direction = DOWN;
|
||||
break;
|
||||
case KEY_D:
|
||||
s->direction = RIGHT;
|
||||
break;
|
||||
case KEY_G:
|
||||
grow_snake(s);
|
||||
}
|
||||
}
|
||||
if (collides_with_snake(s, food_x, food_y)){
|
||||
food_x = food_y = -1;
|
||||
score++;
|
||||
snprintf(score_text, 16, "%d", score);
|
||||
grow_snake(s);
|
||||
place_food(s);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_grid(int size){
|
||||
/* DrawGrid(10, screenWidth / 10); */
|
||||
|
||||
for (int i = 0; i < rows; i++){
|
||||
DrawLine(0, i * size, screenWidth, i * size, BLACK);
|
||||
}
|
||||
for (int j = 0; j < cols; j++){
|
||||
DrawLine(j * size, 0, j * size, screenHeight, BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
void init_game(){
|
||||
InitWindow(screenHeight, screenHeight, "Snek");
|
||||
SetTargetFPS(fps);
|
||||
|
||||
int width = screenWidth / cols;
|
||||
int height = screenHeight / rows;
|
||||
size = height > width ? width : height;
|
||||
}
|
||||
|
||||
int main(void){
|
||||
|
||||
init_game();
|
||||
Snake snek = make_snake(100, 5);
|
||||
|
||||
while (!WindowShouldClose()){
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(WHITE);
|
||||
draw_grid(size);
|
||||
if (snek.alive){
|
||||
update_snake(&snek);
|
||||
} else {
|
||||
DrawText("Died!", screenWidth / 2, screenHeight / 2, 20, BLACK);
|
||||
}
|
||||
if (food_x >= 0){
|
||||
DrawRectangle(size * food_x, size * food_y, size, size, RED);
|
||||
}
|
||||
draw_snake(&snek);
|
||||
DrawText(score_text, 0, 0, 20, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
free_snake(&snek);
|
||||
|
||||
CloseWindow();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user