// bala.cpp - Implementació de projectils de la nau // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 #include "game/entities/bala.hpp" #include #include #include #include "core/audio/audio.hpp" #include "core/defaults.hpp" #include "core/graphics/shape_loader.hpp" #include "core/rendering/shape_renderer.hpp" #include "game/constants.hpp" Bala::Bala(SDL_Renderer* renderer) : renderer_(renderer), centre_({.x = 0.0F, .y = 0.0F}), angle_(0.0F), velocitat_(0.0F), esta_(false), grace_timer_(0.0F), brightness_(Defaults::Brightness::BALA) { // [NUEVO] Carregar forma compartida des de fitxer forma_ = Graphics::ShapeLoader::load("bullet.shp"); if (!forma_ || !forma_->es_valida()) { std::cerr << "[Bala] Error: no s'ha pogut carregar bullet.shp" << std::endl; } } void Bala::inicialitzar() { // Inicialment inactiva esta_ = false; centre_ = {.x = 0.0F, .y = 0.0F}; angle_ = 0.0F; velocitat_ = 0.0F; grace_timer_ = 0.0F; } void Bala::disparar(const Punt& posicio, float angle, uint8_t owner_id) { // Activar bala i posicionar-la a la nau // Basat en joc_asteroides.cpp línies 188-200 // Activar bala esta_ = true; // Posició inicial = centre de la nau centre_.x = posicio.x; centre_.y = posicio.y; // Angle = angle de la nau (dispara en la direcció que apunta) angle_ = angle; // Almacenar propietario (0=P1, 1=P2) owner_id_ = owner_id; // Velocitat alta (el joc Pascal original usava 7 px/frame) // 7 px/frame × 20 FPS = 140 px/s velocitat_ = 140.0F; // Activar grace period (prevents instant self-collision) grace_timer_ = Defaults::Game::BULLET_GRACE_PERIOD; // Reproducir sonido de disparo láser Audio::get()->playSound(Defaults::Sound::LASER, Audio::Group::GAME); } void Bala::actualitzar(float delta_time) { if (esta_) { // Decrementar grace timer if (grace_timer_ > 0.0F) { grace_timer_ -= delta_time; grace_timer_ = std::max(grace_timer_, 0.0F); } mou(delta_time); } } void Bala::dibuixar() const { if (esta_ && forma_) { // [NUEVO] Usar render_shape en lloc de rota_pol // Les bales roten segons l'angle de trajectòria Rendering::render_shape(renderer_, forma_, centre_, angle_, 1.0F, true, 1.0F, brightness_); } } void Bala::mou(float delta_time) { // Moviment rectilini de la bala // Basat en el codi Pascal original: procedure mou_bales // Copiat EXACTAMENT de joc_asteroides.cpp línies 396-419 // Calcular nova posició (moviment polar time-based) // velocitat ja està en px/s (140 px/s), només cal multiplicar per delta_time float velocitat_efectiva = velocitat_ * delta_time; // Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt) float dy = velocitat_efectiva * std::sin(angle_ - (Constants::PI / 2.0F)); float dx = velocitat_efectiva * std::cos(angle_ - (Constants::PI / 2.0F)); // Acumulació directa amb precisió subpíxel centre_.y += dy; centre_.x += dx; // Desactivar si surt de la zona de joc (no rebota com els ORNIs) // CORRECCIÓ: Usar límits segurs amb radi de la bala float min_x; float max_x; float min_y; float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::BULLET_RADIUS, min_x, max_x, min_y, max_y); if (centre_.x < min_x || centre_.x > max_x || centre_.y < min_y || centre_.y > max_y) { esta_ = false; } }