Files
snake-sdl2/main.cpp
Daniel Cortés 08b500f502 First upload
2019-04-16 11:39:56 -04:00

209 lines
6.1 KiB
C++

#include<iostream>
#include<list>
#include<cstdlib>
#include<iostream>
#include<SDL2/SDL.h>
const int WORLD_WIDTH = 240;
const int WORLD_HEIGHT = 160;
const int SCREEN_WIDTH = WORLD_WIDTH * 4;
const int SCREEN_HEIGHT = WORLD_HEIGHT * 4;
const int TILE_SIZE = 10;
Uint32 MS_PER_UPDATE = 100;
SDL_Window *gWindow = nullptr;
SDL_Renderer *gRenderer = nullptr;
bool init() {
if (SDL_Init(SDL_INIT_VIDEO) < 0){
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return false;
}
gWindow = SDL_CreateWindow("Snake", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(gWindow == nullptr) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
return false;
}
gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
if(gRenderer == nullptr) {
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
return false;
}
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
SDL_RenderSetLogicalSize(gRenderer, WORLD_WIDTH, WORLD_HEIGHT);
return true;
}
void close() {
SDL_DestroyWindow(gWindow);
gWindow = nullptr;
SDL_DestroyRenderer(gRenderer);
gRenderer = nullptr;
SDL_Quit();
}
struct body {
int x, y;
};
struct food {
int x, y;
};
void loop() {
Uint32 previous = SDL_GetTicks();
Uint32 lag = 0;
srand((unsigned)time(0));
std::list<body> snake = {{0, 0}, {0, TILE_SIZE}, {0, TILE_SIZE * 2}, {0, TILE_SIZE * 3}};
food f = {TILE_SIZE*10, TILE_SIZE*10};
bool alive = true;
bool quit = false;
bool reset = false;
int move = 0;
SDL_Event e;
while(!quit){
if(reset){
snake = {{0, 0}, {0, TILE_SIZE}, {0, TILE_SIZE * 2}, {0, TILE_SIZE * 3}};
alive = true;
reset = false;
move = 0;
}
Uint32 current = SDL_GetTicks();
Uint32 elapsed = current - previous;
previous = current;
lag += elapsed;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
quit = true;
}
if (e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym) {
case SDLK_LEFT:
if(move != 3)
move = 1;
break;
case SDLK_UP:
if(move != 4)
move = 2;
break;
case SDLK_RIGHT:
if(move != 1)
move = 3;
break;
case SDLK_DOWN:
if(move != 2)
move = 4;
break;
case SDLK_r:
reset = true;
break;
case SDLK_MINUS:
MS_PER_UPDATE += 10;
break;
case SDLK_EQUALS:
MS_PER_UPDATE -= 10;
if(MS_PER_UPDATE <= 0)
MS_PER_UPDATE = 10;
break;
}
}
}
while(lag >= MS_PER_UPDATE){
if(alive){
switch(move){
case 1:
snake.push_front({snake.front().x - TILE_SIZE, snake.front().y});
snake.pop_back();
break;
case 2:
snake.push_front({snake.front().x, snake.front().y - TILE_SIZE});
snake.pop_back();
break;
case 3:
snake.push_front({snake.front().x + TILE_SIZE, snake.front().y});
snake.pop_back();
break;
case 4:
snake.push_front({snake.front().x, snake.front().y + TILE_SIZE});
snake.pop_back();
break;
}
if(snake.front().x > WORLD_WIDTH || snake.front().x < 0){
alive = false;
}else if(snake.front().y > WORLD_HEIGHT || snake.front().y < 0){
alive = false;
}
for(std::list<body>::iterator s = snake.begin(); s != snake.end(); s++) {
if(s != snake.begin() && s->x == snake.front().x && s->y == snake.front().y){
alive = false;
break;
}
}
if(snake.front().x == f.x && snake.front().y == f.y){
snake.push_back({snake.back().x, snake.back().y});
while(true){
f.x = (rand() % (WORLD_WIDTH / TILE_SIZE)) * TILE_SIZE;
f.y = (rand() % (WORLD_HEIGHT / TILE_SIZE)) * TILE_SIZE;
bool intersects = false;
for(auto s: snake){
if(f.x == s.x && f.y == s.y){
intersects = true;
}
}
if(!intersects)
break;
}
}
}
lag -= MS_PER_UPDATE;
}
SDL_RenderClear(gRenderer);
SDL_SetRenderDrawColor(gRenderer, 152, 30, 170, SDL_ALPHA_OPAQUE);
for(auto s: snake){
SDL_Rect snake_rect = {s.x, s.y, TILE_SIZE, TILE_SIZE};
SDL_RenderFillRect(gRenderer, &snake_rect);
}
SDL_SetRenderDrawColor(gRenderer, 239, 11, 95, SDL_ALPHA_OPAQUE);
SDL_Rect food_rect = {f.x, f.y, TILE_SIZE, TILE_SIZE};
SDL_RenderFillRect(gRenderer, &food_rect);
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderPresent(gRenderer);
}
}
int main(int argc, char* args[]){
if(!init()) {
std::cout << "Init Error: " << std::endl;
return 1;
}
loop();
close();
return 0;
}