diff --git a/components/insa/include/ui/ScreenSaver.h b/components/insa/include/ui/ScreenSaver.h index 96db379..57ac697 100644 --- a/components/insa/include/ui/ScreenSaver.h +++ b/components/insa/include/ui/ScreenSaver.h @@ -21,13 +21,13 @@ */ class ScreenSaver final : public Widget { -public: + public: explicit ScreenSaver(menu_options_t *options); void update(uint64_t dt) override; void render() override; void onButtonClicked(ButtonType button) override; -private: + private: /** * @enum VehicleType * @brief Types of available vehicles @@ -57,20 +57,22 @@ private: */ struct Vehicle { - int x; // X position on screen - int y; // Y position on screen - float speed; // Movement speed - VehicleType type; // Type of vehicle + int x; // X position on screen + int y; // Y position on screen + float speed; // Movement speed + VehicleType type; // Type of vehicle Direction direction; // Movement direction - bool active; // Whether a vehicle is currently active + bool active; // Whether a vehicle is currently active }; static constexpr int MAX_LEFT_VEHICLES = 2; static constexpr int MAX_RIGHT_VEHICLES = 2; static constexpr int MAX_VEHICLES = MAX_LEFT_VEHICLES + MAX_RIGHT_VEHICLES; - static constexpr int VEHICLE_SPAWN_DELAY = 1000; // milliseconds + static constexpr int VEHICLE_SPAWN_DELAY = 2500; // milliseconds static constexpr float MIN_SPEED = 1.0f; static constexpr float MAX_SPEED = 2.0f; + static constexpr int MIN_SAME_DIRECTION_DISTANCE = 48; // 32 + 16 pixels + static constexpr int MAX_SAME_DIRECTION_DISTANCE = 64; // 32 + 32 pixels menu_options_t *m_options; uint64_t m_animationCounter; @@ -130,4 +132,11 @@ private: * @return Pointer to bitmap data */ static const unsigned char *getVehicleBitmap(VehicleType type, Direction direction, int &width, int &height); + + /** + * @brief Check if there's enough distance to spawn a vehicle in a specific direction + * @param direction Direction to check + * @return true if spawning is allowed + */ + bool canSpawnInDirection(Direction direction) const; }; \ No newline at end of file diff --git a/components/insa/src/ui/ScreenSaver.cpp b/components/insa/src/ui/ScreenSaver.cpp index aeca286..67a1500 100644 --- a/components/insa/src/ui/ScreenSaver.cpp +++ b/components/insa/src/ui/ScreenSaver.cpp @@ -1,14 +1,10 @@ #include "ui/ScreenSaver.h" -#include #include "data/roads.h" #include "data/vehicles.h" +#include ScreenSaver::ScreenSaver(menu_options_t *options) - : Widget(options->u8g2), - m_options(options), - m_animationCounter(0), - m_lastSpawnTime(0), - m_leftVehicleCount(0), + : Widget(options->u8g2), m_options(options), m_animationCounter(0), m_lastSpawnTime(0), m_leftVehicleCount(0), m_rightVehicleCount(0) { initVehicles(); @@ -82,6 +78,43 @@ void ScreenSaver::update(const uint64_t dt) } } +bool ScreenSaver::canSpawnInDirection(Direction direction) const +{ + // Minimalen Abstand zwischen 48 und 64 Pixel zufällig wählen + int requiredDistance = + MIN_SAME_DIRECTION_DISTANCE + (random() % (MAX_SAME_DIRECTION_DISTANCE - MIN_SAME_DIRECTION_DISTANCE + 1)); + + for (const auto &vehicle : m_vehicles) + { + if (!vehicle.active || vehicle.direction != direction) + continue; + + // Abstand zum nächsten Fahrzeug in gleicher Richtung prüfen + if (direction == Direction::LEFT) + { + // Fahrzeuge fahren von rechts nach links + // Neues Fahrzeug würde bei u8g2->width + 16 starten + int newVehicleX = u8g2->width + 16; + + // Prüfen ob genug Abstand zum existierenden Fahrzeug + if (newVehicleX - vehicle.x < requiredDistance) + return false; + } + else // Direction::RIGHT + { + // Fahrzeuge fahren von links nach rechts + // Neues Fahrzeug würde bei -32 starten + int newVehicleX = -32; + + // Prüfen ob genug Abstand zum existierenden Fahrzeug + if (vehicle.x - newVehicleX < requiredDistance) + return false; + } + } + + return true; +} + void ScreenSaver::trySpawnVehicle() { // Check if we can spawn a new vehicle @@ -115,6 +148,11 @@ void ScreenSaver::trySpawnVehicle() return; } + if (!canSpawnInDirection(direction)) + { + return; + } + // Create new vehicle Vehicle &newVehicle = m_vehicles[availableSlot]; newVehicle.type = getRandomVehicleType(); @@ -185,7 +223,7 @@ void ScreenSaver::render() // Calculate offsets const int roadOffset = (m_animationCounter / 100) % road_horizontal_width; - + // Draw all active vehicles with a scene offset for (const auto &vehicle : m_vehicles) { @@ -234,8 +272,8 @@ void ScreenSaver::drawTransparentBitmap(const int x, const int y, const int widt const int screenX = x + px; // Bounds checking - if (const int screenY = y + py; screenX >= 0 && screenX < u8g2->width && - screenY >= 0 && screenY < u8g2->height) + if (const int screenY = y + py; + screenX >= 0 && screenX < u8g2->width && screenY >= 0 && screenY < u8g2->height) { u8g2_DrawPixel(u8g2, screenX, screenY); }