-
Taha Belkhiri authoredTaha Belkhiri authored
snakes.c 8.04 KiB
#include <SDL2/SDL.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#define NB_BLOCS 4
#define NB_SNAKES 10
typedef struct bloc {
int p1[2];
int p2[2];
int p3[2];
int p4[2];
} bloc_t;
typedef struct snake {
bloc_t * blocs[NB_BLOCS];
} snake_t;
int running = 1;
void end_sdl(char ok,
char const* msg,
SDL_Window* window,
SDL_Renderer* renderer) {
char msg_formated[255];
int l;
if (!ok) {
strncpy(msg_formated, msg, 250);
l = strlen(msg_formated);
strcpy(msg_formated + l, " : %s\n");
SDL_Log(msg_formated, SDL_GetError());
}
if (renderer != NULL) {
SDL_DestroyRenderer(renderer);
renderer = NULL;
}
if (window != NULL) {
SDL_DestroyWindow(window);
window= NULL;
}
SDL_Quit();
if (!ok) {
exit(EXIT_FAILURE);
}
}
void draw_snake(SDL_Renderer* renderer, snake_t * Snake_to_draw) {
for (int i = 0; i < NB_BLOCS; i++) {
SDL_SetRenderDrawColor(renderer, rand() % 255, rand() % 255, rand() % 255, 255);
SDL_RenderDrawLine(renderer, Snake_to_draw->blocs[i]->p1[0], Snake_to_draw->blocs[i]->p1[1], Snake_to_draw->blocs[i]->p2[0], Snake_to_draw->blocs[i]->p2[1]);
SDL_RenderDrawLine(renderer, Snake_to_draw->blocs[i]->p2[0], Snake_to_draw->blocs[i]->p2[1], Snake_to_draw->blocs[i]->p3[0], Snake_to_draw->blocs[i]->p3[1]);
SDL_RenderDrawLine(renderer, Snake_to_draw->blocs[i]->p3[0], Snake_to_draw->blocs[i]->p3[1], Snake_to_draw->blocs[i]->p4[0], Snake_to_draw->blocs[i]->p4[1]);
SDL_RenderDrawLine(renderer, Snake_to_draw->blocs[i]->p4[0], Snake_to_draw->blocs[i]->p4[1], Snake_to_draw->blocs[i]->p1[0], Snake_to_draw->blocs[i]->p1[1]);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
}
}
snake_t * init_snake(int x, int y, int h, int w) {
snake_t * snake = malloc(sizeof(snake_t));
for (int i = 0; i < NB_BLOCS; i++) {
snake->blocs[i] = malloc(sizeof(bloc_t));
if (i == 0){
snake->blocs[i]->p1[0] = x;
snake->blocs[i]->p1[1] = y;
snake->blocs[i]->p2[0] = x;
snake->blocs[i]->p2[1] = y+h;
snake->blocs[i]->p3[0] = x+w;
snake->blocs[i]->p3[1] = y+h;
snake->blocs[i]->p4[0] = x+w;
snake->blocs[i]->p4[1] = y;
}
else {
snake->blocs[i]->p1[0] = snake->blocs[i-1]->p2[0];
snake->blocs[i]->p1[1] = snake->blocs[i-1]->p2[1];
snake->blocs[i]->p2[0] = snake->blocs[i]->p1[0];
snake->blocs[i]->p2[1] = snake->blocs[i]->p1[1] + h/(i+2);
snake->blocs[i]->p4[0] = snake->blocs[i-1]->p3[0];
snake->blocs[i]->p4[1] = snake->blocs[i-1]->p3[1];
snake->blocs[i]->p3[0] = snake->blocs[i]->p4[0];
snake->blocs[i]->p3[1] = snake->blocs[i]->p4[1] + h/(i+2);
}
}
return snake;
}
void rotate_bloc(float angle, bloc_t * bloc){
float x1 = bloc->p1[0];
float y1 = bloc->p1[1];
float x2 = bloc->p2[0];
float y2 = bloc->p2[1];
float x3 = bloc->p3[0];
float y3 = bloc->p3[1];
float x4 = bloc->p4[0];
float y4 = bloc->p4[1];
// middle is center of rotation
float middle_x = (x1 + x4)/2;
float middle_y = (y1 + y4)/2;
float x1_new = x1 - middle_x;
float y1_new = y1 - middle_y;
float x2_new = x2 - middle_x;
float y2_new = y2 - middle_y;
float x3_new = x3 - middle_x;
float y3_new = y3 - middle_y;
float x4_new = x4 - middle_x;
float y4_new = y4 - middle_y;
// rotate
x1_new = x1_new * cos(angle) - y1_new * sin(angle);
y1_new = x1_new * sin(angle) + y1_new * cos(angle);
x2_new = x2_new * cos(angle) - y2_new * sin(angle);
y2_new = x2_new * sin(angle) + y2_new * cos(angle);
x3_new = x3_new * cos(angle) - y3_new * sin(angle);
y3_new = x3_new * sin(angle) + y3_new * cos(angle);
x4_new = x4_new * cos(angle) - y4_new * sin(angle);
y4_new = x4_new * sin(angle) + y4_new * cos(angle);
// move back
x1_new = x1_new + middle_x;
y1_new = y1_new + middle_y;
x2_new = x2_new + middle_x;
y2_new = y2_new + middle_y;
x3_new = x3_new + middle_x;
y3_new = y3_new + middle_y;
x4_new = x4_new + middle_x;
y4_new = y4_new + middle_y;
// assign new values
bloc->p1[0] = x1_new;
bloc->p1[1] = y1_new;
bloc->p2[0] = x2_new;
bloc->p2[1] = y2_new;
bloc->p3[0] = x3_new;
bloc->p3[1] = y3_new;
bloc->p4[0] = x4_new;
bloc->p4[1] = y4_new;
}
float random_angle_radian() {
return (float)rand() / (float)RAND_MAX * 2 * M_PI;
}
void move_bloc(int x, int y, bloc_t * bloc){
bloc->p1[0] += x;
bloc->p1[1] += y;
bloc->p2[0] += x;
bloc->p2[1] += y;
bloc->p3[0] += x;
bloc->p3[1] += y;
bloc->p4[0] += x;
bloc->p4[1] += y;
}
void move_snake(int x, int y, snake_t * snake){
for (int i = NB_BLOCS-1; i >= 0; i--) {
move_bloc(x, y, snake->blocs[i]);
}
}
void rotate_snake(float angle, snake_t * snake) {
for (int i = 0; i < NB_BLOCS; i++) {
if (i == 0){
rotate_bloc(angle, snake->blocs[i]);
}
else {
rotate_bloc(angle, snake->blocs[i]);
snake->blocs[i]->p1[0] = snake->blocs[i-1]->p2[0];
snake->blocs[i]->p1[1] = snake->blocs[i-1]->p2[1];
snake->blocs[i]->p4[0] = snake->blocs[i-1]->p3[0];
snake->blocs[i]->p4[1] = snake->blocs[i-1]->p3[1];
}
}
}
int main(int argc, char** argv) {
(void)argc;
(void)argv;
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_DisplayMode screen;
/*********************************************************************************************************************/
/* Initialisation de la SDL + gestion de l'échec possible */
if (SDL_Init(SDL_INIT_VIDEO) != 0) end_sdl(0, "ERROR SDL INIT", window, renderer);
SDL_GetCurrentDisplayMode(0, &screen);
printf("Résolution écran\n\tw : %d\n\th : %d\n",
screen.w, screen.h);
/* Création de la fenêtre */
window = SDL_CreateWindow("Premier dessin",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, screen.w,
screen.h,
SDL_WINDOW_OPENGL);
if (window == NULL) end_sdl(0, "ERROR WINDOW CREATION", window, renderer);
/* Création du renderer */
renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL) end_sdl(0, "ERROR RENDERER CREATION", window, renderer);
snake_t * snakeList[NB_SNAKES];
for (int i = 0; i < NB_SNAKES; i++) {
// random int between 0 and WIDTH
snakeList[i] = init_snake(rand()%screen.w, rand()%screen.h, rand()%200, rand()%50);
}
for (int i=0; i< 50; i++){
for (int j=0; j<NB_SNAKES; j++){
float angle = 0.2 * pow(-1, 1 + rand()%2);
rotate_snake(angle, snakeList[j]);
move_snake(rand()%10, rand()%10, snakeList[j]);
draw_snake(renderer, snakeList[j]);
}
SDL_RenderPresent(renderer);
SDL_Delay(100);
SDL_RenderClear(renderer);
}
/* on referme proprement la SDL */
end_sdl(1, "Normal ending", window, renderer);
return EXIT_SUCCESS;
}