migrant a SDL3

This commit is contained in:
2025-11-27 17:32:01 +01:00
parent 93fed0b984
commit 0d69af667d
4 changed files with 688 additions and 90 deletions

View File

@@ -29,8 +29,8 @@ void JocAsteroides::inicialitzar() {
nau_.p3.angle = (3.0f * Constants::PI) / 4.0f; // 135°
nau_.angle = 0.0f;
nau_.centre.x = 320;
nau_.centre.y = 240;
nau_.centre.x = 320.0f;
nau_.centre.y = 240.0f;
nau_.velocitat = 0.0f;
// Inicialitzar estat de col·lisió
@@ -43,8 +43,8 @@ void JocAsteroides::inicialitzar() {
crear_poligon_regular(orni_[i], 5, 20.0f);
// Posició aleatòria dins de l'àrea de joc
orni_[i].centre.x = (std::rand() % 580) + 30; // 30-610
orni_[i].centre.y = (std::rand() % 420) + 30; // 30-450
orni_[i].centre.x = static_cast<float>((std::rand() % 580) + 30); // 30-610
orni_[i].centre.y = static_cast<float>((std::rand() % 420) + 30); // 30-450
// Angle aleatori
orni_[i].angle = (std::rand() % 360) * Constants::PI / 180.0f;
@@ -52,6 +52,16 @@ void JocAsteroides::inicialitzar() {
// Està actiu
orni_[i].esta = true;
}
// Inicialitzar bales
// Basat en el codi Pascal original: inicialment inactives
for (int i = 0; i < Constants::MAX_BALES; i++) {
// Crear pentàgon petit (5 costats, radi 5)
crear_poligon_regular(bales_[i], 5, 5.0f);
// Inicialment inactiva
bales_[i].esta = false;
}
}
void JocAsteroides::actualitzar(float delta_time) {
@@ -59,11 +69,11 @@ void JocAsteroides::actualitzar(float delta_time) {
// Basat en el codi Pascal original: lines 394-417
// Convertit a time-based per ser independent del framerate
// Constants de física (calibrades per sentir-se com l'original a ~20 FPS)
constexpr float ROTATION_SPEED = 2.5f; // ~143°/s (rotació suau)
constexpr float ACCELERATION = 100.0f; // px/s² (acceleració notable)
constexpr float MAX_VELOCITY = 200.0f; // px/s (velocitat màxima)
constexpr float FRICTION = 6.0f; // px/s² (fricció notable)
// Constants de física (convertides des del Pascal original a ~20 FPS)
constexpr float ROTATION_SPEED = 3.14f; // rad/s (0.157 rad/frame × 20 = 3.14 rad/s, ~180°/s)
constexpr float ACCELERATION = 400.0f; // px/s² (0.2 u/frame × 20 × 100 = 400 px/s²)
constexpr float MAX_VELOCITY = 120.0f; // px/s (6 u/frame × 20 = 120 px/s)
constexpr float FRICTION = 20.0f; // px/s² (0.1 u/frame × 20 × 10 = 20 px/s²)
// Obtenir estat actual del teclat (no events, sinó estat continu)
const bool* keyboard_state = SDL_GetKeyboardState(nullptr);
@@ -95,12 +105,13 @@ void JocAsteroides::actualitzar(float delta_time) {
+ nau_.centre.x;
// Boundary checking - només actualitzar si dins dels marges
// Acumulació directa amb precisió subpíxel
if (dy > Constants::MARGE_DALT && dy < Constants::MARGE_BAIX) {
nau_.centre.y = static_cast<int>(std::round(dy));
nau_.centre.y = dy;
}
if (dx > Constants::MARGE_ESQ && dx < Constants::MARGE_DRET) {
nau_.centre.x = static_cast<int>(std::round(dx));
nau_.centre.x = dx;
}
// Fricció - desacceleració gradual (time-based)
@@ -124,25 +135,33 @@ void JocAsteroides::actualitzar(float delta_time) {
time_accumulator -= 1.0f;
}
// Actualitzar rotació dels enemics
// Actualitzar moviment i rotació dels enemics (ORNIs)
// Basat en el codi Pascal original: lines 429-432
for (auto& enemy : orni_) {
if (enemy.esta) {
enemy.rotacio += enemy.drotacio;
// Moviment autònom (Fase 8)
mou_orni(enemy, delta_time);
// Rotació visual (time-based: drotacio està en rad/s)
enemy.rotacio += enemy.drotacio * delta_time;
}
}
// TODO: Actualitzar moviment ORNIs (Fase 8)
// TODO: Actualitzar bales (Fase 9)
// Actualitzar moviment de bales (Fase 9)
for (auto& bala : bales_) {
if (bala.esta) {
mou_bales(bala, delta_time);
}
}
}
void JocAsteroides::dibuixar() {
// Dibuixar la nau si no està en seqüència de mort
if (itocado_ == 0) {
// Escalar velocitat per l'efect visual (200 px/s → ~6 px d'efecte)
// Escalar velocitat per l'efect visual (120 px/s → ~6 px d'efecte)
// El codi Pascal original sumava velocitat (0-6) al radi per donar
// sensació de "empenta". Ara velocitat està en px/s (0-200).
float velocitat_visual = nau_.velocitat / 33.33f;
// sensació de "empenta". Ara velocitat està en px/s (0-120).
float velocitat_visual = nau_.velocitat / 20.0f;
rota_tri(nau_, nau_.angle, velocitat_visual, true);
}
@@ -154,7 +173,14 @@ void JocAsteroides::dibuixar() {
}
}
// TODO: Dibuixar bales (Fase 9)
// Dibuixar bales (Fase 9)
for (const auto& bala : bales_) {
if (bala.esta) {
// Dibuixar com a pentàgon petit, sense rotació visual (sempre mateix angle)
rota_pol(bala, 0.0f, true);
}
}
// TODO: Dibuixar marges (Fase 11)
}
@@ -166,6 +192,30 @@ void JocAsteroides::processar_input(const SDL_Event& event) {
switch (event.key.key) {
case SDLK_SPACE:
// Disparar (Fase 9)
// Basat en el codi Pascal original: crear bala en posició de la nau
// El joc original només permetia 1 bala activa alhora
// Buscar primera bala inactiva
for (auto& bala : bales_) {
if (!bala.esta) {
// Activar bala
bala.esta = true;
// Posició inicial = centre de la nau
bala.centre.x = nau_.centre.x;
bala.centre.y = nau_.centre.y;
// Angle = angle de la nau (dispara en la direcció que apunta)
bala.angle = nau_.angle;
// Velocitat alta (el joc Pascal original usava 7 px/frame)
// 7 px/frame × 20 FPS = 140 px/s
bala.velocitat = 140.0f;
// Només una bala alhora (com el joc original)
break;
}
}
break;
default:
@@ -217,12 +267,14 @@ void JocAsteroides::crear_poligon_regular(Poligon& pol, uint8_t n, float r) {
}
// Inicialitzar propietats del polígon
pol.centre.x = 320;
pol.centre.y = 200;
pol.centre.x = 320.0f;
pol.centre.y = 200.0f;
pol.angle = 0.0f;
pol.velocitat = static_cast<float>(Constants::VELOCITAT);
// Convertir velocitat de px/frame a px/s: 2 px/frame × 20 FPS = 40 px/s
pol.velocitat = static_cast<float>(Constants::VELOCITAT) * 20.0f;
pol.n = n;
pol.drotacio = 0.078539816f; // ~4.5 graus per frame
// Convertir rotació de rad/frame a rad/s: 0.0785 rad/frame × 20 FPS = 1.57 rad/s (~90°/s)
pol.drotacio = 0.078539816f * 20.0f;
pol.rotacio = 0.0f;
pol.esta = true;
}
@@ -364,12 +416,66 @@ void JocAsteroides::rota_pol(const Poligon& pol, float angul, bool dibuixar) {
linea(xy[pol.n - 1].x, xy[pol.n - 1].y, xy[0].x, xy[0].y, dibuixar);
}
void JocAsteroides::mou_orni(Poligon& orni) {
// TODO: Implementar moviment d'ORNI
void JocAsteroides::mou_orni(Poligon& orni, float delta_time) {
// Moviment autònom d'ORNI (enemic pentàgon)
// Basat en el codi Pascal original: procedure mou_orni
// Cambio aleatori d'angle (5% probabilitat per crida)
// En el Pascal original: if (random<0.05) then orni.angle:=random*2*pi
float random_val = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
if (random_val < 0.05f) {
// Assignar un angle completament aleatori (0-360°)
orni.angle = (static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX))
* 2.0f * Constants::PI;
}
// Calcular nova posició (moviment polar time-based)
// velocitat ja està en px/s (40 px/s), només cal multiplicar per delta_time
float velocitat_efectiva = orni.velocitat * delta_time;
// Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt)
float dy = velocitat_efectiva * std::sin(orni.angle - Constants::PI / 2.0f);
float dx = velocitat_efectiva * std::cos(orni.angle - Constants::PI / 2.0f);
// Acumulació directa amb precisió subpíxel
orni.centre.y += dy;
orni.centre.x += dx;
// Boundary checking amb rebot (reflexió d'angle)
// Si toca paret esquerra/dreta: angle = PI - angle
if (orni.centre.x < Constants::MARGE_ESQ || orni.centre.x > Constants::MARGE_DRET) {
orni.angle = Constants::PI - orni.angle;
}
// Si toca paret dalt/baix: angle = 2*PI - angle
if (orni.centre.y < Constants::MARGE_DALT || orni.centre.y > Constants::MARGE_BAIX) {
orni.angle = 2.0f * Constants::PI - orni.angle;
}
// Nota: La rotació visual (orni.rotacio += orni.drotacio) ja es fa a actualitzar()
}
void JocAsteroides::mou_bales(Poligon& bala) {
// TODO: Implementar moviment de bala
void JocAsteroides::mou_bales(Poligon& bala, float delta_time) {
// Moviment rectilini de la bala
// Basat en el codi Pascal original: procedure mou_bales
// 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 = bala.velocitat * delta_time;
// Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt)
float dy = velocitat_efectiva * std::sin(bala.angle - Constants::PI / 2.0f);
float dx = velocitat_efectiva * std::cos(bala.angle - Constants::PI / 2.0f);
// Acumulació directa amb precisió subpíxel
bala.centre.y += dy;
bala.centre.x += dx;
// Desactivar si surt dels marges (no rebota com els ORNIs)
if (bala.centre.x < Constants::MARGE_ESQ || bala.centre.x > Constants::MARGE_DRET ||
bala.centre.y < Constants::MARGE_DALT || bala.centre.y > Constants::MARGE_BAIX) {
bala.esta = false;
}
}
void JocAsteroides::tocado() {

View File

@@ -30,8 +30,8 @@ struct IPunt {
};
struct Punt {
int x;
int y;
float x;
float y;
};
struct Triangle {
@@ -86,8 +86,8 @@ private:
void rota_pol(const Poligon& pol, float angul, bool dibuixar);
// Moviment
void mou_orni(Poligon& orni);
void mou_bales(Poligon& bala);
void mou_orni(Poligon& orni, float delta_time);
void mou_bales(Poligon& bala, float delta_time);
void tocado();
};