Fase 1a: Punt -> Vec2 amb operadors moderns
Primera sub-fase del naming sweep. Punt era un struct sense
operacions, conservat per compatibilitat amb el Pascal original.
Substituit per Vec2, un aggregate amb operadors aritmetics, dot,
length, normalized i length_squared (camelBack: lengthSquared)
seguint les regles del .clang-tidy del projecte.
Canvis:
- core/types.hpp reescrit: nou struct Vec2 amb +=,-=,*=,/=,
unary -, ==, dot, length, lengthSquared, normalized
- Operadors fora de la classe: +, -, *, / (amb float per ambdues
bandes), - unari, ==
- Vec2 segueix sent aggregate (sense constructors definits):
els 'designated initializers' del codi existent funcionen igual:
Vec2{.x = ..., .y = ...}
- Sed global sobre 35 fitxers: tots els 'Punt' -> 'Vec2'
Net: 35 fitxers tocats, +180 / -114. Compila i enllaça.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -464,7 +464,7 @@ constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotant: escala
|
|||||||
// Fórmula: (radi màxim de la nau * escala d'entrada) + marge
|
// Fórmula: (radi màxim de la nau * escala d'entrada) + marge
|
||||||
constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN;
|
constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN;
|
||||||
|
|
||||||
// Punt de fuga (centre per a l'animació de sortida)
|
// Vec2 de fuga (centre per a l'animació de sortida)
|
||||||
constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f
|
constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f
|
||||||
constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f
|
constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class Entitat {
|
|||||||
[[nodiscard]] virtual bool es_collidable() const { return false; }
|
[[nodiscard]] virtual bool es_collidable() const { return false; }
|
||||||
|
|
||||||
// Getters comuns (inline, sense overhead)
|
// Getters comuns (inline, sense overhead)
|
||||||
[[nodiscard]] const Punt& get_centre() const { return centre_; }
|
[[nodiscard]] const Vec2& get_centre() const { return centre_; }
|
||||||
[[nodiscard]] float get_angle() const { return angle_; }
|
[[nodiscard]] float get_angle() const { return angle_; }
|
||||||
[[nodiscard]] float get_brightness() const { return brightness_; }
|
[[nodiscard]] float get_brightness() const { return brightness_; }
|
||||||
[[nodiscard]] const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
|
[[nodiscard]] const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
|
||||||
@@ -36,7 +36,7 @@ class Entitat {
|
|||||||
// Estat comú (accés directe, sense overhead)
|
// Estat comú (accés directe, sense overhead)
|
||||||
SDL_Renderer* renderer_;
|
SDL_Renderer* renderer_;
|
||||||
std::shared_ptr<Graphics::Shape> forma_;
|
std::shared_ptr<Graphics::Shape> forma_;
|
||||||
Punt centre_;
|
Vec2 centre_;
|
||||||
float angle_{0.0F};
|
float angle_{0.0F};
|
||||||
float brightness_{1.0F};
|
float brightness_{1.0F};
|
||||||
|
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ void Shape::parse_center(const std::string& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper: parse points "x1,y1 x2,y2 x3,y3"
|
// Helper: parse points "x1,y1 x2,y2 x3,y3"
|
||||||
std::vector<Punt> Shape::parse_points(const std::string& str) const {
|
std::vector<Vec2> Shape::parse_points(const std::string& str) const {
|
||||||
std::vector<Punt> points;
|
std::vector<Vec2> points;
|
||||||
std::istringstream iss(trim(str));
|
std::istringstream iss(trim(str));
|
||||||
std::string pair;
|
std::string pair;
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ enum class PrimitiveType {
|
|||||||
// Primitiva individual (polyline o line)
|
// Primitiva individual (polyline o line)
|
||||||
struct ShapePrimitive {
|
struct ShapePrimitive {
|
||||||
PrimitiveType type;
|
PrimitiveType type;
|
||||||
std::vector<Punt> points; // 2+ punts per polyline, exactament 2 per line
|
std::vector<Vec2> points; // 2+ punts per polyline, exactament 2 per line
|
||||||
};
|
};
|
||||||
|
|
||||||
// Classe Shape - representa una forma vectorial carregada des de .shp
|
// Classe Shape - representa una forma vectorial carregada des de .shp
|
||||||
@@ -39,7 +39,7 @@ class Shape {
|
|||||||
[[nodiscard]] const std::vector<ShapePrimitive>& get_primitives() const {
|
[[nodiscard]] const std::vector<ShapePrimitive>& get_primitives() const {
|
||||||
return primitives_;
|
return primitives_;
|
||||||
}
|
}
|
||||||
[[nodiscard]] const Punt& get_centre() const { return centre_; }
|
[[nodiscard]] const Vec2& get_centre() const { return centre_; }
|
||||||
[[nodiscard]] float get_escala_defecte() const { return escala_defecte_; }
|
[[nodiscard]] float get_escala_defecte() const { return escala_defecte_; }
|
||||||
[[nodiscard]] bool es_valida() const { return !primitives_.empty(); }
|
[[nodiscard]] bool es_valida() const { return !primitives_.empty(); }
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ class Shape {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ShapePrimitive> primitives_;
|
std::vector<ShapePrimitive> primitives_;
|
||||||
Punt centre_; // Centre/origen de la forma
|
Vec2 centre_; // Centre/origen de la forma
|
||||||
float escala_defecte_; // Escala per defecte (normalment 1.0)
|
float escala_defecte_; // Escala per defecte (normalment 1.0)
|
||||||
std::string nom_; // Nom de la forma (per depuració)
|
std::string nom_; // Nom de la forma (per depuració)
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ class Shape {
|
|||||||
[[nodiscard]] bool starts_with(const std::string& str, const std::string& prefix) const;
|
[[nodiscard]] bool starts_with(const std::string& str, const std::string& prefix) const;
|
||||||
[[nodiscard]] std::string extract_value(const std::string& line) const;
|
[[nodiscard]] std::string extract_value(const std::string& line) const;
|
||||||
void parse_center(const std::string& value);
|
void parse_center(const std::string& value);
|
||||||
[[nodiscard]] std::vector<Punt> parse_points(const std::string& str) const;
|
[[nodiscard]] std::vector<Vec2> parse_points(const std::string& str) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Graphics
|
} // namespace Graphics
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Graphics {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Starfield::Starfield(SDL_Renderer* renderer,
|
Starfield::Starfield(SDL_Renderer* renderer,
|
||||||
const Punt& punt_fuga,
|
const Vec2& punt_fuga,
|
||||||
const SDL_FRect& area,
|
const SDL_FRect& area,
|
||||||
int densitat)
|
int densitat)
|
||||||
: renderer_(renderer),
|
: renderer_(renderer),
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class Starfield {
|
|||||||
// - area: rectangle on actuen les estrelles (SDL_FRect)
|
// - area: rectangle on actuen les estrelles (SDL_FRect)
|
||||||
// - densitat: nombre total d'estrelles (es divideix entre capes)
|
// - densitat: nombre total d'estrelles (es divideix entre capes)
|
||||||
Starfield(SDL_Renderer* renderer,
|
Starfield(SDL_Renderer* renderer,
|
||||||
const Punt& punt_fuga,
|
const Vec2& punt_fuga,
|
||||||
const SDL_FRect& area,
|
const SDL_FRect& area,
|
||||||
int densitat = 150);
|
int densitat = 150);
|
||||||
|
|
||||||
@@ -41,13 +41,13 @@ class Starfield {
|
|||||||
void dibuixar();
|
void dibuixar();
|
||||||
|
|
||||||
// Setters per ajustar paràmetres en temps real
|
// Setters per ajustar paràmetres en temps real
|
||||||
void set_punt_fuga(const Punt& punt) { punt_fuga_ = punt; }
|
void set_punt_fuga(const Vec2& punt) { punt_fuga_ = punt; }
|
||||||
void set_brightness(float multiplier);
|
void set_brightness(float multiplier);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Estructura interna per cada estrella
|
// Estructura interna per cada estrella
|
||||||
struct Estrella {
|
struct Estrella {
|
||||||
Punt posicio; // Posició actual
|
Vec2 posicio; // Posició actual
|
||||||
float angle; // Angle de moviment (radians)
|
float angle; // Angle de moviment (radians)
|
||||||
float distancia_centre; // Distància normalitzada del centre (0.0-1.0)
|
float distancia_centre; // Distància normalitzada del centre (0.0-1.0)
|
||||||
int capa; // Índex de capa (0=lluny, 1=mitjà, 2=prop)
|
int capa; // Índex de capa (0=lluny, 1=mitjà, 2=prop)
|
||||||
@@ -72,7 +72,7 @@ class Starfield {
|
|||||||
SDL_Renderer* renderer_;
|
SDL_Renderer* renderer_;
|
||||||
|
|
||||||
// Configuració
|
// Configuració
|
||||||
Punt punt_fuga_; // Punt d'origen de les estrelles
|
Vec2 punt_fuga_; // Vec2 d'origen de les estrelles
|
||||||
SDL_FRect area_; // Àrea activa
|
SDL_FRect area_; // Àrea activa
|
||||||
float radi_max_; // Distància màxima del centre al límit de pantalla
|
float radi_max_; // Distància màxima del centre al límit de pantalla
|
||||||
int densitat_; // Nombre total d'estrelles
|
int densitat_; // Nombre total d'estrelles
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ bool VectorText::is_supported(char c) const {
|
|||||||
return chars_.contains(c);
|
return chars_.contains(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorText::render(const std::string& text, const Punt& posicio, float escala, float spacing, float brightness) const {
|
void VectorText::render(const std::string& text, const Vec2& posicio, float escala, float spacing, float brightness) const {
|
||||||
if (renderer_ == nullptr) {
|
if (renderer_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca
|
|||||||
// Renderizar carácter
|
// Renderizar carácter
|
||||||
// Ajustar X e Y para que posicio represente esquina superior izquierda
|
// Ajustar X e Y para que posicio represente esquina superior izquierda
|
||||||
// (render_shape espera el centro, así que sumamos la mitad de ancho y altura)
|
// (render_shape espera el centro, así que sumamos la mitad de ancho y altura)
|
||||||
Punt char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = posicio.y + (char_height_scaled / 2.0F)};
|
Vec2 char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = posicio.y + (char_height_scaled / 2.0F)};
|
||||||
Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, escala, 1.0F, brightness);
|
Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, escala, 1.0F, brightness);
|
||||||
|
|
||||||
// Avanzar posición
|
// Avanzar posición
|
||||||
@@ -237,14 +237,14 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorText::render_centered(const std::string& text, const Punt& centre_punt, float escala, float spacing, float brightness) const {
|
void VectorText::render_centered(const std::string& text, const Vec2& centre_punt, float escala, float spacing, float brightness) const {
|
||||||
// Calcular dimensions del text
|
// Calcular dimensions del text
|
||||||
float text_width = get_text_width(text, escala, spacing);
|
float text_width = get_text_width(text, escala, spacing);
|
||||||
float text_height = get_text_height(escala);
|
float text_height = get_text_height(escala);
|
||||||
|
|
||||||
// Calcular posició de l'esquina superior esquerra
|
// Calcular posició de l'esquina superior esquerra
|
||||||
// restant la meitat de les dimensions del punt central
|
// restant la meitat de les dimensions del punt central
|
||||||
Punt posicio_esquerra = {
|
Vec2 posicio_esquerra = {
|
||||||
.x = centre_punt.x - (text_width / 2.0F),
|
.x = centre_punt.x - (text_width / 2.0F),
|
||||||
.y = centre_punt.y - (text_height / 2.0F)};
|
.y = centre_punt.y - (text_height / 2.0F)};
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class VectorText {
|
|||||||
// - escala: factor de escala (1.0 = 20×40 px por carácter)
|
// - escala: factor de escala (1.0 = 20×40 px por carácter)
|
||||||
// - spacing: espacio entre caracteres en píxeles (a escala 1.0)
|
// - spacing: espacio entre caracteres en píxeles (a escala 1.0)
|
||||||
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
|
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
|
||||||
void render(const std::string& text, const Punt& posicio, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const;
|
void render(const std::string& text, const Vec2& posicio, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const;
|
||||||
|
|
||||||
// Renderizar string centrado en un punto
|
// Renderizar string centrado en un punto
|
||||||
// - text: cadena a renderizar
|
// - text: cadena a renderizar
|
||||||
@@ -33,7 +33,7 @@ class VectorText {
|
|||||||
// - escala: factor de escala (1.0 = 20×40 px por carácter)
|
// - escala: factor de escala (1.0 = 20×40 px por carácter)
|
||||||
// - spacing: espacio entre caracteres en píxeles (a escala 1.0)
|
// - spacing: espacio entre caracteres en píxeles (a escala 1.0)
|
||||||
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
|
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
|
||||||
void render_centered(const std::string& text, const Punt& centre_punt, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const;
|
void render_centered(const std::string& text, const Vec2& centre_punt, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const;
|
||||||
|
|
||||||
// Calcular ancho total de un string (útil para centrado)
|
// Calcular ancho total de un string (útil para centrado)
|
||||||
[[nodiscard]] float get_text_width(const std::string& text, float escala = 1.0F, float spacing = 2.0F) const;
|
[[nodiscard]] float get_text_width(const std::string& text, float escala = 1.0F, float spacing = 2.0F) const;
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ inline bool check_collision(const Entities::Entitat& a, const Entities::Entitat&
|
|||||||
float suma_radis_sq = suma_radis * suma_radis;
|
float suma_radis_sq = suma_radis * suma_radis;
|
||||||
|
|
||||||
// Comprovació distància al quadrat (sense sqrt)
|
// Comprovació distància al quadrat (sense sqrt)
|
||||||
const Punt& pos_a = a.get_centre();
|
const Vec2& pos_a = a.get_centre();
|
||||||
const Punt& pos_b = b.get_centre();
|
const Vec2& pos_b = b.get_centre();
|
||||||
float dx = pos_a.x - pos_b.x;
|
float dx = pos_a.x - pos_b.x;
|
||||||
float dy = pos_a.y - pos_b.y;
|
float dy = pos_a.y - pos_b.y;
|
||||||
float dist_sq = (dx * dx) + (dy * dy);
|
float dist_sq = (dx * dx) + (dy * dy);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
namespace Rendering {
|
namespace Rendering {
|
||||||
|
|
||||||
// Helper: aplicar rotació 3D a un punt 2D (assumeix Z=0)
|
// Helper: aplicar rotació 3D a un punt 2D (assumeix Z=0)
|
||||||
static Punt apply_3d_rotation(float x, float y, const Rotation3D& rot) {
|
static Vec2 apply_3d_rotation(float x, float y, const Rotation3D& rot) {
|
||||||
float z = 0.0F; // Tots els punts 2D comencen a Z=0
|
float z = 0.0F; // Tots els punts 2D comencen a Z=0
|
||||||
|
|
||||||
// Pitch (rotació eix X): cabeceo arriba/baix
|
// Pitch (rotació eix X): cabeceo arriba/baix
|
||||||
@@ -42,14 +42,14 @@ static Punt apply_3d_rotation(float x, float y, const Rotation3D& rot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper: transformar un punt amb rotació, escala i trasllació
|
// Helper: transformar un punt amb rotació, escala i trasllació
|
||||||
static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala, const Rotation3D* rotation_3d) {
|
static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& posicio, float angle, float escala, const Rotation3D* rotation_3d) {
|
||||||
// 1. Centrar el punt respecte al centre de la forma
|
// 1. Centrar el punt respecte al centre de la forma
|
||||||
float centered_x = point.x - shape_centre.x;
|
float centered_x = point.x - shape_centre.x;
|
||||||
float centered_y = point.y - shape_centre.y;
|
float centered_y = point.y - shape_centre.y;
|
||||||
|
|
||||||
// 2. Aplicar rotació 3D (si es proporciona)
|
// 2. Aplicar rotació 3D (si es proporciona)
|
||||||
if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) {
|
if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) {
|
||||||
Punt rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d);
|
Vec2 rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d);
|
||||||
centered_x = rotated_3d.x;
|
centered_x = rotated_3d.x;
|
||||||
centered_y = rotated_3d.y;
|
centered_y = rotated_3d.y;
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P
|
|||||||
|
|
||||||
void render_shape(SDL_Renderer* renderer,
|
void render_shape(SDL_Renderer* renderer,
|
||||||
const std::shared_ptr<Graphics::Shape>& shape,
|
const std::shared_ptr<Graphics::Shape>& shape,
|
||||||
const Punt& posicio,
|
const Vec2& posicio,
|
||||||
float angle,
|
float angle,
|
||||||
float escala,
|
float escala,
|
||||||
float progress,
|
float progress,
|
||||||
@@ -91,15 +91,15 @@ void render_shape(SDL_Renderer* renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtenir el centre de la forma per a transformacions
|
// Obtenir el centre de la forma per a transformacions
|
||||||
const Punt& shape_centre = shape->get_centre();
|
const Vec2& shape_centre = shape->get_centre();
|
||||||
|
|
||||||
// Iterar sobre totes les primitives
|
// Iterar sobre totes les primitives
|
||||||
for (const auto& primitive : shape->get_primitives()) {
|
for (const auto& primitive : shape->get_primitives()) {
|
||||||
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
|
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
|
||||||
// POLYLINE: connectar punts consecutius
|
// POLYLINE: connectar punts consecutius
|
||||||
for (size_t i = 0; i < primitive.points.size() - 1; i++) {
|
for (size_t i = 0; i < primitive.points.size() - 1; i++) {
|
||||||
Punt p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala, rotation_3d);
|
Vec2 p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala, rotation_3d);
|
||||||
Punt p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala, rotation_3d);
|
Vec2 p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala, rotation_3d);
|
||||||
|
|
||||||
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y),
|
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y),
|
||||||
static_cast<int>(p2.x), static_cast<int>(p2.y), brightness);
|
static_cast<int>(p2.x), static_cast<int>(p2.y), brightness);
|
||||||
@@ -107,8 +107,8 @@ void render_shape(SDL_Renderer* renderer,
|
|||||||
} else { // PrimitiveType::LINE
|
} else { // PrimitiveType::LINE
|
||||||
// LINE: exactament 2 punts
|
// LINE: exactament 2 punts
|
||||||
if (primitive.points.size() >= 2) {
|
if (primitive.points.size() >= 2) {
|
||||||
Punt p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala, rotation_3d);
|
Vec2 p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala, rotation_3d);
|
||||||
Punt p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala, rotation_3d);
|
Vec2 p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala, rotation_3d);
|
||||||
|
|
||||||
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y),
|
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y),
|
||||||
static_cast<int>(p2.x), static_cast<int>(p2.y), brightness);
|
static_cast<int>(p2.x), static_cast<int>(p2.y), brightness);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ struct Rotation3D {
|
|||||||
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
|
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
|
||||||
void render_shape(SDL_Renderer* renderer,
|
void render_shape(SDL_Renderer* renderer,
|
||||||
const std::shared_ptr<Graphics::Shape>& shape,
|
const std::shared_ptr<Graphics::Shape>& shape,
|
||||||
const Punt& posicio,
|
const Vec2& posicio,
|
||||||
float angle,
|
float angle,
|
||||||
float escala = 1.0F,
|
float escala = 1.0F,
|
||||||
float progress = 1.0F,
|
float progress = 1.0F,
|
||||||
|
|||||||
+69
-3
@@ -1,6 +1,72 @@
|
|||||||
|
// types.hpp - Tipos básicos compartidos
|
||||||
|
// © 2025 Orni Attack
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Punt cartesià - ÚNICA estructura de coordenades del joc
|
#include <cmath>
|
||||||
struct Punt {
|
|
||||||
float x, y;
|
// Vector 2D cartesiano - única estructura de coordenadas del juego.
|
||||||
|
// Aggregate (sin constructores definidos) para soportar designated initializers:
|
||||||
|
// Vec2{.x = 1.0F, .y = 2.0F}
|
||||||
|
// y aggregate initialization clásica:
|
||||||
|
// Vec2{1.0F, 2.0F}
|
||||||
|
struct Vec2 {
|
||||||
|
float x{0.0F};
|
||||||
|
float y{0.0F};
|
||||||
|
|
||||||
|
constexpr auto operator+=(const Vec2& o) -> Vec2& {
|
||||||
|
x += o.x;
|
||||||
|
y += o.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr auto operator-=(const Vec2& o) -> Vec2& {
|
||||||
|
x -= o.x;
|
||||||
|
y -= o.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr auto operator*=(float s) -> Vec2& {
|
||||||
|
x *= s;
|
||||||
|
y *= s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr auto operator/=(float s) -> Vec2& {
|
||||||
|
x /= s;
|
||||||
|
y /= s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto lengthSquared() const -> float { return (x * x) + (y * y); }
|
||||||
|
[[nodiscard]] auto length() const -> float { return std::sqrt(lengthSquared()); }
|
||||||
|
[[nodiscard]] auto dot(const Vec2& o) const -> float { return (x * o.x) + (y * o.y); }
|
||||||
|
|
||||||
|
// Devuelve el vector normalizado; si la magnitud es 0 devuelve {0,0}.
|
||||||
|
[[nodiscard]] auto normalized() const -> Vec2 {
|
||||||
|
const float L = length();
|
||||||
|
return L > 0.0F ? Vec2{.x = x / L, .y = y / L} : Vec2{};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto operator+(Vec2 a, const Vec2& b) -> Vec2 {
|
||||||
|
a += b;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
constexpr auto operator-(Vec2 a, const Vec2& b) -> Vec2 {
|
||||||
|
a -= b;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
constexpr auto operator*(Vec2 v, float s) -> Vec2 {
|
||||||
|
v *= s;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
constexpr auto operator*(float s, Vec2 v) -> Vec2 {
|
||||||
|
v *= s;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
constexpr auto operator/(Vec2 v, float s) -> Vec2 {
|
||||||
|
v /= s;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
constexpr auto operator-(const Vec2& v) -> Vec2 { return {.x = -v.x, .y = -v.y}; }
|
||||||
|
constexpr auto operator==(const Vec2& a, const Vec2& b) -> bool {
|
||||||
|
return a.x == b.x && a.y == b.y;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ namespace Effects {
|
|||||||
// Representa un fragment d'una forma destruïda (nau, enemic, bala)
|
// Representa un fragment d'una forma destruïda (nau, enemic, bala)
|
||||||
struct Debris {
|
struct Debris {
|
||||||
// Geometria del segment (2 punts en coordenades mundials)
|
// Geometria del segment (2 punts en coordenades mundials)
|
||||||
Punt p1; // Punt inicial del segment
|
Vec2 p1; // Vec2 inicial del segment
|
||||||
Punt p2; // Punt final del segment
|
Vec2 p2; // Vec2 final del segment
|
||||||
|
|
||||||
// Física
|
// Física
|
||||||
Punt velocitat; // Velocitat en px/s (components x, y)
|
Vec2 velocitat; // Velocitat en px/s (components x, y)
|
||||||
float acceleracio; // Acceleració negativa (fricció) en px/s²
|
float acceleracio; // Acceleració negativa (fricció) en px/s²
|
||||||
|
|
||||||
// Rotació
|
// Rotació
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Effects {
|
|||||||
|
|
||||||
// Helper: transformar punt amb rotació, escala i trasllació
|
// Helper: transformar punt amb rotació, escala i trasllació
|
||||||
// (Copiat de shape_renderer.cpp:12-34)
|
// (Copiat de shape_renderer.cpp:12-34)
|
||||||
static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala) {
|
static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& posicio, float angle, float escala) {
|
||||||
// 1. Centrar el punt respecte al centre de la forma
|
// 1. Centrar el punt respecte al centre de la forma
|
||||||
float centered_x = point.x - shape_centre.x;
|
float centered_x = point.x - shape_centre.x;
|
||||||
float centered_y = point.y - shape_centre.y;
|
float centered_y = point.y - shape_centre.y;
|
||||||
@@ -45,12 +45,12 @@ DebrisManager::DebrisManager(SDL_Renderer* renderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||||
const Punt& centre,
|
const Vec2& centre,
|
||||||
float angle,
|
float angle,
|
||||||
float escala,
|
float escala,
|
||||||
float velocitat_base,
|
float velocitat_base,
|
||||||
float brightness,
|
float brightness,
|
||||||
const Punt& velocitat_objecte,
|
const Vec2& velocitat_objecte,
|
||||||
float velocitat_angular,
|
float velocitat_angular,
|
||||||
float factor_herencia_visual,
|
float factor_herencia_visual,
|
||||||
const std::string& sound) {
|
const std::string& sound) {
|
||||||
@@ -62,12 +62,12 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
|||||||
Audio::get()->playSound(sound, Audio::Group::GAME);
|
Audio::get()->playSound(sound, Audio::Group::GAME);
|
||||||
|
|
||||||
// Obtenir centre de la forma per a transformacions
|
// Obtenir centre de la forma per a transformacions
|
||||||
const Punt& shape_centre = shape->get_centre();
|
const Vec2& shape_centre = shape->get_centre();
|
||||||
|
|
||||||
// Iterar sobre totes les primitives de la forma
|
// Iterar sobre totes les primitives de la forma
|
||||||
for (const auto& primitive : shape->get_primitives()) {
|
for (const auto& primitive : shape->get_primitives()) {
|
||||||
// Processar cada segment de línia
|
// Processar cada segment de línia
|
||||||
std::vector<std::pair<Punt, Punt>> segments;
|
std::vector<std::pair<Vec2, Vec2>> segments;
|
||||||
|
|
||||||
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
|
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
|
||||||
// Polyline: extreure segments consecutius
|
// Polyline: extreure segments consecutius
|
||||||
@@ -84,9 +84,9 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
|||||||
// Crear debris per a cada segment
|
// Crear debris per a cada segment
|
||||||
for (const auto& [local_p1, local_p2] : segments) {
|
for (const auto& [local_p1, local_p2] : segments) {
|
||||||
// 1. Transformar punts locals → coordenades mundials
|
// 1. Transformar punts locals → coordenades mundials
|
||||||
Punt world_p1 =
|
Vec2 world_p1 =
|
||||||
transform_point(local_p1, shape_centre, centre, angle, escala);
|
transform_point(local_p1, shape_centre, centre, angle, escala);
|
||||||
Punt world_p2 =
|
Vec2 world_p2 =
|
||||||
transform_point(local_p2, shape_centre, centre, angle, escala);
|
transform_point(local_p2, shape_centre, centre, angle, escala);
|
||||||
|
|
||||||
// 2. Trobar slot lliure
|
// 2. Trobar slot lliure
|
||||||
@@ -101,7 +101,7 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
|||||||
debris->p2 = world_p2;
|
debris->p2 = world_p2;
|
||||||
|
|
||||||
// 4. Calcular direcció d'explosió (radial, des del centre cap a fora)
|
// 4. Calcular direcció d'explosió (radial, des del centre cap a fora)
|
||||||
Punt direccio = calcular_direccio_explosio(world_p1, world_p2, centre);
|
Vec2 direccio = calcular_direccio_explosio(world_p1, world_p2, centre);
|
||||||
|
|
||||||
// 5. Velocitat inicial (base ± variació aleatòria + velocitat heretada)
|
// 5. Velocitat inicial (base ± variació aleatòria + velocitat heretada)
|
||||||
float speed =
|
float speed =
|
||||||
@@ -271,7 +271,7 @@ void DebrisManager::actualitzar(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. Calcular centre del segment
|
// 3. Calcular centre del segment
|
||||||
Punt centre = {.x = (debris.p1.x + debris.p2.x) / 2.0F,
|
Vec2 centre = {.x = (debris.p1.x + debris.p2.x) / 2.0F,
|
||||||
.y = (debris.p1.y + debris.p2.y) / 2.0F};
|
.y = (debris.p1.y + debris.p2.y) / 2.0F};
|
||||||
|
|
||||||
// 4. Actualitzar posició del centre
|
// 4. Actualitzar posició del centre
|
||||||
@@ -327,9 +327,9 @@ Debris* DebrisManager::trobar_slot_lliure() {
|
|||||||
return nullptr; // Pool ple
|
return nullptr; // Pool ple
|
||||||
}
|
}
|
||||||
|
|
||||||
Punt DebrisManager::calcular_direccio_explosio(const Punt& p1,
|
Vec2 DebrisManager::calcular_direccio_explosio(const Vec2& p1,
|
||||||
const Punt& p2,
|
const Vec2& p2,
|
||||||
const Punt& centre_objecte) const {
|
const Vec2& centre_objecte) const {
|
||||||
// 1. Calcular centre del segment
|
// 1. Calcular centre del segment
|
||||||
float centro_seg_x = (p1.x + p2.x) / 2.0F;
|
float centro_seg_x = (p1.x + p2.x) / 2.0F;
|
||||||
float centro_seg_y = (p1.y + p2.y) / 2.0F;
|
float centro_seg_y = (p1.y + p2.y) / 2.0F;
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ class DebrisManager {
|
|||||||
// - velocitat_angular: velocitat angular heretada (rad/s, per defecte 0)
|
// - velocitat_angular: velocitat angular heretada (rad/s, per defecte 0)
|
||||||
// - factor_herencia_visual: factor de herència rotació visual (0.0-1.0, per defecte 0.0)
|
// - factor_herencia_visual: factor de herència rotació visual (0.0-1.0, per defecte 0.0)
|
||||||
void explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
void explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||||
const Punt& centre,
|
const Vec2& centre,
|
||||||
float angle,
|
float angle,
|
||||||
float escala,
|
float escala,
|
||||||
float velocitat_base,
|
float velocitat_base,
|
||||||
float brightness = 1.0F,
|
float brightness = 1.0F,
|
||||||
const Punt& velocitat_objecte = {.x = 0.0F, .y = 0.0F},
|
const Vec2& velocitat_objecte = {.x = 0.0F, .y = 0.0F},
|
||||||
float velocitat_angular = 0.0F,
|
float velocitat_angular = 0.0F,
|
||||||
float factor_herencia_visual = 0.0F,
|
float factor_herencia_visual = 0.0F,
|
||||||
const std::string& sound = Defaults::Sound::EXPLOSION);
|
const std::string& sound = Defaults::Sound::EXPLOSION);
|
||||||
@@ -67,7 +67,7 @@ class DebrisManager {
|
|||||||
Debris* trobar_slot_lliure();
|
Debris* trobar_slot_lliure();
|
||||||
|
|
||||||
// Calcular direcció d'explosió (radial, des del centre cap al segment)
|
// Calcular direcció d'explosió (radial, des del centre cap al segment)
|
||||||
[[nodiscard]] Punt calcular_direccio_explosio(const Punt& p1, const Punt& p2, const Punt& centre_objecte) const;
|
[[nodiscard]] Vec2 calcular_direccio_explosio(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Effects
|
} // namespace Effects
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ GestorPuntuacioFlotant::GestorPuntuacioFlotant(SDL_Renderer* renderer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) {
|
void GestorPuntuacioFlotant::crear(int punts, const Vec2& posicio) {
|
||||||
// 1. Trobar slot lliure
|
// 1. Trobar slot lliure
|
||||||
PuntuacioFlotant* pf = trobar_slot_lliure();
|
PuntuacioFlotant* pf = trobar_slot_lliure();
|
||||||
if (pf == nullptr) {
|
if (pf == nullptr) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class GestorPuntuacioFlotant {
|
|||||||
// Crear número flotant
|
// Crear número flotant
|
||||||
// - punts: valor numèric (100, 150, 200)
|
// - punts: valor numèric (100, 150, 200)
|
||||||
// - posicio: on apareix (normalment centre d'enemic destruït)
|
// - posicio: on apareix (normalment centre d'enemic destruït)
|
||||||
void crear(int punts, const Punt& posicio);
|
void crear(int punts, const Vec2& posicio);
|
||||||
|
|
||||||
// Actualitzar tots els números actius
|
// Actualitzar tots els números actius
|
||||||
void actualitzar(float delta_time);
|
void actualitzar(float delta_time);
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ struct PuntuacioFlotant {
|
|||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
// Posició actual (coordenades mundials)
|
// Posició actual (coordenades mundials)
|
||||||
Punt posicio;
|
Vec2 posicio;
|
||||||
|
|
||||||
// Animació de moviment
|
// Animació de moviment
|
||||||
Punt velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f})
|
Vec2 velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f})
|
||||||
|
|
||||||
// Animació de fade
|
// Animació de fade
|
||||||
float temps_vida; // Temps transcorregut (segons)
|
float temps_vida; // Temps transcorregut (segons)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void Bala::inicialitzar() {
|
|||||||
grace_timer_ = 0.0F;
|
grace_timer_ = 0.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bala::disparar(const Punt& posicio, float angle, uint8_t owner_id) {
|
void Bala::disparar(const Vec2& posicio, float angle, uint8_t owner_id) {
|
||||||
// Activar bala i posicionar-la a la nau
|
// Activar bala i posicionar-la a la nau
|
||||||
// Basat en joc_asteroides.cpp línies 188-200
|
// Basat en joc_asteroides.cpp línies 188-200
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class Bala : public Entities::Entitat {
|
|||||||
Bala(SDL_Renderer* renderer);
|
Bala(SDL_Renderer* renderer);
|
||||||
|
|
||||||
void inicialitzar() override;
|
void inicialitzar() override;
|
||||||
void disparar(const Punt& posicio, float angle, uint8_t owner_id);
|
void disparar(const Vec2& posicio, float angle, uint8_t owner_id);
|
||||||
void actualitzar(float delta_time) override;
|
void actualitzar(float delta_time) override;
|
||||||
void dibuixar() const override;
|
void dibuixar() const override;
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Enemic::Enemic(SDL_Renderer* renderer)
|
|||||||
// Constructor no carrega forma per permetre tipus diferents
|
// Constructor no carrega forma per permetre tipus diferents
|
||||||
}
|
}
|
||||||
|
|
||||||
void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) {
|
void Enemic::inicialitzar(TipusEnemic tipus, const Vec2* ship_pos) {
|
||||||
// Guardar tipus
|
// Guardar tipus
|
||||||
tipus_ = tipus;
|
tipus_ = tipus;
|
||||||
|
|
||||||
@@ -523,7 +523,7 @@ void Enemic::set_tracking_strength(float strength) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [NEW] Safe spawn helper - checks if position is away from ship
|
// [NEW] Safe spawn helper - checks if position is away from ship
|
||||||
bool Enemic::intent_spawn_safe(const Punt& ship_pos, float& out_x, float& out_y) {
|
bool Enemic::intent_spawn_safe(const Vec2& ship_pos, float& out_x, float& out_y) {
|
||||||
// Generate random position within safe bounds
|
// Generate random position within safe bounds
|
||||||
float min_x;
|
float min_x;
|
||||||
float max_x;
|
float max_x;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class Enemic : public Entities::Entitat {
|
|||||||
Enemic(SDL_Renderer* renderer);
|
Enemic(SDL_Renderer* renderer);
|
||||||
|
|
||||||
void inicialitzar() override { inicialitzar(TipusEnemic::PENTAGON, nullptr); }
|
void inicialitzar() override { inicialitzar(TipusEnemic::PENTAGON, nullptr); }
|
||||||
void inicialitzar(TipusEnemic tipus, const Punt* ship_pos = nullptr);
|
void inicialitzar(TipusEnemic tipus, const Vec2* ship_pos = nullptr);
|
||||||
void actualitzar(float delta_time) override;
|
void actualitzar(float delta_time) override;
|
||||||
void dibuixar() const override;
|
void dibuixar() const override;
|
||||||
|
|
||||||
@@ -61,14 +61,14 @@ class Enemic : public Entities::Entitat {
|
|||||||
// Getters (API pública sense canvis)
|
// Getters (API pública sense canvis)
|
||||||
void destruir() { esta_ = false; }
|
void destruir() { esta_ = false; }
|
||||||
[[nodiscard]] float get_drotacio() const { return drotacio_; }
|
[[nodiscard]] float get_drotacio() const { return drotacio_; }
|
||||||
[[nodiscard]] Punt get_velocitat_vector() const {
|
[[nodiscard]] Vec2 get_velocitat_vector() const {
|
||||||
return {
|
return {
|
||||||
.x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
|
.x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
|
||||||
.y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
|
.y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set ship position reference for tracking behavior
|
// Set ship position reference for tracking behavior
|
||||||
void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; }
|
void set_ship_position(const Vec2* ship_pos) { ship_position_ = ship_pos; }
|
||||||
|
|
||||||
// [NEW] Getters for stage system (base stats)
|
// [NEW] Getters for stage system (base stats)
|
||||||
[[nodiscard]] float get_base_velocity() const;
|
[[nodiscard]] float get_base_velocity() const;
|
||||||
@@ -102,7 +102,7 @@ class Enemic : public Entities::Entitat {
|
|||||||
|
|
||||||
// [NEW] Behavior state (type-specific)
|
// [NEW] Behavior state (type-specific)
|
||||||
float tracking_timer_; // For Quadrat: time since last angle update
|
float tracking_timer_; // For Quadrat: time since last angle update
|
||||||
const Punt* ship_position_; // Pointer to ship position (for tracking)
|
const Vec2* ship_position_; // Pointer to ship position (for tracking)
|
||||||
float tracking_strength_; // For Quadrat: tracking intensity (0.0-1.5), default 0.5
|
float tracking_strength_; // For Quadrat: tracking intensity (0.0-1.5), default 0.5
|
||||||
|
|
||||||
// [NEW] Invulnerability state
|
// [NEW] Invulnerability state
|
||||||
@@ -119,5 +119,5 @@ class Enemic : public Entities::Entitat {
|
|||||||
void comportament_quadrat(float delta_time);
|
void comportament_quadrat(float delta_time);
|
||||||
void comportament_molinillo(float delta_time);
|
void comportament_molinillo(float delta_time);
|
||||||
[[nodiscard]] float calcular_escala_actual() const; // Returns scale with palpitation applied
|
[[nodiscard]] float calcular_escala_actual() const; // Returns scale with palpitation applied
|
||||||
bool intent_spawn_safe(const Punt& ship_pos, float& out_x, float& out_y);
|
bool intent_spawn_safe(const Vec2& ship_pos, float& out_x, float& out_y);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ Nau::Nau(SDL_Renderer* renderer, const char* shape_file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nau::inicialitzar(const Punt* spawn_point, bool activar_invulnerabilitat) {
|
void Nau::inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat) {
|
||||||
// Inicialització de la nau (triangle)
|
// Inicialització de la nau (triangle)
|
||||||
// Basat en el codi Pascal original: lines 380-384
|
// Basat en el codi Pascal original: lines 380-384
|
||||||
// Copiat de joc_asteroides.cpp línies 30-44
|
// Copiat de joc_asteroides.cpp línies 30-44
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Nau : public Entities::Entitat {
|
|||||||
Nau(SDL_Renderer* renderer, const char* shape_file = "ship.shp");
|
Nau(SDL_Renderer* renderer, const char* shape_file = "ship.shp");
|
||||||
|
|
||||||
void inicialitzar() override { inicialitzar(nullptr, false); }
|
void inicialitzar() override { inicialitzar(nullptr, false); }
|
||||||
void inicialitzar(const Punt* spawn_point, bool activar_invulnerabilitat = false);
|
void inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat = false);
|
||||||
void processar_input(float delta_time, uint8_t player_id);
|
void processar_input(float delta_time, uint8_t player_id);
|
||||||
void actualitzar(float delta_time) override;
|
void actualitzar(float delta_time) override;
|
||||||
void dibuixar() const override;
|
void dibuixar() const override;
|
||||||
@@ -40,14 +40,14 @@ class Nau : public Entities::Entitat {
|
|||||||
[[nodiscard]] bool esta_viva() const { return !esta_tocada_; }
|
[[nodiscard]] bool esta_viva() const { return !esta_tocada_; }
|
||||||
[[nodiscard]] bool esta_tocada() const { return esta_tocada_; }
|
[[nodiscard]] bool esta_tocada() const { return esta_tocada_; }
|
||||||
[[nodiscard]] bool es_invulnerable() const { return invulnerable_timer_ > 0.0F; }
|
[[nodiscard]] bool es_invulnerable() const { return invulnerable_timer_ > 0.0F; }
|
||||||
[[nodiscard]] Punt get_velocitat_vector() const {
|
[[nodiscard]] Vec2 get_velocitat_vector() const {
|
||||||
return {
|
return {
|
||||||
.x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
|
.x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
|
||||||
.y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
|
.y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setters
|
// Setters
|
||||||
void set_centre(const Punt& nou_centre) { centre_ = nou_centre; }
|
void set_centre(const Vec2& nou_centre) { centre_ = nou_centre; }
|
||||||
|
|
||||||
// Col·lisions (Fase 10)
|
// Col·lisions (Fase 10)
|
||||||
void marcar_tocada() { esta_tocada_ = true; }
|
void marcar_tocada() { esta_tocada_ = true; }
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ void EscenaJoc::inicialitzar() {
|
|||||||
|
|
||||||
if (jugador_actiu) {
|
if (jugador_actiu) {
|
||||||
// Jugador actiu: inicialitzar normalment
|
// Jugador actiu: inicialitzar normalment
|
||||||
Punt spawn_pos = obtenir_punt_spawn(i);
|
Vec2 spawn_pos = obtenir_punt_spawn(i);
|
||||||
naus_[i].inicialitzar(&spawn_pos, false); // No invulnerability at start
|
naus_[i].inicialitzar(&spawn_pos, false); // No invulnerability at start
|
||||||
std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inicialitzat\n";
|
std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inicialitzat\n";
|
||||||
} else {
|
} else {
|
||||||
@@ -326,7 +326,7 @@ void EscenaJoc::actualitzar(float delta_time) {
|
|||||||
|
|
||||||
if (vides_per_jugador_[i] > 0) {
|
if (vides_per_jugador_[i] > 0) {
|
||||||
// Respawn ship en spawn position con invulnerabilidad
|
// Respawn ship en spawn position con invulnerabilidad
|
||||||
Punt spawn_pos = obtenir_punt_spawn(i);
|
Vec2 spawn_pos = obtenir_punt_spawn(i);
|
||||||
naus_[i].inicialitzar(&spawn_pos, true);
|
naus_[i].inicialitzar(&spawn_pos, true);
|
||||||
itocado_per_jugador_[i] = 0.0F;
|
itocado_per_jugador_[i] = 0.0F;
|
||||||
} else {
|
} else {
|
||||||
@@ -397,12 +397,12 @@ void EscenaJoc::actualitzar(float delta_time) {
|
|||||||
|
|
||||||
// [MODIFICAT] Animar AMBAS naus con sus progress respectivos
|
// [MODIFICAT] Animar AMBAS naus con sus progress respectivos
|
||||||
if (config_partida_.jugador1_actiu && ship1_progress < 1.0F) {
|
if (config_partida_.jugador1_actiu && ship1_progress < 1.0F) {
|
||||||
Punt pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0);
|
Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0);
|
||||||
naus_[0].set_centre(pos_p1);
|
naus_[0].set_centre(pos_p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_partida_.jugador2_actiu && ship2_progress < 1.0F) {
|
if (config_partida_.jugador2_actiu && ship2_progress < 1.0F) {
|
||||||
Punt pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1);
|
Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1);
|
||||||
naus_[1].set_centre(pos_p2);
|
naus_[1].set_centre(pos_p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,11 +708,11 @@ void EscenaJoc::tocado(uint8_t player_id) {
|
|||||||
naus_[player_id].marcar_tocada();
|
naus_[player_id].marcar_tocada();
|
||||||
|
|
||||||
// Create ship explosion
|
// Create ship explosion
|
||||||
const Punt& ship_pos = naus_[player_id].get_centre();
|
const Vec2& ship_pos = naus_[player_id].get_centre();
|
||||||
float ship_angle = naus_[player_id].get_angle();
|
float ship_angle = naus_[player_id].get_angle();
|
||||||
Punt vel_nau = naus_[player_id].get_velocitat_vector();
|
Vec2 vel_nau = naus_[player_id].get_velocitat_vector();
|
||||||
// Reduir a 80% la velocitat heretada per la nau (més realista)
|
// Reduir a 80% la velocitat heretada per la nau (més realista)
|
||||||
Punt vel_nau_80 = {.x = vel_nau.x * 0.8F, .y = vel_nau.y * 0.8F};
|
Vec2 vel_nau_80 = {.x = vel_nau.x * 0.8F, .y = vel_nau.y * 0.8F};
|
||||||
|
|
||||||
debris_manager_.explotar(
|
debris_manager_.explotar(
|
||||||
naus_[player_id].get_forma(), // Ship shape (3 lines)
|
naus_[player_id].get_forma(), // Ship shape (3 lines)
|
||||||
@@ -855,7 +855,7 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) {
|
|||||||
text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing);
|
text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
|
Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
|
||||||
// Animació de la nau pujant des de baix amb easing
|
// Animació de la nau pujant des de baix amb easing
|
||||||
// [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END)
|
// [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END)
|
||||||
|
|
||||||
@@ -865,7 +865,7 @@ Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id)
|
|||||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||||
|
|
||||||
// Calcular posició final segons jugador (reutilitza obtenir_punt_spawn)
|
// Calcular posició final segons jugador (reutilitza obtenir_punt_spawn)
|
||||||
Punt spawn_final = obtenir_punt_spawn(player_id);
|
Vec2 spawn_final = obtenir_punt_spawn(player_id);
|
||||||
float x_final = spawn_final.x;
|
float x_final = spawn_final.x;
|
||||||
float y_final = spawn_final.y;
|
float y_final = spawn_final.y;
|
||||||
|
|
||||||
@@ -957,7 +957,7 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() {
|
|||||||
if (Physics::check_collision(bala, enemic, AMPLIFIER)) {
|
if (Physics::check_collision(bala, enemic, AMPLIFIER)) {
|
||||||
// *** COL·LISIÓ DETECTADA ***
|
// *** COL·LISIÓ DETECTADA ***
|
||||||
|
|
||||||
const Punt& pos_enemic = enemic.get_centre();
|
const Vec2& pos_enemic = enemic.get_centre();
|
||||||
|
|
||||||
// 1. Calculate score for enemy type
|
// 1. Calculate score for enemy type
|
||||||
int punts = 0;
|
int punts = 0;
|
||||||
@@ -984,7 +984,7 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() {
|
|||||||
enemic.destruir();
|
enemic.destruir();
|
||||||
|
|
||||||
// 2. Crear explosió de fragments
|
// 2. Crear explosió de fragments
|
||||||
Punt vel_enemic = enemic.get_velocitat_vector();
|
Vec2 vel_enemic = enemic.get_velocitat_vector();
|
||||||
debris_manager_.explotar(
|
debris_manager_.explotar(
|
||||||
enemic.get_forma(), // Forma vectorial del pentàgon
|
enemic.get_forma(), // Forma vectorial del pentàgon
|
||||||
pos_enemic, // Posició central
|
pos_enemic, // Posició central
|
||||||
@@ -1174,7 +1174,7 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
|
|||||||
float y = play_area.y + (play_area.h * Defaults::Game::STAGE_MESSAGE_Y_RATIO) - (text_height / 2.0F);
|
float y = play_area.y + (play_area.h * Defaults::Game::STAGE_MESSAGE_Y_RATIO) - (text_height / 2.0F);
|
||||||
|
|
||||||
// Render only the partial message (typewriter effect)
|
// Render only the partial message (typewriter effect)
|
||||||
Punt pos = {.x = x, .y = y};
|
Vec2 pos = {.x = x, .y = y};
|
||||||
text_.render(partial_message, pos, escala, spacing);
|
text_.render(partial_message, pos, escala, spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1182,7 +1182,7 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
|
|||||||
// Helper methods for 2-player support
|
// Helper methods for 2-player support
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
Punt EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const {
|
Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const {
|
||||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||||
|
|
||||||
float x_ratio;
|
float x_ratio;
|
||||||
@@ -1211,7 +1211,7 @@ void EscenaJoc::disparar_bala(uint8_t player_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calcular posición en la punta de la nave
|
// Calcular posición en la punta de la nave
|
||||||
const Punt& ship_centre = naus_[player_id].get_centre();
|
const Vec2& ship_centre = naus_[player_id].get_centre();
|
||||||
float ship_angle = naus_[player_id].get_angle();
|
float ship_angle = naus_[player_id].get_angle();
|
||||||
|
|
||||||
constexpr float LOCAL_TIP_X = 0.0F;
|
constexpr float LOCAL_TIP_X = 0.0F;
|
||||||
@@ -1220,7 +1220,7 @@ void EscenaJoc::disparar_bala(uint8_t player_id) {
|
|||||||
float sin_a = std::sin(ship_angle);
|
float sin_a = std::sin(ship_angle);
|
||||||
float tip_x = (LOCAL_TIP_X * cos_a) - (LOCAL_TIP_Y * sin_a) + ship_centre.x;
|
float tip_x = (LOCAL_TIP_X * cos_a) - (LOCAL_TIP_Y * sin_a) + ship_centre.x;
|
||||||
float tip_y = (LOCAL_TIP_X * sin_a) + (LOCAL_TIP_Y * cos_a) + ship_centre.y;
|
float tip_y = (LOCAL_TIP_X * sin_a) + (LOCAL_TIP_Y * cos_a) + ship_centre.y;
|
||||||
Punt posicio_dispar = {.x = tip_x, .y = tip_y};
|
Vec2 posicio_dispar = {.x = tip_x, .y = tip_y};
|
||||||
|
|
||||||
// Buscar primera bala inactiva en el pool del jugador
|
// Buscar primera bala inactiva en el pool del jugador
|
||||||
int start_idx = player_id * 3; // P1=[0,1,2], P2=[3,4,5]
|
int start_idx = player_id * 3; // P1=[0,1,2], P2=[3,4,5]
|
||||||
@@ -1295,7 +1295,7 @@ void EscenaJoc::processar_input_continue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Spawn with invulnerability
|
// Spawn with invulnerability
|
||||||
Punt spawn_pos = obtenir_punt_spawn(player_to_revive);
|
Vec2 spawn_pos = obtenir_punt_spawn(player_to_revive);
|
||||||
naus_[player_to_revive].inicialitzar(&spawn_pos, true);
|
naus_[player_to_revive].inicialitzar(&spawn_pos, true);
|
||||||
|
|
||||||
// Check if other player wants to continue too
|
// Check if other player wants to continue too
|
||||||
@@ -1305,7 +1305,7 @@ void EscenaJoc::processar_input_continue() {
|
|||||||
vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES;
|
vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES;
|
||||||
itocado_per_jugador_[other_player] = 0.0F;
|
itocado_per_jugador_[other_player] = 0.0F;
|
||||||
config_partida_.jugador2_actiu = true;
|
config_partida_.jugador2_actiu = true;
|
||||||
Punt spawn_pos2 = obtenir_punt_spawn(other_player);
|
Vec2 spawn_pos2 = obtenir_punt_spawn(other_player);
|
||||||
naus_[other_player].inicialitzar(&spawn_pos2, true);
|
naus_[other_player].inicialitzar(&spawn_pos2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1391,7 +1391,7 @@ void EscenaJoc::unir_jugador(uint8_t player_id) {
|
|||||||
itocado_per_jugador_[player_id] = 0.0F;
|
itocado_per_jugador_[player_id] = 0.0F;
|
||||||
|
|
||||||
// Spawn with invulnerability
|
// Spawn with invulnerability
|
||||||
Punt spawn_pos = obtenir_punt_spawn(player_id);
|
Vec2 spawn_pos = obtenir_punt_spawn(player_id);
|
||||||
naus_[player_id].inicialitzar(&spawn_pos, true);
|
naus_[player_id].inicialitzar(&spawn_pos, true);
|
||||||
|
|
||||||
// No visual message, just spawn (per user requirement)
|
// No visual message, just spawn (per user requirement)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class EscenaJoc {
|
|||||||
float continue_tick_timer_; // Timer for countdown tick (1.0s)
|
float continue_tick_timer_; // Timer for countdown tick (1.0s)
|
||||||
int continues_usados_; // Continues used this game (0-3 max)
|
int continues_usados_; // Continues used this game (0-3 max)
|
||||||
float game_over_timer_; // Final GAME OVER timer before title screen
|
float game_over_timer_; // Final GAME OVER timer before title screen
|
||||||
Punt punt_mort_; // Death position (for respawn)
|
Vec2 punt_mort_; // Death position (for respawn)
|
||||||
std::array<int, 2> puntuacio_per_jugador_; // [0]=P1, [1]=P2
|
std::array<int, 2> puntuacio_per_jugador_; // [0]=P1, [1]=P2
|
||||||
|
|
||||||
// Text vectorial
|
// Text vectorial
|
||||||
@@ -85,7 +85,7 @@ class EscenaJoc {
|
|||||||
void dibuixar_marges() const; // Dibuixar vores de la zona de joc
|
void dibuixar_marges() const; // Dibuixar vores de la zona de joc
|
||||||
void dibuixar_marcador(); // Dibuixar marcador de puntuació
|
void dibuixar_marcador(); // Dibuixar marcador de puntuació
|
||||||
void disparar_bala(uint8_t player_id); // Shoot bullet from player
|
void disparar_bala(uint8_t player_id); // Shoot bullet from player
|
||||||
[[nodiscard]] Punt obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player
|
[[nodiscard]] Vec2 obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player
|
||||||
|
|
||||||
// [NEW] Continue & Join system
|
// [NEW] Continue & Join system
|
||||||
void unir_jugador(uint8_t player_id); // Join inactive player mid-game
|
void unir_jugador(uint8_t player_id); // Join inactive player mid-game
|
||||||
@@ -100,7 +100,7 @@ class EscenaJoc {
|
|||||||
// [NEW] Funcions d'animació per INIT_HUD
|
// [NEW] Funcions d'animació per INIT_HUD
|
||||||
void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme
|
void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme
|
||||||
void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix
|
void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix
|
||||||
[[nodiscard]] Punt calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau
|
[[nodiscard]] Vec2 calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau
|
||||||
|
|
||||||
// [NEW] Función helper del sistema de animación INIT_HUD
|
// [NEW] Función helper del sistema de animación INIT_HUD
|
||||||
[[nodiscard]] float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const;
|
[[nodiscard]] float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const;
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ void EscenaLogo::dibuixar() {
|
|||||||
? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F)
|
? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F)
|
||||||
: 1.0F; // POST: mantenir al 100%
|
: 1.0F; // POST: mantenir al 100%
|
||||||
|
|
||||||
const Punt ORIGEN_ZOOM = {.x = ORIGEN_ZOOM_X, .y = ORIGEN_ZOOM_Y};
|
const Vec2 ORIGEN_ZOOM = {.x = ORIGEN_ZOOM_X, .y = ORIGEN_ZOOM_Y};
|
||||||
|
|
||||||
for (size_t i = 0; i < lletres_.size(); i++) {
|
for (size_t i = 0; i < lletres_.size(); i++) {
|
||||||
const auto& lletra = lletres_[i];
|
const auto& lletra = lletres_[i];
|
||||||
@@ -362,7 +362,7 @@ void EscenaLogo::dibuixar() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Punt pos_actual;
|
Vec2 pos_actual;
|
||||||
pos_actual.x =
|
pos_actual.x =
|
||||||
ORIGEN_ZOOM.x + ((lletra.posicio.x - ORIGEN_ZOOM.x) * letra_progress);
|
ORIGEN_ZOOM.x + ((lletra.posicio.x - ORIGEN_ZOOM.x) * letra_progress);
|
||||||
pos_actual.y =
|
pos_actual.y =
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class EscenaLogo {
|
|||||||
// Estructura per a cada lletra del logo
|
// Estructura per a cada lletra del logo
|
||||||
struct LetraLogo {
|
struct LetraLogo {
|
||||||
std::shared_ptr<Graphics::Shape> forma;
|
std::shared_ptr<Graphics::Shape> forma;
|
||||||
Punt posicio; // Posició final en pantalla
|
Vec2 posicio; // Posició final en pantalla
|
||||||
float ancho; // Ancho del bounding box
|
float ancho; // Ancho del bounding box
|
||||||
float offset_centre; // Distància de min_x a shape_centre.x
|
float offset_centre; // Distància de min_x a shape_centre.x
|
||||||
};
|
};
|
||||||
@@ -74,8 +74,8 @@ class EscenaLogo {
|
|||||||
|
|
||||||
// Constants d'animació seqüencial
|
// Constants d'animació seqüencial
|
||||||
static constexpr float THRESHOLD_LETRA = 0.6F; // Umbral per activar següent lletra (0.0-1.0)
|
static constexpr float THRESHOLD_LETRA = 0.6F; // Umbral per activar següent lletra (0.0-1.0)
|
||||||
static constexpr float ORIGEN_ZOOM_X = Defaults::Game::WIDTH * 0.5F; // Punt inicial X del zoom
|
static constexpr float ORIGEN_ZOOM_X = Defaults::Game::WIDTH * 0.5F; // Vec2 inicial X del zoom
|
||||||
static constexpr float ORIGEN_ZOOM_Y = Defaults::Game::HEIGHT * 0.4F; // Punt inicial Y del zoom
|
static constexpr float ORIGEN_ZOOM_Y = Defaults::Game::HEIGHT * 0.4F; // Vec2 inicial Y del zoom
|
||||||
|
|
||||||
// Mètodes privats
|
// Mètodes privats
|
||||||
void inicialitzar_lletres();
|
void inicialitzar_lletres();
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crear starfield de fons
|
// Crear starfield de fons
|
||||||
Punt centre_pantalla{
|
Vec2 centre_pantalla{
|
||||||
.x = Defaults::Game::WIDTH / 2.0F,
|
.x = Defaults::Game::WIDTH / 2.0F,
|
||||||
.y = Defaults::Game::HEIGHT / 2.0F};
|
.y = Defaults::Game::HEIGHT / 2.0F};
|
||||||
|
|
||||||
@@ -583,7 +583,7 @@ void EscenaTitol::dibuixar() {
|
|||||||
|
|
||||||
// Ombra "ORNI"
|
// Ombra "ORNI"
|
||||||
for (size_t i = 0; i < lletres_orni_.size(); ++i) {
|
for (size_t i = 0; i < lletres_orni_.size(); ++i) {
|
||||||
Punt pos_shadow;
|
Vec2 pos_shadow;
|
||||||
pos_shadow.x = posicions_originals_orni_[i].x + static_cast<int>(std::round(shadow_offset_x));
|
pos_shadow.x = posicions_originals_orni_[i].x + static_cast<int>(std::round(shadow_offset_x));
|
||||||
pos_shadow.y = posicions_originals_orni_[i].y + static_cast<int>(std::round(shadow_offset_y));
|
pos_shadow.y = posicions_originals_orni_[i].y + static_cast<int>(std::round(shadow_offset_y));
|
||||||
|
|
||||||
@@ -600,7 +600,7 @@ void EscenaTitol::dibuixar() {
|
|||||||
|
|
||||||
// Ombra "ATTACK!"
|
// Ombra "ATTACK!"
|
||||||
for (size_t i = 0; i < lletres_attack_.size(); ++i) {
|
for (size_t i = 0; i < lletres_attack_.size(); ++i) {
|
||||||
Punt pos_shadow;
|
Vec2 pos_shadow;
|
||||||
pos_shadow.x = posicions_originals_attack_[i].x + static_cast<int>(std::round(shadow_offset_x));
|
pos_shadow.x = posicions_originals_attack_[i].x + static_cast<int>(std::round(shadow_offset_x));
|
||||||
pos_shadow.y = posicions_originals_attack_[i].y + static_cast<int>(std::round(shadow_offset_y));
|
pos_shadow.y = posicions_originals_attack_[i].y + static_cast<int>(std::round(shadow_offset_y));
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class EscenaTitol {
|
|||||||
// Estructura per emmagatzemar informació de cada lletra del títol
|
// Estructura per emmagatzemar informació de cada lletra del títol
|
||||||
struct LetraLogo {
|
struct LetraLogo {
|
||||||
std::shared_ptr<Graphics::Shape> forma; // Forma vectorial de la lletra
|
std::shared_ptr<Graphics::Shape> forma; // Forma vectorial de la lletra
|
||||||
Punt posicio; // Posició en pantalla
|
Vec2 posicio; // Posició en pantalla
|
||||||
float ancho; // Amplada escalada
|
float ancho; // Amplada escalada
|
||||||
float altura; // Altura escalada
|
float altura; // Altura escalada
|
||||||
float offset_centre; // Offset del centre per posicionament
|
float offset_centre; // Offset del centre per posicionament
|
||||||
@@ -66,8 +66,8 @@ class EscenaTitol {
|
|||||||
|
|
||||||
// Estat d'animació del logo
|
// Estat d'animació del logo
|
||||||
float temps_animacio_; // Temps acumulat per animació orbital
|
float temps_animacio_; // Temps acumulat per animació orbital
|
||||||
std::vector<Punt> posicions_originals_orni_; // Posicions originals de "ORNI"
|
std::vector<Vec2> posicions_originals_orni_; // Posicions originals de "ORNI"
|
||||||
std::vector<Punt> posicions_originals_attack_; // Posicions originals de "ATTACK!"
|
std::vector<Vec2> posicions_originals_attack_; // Posicions originals de "ATTACK!"
|
||||||
|
|
||||||
// Estat d'arrencada de l'animació
|
// Estat d'arrencada de l'animació
|
||||||
float temps_estat_main_; // Temps acumulat en estat MAIN
|
float temps_estat_main_; // Temps acumulat en estat MAIN
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ TipusEnemic SpawnController::seleccionar_tipus_aleatori() const {
|
|||||||
return TipusEnemic::MOLINILLO;
|
return TipusEnemic::MOLINILLO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos) {
|
void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Vec2* ship_pos) {
|
||||||
// Initialize enemy (with safe spawn if ship_pos provided)
|
// Initialize enemy (with safe spawn if ship_pos provided)
|
||||||
enemic.inicialitzar(tipus, ship_pos);
|
enemic.inicialitzar(tipus, ship_pos);
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class SpawnController {
|
|||||||
[[nodiscard]] uint8_t get_enemics_spawnejats() const;
|
[[nodiscard]] uint8_t get_enemics_spawnejats() const;
|
||||||
|
|
||||||
// [NEW] Set ship position reference for safe spawn
|
// [NEW] Set ship position reference for safe spawn
|
||||||
void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; }
|
void set_ship_position(const Vec2* ship_pos) { ship_position_ = ship_pos; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ConfigStage* config_; // Non-owning pointer to current stage config
|
const ConfigStage* config_; // Non-owning pointer to current stage config
|
||||||
@@ -50,9 +50,9 @@ class SpawnController {
|
|||||||
// Spawn generation
|
// Spawn generation
|
||||||
void generar_spawn_events();
|
void generar_spawn_events();
|
||||||
[[nodiscard]] TipusEnemic seleccionar_tipus_aleatori() const;
|
[[nodiscard]] TipusEnemic seleccionar_tipus_aleatori() const;
|
||||||
void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos = nullptr);
|
void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Vec2* ship_pos = nullptr);
|
||||||
void aplicar_multiplicadors(Enemic& enemic) const;
|
void aplicar_multiplicadors(Enemic& enemic) const;
|
||||||
const Punt* ship_position_; // [NEW] Non-owning pointer to ship position
|
const Vec2* ship_position_; // [NEW] Non-owning pointer to ship position
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace StageSystem
|
} // namespace StageSystem
|
||||||
|
|||||||
@@ -232,8 +232,8 @@ void ShipAnimator::actualitzar_exiting(NauTitol& nau, float delta_time) {
|
|||||||
// Aplicar easing (ease_in_quad per acceleració cap al punt de fuga)
|
// Aplicar easing (ease_in_quad per acceleració cap al punt de fuga)
|
||||||
float eased_progress = Easing::ease_in_quad(progress);
|
float eased_progress = Easing::ease_in_quad(progress);
|
||||||
|
|
||||||
// Punt de fuga (centre del starfield)
|
// Vec2 de fuga (centre del starfield)
|
||||||
constexpr Punt punt_fuga{.x = VANISHING_POINT_X, .y = VANISHING_POINT_Y};
|
constexpr Vec2 punt_fuga{.x = VANISHING_POINT_X, .y = VANISHING_POINT_Y};
|
||||||
|
|
||||||
// Lerp posició cap al punt de fuga (preservar posició inicial actual)
|
// Lerp posició cap al punt de fuga (preservar posició inicial actual)
|
||||||
// Nota: posicio_inicial conté la posició on estava quan es va activar EXITING
|
// Nota: posicio_inicial conté la posició on estava quan es va activar EXITING
|
||||||
@@ -320,7 +320,7 @@ void ShipAnimator::configurar_nau_p2(NauTitol& nau) {
|
|||||||
nau.visible = true;
|
nau.visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Punt ShipAnimator::calcular_posicio_fora_pantalla(float angle_rellotge) const {
|
Vec2 ShipAnimator::calcular_posicio_fora_pantalla(float angle_rellotge) const {
|
||||||
using namespace Defaults::Title::Ships;
|
using namespace Defaults::Title::Ships;
|
||||||
|
|
||||||
// Convertir angle del rellotge a radians (per exemple: 240° per clock 8)
|
// Convertir angle del rellotge a radians (per exemple: 240° per clock 8)
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ struct NauTitol {
|
|||||||
float temps_estat; // Temps acumulat en l'estat actual
|
float temps_estat; // Temps acumulat en l'estat actual
|
||||||
|
|
||||||
// Posicions
|
// Posicions
|
||||||
Punt posicio_inicial; // Posició d'inici (fora de pantalla per ENTERING)
|
Vec2 posicio_inicial; // Posició d'inici (fora de pantalla per ENTERING)
|
||||||
Punt posicio_objectiu; // Posició objectiu (rellotge 8 o 4)
|
Vec2 posicio_objectiu; // Posició objectiu (rellotge 8 o 4)
|
||||||
Punt posicio_actual; // Posició interpolada actual
|
Vec2 posicio_actual; // Posició interpolada actual
|
||||||
|
|
||||||
// Escales (simulació eix Z)
|
// Escales (simulació eix Z)
|
||||||
float escala_inicial; // Escala d'inici (més gran = més a prop)
|
float escala_inicial; // Escala d'inici (més gran = més a prop)
|
||||||
@@ -91,7 +91,7 @@ class ShipAnimator {
|
|||||||
// Configuració
|
// Configuració
|
||||||
void configurar_nau_p1(NauTitol& nau);
|
void configurar_nau_p1(NauTitol& nau);
|
||||||
void configurar_nau_p2(NauTitol& nau);
|
void configurar_nau_p2(NauTitol& nau);
|
||||||
[[nodiscard]] Punt calcular_posicio_fora_pantalla(float angle_rellotge) const;
|
[[nodiscard]] Vec2 calcular_posicio_fora_pantalla(float angle_rellotge) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Title
|
} // namespace Title
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// main.cpp - Punt d'entrada del joc Asteroides
|
// main.cpp - Vec2 d'entrada del joc Asteroides
|
||||||
// © 1999 Visente i Sergi (versió Pascal)
|
// © 1999 Visente i Sergi (versió Pascal)
|
||||||
// © 2025 Port a C++20 amb SDL3
|
// © 2025 Port a C++20 amb SDL3
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user