#include <stdlib.h> #include <string> #include <sstream> #include <iostream> #include <SDL/SDL.h> #include <SDL/SDL_image.h> #include <SDL/SDL_ttf.h> #include <time.h> #define N 500 /*snake length*/ #define W 1000 #define NODESIZE 10 /*node height & width*/ #define WINSIZEW 800 #define WINSIZEH 480 typedef enum {Up, Down, Right, Left}TDirection; //Possible directions SDL_Surface* screen = NULL; SDL_Surface* Table[N] = {NULL}; SDL_Surface* blank; SDL_Surface* message = NULL; SDL_Surface* puce; //Snake puce //FONT TTF_Font *font = NULL; SDL_Color textColor = {0, 0, 0}; SDL_Rect Tabpos[N], ppuce, Wallpos[W]; //WALLS SDL_Rect left, right, top, bot; bool running = true; int NodeCounter; int score = 0; TDirection direction; SDL_TimerID timer; Uint32 Anime_it (Uint32, void *); int snakeColl(void); int consoleOutput(const char* text); void initWalls(void); void Quitter(void); //will be executed when exiting void SetPos(void); void MoveSnake(void); void Show(void); void PurgeScreen(void); void SetPuce(void); void Lose(void); void freeNodes(void); void AddNode(void); int main (int argc, char** argv) { Uint32 speed; //game speed SDL_Event event; int done; int i; srand (time(NULL)); i = SDL_Init(SDL_INIT_VIDEO|SDL_DOUBLEBUF|SDL_INIT_TIMER); if (i < 0){ exit(EXIT_FAILURE); } atexit (Quitter); screen = SDL_SetVideoMode(WINSIZEW, WINSIZEH, 16, SDL_HWSURFACE); if (screen == NULL){ exit(EXIT_FAILURE); } SDL_WM_SetCaption("SnakeDL", NULL); //S(nake)DL //Initialisations of fonts if (TTF_Init() == -1) { consoleOutput("Error TTF_Init"); return false; } font = TTF_OpenFont("./data/borgnine.ttf", 28); if (font == NULL) { //consoleOutput(("Error %s", TTF_GetError())); return false; } speed = 80; //done = 1; NodeCounter = 5; direction = Right; initWalls(); Table[0] = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0); SDL_FillRect(Table[0], NULL, SDL_MapRGB(Table[0]->format, 0, 255, 0)); Tabpos[0].x = screen->w/2; Tabpos[0].y = screen->h/2; for (i = 1; i < NodeCounter; i++){ Table[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0); SDL_FillRect (Table[i], NULL, SDL_MapRGB (Table[i]->format, 0, 0, 0)); Tabpos[i].x = Tabpos[i-1].x - NODESIZE; Tabpos[i].y = screen->h/2; } SDL_ShowCursor(0); Show(); SDL_Flip(screen); timer = SDL_AddTimer(1, Anime_it, &speed); SetPuce(); while (running){ SDL_WaitEvent(&event); switch (event.type){ case SDL_QUIT: running = false; break; case SDL_KEYDOWN: switch (event.key.keysym.sym){ case SDLK_w: if (direction != Down) direction = Up; break; case SDLK_s: if (direction != Up) direction = Down; break; case SDLK_d: if (direction != Left) direction = Right; break; case SDLK_a: if (direction != Right) direction = Left; break; case SDLK_u: //INCREASE SPEED if ((speed-5)>0) speed -= 5; break; case SDLK_l: //DECREASE SPEED if ((speed+5)<100) speed += 5; break; case SDLK_q: Quitter(); break; } break; }//SWITCH } //WHILE return 0; } int consoleOutput(const char* text) { using namespace std; cout << text << endl; return 0; } void MoveSnake() { switch (direction){ case Up: if ((Tabpos[0].y - NODESIZE) >= 10) Tabpos[0].y -= NODESIZE; else Lose(); //Tabpos[0].y -= NODESIZE; break; case Down: if ((Tabpos[0].y + NODESIZE) < (screen->h - 10)) Tabpos[0].y += NODESIZE; else Lose(); //Tabpos[0].y += NODESIZE; break; case Right: if ((Tabpos[0].x + NODESIZE) < (screen->w - 10)) Tabpos[0].x += NODESIZE; else Lose(); //Tabpos[0].x += NODESIZE; break; case Left: if ((Tabpos[0].x - NODESIZE) >= 10) Tabpos[0].x -= NODESIZE; else Lose(); //Tabpos[0].x -= NODESIZE; break; } //Incase teleporting from wall to opposite wall instead of loosing game /*if ((Tabpos[0].x == WINSIZEW )) Tabpos[0].x = 0; else if ((Tabpos[0].x == 0)) Tabpos[0].x = WINSIZEW; else if ((Tabpos[0].y == WINSIZEH)) Tabpos[0].y = 0; else if ((Tabpos[0].y == 0)) Tabpos[0].y = WINSIZEH;*/ if ((Tabpos[0].x == ppuce.x) && (Tabpos[0].y == ppuce.y)) { score++; AddNode(); } if (snakeColl()) Lose(); } void SetPos(void) { int i; for (i = (NodeCounter-1); i>0; i--) { Tabpos[i].x = Tabpos[i-1].x; Tabpos[i].y = Tabpos[i-1].y; } } void initWalls(void) { left.x = 0; left.y = 0; left.w = 10; left.h = WINSIZEH; right.x = (WINSIZEW - 10); right.y = 0; right.w = 10; right.h = WINSIZEH; top.x = 10; top.y = 0; top.w = (WINSIZEW - 20); top.h = 10; bot.x = 10; bot.y = (WINSIZEH - 10); bot.w = (WINSIZEW - 20); bot.h = 10; } void Show(void) { int i; int y; char intScore[32]; SDL_Rect msgOffset; for (i=0; i < NodeCounter; i++) SDL_BlitSurface(Table[i], NULL, screen, &Tabpos[i]); SDL_BlitSurface(puce, NULL, screen, &ppuce); SDL_FillRect(screen, &left, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_FillRect(screen, &right, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_FillRect(screen, &top, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_FillRect(screen, &bot, SDL_MapRGB(screen->format, 0, 0, 0)); msgOffset.x = 20; msgOffset.y = (WINSIZEH - 38); sprintf(intScore, "Score: %d", score); message = TTF_RenderText_Solid(font, intScore, textColor); if (message == NULL) { consoleOutput("Error TTF_RenderText_solid in Show()"); } SDL_BlitSurface(message, NULL, screen, &msgOffset); } void Quitter(void) { freeNodes(); SDL_FreeSurface(puce); SDL_FreeSurface(screen); SDL_FreeSurface(message); running = false; SDL_Quit(); } void PurgeScreen(void) { SDL_Rect p; p.x = 0; p.y = 0; blank = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w, screen->h, 16, 0, 0, 0, 0); SDL_FillRect(blank, NULL, SDL_MapRGB(blank->format, 189, 220, 144)); SDL_BlitSurface(blank, NULL, screen, &p); SDL_FreeSurface(blank); } void SetPuce() { int genx, geny, flag = 1, cpt; while (flag) { flag = 0; genx = (rand() % ((WINSIZEW - 10)/10))*NODESIZE; for (cpt=10; cpt < NodeCounter; cpt++) if (genx == Tabpos[cpt].x) { flag = 1; break; } } flag = 1; while (flag) { flag = 0; geny = (rand() % ((WINSIZEH - 10)/10))*NODESIZE; for (cpt=10; cpt < NodeCounter; cpt ++) if (geny == Tabpos[cpt].y) { flag = 1; break; } } puce = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0); SDL_FillRect (puce, NULL, SDL_MapRGB (puce->format, 0, 0, 0)); ppuce.x = genx; ppuce.y = geny; SDL_BlitSurface(puce, NULL, screen, &ppuce); } Uint32 Anime_it(Uint32 interval, void *param) { Uint32 *t = (Uint32*)param; SDL_Delay (*t); MoveSnake(); SetPos(); PurgeScreen(); Show(); SDL_Flip(screen); return interval; } void Lose(void) { SDL_RemoveTimer(timer); //running = false; Quitter(); } void freeNodes(void) { int i; for (i = 0; i < NodeCounter; i++) SDL_FreeSurface(Table[i]); } void AddNode(void) { NodeCounter++; Table[NodeCounter-1] = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0); SDL_FillRect(Table[NodeCounter-1], NULL, SDL_MapRGB (Table[NodeCounter-1]->format, 0, 0, 0)); SetPuce(); } int snakeColl(void) { int i, cl = 0; for (i = 3; i < NodeCounter; i++) if ((Tabpos[0].x == Tabpos[i].x) && (Tabpos[0].y == Tabpos[i].y)) { cl = 1; break; } return cl; }