Renew Projects
This commit is contained in:
155
Huajisheblockade/Snake.cpp
Normal file
155
Huajisheblockade/Snake.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include "Snake.h"
|
||||
#include "SDL3/SDL_oldnames.h"
|
||||
#include "SDL3/SDL_render.h"
|
||||
|
||||
static std::mt19937 gen(static_cast<unsigned int>(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<int> distX(5, maxGridX - 5);
|
||||
std::uniform_int_distribution<int> 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<int> distX(5, maxGridX - 5);
|
||||
std::uniform_int_distribution<int> 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<int> 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<SDL_Point> Snake::GetBody() const {
|
||||
return body;
|
||||
}
|
||||
Reference in New Issue
Block a user