209 lines
6.1 KiB
C++
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;
|
|
}
|