feat: save mechanic and cactus/dino spawn logic

This commit is contained in:
theoleuthardt 2025-03-13 13:23:10 +01:00
parent d5060f7552
commit c7554cbb81
5 changed files with 63 additions and 6 deletions

View file

@ -1,6 +1,6 @@
#include "Cactus.hpp"
Cactus::Cactus(Texture2D texture, float x) : texture(texture) {
Cactus::Cactus(Texture2D texture, float x, float y) : texture(texture) {
rect = {static_cast<float>(x), static_cast<float>(300 - texture.height),
static_cast<float>(texture.width), static_cast<float>(texture.height)};
}
@ -18,5 +18,11 @@ bool Cactus::IsOffScreen() {
}
Rectangle Cactus::GetRect() {
return rect;
float hitboxWidth = texture.width * 0.8f;
float hitboxHeight = texture.height * 0.7f;
float hitboxX = rect.x + (texture.width - hitboxWidth) / 2;
float hitboxY = rect.y + (texture.height - hitboxHeight);
return {hitboxX, hitboxY, hitboxWidth, hitboxHeight};
}

View file

@ -4,7 +4,7 @@
class Cactus {
public:
Cactus(Texture2D texture, float x);
Cactus(Texture2D texture, float x, float y);
void Update();
void Draw();
bool IsOffScreen();

View file

@ -1,7 +1,7 @@
#include "Dino.hpp"
Dino::Dino(Texture2D tex) : texture(tex), velocityY(0), isJumping(false) {
rect = {50.0f, static_cast<float>(300 - texture.height),
rect = {50.0f, static_cast<float>(330 - texture.height),
static_cast<float>(texture.width), static_cast<float>(texture.height)};
}

View file

@ -15,7 +15,9 @@ Game::Game() {
dino = new Dino(dinoTexture);
score = 0;
highscore = 0;
gameOver = false;
cacti.push_back(Cactus(cactusTexture, 800, 330 - cactusTexture.height));
}
Game::~Game() {
@ -27,6 +29,8 @@ Game::~Game() {
}
void Game::Run() {
Load();
while (!WindowShouldClose()) {
Update();
Draw();
@ -41,8 +45,27 @@ void Game::Update() {
dino->Update();
if (GetRandomValue(0, 100) < 2) {
cacti.push_back(Cactus(cactusTexture, 800));
static int frameCounter = 0;
frameCounter++;
int spawnInterval = max(20, 50 - score / 1000);
int spawnChance = max(2, 8 - score / 2500);
if (frameCounter >= spawnInterval) {
frameCounter = 0;
if (GetRandomValue(1, spawnChance) == 1) {
bool canSpawn = true;
for (auto &cactus : cacti) {
if (cactus.GetRect().x > GetScreenWidth() * 2/3) {
canSpawn = false;
break;
}
}
if (canSpawn) {
cacti.push_back(Cactus(cactusTexture, 800, 330 - cactusTexture.height));
}
}
}
for (auto &cactus : cacti) {
@ -68,6 +91,7 @@ void Game::Draw() {
ClearBackground(RAYWHITE);
DrawText(TextFormat("Score: %d", score), 10, 10, 20, BLACK);
DrawText(TextFormat("Highscore: %d", highscore), 10, 30, 20, BLACK);
DrawTexture(groundTexture, 0, 300, WHITE);
if (!gameOver) {
@ -87,6 +111,8 @@ void Game::Draw() {
int exitTextWidth = MeasureText("Press ESC to close the game!", 20);
DrawText("Press ESC to close the game!", GetScreenWidth()/2 - exitTextWidth/2, 210, 20, BLACK);
Save();
}
EndDrawing();
@ -96,8 +122,30 @@ void Game::Reset() {
delete dino;
dino = new Dino(dinoTexture);
cacti.clear();
highscore = max(highscore, score);
score = 0;
gameOver = false;
cacti.push_back(Cactus(cactusTexture, 900, 300 - cactusTexture.height));
}
void Game::Save() {
FILE *file = fopen("save.dat", "wb");
if (file) {
fwrite(&highscore, sizeof(highscore), 1, file);
fclose(file);
} else {
TraceLog(LOG_WARNING, "Failed to save highscore");
}
}
void Game::Load() {
FILE *file = fopen("save.dat", "rb");
if (file) {
fread(&highscore, sizeof(highscore), 1, file);
fclose(file);
} else {
TraceLog(LOG_WARNING, "Failed to load highscore");
}
}
bool Game::CheckCollision(Dino &dino, Cactus &cactus) {

View file

@ -17,6 +17,8 @@ private:
void Update();
void Draw();
void Reset();
void Save();
void Load();
bool CheckCollision(Dino &dino, Cactus &cactus);
Texture2D dinoTexture;
@ -25,6 +27,7 @@ private:
Dino *dino;
vector<Cactus> cacti;
int score;
int highscore;
bool gameOver;
};