feat: implementar jerarquia d'entitats amb classe base Entitat

This commit is contained in:
2025-12-19 13:01:58 +01:00
parent 70f2642e6d
commit 47f7ffb169
12 changed files with 188 additions and 141 deletions

View File

@@ -12,9 +12,11 @@
#include <vector>
#include "core/audio/audio.hpp"
#include "core/entities/entitat.hpp"
#include "core/input/input.hpp"
#include "core/input/mouse.hpp"
#include "core/math/easing.hpp"
#include "core/physics/collision.hpp"
#include "core/rendering/line_renderer.hpp"
#include "core/system/context_escenes.hpp"
#include "core/system/global_events.hpp"
@@ -942,40 +944,21 @@ std::string EscenaJoc::construir_marcador() const {
}
void EscenaJoc::detectar_col·lisions_bales_enemics() {
// Constants amplificades per hitbox més generós (115%)
constexpr float RADI_BALA = Defaults::Entities::BULLET_RADIUS;
constexpr float RADI_ENEMIC = Defaults::Entities::ENEMY_RADIUS;
constexpr float SUMA_RADIS = (RADI_BALA + RADI_ENEMIC) * 1.15F; // 28.75 px
constexpr float SUMA_RADIS_QUADRAT = SUMA_RADIS * SUMA_RADIS; // 826.56
// Amplificador per hitbox més generós (115%)
constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_ENEMY_AMPLIFIER;
// Velocitat d'explosió reduïda per efecte suau
constexpr float VELOCITAT_EXPLOSIO = 80.0F; // px/s (en lloc de 80.0f per defecte)
// Iterar per totes les bales actives
// Iterar per totes les bales i enemics
for (auto& bala : bales_) {
if (!bala.esta_activa()) {
continue;
}
const Punt& pos_bala = bala.get_centre();
// Comprovar col·lisió amb tots els enemics actius
for (auto& enemic : orni_) {
if (!enemic.esta_actiu()) {
continue;
}
const Punt& pos_enemic = enemic.get_centre();
// Calcular distància quadrada (evita sqrt)
float dx = pos_bala.x - pos_enemic.x;
float dy = pos_bala.y - pos_enemic.y;
float distancia_quadrada = (dx * dx) + (dy * dy);
// Comprovar col·lisió
if (distancia_quadrada <= SUMA_RADIS_QUADRAT) {
// Comprovar col·lisió utilitzant la interfície genèrica
if (Physics::check_collision(bala, enemic, AMPLIFIER)) {
// *** COL·LISIÓ DETECTADA ***
const Punt& pos_enemic = enemic.get_centre();
// 1. Calculate score for enemy type
int punts = 0;
switch (enemic.get_tipus()) {
@@ -1025,12 +1008,8 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() {
}
void EscenaJoc::detectar_col·lisio_naus_enemics() {
// Generous collision detection (80% hitbox)
constexpr float RADI_NAU = Defaults::Entities::SHIP_RADIUS;
constexpr float RADI_ENEMIC = Defaults::Entities::ENEMY_RADIUS;
constexpr float SUMA_RADIS =
(RADI_NAU + RADI_ENEMIC) * Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER;
constexpr float SUMA_RADIS_QUADRAT = SUMA_RADIS * SUMA_RADIS;
// Amplificador per hitbox generós (80%)
constexpr float AMPLIFIER = Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER;
// Check collision for BOTH players
for (uint8_t i = 0; i < 2; i++) {
@@ -1045,28 +1024,15 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() {
continue;
}
const Punt& pos_nau = naus_[i].get_centre();
// Check collision with all active enemies
for (const auto& enemic : orni_) {
if (!enemic.esta_actiu()) {
continue;
}
// Skip collision if enemy is invulnerable
if (enemic.es_invulnerable()) {
continue;
}
const Punt& pos_enemic = enemic.get_centre();
// Calculate squared distance (avoid sqrt)
auto dx = static_cast<float>(pos_nau.x - pos_enemic.x);
auto dy = static_cast<float>(pos_nau.y - pos_enemic.y);
float distancia_quadrada = (dx * dx) + (dy * dy);
// Check collision
if (distancia_quadrada <= SUMA_RADIS_QUADRAT) {
// Comprovar col·lisió utilitzant la interfície genèrica
if (Physics::check_collision(naus_[i], enemic, AMPLIFIER)) {
tocado(i); // Trigger death sequence for player i
break; // Only one collision per player per frame
}
@@ -1080,12 +1046,8 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() {
return;
}
// Collision constants (exact hitbox, 1.0x amplification)
constexpr float RADI_NAU = Defaults::Entities::SHIP_RADIUS;
constexpr float RADI_BALA = Defaults::Entities::BULLET_RADIUS;
constexpr float SUMA_RADIS = (RADI_NAU + RADI_BALA) *
Defaults::Game::COLLISION_BULLET_PLAYER_AMPLIFIER; // 15.0 px
constexpr float SUMA_RADIS_QUADRAT = SUMA_RADIS * SUMA_RADIS; // 225.0
// Amplificador per hitbox exacte (100%)
constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_PLAYER_AMPLIFIER;
// Check all active bullets
for (auto& bala : bales_) {
@@ -1098,7 +1060,6 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() {
continue;
}
const Punt& pos_bala = bala.get_centre();
uint8_t bullet_owner = bala.get_owner_id();
// Check collision with BOTH players
@@ -1121,15 +1082,8 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() {
continue;
}
const Punt& pos_nau = naus_[player_id].get_centre();
// Calculate squared distance (avoid sqrt)
float dx = pos_bala.x - pos_nau.x;
float dy = pos_bala.y - pos_nau.y;
float distancia_quadrada = (dx * dx) + (dy * dy);
// Check collision
if (distancia_quadrada <= SUMA_RADIS_QUADRAT) {
// Comprovar col·lisió utilitzant la interfície genèrica
if (Physics::check_collision(bala, naus_[player_id], AMPLIFIER)) {
// *** FRIENDLY FIRE HIT ***
if (bullet_owner == player_id) {