// enemic.cpp - Implementació d'enemics (ORNIs) // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 #include "game/entities/enemic.hpp" #include "core/rendering/polygon_renderer.hpp" #include "core/rendering/primitives.hpp" #include "game/constants.hpp" #include #include Enemic::Enemic(SDL_Renderer *renderer) : renderer_(renderer) {} void Enemic::inicialitzar() { // Inicialitzar enemic com a pentàgon // Copiat de joc_asteroides.cpp línies 41-54 // Crear pentàgon regular (5 costats, radi 20) crear_poligon_regular(dades_, 5, 20.0f); // Posició aleatòria dins de l'àrea de joc dades_.centre.x = static_cast((std::rand() % 580) + 30); // 30-610 dades_.centre.y = static_cast((std::rand() % 420) + 30); // 30-450 // Angle aleatori dades_.angle = (std::rand() % 360) * Constants::PI / 180.0f; // Està actiu dades_.esta = true; } void Enemic::actualitzar(float delta_time) { if (dades_.esta) { // Moviment autònom mou(delta_time); // Rotació visual (time-based: drotacio està en rad/s) dades_.rotacio += dades_.drotacio * delta_time; } } void Enemic::dibuixar() const { if (dades_.esta) { Rendering::rota_pol(renderer_, dades_, dades_.rotacio, true); } } void Enemic::mou(float delta_time) { // Moviment autònom d'ORNI (enemic pentàgon) // Basat EXACTAMENT en el codi Pascal original: ASTEROID.PAS lines 279-293 // Copiat EXACTAMENT de joc_asteroides.cpp línies 348-394 // // IMPORTANT: El Pascal original NO té canvi aleatori continu! // Només ajusta l'angle quan toca una paret. // Calcular nova posició PROPUESTA (time-based, però lògica Pascal) // velocitat ja està en px/s (40 px/s), multiplicar per delta_time float velocitat_efectiva = dades_.velocitat * delta_time; // Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt) float dy = velocitat_efectiva * std::sin(dades_.angle - Constants::PI / 2.0f); float dx = velocitat_efectiva * std::cos(dades_.angle - Constants::PI / 2.0f); float new_y = dades_.centre.y + dy; float new_x = dades_.centre.x + dx; // Lògica Pascal: Actualitza Y si dins, sinó ajusta angle aleatòriament // if (dy>marge_dalt) and (dy Constants::MARGE_DALT && new_y < Constants::MARGE_BAIX) { dades_.centre.y = new_y; } else { // Pequeño ajuste aleatorio: (random(256)/512)*(random(3)-1) // random(256) = 0..255, /512 = 0..0.498 // random(3) = 0,1,2, -1 = -1,0,1 // Resultado: ±0.5 rad aprox float rand1 = (static_cast(std::rand() % 256) / 512.0f); int rand2 = (std::rand() % 3) - 1; // -1, 0, o 1 dades_.angle += rand1 * static_cast(rand2); } // Lògica Pascal: Actualitza X si dins, sinó ajusta angle aleatòriament // if (dx>marge_esq) and (dx Constants::MARGE_ESQ && new_x < Constants::MARGE_DRET) { dades_.centre.x = new_x; } else { float rand1 = (static_cast(std::rand() % 256) / 512.0f); int rand2 = (std::rand() % 3) - 1; dades_.angle += rand1 * static_cast(rand2); } // Nota: La rotació visual (dades_.rotacio += dades_.drotacio) ja es fa a // actualitzar() }