#include "Snake.h" #include "SDL3/SDL_oldnames.h" #include "SDL3/SDL_render.h" static std::mt19937 gen(static_cast(std::time(nullptr))); Snake::Snake(int screenWidth, int screenHeight, int segmentSize = 25) { this->segmentSize = segmentSize; int maxGridX = (screenWidth / segmentSize) - 1; int maxGridY = (screenHeight / segmentSize) - 1; std::uniform_int_distribution distX(5, maxGridX - 5); std::uniform_int_distribution distY(5, maxGridY - 5); SDL_Point startPoint = { distX(gen), distY(gen) }; body.clear(); body.push_front(startPoint); RandomizeDirection(); growing = false; } void Snake::Reset(int screenWidth, int screenHeight) { int maxGridX = (screenWidth / segmentSize) - 1; int maxGridY = (screenHeight / segmentSize) - 1; std::uniform_int_distribution distX(5, maxGridX - 5); std::uniform_int_distribution distY(5, maxGridY - 5); SDL_Point startPoint = { distX(gen), distY(gen) }; body.clear(); body.push_front(startPoint); } void Snake::HandleInput(SDL_Keycode key) { switch(key) { case SDLK_UP: if (direction.y != 1) { direction.x = 0; direction.y = -1; } break; case SDLK_DOWN: if (direction.y != -1) { direction.x = 0; direction.y = 1; } break; case SDLK_LEFT: if (direction.x != 1) { direction.x = -1; direction.y = 0; } break; case SDLK_RIGHT: if (direction.x != -1) { direction.x = 1; direction.y = 0; } break; } } void Snake::Update(){ SDL_Point newPoint = {body.front().x + direction.x, body.front().y + direction.y}; body.push_front(newPoint); if(!growing){ body.pop_back(); } else { growing = false; } } void Snake::Render(SDL_Renderer* renderer) { for (size_t i = 0; i < body.size(); ++i) { SDL_FRect rect = { (float)(body[i].x * segmentSize), (float)(body[i].y * segmentSize), (float)segmentSize - 1.0f, (float)segmentSize - 1.0f }; if (i == 0) { SDL_SetRenderDrawColor(renderer, 0, 200, 0, 255); SDL_RenderFillRect(renderer, &rect); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_FRect leftEye = { rect.x + 4, rect.y + 4, 6, 6 }; SDL_FRect rightEye = { rect.x + rect.w - 10, rect.y + 4, 6, 6 }; SDL_RenderFillRect(renderer, &leftEye); SDL_RenderFillRect(renderer, &rightEye); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderPoint(renderer, leftEye.x + 3, leftEye.y + 3); SDL_RenderPoint(renderer, rightEye.x + 3, rightEye.y + 3); } else { SDL_SetRenderDrawColor(renderer, 50, 255, 50, 255); SDL_RenderFillRect(renderer, &rect); } } } void Snake::Grow(){ growing = true; } // Snake.cpp void Snake::RandomizeDirection() { // Define 4 possible directions: Up, Down, Left, Right // Remember: SDL3 Y-axis increases downwards static const SDL_Point directions[] = { {0, -1}, // Up {0, 1}, // Down {-1, 0}, // Left {1, 0} // Right }; std::uniform_int_distribution dist(0, 3); int randomIndex = dist(gen); this->direction = directions[randomIndex]; } bool Snake::CheckCollision(int screenWidth, int screenHeight){ if(body.empty()) return false; SDL_Point head = body.front(); // Boundary Collision (Wall) int gridWidth = screenWidth / segmentSize; int gridHeight = screenHeight / segmentSize; if (head.x < 0 || head.x >= gridWidth || head.y < 0 || head.y >= gridHeight) { return true; } // Self Collision // Start loop from index 1 to skip the head itself for (size_t i = 1; i < body.size(); ++i) { if (head.x == body[i].x && head.y == body[i].y) { return true; // Bit its own tail } } return false; } SDL_Point Snake::GetHeadPos() const{ return body.front(); } std::deque Snake::GetBody() const { return body; }