From 09da191dbe531f21c1d20f626761e01323e2124a Mon Sep 17 00:00:00 2001 From: "leo.muff" <leomuffmail@gmail.com> Date: Mon, 16 Jan 2023 23:43:41 +0100 Subject: [PATCH] gen_food ok, time need fix --- gfx/gfx.c | 107 ++++++++++++++++++++++++++++++++++++++++++ gfx/gfx.h | 42 +++++++++++++++++ main.c | 97 ++++++++++++++++++++++++++++++++++++++ queue/queue_ptr_int.c | 84 +++++++++++++++++++++++++++++++++ queue/queue_ptr_int.h | 39 +++++++++++++++ 5 files changed, 369 insertions(+) create mode 100644 gfx/gfx.c create mode 100644 gfx/gfx.h create mode 100644 main.c create mode 100644 queue/queue_ptr_int.c create mode 100644 queue/queue_ptr_int.h diff --git a/gfx/gfx.c b/gfx/gfx.c new file mode 100644 index 0000000..2f9a5ab --- /dev/null +++ b/gfx/gfx.c @@ -0,0 +1,107 @@ +/// @file gfx.c +/// @author Florent Gluck +/// @date November 6, 2016 +/// Helper routines to render pixels in fullscreen graphic mode. +/// Uses the SDL2 library. + +#include <assert.h> +#include "gfx.h" + +/// Create a fullscreen graphic window. +/// @param title Title of the window. +/// @param width Width of the window in pixels. +/// @param height Height of the window in pixels. +/// @return a pointer to the graphic context or NULL if it failed. +struct gfx_context_t* gfx_create(char *title, uint width, uint height, uint32_t *tab) { + if (SDL_Init(SDL_INIT_VIDEO) != 0) goto error; + SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_MAXIMIZED); + SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0); + SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, width, height); + uint32_t *pixels = tab; + struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t)); + + if (!window || !renderer || !texture || !pixels || !ctxt) goto error; + + ctxt->renderer = renderer; + ctxt->texture = texture; + ctxt->window = window; + ctxt->width = width; + ctxt->height = height; + ctxt->pixels = pixels; + + SDL_ShowCursor(SDL_DISABLE); + //gfx_clear(ctxt, COLOR_BLACK); + return ctxt; + +error: + return NULL; +} + +/// Draw a pixel in the specified graphic context. +/// @param ctxt Graphic context where the pixel is to be drawn. +/// @param x X coordinate of the pixel. +/// @param y Y coordinate of the pixel. +/// @param color Color of the pixel. +void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color) { + if (x < ctxt->width && y < ctxt->height) + ctxt->pixels[ctxt->width*y+x] = color; +} + +/// Get a pixel in the specified graphic context. +/// @param ctxt Graphic context where we want to get the pixel. +/// @param x X coordinate of the pixel. +/// @param y Y coordinate of the pixel. +/// @param color Color of the pixel. +/// @return color at position x, y. +uint32_t gfx_getpixel(struct gfx_context_t *ctxt, int x, int y) { + assert(x >= 0 && x < ctxt->width && y >= 0 && y < ctxt->height); + return ctxt->pixels[ctxt->width*y+x]; +} + +/// Clear the specified graphic context. +/// @param ctxt Graphic context to clear. +/// @param color Color to use. +void gfx_clear(struct gfx_context_t *ctxt, uint32_t color) { + int n = ctxt->width*ctxt->height; + while (n) + ctxt->pixels[--n] = color; +} + +/// Display the graphic context. +/// @param ctxt Graphic context to clear. +void gfx_present(struct gfx_context_t *ctxt) { + SDL_UpdateTexture(ctxt->texture, NULL, ctxt->pixels, ctxt->width*sizeof(uint32_t)); + SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL); + SDL_RenderPresent(ctxt->renderer); +} + +/// Destroy a graphic window. +/// @param ctxt Graphic context of the window to close. +void gfx_destroy(struct gfx_context_t *ctxt) { + SDL_ShowCursor(SDL_ENABLE); + SDL_DestroyTexture(ctxt->texture); + SDL_DestroyRenderer(ctxt->renderer); + SDL_DestroyWindow(ctxt->window); + free(ctxt->pixels); + ctxt->texture = NULL; + ctxt->renderer = NULL; + ctxt->window = NULL; + ctxt->pixels = NULL; + SDL_Quit(); + free(ctxt); +} + +/// If a key was pressed, returns its key code (non blocking call). +/// List of key codes: https://wiki.libsdl.org/SDL_Keycode +/// @return the key that was pressed or 0 if none was pressed. +SDL_Keycode gfx_keypressed() { + SDL_Event event; + if (SDL_PollEvent(&event)) { + if (event.type == SDL_KEYDOWN) + return event.key.keysym.sym; + } + return 0; +} + diff --git a/gfx/gfx.h b/gfx/gfx.h new file mode 100644 index 0000000..c45a399 --- /dev/null +++ b/gfx/gfx.h @@ -0,0 +1,42 @@ +#ifndef _GFX_H_ +#define _GFX_H_ + +#include <stdint.h> +#include <stdbool.h> +#include <SDL2/SDL.h> + +#define MAKE_COLOR(r,g,b) ((uint32_t)b|((uint32_t)g<<8)|((uint32_t)r<<16)) + +#define COLOR_GET_B(color) (color & 0xff) +#define COLOR_GET_G(color) ((color >> 8) & 0xff) +#define COLOR_GET_R(color) ((color >> 16) & 0xff) + +#define COLOR_BLACK 0x00000000 +#define COLOR_RED 0x00FF0000 +#define COLOR_GREEN 0x0000FF00 +#define COLOR_BLUE 0x000000FF +#define COLOR_WHITE 0x00FFFFFF +#define COLOR_YELLOW 0x00FFFF00 + +typedef unsigned int uint; +typedef unsigned long ulong; +typedef unsigned char uchar; + +struct gfx_context_t { + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Texture *texture; + uint32_t *pixels; + int width; + int height; +}; + +extern uint32_t gfx_getpixel(struct gfx_context_t *ctxt, int x, int y); +extern void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color); +extern void gfx_clear(struct gfx_context_t *ctxt, uint32_t color); +extern struct gfx_context_t* gfx_create(char *text, uint width, uint height, uint32_t *tab); +extern void gfx_destroy(struct gfx_context_t *ctxt); +extern void gfx_present(struct gfx_context_t *ctxt); +extern SDL_Keycode gfx_keypressed(); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..c711c88 --- /dev/null +++ b/main.c @@ -0,0 +1,97 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include "gfx/gfx.h" +#include "queue/queue_ptr_int.h" +#include "snake.h" +#define SCREEN_W 500 +#define SCREEN_H 500 + +/* int main(){ + tant que (jeu pas fini){ + lire_clavier (asdw ou esc); + //on bouge et on décide si on a gané mangé perdu + avancer(snake); // et grandir si on mange + gen_nourriture(); + affichage(); + quitter_si_esc; + } +} + */ + + void print_board(board_t board){ + for (int i = 0; i< board.size_y; i++){ + for (int j=0; j< board.size_x; j++){ + if ( board.pixels[board.size_x*i+j] == WALL){ + printf("3"); + } + else if (board.pixels[board.size_x*i+j] == SNAKE){ + printf("1"); + } + else if (board.pixels[board.size_x*i+j] == EMPTY){ + printf("0"); + } + else if (board.pixels[board.size_x*i+j] == FOOD){ + printf("2"); + } + } + printf("\n"); + } + } + + int main(){ + struct timespec start, finish; + int elapsed; // vars for time func + + snake_t snake = create_snake(SCREEN_W, SCREEN_H); + board_t board = create_board(SCREEN_W, SCREEN_H); + + + struct gfx_context_t *ctxt = gfx_create("Snake", SCREEN_W, SCREEN_H, board.pixels); + if (!ctxt) + { + fprintf(stderr, "Graphics initialization failed!\n"); + return EXIT_FAILURE; + } + + game_status_t status; + + + int nb_food = 8; + int sec = 5; + double total_time; + + + while(status != WON && status != LOST){ + clock_gettime(CLOCK_MONOTONIC, &start); + gfx_present(ctxt); + + SDL_Keycode key = gfx_keypressed(); + if (key == SDLK_ESCAPE) + { + break; + } + else if(key == A || key == W || key == S || key == D){ + snake.dir = key; + } + status = move(&snake, &board); + /* print_board(board); + printf("%d\n", queue_count(snake.body)); + printf("debut %d\n", snake.body.debut->coordinates.x); */ + + if (total_time >= sec){ + gen_food(nb_food, &board); + total_time = 0; + } + + // Algorithme de mise à jour d'une frame + clock_gettime(CLOCK_MONOTONIC, &finish); + elapsed = (finish.tv_nsec - start.tv_nsec); + total_time += (finish.tv_sec - start.tv_sec); + usleep(elapsed / 100); + } + gfx_destroy(ctxt); + queue_detruire(&snake.body); + return 0; + } \ No newline at end of file diff --git a/queue/queue_ptr_int.c b/queue/queue_ptr_int.c new file mode 100644 index 0000000..7bfb79f --- /dev/null +++ b/queue/queue_ptr_int.c @@ -0,0 +1,84 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <assert.h> +#include "queue_ptr_int.h" + + +//Creer une nouvelle queue vide +queue queue_creer() { + queue fa; + fa.tete = fa.debut = NULL; + return fa; +} + +coord_t init_coord(int x, int y){ + coord_t coord = {x, y}; + return coord; +} + +//Inserer un élement en début de queue +void queue_inserer(queue* fa,coord_t coord) { + element* elmt = malloc(sizeof(element)); + elmt->coordinates = coord; + elmt->next = NULL; + if (queue_est_vide(*fa)) { + fa->tete = elmt; + } else { + fa->debut->next = elmt; + } + fa->debut = elmt; +} + +//Extraire un élément en tête de queue +coord_t queue_extraire(queue* fa) { + coord_t coord = queue_tete(*fa); + element* elmt = fa->tete; + fa->tete = fa->tete->next; + free(elmt); + if (NULL == fa->tete) { + fa->debut = NULL; + } + return coord; +} + +//Désallouer complètement la queue +void queue_detruire(queue* fa) { + coord_t coord; + while (!queue_est_vide(*fa)) { + coord = queue_extraire(fa); + } + +} + +//Tester si la queue est vide +bool queue_est_vide(queue fa) { + return (NULL == fa.tete && NULL == fa.debut); +} + +//Consulter l'élément en tête de queue +coord_t queue_tete(queue fa) { + assert(!queue_est_vide(fa)); + return fa.tete->coordinates; +} + +//Consulter l'élément en début de queue +coord_t queue_debut(queue fa) { + assert(!queue_est_vide(fa)); + return fa.debut->coordinates; +} + +//Compter le nombre d'éléments de la queue: +int queue_count(queue fa) { + int cnt = 0; + if( fa.tete == NULL){ + return 0; + } + while (NULL != fa.tete->next) { + fa.tete = fa.tete->next; + cnt++; + } + cnt++; + return cnt; +} + diff --git a/queue/queue_ptr_int.h b/queue/queue_ptr_int.h new file mode 100644 index 0000000..7a5d63e --- /dev/null +++ b/queue/queue_ptr_int.h @@ -0,0 +1,39 @@ +/* pour éviter que le précompilateur inclue plusieurs fois le fichier .h */ +#ifndef QUEUE_PTR_INT_H +#define QUEUE_PTR_INT_H +#include <stdbool.h> + +typedef struct _coord { + int x; + int y; +} coord_t; + +/* Utilité du typedef : Element a; <=> struct Element a; */ +typedef struct _element { + coord_t coordinates; + struct _element* next; +} element; + +typedef struct _queue { + element* tete; + element* debut; +} queue; + +coord_t init_coord(int x, int y); +//Créer d'une nouvelle queue vide +queue queue_creer(); +//Désallouer complètement la queue +void queue_detruire(queue* fa); +//Insérer un élement en début de queue +void queue_inserer(queue* fa,coord_t coord); +//Extraire un élément de la queue +coord_t queue_extraire(queue* fa); +//Consulter l'élément en tête de queue +coord_t queue_tete(queue fa); +//Consulter l'élément en début de queue +coord_t queue_debut(queue fa); +//Tester si la queue est vide +bool queue_est_vide(queue fa); +//Compter le nombre d'éléments de la queue: +int queue_count(queue fa); +#endif -- GitLab