// 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 "core/graphics/shape_loader.hpp" #include "core/rendering/shape_renderer.hpp" #include "game/constants.hpp" Bala::Bala(SDL_Renderer* renderer) : renderer_(renderer), centre_({0.0f, 0.0f}), angle_(0.0f), velocitat_(0.0f), esta_(false) { // [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_ = {0.0f, 0.0f}; angle_ = 0.0f; velocitat_ = 0.0f; } void Bala::disparar(const Punt& posicio, float angle) { // 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; // Velocitat alta (el joc Pascal original usava 7 px/frame) // 7 px/frame × 20 FPS = 140 px/s velocitat_ = 140.0f; } void Bala::actualitzar(float delta_time) { if (esta_) { mou(delta_time); } } void Bala::dibuixar() const { if (esta_ && forma_) { // [NUEVO] Usar render_shape en lloc de rota_pol // Les bales no roten visualment (angle sempre 0.0f) Rendering::render_shape(renderer_, forma_, centre_, 0.0f, 1.0f, true); } } 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, max_x, min_y, 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; } }