debris hereta brillantor i velocitat

This commit is contained in:
2025-12-09 09:25:46 +01:00
parent cd7f06f3a1
commit ec6565bf71
8 changed files with 85 additions and 40 deletions

View File

@@ -63,6 +63,11 @@ endif
# ==============================================================================
PACK_TOOL := tools/pack_resources/pack_resources
# ==============================================================================
# DEFAULT GOAL
# ==============================================================================
.DEFAULT_GOAL := all
.PHONY: pack_tool resources.pack
pack_tool:

View File

@@ -28,6 +28,9 @@ struct Debris {
// Shrinking (reducció de distància entre punts)
float factor_shrink; // Factor de reducció per segon (0.0-1.0)
// Rendering
float brightness; // Factor de brillantor (0.0-1.0, heretat de l'objecte original)
};
} // namespace Effects

View File

@@ -47,7 +47,9 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
const Punt& centre,
float angle,
float escala,
float velocitat_base) {
float velocitat_base,
float brightness,
const Punt& velocitat_objecte) {
if (!shape || !shape->es_valida()) {
return;
}
@@ -94,17 +96,18 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
debris->p1 = world_p1;
debris->p2 = world_p2;
// 4. Calcular direcció perpendicular
Punt direccio = calcular_direccio_perpendicular(world_p1, world_p2);
// 4. Calcular direcció d'explosió (radial, des del centre cap a fora)
Punt direccio = calcular_direccio_explosio(world_p1, world_p2, centre);
// 5. Velocitat inicial (base ± variació aleatòria)
// 5. Velocitat inicial (base ± variació aleatòria + velocitat heretada)
float speed =
velocitat_base +
((std::rand() / static_cast<float>(RAND_MAX)) * 2.0f - 1.0f) *
Defaults::Physics::Debris::VARIACIO_VELOCITAT;
debris->velocitat.x = direccio.x * speed;
debris->velocitat.y = direccio.y * speed;
// Heredar velocitat de l'objecte original (suma vectorial)
debris->velocitat.x = direccio.x * speed + velocitat_objecte.x;
debris->velocitat.y = direccio.y * speed + velocitat_objecte.y;
debris->acceleracio = Defaults::Physics::Debris::ACCELERACIO;
// 6. Rotació lenta aleatòria
@@ -126,7 +129,10 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
debris->temps_max = Defaults::Physics::Debris::TEMPS_VIDA;
debris->factor_shrink = Defaults::Physics::Debris::SHRINK_RATE;
// 8. Activar
// 8. Heredar brightness
debris->brightness = brightness;
// 9. Activar
debris->actiu = true;
}
}
@@ -206,8 +212,14 @@ void DebrisManager::dibuixar() const {
if (!debris.actiu)
continue;
// Dibuixar segment de línia
Rendering::linea(renderer_, static_cast<int>(debris.p1.x), static_cast<int>(debris.p1.y), static_cast<int>(debris.p2.x), static_cast<int>(debris.p2.y), true);
// Dibuixar segment de línia amb brightness heretat
Rendering::linea(renderer_,
static_cast<int>(debris.p1.x),
static_cast<int>(debris.p1.y),
static_cast<int>(debris.p2.x),
static_cast<int>(debris.p2.y),
true,
debris.brightness);
}
}
@@ -220,16 +232,22 @@ Debris* DebrisManager::trobar_slot_lliure() {
return nullptr; // Pool ple
}
Punt DebrisManager::calcular_direccio_perpendicular(const Punt& p1,
const Punt& p2) const {
// 1. Calcular vector de la línia (p1 → p2)
float dx = p2.x - p1.x;
float dy = p2.y - p1.y;
Punt DebrisManager::calcular_direccio_explosio(const Punt& p1,
const Punt& p2,
const Punt& centre_objecte) const {
// 1. Calcular centre del segment
float centro_seg_x = (p1.x + p2.x) / 2.0f;
float centro_seg_y = (p1.y + p2.y) / 2.0f;
// 2. Normalitzar (obtenir vector unitari)
// 2. Calcular vector des del centre de l'objecte cap al centre del segment
// Això garanteix que la direcció sempre apunte cap a fora (direcció radial)
float dx = centro_seg_x - centre_objecte.x;
float dy = centro_seg_y - centre_objecte.y;
// 3. Normalitzar (obtenir vector unitari)
float length = std::sqrt(dx * dx + dy * dy);
if (length < 0.001f) {
// Línia degenerada, retornar direcció aleatòria
// Segment al centre (cas extrem molt improbable), retornar direcció aleatòria
float angle_rand =
(std::rand() / static_cast<float>(RAND_MAX)) * 2.0f * Defaults::Math::PI;
return {std::cos(angle_rand), std::sin(angle_rand)};
@@ -238,26 +256,15 @@ Punt DebrisManager::calcular_direccio_perpendicular(const Punt& p1,
dx /= length;
dy /= length;
// 3. Rotar 90° (perpendicular)
// Rotació 90° sentit antihorari: (x,y) → (-y, x)
float perp_x = -dy;
float perp_y = dx;
// 4. Afegir variació aleatòria petita (±15°)
// 4. Afegir variació aleatòria petita (±15°) per varietat visual
float angle_variacio =
((std::rand() % 30) - 15) * Defaults::Math::PI / 180.0f;
float cos_v = std::cos(angle_variacio);
float sin_v = std::sin(angle_variacio);
float final_x = perp_x * cos_v - perp_y * sin_v;
float final_y = perp_x * sin_v + perp_y * cos_v;
// 5. Afegir ± direcció aleatòria (50% probabilitat d'invertir)
if (std::rand() % 2 == 0) {
final_x = -final_x;
final_y = -final_y;
}
float final_x = dx * cos_v - dy * sin_v;
float final_y = dx * sin_v + dy * cos_v;
return {final_x, final_y};
}

View File

@@ -25,11 +25,15 @@ class DebrisManager {
// - angle: orientació de l'objecte (radians)
// - escala: escala de l'objecte (1.0 = normal)
// - velocitat_base: velocitat inicial dels fragments (px/s)
// - brightness: factor de brillantor heretat (0.0-1.0, per defecte 1.0)
// - velocitat_objecte: velocitat de l'objecte que explota (px/s, per defecte 0)
void explotar(const std::shared_ptr<Graphics::Shape>& shape,
const Punt& centre,
float angle,
float escala,
float velocitat_base);
float velocitat_base,
float brightness = 1.0f,
const Punt& velocitat_objecte = {0.0f, 0.0f});
// Actualitzar tots els fragments actius
void actualitzar(float delta_time);
@@ -56,8 +60,8 @@ class DebrisManager {
// Trobar primer slot inactiu
Debris* trobar_slot_lliure();
// Calcular direcció perpendicular a un segment
Punt calcular_direccio_perpendicular(const Punt& p1, const Punt& p2) const;
// Calcular direcció d'explosió (radial, des del centre cap al segment)
Punt calcular_direccio_explosio(const Punt& p1, const Punt& p2, const Punt& centre_objecte) const;
};
} // namespace Effects

View File

@@ -9,6 +9,7 @@
#include "core/graphics/shape.hpp"
#include "core/types.hpp"
#include "game/constants.hpp"
// Tipus d'enemic
enum class TipusEnemic : uint8_t {
@@ -48,6 +49,13 @@ class Enemic {
const Punt& get_centre() const { return centre_; }
const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
void destruir() { esta_ = false; }
float get_brightness() const { return brightness_; }
Punt get_velocitat_vector() const {
return {
velocitat_ * std::cos(angle_ - Constants::PI / 2.0f),
velocitat_ * std::sin(angle_ - Constants::PI / 2.0f)
};
}
// Set ship position reference for tracking behavior
void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; }

View File

@@ -9,6 +9,7 @@
#include "core/graphics/shape.hpp"
#include "core/types.hpp"
#include "game/constants.hpp"
class Nau {
public:
@@ -26,6 +27,13 @@ class Nau {
float get_angle() const { return angle_; }
bool esta_viva() const { return !esta_tocada_; }
const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
float get_brightness() const { return brightness_; }
Punt get_velocitat_vector() const {
return {
velocitat_ * std::cos(angle_ - Constants::PI / 2.0f),
velocitat_ * std::sin(angle_ - Constants::PI / 2.0f)
};
}
// Col·lisions (Fase 10)
void marcar_tocada() { esta_tocada_ = true; }

View File

@@ -417,13 +417,18 @@ void EscenaJoc::tocado() {
// Create ship explosion
const Punt& ship_pos = nau_.get_centre();
float ship_angle = nau_.get_angle();
Punt vel_nau = nau_.get_velocitat_vector();
// Reduir a 80% la velocitat heretada per la nau (més realista)
Punt vel_nau_80 = {vel_nau.x * 0.8f, vel_nau.y * 0.8f};
debris_manager_.explotar(
nau_.get_forma(), // Ship shape (3 lines)
ship_pos, // Center position
ship_angle, // Ship orientation
1.0f, // Normal scale
Defaults::Physics::Debris::VELOCITAT_BASE // 80 px/s
Defaults::Physics::Debris::VELOCITAT_BASE, // 80 px/s
nau_.get_brightness(), // Heredar brightness
vel_nau_80 // Heredar 60% velocitat
);
// Start death timer (non-zero to avoid re-triggering)
@@ -517,12 +522,15 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() {
enemic.destruir();
// 2. Crear explosió de fragments
Punt vel_enemic = enemic.get_velocitat_vector();
debris_manager_.explotar(
enemic.get_forma(), // Forma vectorial del pentàgon
pos_enemic, // Posició central
0.0f, // Angle (enemic té rotació interna)
1.0f, // Escala normal
VELOCITAT_EXPLOSIO // 50 px/s (explosió suau)
enemic.get_forma(), // Forma vectorial del pentàgon
pos_enemic, // Posició central
0.0f, // Angle (enemic té rotació interna)
1.0f, // Escala normal
VELOCITAT_EXPLOSIO, // 50 px/s (explosió suau)
enemic.get_brightness(), // Heredar brightness
vel_enemic // Heredar velocitat
);
// 3. Desactivar bala

View File

@@ -240,7 +240,9 @@ void EscenaLogo::actualitzar_explosions(float delta_time) {
lletra.posicio, // Posició
0.0f, // Angle (sense rotació)
ESCALA_FINAL, // Escala (lletres a escala final)
VELOCITAT_EXPLOSIO // Velocitat base
VELOCITAT_EXPLOSIO, // Velocitat base
1.0f, // Brightness màxim (per defecte)
{0.0f, 0.0f} // Sense velocitat (per defecte)
);
std::cout << "[EscenaLogo] Explota lletra " << lletra_explosio_index_ << "\n";