Last active
April 22, 2018 20:36
-
-
Save wldomiciano/b28fc30450c5aac0e8df21a4910388ed to your computer and use it in GitHub Desktop.
A simple Snake clone implementation in C with SDL 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <SDL2/SDL.h> | |
#define TIMEOUT 150 | |
#define SIZE 25 | |
#define BOARD_COLS 10 | |
#define BOARD_ROWS 10 | |
#define BOARD_SIZE (BOARD_COLS * BOARD_ROWS) | |
int head = 0; | |
int apple = 45; | |
int direction = 1; | |
int tail[BOARD_SIZE] = {0}; | |
int accumulator = 0; | |
int length = 0; | |
int i = 0; | |
bool isDead = false; | |
SDL_Renderer* ctx = NULL; | |
SDL_Window* canvas = NULL; | |
Uint32 previousTicks = 0; | |
void draw(int position, int r, int g, int b) { | |
SDL_Rect rect = {position % BOARD_COLS, position / BOARD_COLS, SIZE, SIZE}; | |
rect.x *= SIZE; | |
rect.y *= SIZE; | |
SDL_SetRenderDrawColor(ctx, r, g, b, SDL_ALPHA_OPAQUE); | |
SDL_RenderFillRect(ctx, &rect); | |
} | |
int random() { | |
return rand() % BOARD_SIZE; | |
} | |
bool isOnLimits() { | |
return (direction == 1 && head % BOARD_COLS == 0) || | |
(direction == -1 && (head + 1) % BOARD_COLS == 0); | |
} | |
bool hasCollisionWithTail(int position) { | |
for (int i = 0; i < length; i++) | |
if (tail[i] == position) return true; | |
return false; | |
} | |
void placeApple() { | |
do apple = random(); | |
while (head == apple || hasCollisionWithTail(apple)); | |
} | |
void setDirection(int dir) { | |
if (dir != -direction || length == 0) | |
direction = dir; | |
} | |
void drawBoard() { | |
for (int i = 0; i < length; ++i) | |
draw(tail[i], 0, 255, 0); | |
draw(head, 0, 0, 255); | |
draw(apple, 255, 0, 0); | |
} | |
void move() { | |
tail[i] = head; | |
head += direction; | |
if (++i >= length) i = 0; | |
if (isOnLimits()) | |
head -= BOARD_COLS * direction; | |
else if (head < 0) | |
head += BOARD_SIZE; | |
else if (head >= BOARD_SIZE) | |
head -= BOARD_SIZE; | |
} | |
void update(int delta) { | |
accumulator += delta; | |
if (accumulator >= TIMEOUT && !isDead) { | |
accumulator = 0; | |
move(); | |
if (head == apple) { | |
placeApple(); | |
tail[length++] = head; | |
} else if (hasCollisionWithTail(head)) isDead = true; | |
} | |
drawBoard(); | |
} | |
int main(int argc, char **argv) { | |
if (SDL_Init(SDL_INIT_VIDEO) < 0) return EXIT_FAILURE; | |
if (SDL_CreateWindowAndRenderer(SIZE * BOARD_COLS, SIZE * BOARD_ROWS, 0, &canvas, &ctx) < 0) return EXIT_FAILURE; | |
while (!SDL_QuitRequested()) { | |
if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_UP]) setDirection(-BOARD_COLS); | |
else if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_DOWN]) setDirection( BOARD_COLS); | |
else if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_LEFT]) setDirection(-1); | |
else if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_RIGHT]) setDirection( 1); | |
SDL_SetRenderDrawColor(ctx, 0, 0, 0, SDL_ALPHA_OPAQUE); | |
SDL_RenderClear(ctx); | |
Uint32 current = SDL_GetTicks(); | |
Uint32 delta = current - previousTicks; | |
previousTicks = current; | |
update(delta); | |
SDL_RenderPresent(ctx); | |
} | |
SDL_DestroyRenderer(ctx); | |
SDL_DestroyWindow(canvas); | |
SDL_Quit(); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment