Files
HuajisheTools/blockade/main-with-innerttf.cpp
2025-12-30 19:59:45 +08:00

205 lines
6.4 KiB
C++

#include "SDL3/SDL_events.h"
#include "SDL3/SDL_render.h"
#include "SDL3/SDL_video.h"
#include "SDL3/SDL.h"
#include "Snake.h"
#include "Apple.h"
#include <cstring>
/*
Compile through this command
g++ main.cpp Snake.cpp Apple.cpp -o Game.exe -I./SDL3-3.3.6/x86_64-w64-mingw32/include -L. -lSDL3
*/
#define winW 800
#define winH 600
using namespace std;
const Uint64 frameDelay = 1000 / 60; // 60 FPS for Rendering
//For Different States
enum GameState {
STATE_MENU,
STATE_PLAYING,
STATE_GAMEOVER
};
GameState currentState = STATE_MENU;
Uint64 initialInterval = 150;
Uint64 moveInterval = initialInterval;
const Uint64 minInterval = 70; // Hardest speed
int score = 0;
// DrawMenu
void DrawMenu(SDL_Renderer* renderer, int _winW, int _winH) {
const char* title = "SNAKE GAME";
const char* hint = "Press any key to Start";
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
int titleX = (_winW - (int)strlen(title) * 8) / 2;
int hintX = (_winW - (int)strlen(hint) * 8) / 2;
SDL_RenderDebugText(renderer, (float)titleX, (float)(winH / 2 - 20), title);
SDL_RenderDebugText(renderer, (float)hintX, (float)(winH / 2 + 20), hint);
}
void DrawGameOver(SDL_Renderer* renderer, int _winW, int _winH, int _score) {
const char* msg = "GAME OVER";
char scoreBuf[64];
sprintf(scoreBuf, "Final Score: %d", _score);
const char* retry = "Press R to Restart";
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
int msgX = (_winW - (int)strlen(msg) * 8) / 2;
SDL_RenderDebugText(renderer, (float)msgX, (float)(_winH / 2 - 40), msg);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
int scoreX = (_winW - (int)strlen(scoreBuf) * 8) / 2;
int retryX = (_winW - (int)strlen(retry) * 8) / 2;
SDL_RenderDebugText(renderer, (float)scoreX, (float)(_winH / 2), scoreBuf);
SDL_RenderDebugText(renderer, (float)retryX, (float)(_winH / 2 + 40), retry);
}
void DrawScore(SDL_Renderer* renderer, int _winW, int _winH, int _score){
char scoreBuf[64];
sprintf(scoreBuf, "Score: %d", _score);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDebugText(renderer, 10.0f, 10.0f, scoreBuf);
}
int main(int argc, char* argv[]) {
bool x = SDL_Init(SDL_INIT_VIDEO);
if(!x){
SDL_Log("SDL Init Error: %s\n", SDL_GetError());
return -1;
}
SDL_Window* mainWindow = SDL_CreateWindow(
"Blockade: Snake Game",
winW, winH,
SDL_WINDOW_RESIZABLE
);
if(!mainWindow){
SDL_Log("SDL Init Window Error: %s\n", SDL_GetError());
return -1;
}
SDL_Renderer* mainRender = SDL_CreateRenderer(mainWindow, nullptr);
if(!mainRender){
SDL_Log("SDL Init Renderer Error: %s\n", SDL_GetError());
return -1;
}
Snake snake(winW, winH, 25);
Apple apple(winW, winH, 25);
Uint64 lastUpdateTime = SDL_GetTicks();
SDL_Event event;
int running = 1;
while(running){
Uint64 frameStart = SDL_GetTicks();
while(SDL_PollEvent(&event)){
if(event.type == SDL_EVENT_QUIT) running = 0;
if (event.type == SDL_EVENT_KEY_DOWN) {
if (event.key.key == SDLK_ESCAPE) running = false;
if (currentState == STATE_MENU) {
currentState = STATE_PLAYING;
}
else if (currentState == STATE_GAMEOVER) {
if (event.key.key == SDLK_R) {
snake.Reset(winW, winH);
apple.Spawn();
score = 0;
moveInterval = initialInterval;
currentState = STATE_PLAYING;
}
}
else if (currentState == STATE_PLAYING) {
snake.HandleInput(event.key.key);
}
}
}
if(currentState == STATE_PLAYING){
Uint64 currentTime = SDL_GetTicks();
if (currentTime - lastUpdateTime >= moveInterval) {
snake.Update();
SDL_Point head = snake.GetHeadPos();
SDL_Point applePos = apple.GetPos();
if (snake.CheckCollision(winW, winH)) {
SDL_Log("Game Over! Restarting...");
currentState = STATE_GAMEOVER;
}
if(head.x == applePos.x && head.y == applePos.y){
snake.Grow();
apple.Spawn();
score += 10;
if(moveInterval > minInterval){
moveInterval -= 5; //Everytime add Speeeeeeeeeeeeeed
}
//Check if Apple is inside the snake
bool collision;
do {
collision = false;
apple.Spawn();
SDL_Point newApplePos = apple.GetPos();
const std::deque<SDL_Point>& segments = snake.GetBody();
for (const auto& segment : segments) {
if (newApplePos.x == segment.x && newApplePos.y == segment.y) {
collision = true;
break;
}
}
} while (collision);
}
lastUpdateTime = currentTime;
}
}
// Rendering
// Clear screen to Black
SDL_SetRenderDrawColor(mainRender, 0, 0, 0, 255);
SDL_RenderClear(mainRender);
if(currentState == STATE_MENU) {
DrawMenu(mainRender, winW, winH);
}
else if(currentState == STATE_PLAYING) {
// Draw Snake
snake.Render(mainRender);
apple.Render(mainRender);
DrawScore(mainRender, winW, winH, score);
}
else if(currentState == STATE_GAMEOVER) {
DrawGameOver(mainRender, winW, winH, score);
}
// Present the backbuffer
SDL_RenderPresent(mainRender);
// Control FPS (Cap at 60 FPS)
Uint64 frameTime = SDL_GetTicks() - frameStart;
if (frameTime < frameDelay) {
SDL_Delay((Uint32)(frameDelay - frameTime));
}
}
// Cleanup
SDL_DestroyRenderer(mainRender);
SDL_DestroyWindow(mainWindow);
SDL_Quit();
return 0;
}