Advertisement
PolyCreativity

SDL2 Snake Game Example

Jan 1st, 2024 (edited)
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.01 KB | Gaming | 0 0
  1. #include "SDL.h"
  2. #include <stdio.h>
  3.  
  4.  
  5. #define TILE_WIDTH          12
  6. #define TILE_HEIGHT         12
  7. #define SCREEN_WIDTH        960
  8. #define SCREEN_HEIGHT       720
  9. #define FEILD_WIDTH         (SCREEN_WIDTH / TILE_WIDTH)
  10. #define FEILD_HEIGHT        (SCREEN_HEIGHT / TILE_HEIGHT)
  11.  
  12.  
  13. #define FPS 30
  14.  
  15.  
  16. SDL_Window* window;
  17. SDL_Renderer* renderer;
  18. SDL_Event current_event;
  19.  
  20. void cleanup(int, const char* , ...);
  21.  
  22. int** tiles;
  23. int snake_x = FEILD_WIDTH / 2;
  24. int snake_y = FEILD_HEIGHT / 2;
  25. int snake_length = 4;
  26.  
  27. unsigned int counter = 0;
  28.  
  29.  
  30.  
  31. int snake_counter = 0;
  32. int snake_speed = FPS*2;
  33. int snake_grow = 10;
  34.  
  35. #define SNAKE_DIRECTION_NONE    0
  36. #define SNAKE_DIRECTION_UP      1
  37. #define SNAKE_DIRECTION_DOWN    2
  38. #define SNAKE_DIRECTION_LEFT    3
  39. #define SNAKE_DIRECTION_RIGHT   4
  40.  
  41. int snake_direction = SNAKE_DIRECTION_NONE;
  42. int next_direction = SNAKE_DIRECTION_LEFT;
  43.  
  44. #include <stdlib.h>
  45. void spawn_new_food() {
  46.     int food_x = 0;
  47.     int food_y = 0;
  48.     do {
  49.         food_x = rand() % FEILD_WIDTH;
  50.         food_y = rand() % FEILD_HEIGHT;
  51.     } while (tiles[food_y][food_x] != 0);
  52.  
  53.     tiles[food_y][food_x] = -1;
  54.  
  55. }
  56.  
  57. void update_game() {
  58.  
  59.     snake_counter--;
  60.  
  61.     if (snake_counter <= 0) {
  62.         snake_counter += snake_speed;
  63.  
  64.         if (next_direction != snake_direction) {
  65.             snake_direction = next_direction;
  66.         }
  67.  
  68.         switch (snake_direction) {
  69.         case SNAKE_DIRECTION_UP:
  70.             snake_y--;
  71.             break;
  72.         case SNAKE_DIRECTION_DOWN:
  73.             snake_y++;
  74.             break;
  75.         case SNAKE_DIRECTION_LEFT:
  76.             snake_x--;
  77.             break;
  78.         case SNAKE_DIRECTION_RIGHT:
  79.             snake_x++;
  80.             break;
  81.  
  82.         }
  83.         if (snake_x < 0 || snake_y < 0 || snake_x >= FEILD_WIDTH || snake_y >= FEILD_HEIGHT) {
  84.             cleanup(0, "You died\n");
  85.         }
  86.         for (int y = 0; y < FEILD_HEIGHT; y++) {
  87.             for (int x = 0; x < FEILD_WIDTH; x++) {
  88.                 if (tiles[y][x] > 0) tiles[y][x]--;
  89.             }
  90.         }
  91.         int tile = tiles[snake_y][snake_x];
  92.         if (tile == -1) {
  93.             snake_length += snake_grow;
  94.             spawn_new_food();
  95.         }
  96.         if (tile > 0) {
  97.             cleanup(0, "You died\n");
  98.         }
  99.  
  100.         tiles[snake_y][snake_x] = snake_length;
  101.  
  102.  
  103.     }
  104.  
  105.  
  106. }
  107. void draw_game() {
  108.  
  109.     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
  110.     SDL_RenderClear(renderer);
  111.     SDL_SetRenderDrawColor(renderer, 192, 192, 0, 255);
  112.     for (int y = 0; y < FEILD_HEIGHT; y++) {
  113.         for (int x = 0; x < FEILD_WIDTH; x++) {
  114.             int tile = tiles[y][x];
  115.             if (tile > 0) {
  116.                 SDL_Rect r = { x * TILE_WIDTH,y * TILE_HEIGHT,TILE_WIDTH,TILE_HEIGHT };
  117.                 SDL_RenderFillRect(renderer, &r);
  118.             }
  119.             else if (tile == -1) {
  120.                 SDL_SetRenderDrawColor(renderer, 192, 128, 128, 255);
  121.                 SDL_Rect r = { x * TILE_WIDTH,y * TILE_HEIGHT,TILE_WIDTH,TILE_HEIGHT };
  122.                 SDL_RenderFillRect(renderer, &r);
  123.                 SDL_SetRenderDrawColor(renderer, 192, 192, 0, 255);
  124.             }
  125.         }
  126.     }
  127.     SDL_RenderPresent(renderer);
  128. }
  129.  
  130.  
  131. Uint32 tick(Uint32 interval, void* name) {
  132.     counter++;
  133.     return 1;
  134. }
  135.  
  136. void setup()
  137. {
  138.     window = SDL_CreateWindow("Snake Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
  139.     if (window == NULL) cleanup(1, "Could not init window\n");
  140.     renderer = SDL_CreateRenderer(window, -1, 0);
  141.     if (renderer == NULL) cleanup(1,"Could not init renderer\n");
  142.  
  143.     SDL_AddTimer(1000. / FPS, &tick, NULL);
  144.  
  145.     //allocate the play field
  146.     tiles = (int**)SDL_malloc(sizeof(int*) * FEILD_HEIGHT);
  147.     if (tiles == NULL) cleanup(1, "Ran out of memory allocating tiles\n");
  148.     for (int y = 0; y < FEILD_HEIGHT; y++) {
  149.         tiles[y] = (int *)SDL_malloc(sizeof(int) * FEILD_WIDTH);
  150.         if (tiles[y] == NULL) cleanup(1, "Ran out of memory allocating tiles\n");
  151.         for (int x = 0; x < FEILD_WIDTH; x++) {
  152.             tiles[y][x] = 0;
  153.         }
  154.     }
  155.     spawn_new_food();
  156.  
  157.  
  158.  
  159. }
  160. void cleanup(int code = 0, const char *message = NULL, ... ) {
  161.  
  162.     if (message != NULL) {
  163.         va_list args;
  164.         va_start(args, message);
  165.         vprintf(message, args);
  166.         va_end(args);
  167.     }
  168.  
  169.     //Unallocate our play field
  170.     if (tiles != NULL) {
  171.         for (int y = 0; y < FEILD_HEIGHT; y++) {
  172.             if (tiles[y] != NULL) SDL_free(tiles[y]);          
  173.         }
  174.         SDL_free(tiles);
  175.     }
  176.     if (renderer != NULL) SDL_DestroyRenderer(renderer);
  177.     if (window != NULL) SDL_DestroyWindow(window);
  178.     exit(code);
  179.  
  180. }
  181.  
  182.  
  183. void game_loop() {
  184.  
  185.     while (true) {
  186.         if (SDL_PollEvent(&current_event)) {
  187.             switch (current_event.type) {
  188.             case SDL_QUIT:
  189.                 cleanup(0);
  190.                 break;
  191.             case SDL_KEYDOWN:
  192.                 switch (current_event.key.keysym.sym) {
  193.                 case SDLK_UP:
  194.                     if (snake_direction != SNAKE_DIRECTION_DOWN) {
  195.  
  196.                         next_direction = SNAKE_DIRECTION_UP;
  197.                     }
  198.                     break;
  199.                 case SDLK_DOWN:
  200.                     if (snake_direction != SNAKE_DIRECTION_UP) {
  201.                         next_direction = SNAKE_DIRECTION_DOWN;
  202.                     }
  203.                     break;
  204.                 case SDLK_LEFT:
  205.                     if (snake_direction != SNAKE_DIRECTION_RIGHT) {
  206.                         next_direction = SNAKE_DIRECTION_LEFT;
  207.                     }
  208.                     break;
  209.                 case SDLK_RIGHT:
  210.                     if (snake_direction != SNAKE_DIRECTION_LEFT) {
  211.                         next_direction = SNAKE_DIRECTION_RIGHT;
  212.                     }
  213.                     break;
  214.  
  215.                 }
  216.                 break;
  217.             }
  218.         }
  219.  
  220.         while (counter > 0) {
  221.             update_game();
  222.             counter--;
  223.         }
  224.  
  225.         draw_game();
  226.  
  227.     }
  228.  
  229. }
  230. int main(int argc, char* argv[])
  231. {
  232.  
  233.     setup();
  234.     game_loop();
  235.     return 0;
  236. }
  237.  
Tags: SDL sdl2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement