treballant en les naus de title
This commit is contained in:
@@ -358,6 +358,60 @@ constexpr int MOLINILLO_SCORE = 200; // Molinillo (agressiu, 50 px/s)
|
||||
|
||||
} // namespace Enemies
|
||||
|
||||
// Title scene ship animations (naus 3D flotants a l'escena de títol)
|
||||
namespace Title {
|
||||
namespace Ships {
|
||||
// Posicions clock (coordenades polars des del centre 320, 240)
|
||||
// En coordenades de pantalla: 0° = dreta, 90° = baix, 180° = esquerra, 270° = dalt
|
||||
constexpr float CLOCK_8_ANGLE = 150.0f * Math::PI / 180.0f; // 8 o'clock = bottom-left
|
||||
constexpr float CLOCK_4_ANGLE = 30.0f * Math::PI / 180.0f; // 4 o'clock = bottom-right
|
||||
constexpr float CLOCK_RADIUS = 150.0f; // Distància des del centre
|
||||
|
||||
// P1 (8 o'clock, bottom-left)
|
||||
// 150° → cos(150°)=-0.866, sin(150°)=0.5 → X = 320 - 130 = 190, Y = 240 + 75 = 315
|
||||
constexpr float P1_TARGET_X = 190.0f;
|
||||
constexpr float P1_TARGET_Y = 315.0f;
|
||||
|
||||
// P2 (4 o'clock, bottom-right)
|
||||
// 30° → cos(30°)=0.866, sin(30°)=0.5 → X = 320 + 130 = 450, Y = 240 + 75 = 315
|
||||
constexpr float P2_TARGET_X = 450.0f;
|
||||
constexpr float P2_TARGET_Y = 315.0f;
|
||||
|
||||
// Escala base de les naus (ajusta aquí per fer-les més grans o petites)
|
||||
constexpr float SHIP_BASE_SCALE = 2.5f; // Multiplicador global (1.0 = mida original)
|
||||
|
||||
// Escales d'animació (perspectiva ja incorporada a les formes .shp)
|
||||
constexpr float ENTRY_SCALE_START = 1.5f * SHIP_BASE_SCALE; // Més gran per veure millor
|
||||
constexpr float FLOATING_SCALE = 1.0f * SHIP_BASE_SCALE; // Mida normal (més grans)
|
||||
|
||||
// Animacions
|
||||
constexpr float ENTRY_DURATION = 2.0f; // Entrada
|
||||
constexpr float ENTRY_OFFSET = 340.0f; // Offset fora de pantalla (considera radi màxim 30px * escala 3.75 + marge)
|
||||
constexpr float EXIT_DURATION = 1.0f; // Sortida (configurable)
|
||||
|
||||
// Flotació (oscil·lació reduïda i diferenciada per nau)
|
||||
constexpr float FLOAT_AMPLITUDE_X = 4.0f; // Era 6.0f
|
||||
constexpr float FLOAT_AMPLITUDE_Y = 2.5f; // Era 4.0f
|
||||
|
||||
// Freqüències base
|
||||
constexpr float FLOAT_FREQUENCY_X_BASE = 0.5f;
|
||||
constexpr float FLOAT_FREQUENCY_Y_BASE = 0.7f;
|
||||
constexpr float FLOAT_PHASE_OFFSET = 1.57f; // π/2 (90°)
|
||||
|
||||
// Delays d'entrada
|
||||
constexpr float P1_ENTRY_DELAY = 0.0f; // P1 entra immediatament
|
||||
constexpr float P2_ENTRY_DELAY = 0.5f; // P2 entra 0.5s després
|
||||
|
||||
// Multiplicadors de freqüència per a cada nau (variació sutil ±12%)
|
||||
constexpr float P1_FREQUENCY_MULTIPLIER = 0.88f; // 12% més lenta
|
||||
constexpr float P2_FREQUENCY_MULTIPLIER = 1.12f; // 12% més ràpida
|
||||
|
||||
// Punt de fuga
|
||||
constexpr float VANISHING_POINT_X = Game::WIDTH / 2.0f; // 320.0f
|
||||
constexpr float VANISHING_POINT_Y = Game::HEIGHT / 2.0f; // 240.0f
|
||||
} // namespace Ships
|
||||
} // namespace Title
|
||||
|
||||
// Floating score numbers (números flotants de puntuació)
|
||||
namespace FloatingScore {
|
||||
constexpr float LIFETIME = 2.0f; // Duració màxima (segons)
|
||||
|
||||
@@ -10,17 +10,55 @@
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
// Helper: aplicar rotació 3D a un punt 2D (assumeix Z=0)
|
||||
static Punt apply_3d_rotation(float x, float y, const Rotation3D& rot) {
|
||||
float z = 0.0f; // Tots els punts 2D comencen a Z=0
|
||||
|
||||
// Pitch (rotació eix X): cabeceo arriba/baix
|
||||
float cos_pitch = std::cos(rot.pitch);
|
||||
float sin_pitch = std::sin(rot.pitch);
|
||||
float y1 = y * cos_pitch - z * sin_pitch;
|
||||
float z1 = y * sin_pitch + z * cos_pitch;
|
||||
|
||||
// Yaw (rotació eix Y): guiñada esquerra/dreta
|
||||
float cos_yaw = std::cos(rot.yaw);
|
||||
float sin_yaw = std::sin(rot.yaw);
|
||||
float x2 = x * cos_yaw + z1 * sin_yaw;
|
||||
float z2 = -x * sin_yaw + z1 * cos_yaw;
|
||||
|
||||
// Roll (rotació eix Z): alabeo lateral
|
||||
float cos_roll = std::cos(rot.roll);
|
||||
float sin_roll = std::sin(rot.roll);
|
||||
float x3 = x2 * cos_roll - y1 * sin_roll;
|
||||
float y3 = x2 * sin_roll + y1 * cos_roll;
|
||||
|
||||
// Proyecció perspectiva (Z-divide simple)
|
||||
// Naus volen cap al punt de fuga (320, 240) a "infinit" (Z → +∞)
|
||||
// Z més gran = més lluny = més petit a pantalla
|
||||
constexpr float perspective_factor = 500.0f;
|
||||
float scale_factor = perspective_factor / (perspective_factor + z2);
|
||||
|
||||
return {x3 * scale_factor, y3 * scale_factor};
|
||||
}
|
||||
|
||||
// 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) {
|
||||
static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala, const Rotation3D* rotation_3d) {
|
||||
// 1. Centrar el punt respecte al centre de la forma
|
||||
float centered_x = point.x - shape_centre.x;
|
||||
float centered_y = point.y - shape_centre.y;
|
||||
|
||||
// 2. Aplicar escala al punt centrat
|
||||
// 2. Aplicar rotació 3D (si es proporciona)
|
||||
if (rotation_3d && rotation_3d->has_rotation()) {
|
||||
Punt rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d);
|
||||
centered_x = rotated_3d.x;
|
||||
centered_y = rotated_3d.y;
|
||||
}
|
||||
|
||||
// 3. Aplicar escala al punt (després de rotació 3D)
|
||||
float scaled_x = centered_x * escala;
|
||||
float scaled_y = centered_y * escala;
|
||||
|
||||
// 3. Aplicar rotació
|
||||
// 4. Aplicar rotació 2D (Z-axis, tradicional)
|
||||
// IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no dreta)
|
||||
// Per això usem (angle - PI/2) per compensar
|
||||
// Però aquí angle ja ve en el sistema correcte del joc
|
||||
@@ -30,7 +68,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P
|
||||
float rotated_x = scaled_x * cos_a - scaled_y * sin_a;
|
||||
float rotated_y = scaled_x * sin_a + scaled_y * cos_a;
|
||||
|
||||
// 4. Aplicar trasllació a posició mundial
|
||||
// 5. Aplicar trasllació a posició mundial
|
||||
return {rotated_x + posicio.x, rotated_y + posicio.y};
|
||||
}
|
||||
|
||||
@@ -41,7 +79,8 @@ void render_shape(SDL_Renderer* renderer,
|
||||
float escala,
|
||||
bool dibuixar,
|
||||
float progress,
|
||||
float brightness) {
|
||||
float brightness,
|
||||
const Rotation3D* rotation_3d) {
|
||||
// Verificar que la forma és vàlida
|
||||
if (!shape || !shape->es_valida()) {
|
||||
return;
|
||||
@@ -60,16 +99,16 @@ void render_shape(SDL_Renderer* renderer,
|
||||
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
|
||||
// POLYLINE: connectar punts consecutius
|
||||
for (size_t i = 0; i < primitive.points.size() - 1; i++) {
|
||||
Punt p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala);
|
||||
Punt p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala);
|
||||
Punt 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);
|
||||
|
||||
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y), static_cast<int>(p2.x), static_cast<int>(p2.y), dibuixar, brightness);
|
||||
}
|
||||
} else { // PrimitiveType::LINE
|
||||
// LINE: exactament 2 punts
|
||||
if (primitive.points.size() >= 2) {
|
||||
Punt p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala);
|
||||
Punt p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala);
|
||||
Punt 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);
|
||||
|
||||
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y), static_cast<int>(p2.x), static_cast<int>(p2.y), dibuixar, brightness);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,20 @@
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
// Estructura per rotacions 3D (pitch, yaw, roll)
|
||||
struct Rotation3D {
|
||||
float pitch; // Rotació eix X (cabeceo arriba/baix)
|
||||
float yaw; // Rotació eix Y (guiñada esquerra/dreta)
|
||||
float roll; // Rotació eix Z (alabeo lateral)
|
||||
|
||||
Rotation3D() : pitch(0.0f), yaw(0.0f), roll(0.0f) {}
|
||||
Rotation3D(float p, float y, float r) : pitch(p), yaw(y), roll(r) {}
|
||||
|
||||
bool has_rotation() const {
|
||||
return pitch != 0.0f || yaw != 0.0f || roll != 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
// Renderitzar forma amb transformacions
|
||||
// - renderer: SDL renderer
|
||||
// - shape: forma vectorial a dibuixar
|
||||
@@ -28,6 +42,7 @@ void render_shape(SDL_Renderer* renderer,
|
||||
float escala = 1.0f,
|
||||
bool dibuixar = true,
|
||||
float progress = 1.0f,
|
||||
float brightness = 1.0f);
|
||||
float brightness = 1.0f,
|
||||
const Rotation3D* rotation_3d = nullptr);
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
Reference in New Issue
Block a user