104 lines
3.0 KiB
C++
104 lines
3.0 KiB
C++
// 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 <cmath>
|
||
#include <iostream>
|
||
|
||
#include "core/audio/audio.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_({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;
|
||
|
||
// Reproducir sonido de disparo láser
|
||
Audio::get()->playSound(Defaults::Sound::LASER, Audio::Group::GAME);
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|