LOGO explota

This commit is contained in:
2025-12-02 08:50:38 +01:00
parent 73f222fcb7
commit 20538af4c6
22 changed files with 1754 additions and 1598 deletions

View File

@@ -3,233 +3,238 @@
// © 2025 Port a C++20 amb SDL3
#include "escena_joc.hpp"
#include "../../core/rendering/line_renderer.hpp"
#include "../../core/system/gestor_escenes.hpp"
#include "../../core/system/global_events.hpp"
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
EscenaJoc::EscenaJoc(SDLManager &sdl)
: sdl_(sdl), debris_manager_(sdl.obte_renderer()),
nau_(sdl.obte_renderer()), itocado_(0), text_(sdl.obte_renderer()) {
// Inicialitzar bales amb renderer
for (auto &bala : bales_) {
bala = Bala(sdl.obte_renderer());
}
#include "../../core/rendering/line_renderer.hpp"
#include "../../core/system/gestor_escenes.hpp"
#include "../../core/system/global_events.hpp"
// Inicialitzar enemics amb renderer
for (auto &enemy : orni_) {
enemy = Enemic(sdl.obte_renderer());
}
EscenaJoc::EscenaJoc(SDLManager& sdl)
: sdl_(sdl),
debris_manager_(sdl.obte_renderer()),
nau_(sdl.obte_renderer()),
itocado_(0),
text_(sdl.obte_renderer()) {
// Inicialitzar bales amb renderer
for (auto& bala : bales_) {
bala = Bala(sdl.obte_renderer());
}
// Inicialitzar enemics amb renderer
for (auto& enemy : orni_) {
enemy = Enemic(sdl.obte_renderer());
}
}
void EscenaJoc::executar() {
std::cout << "Escena Joc: Inicialitzant...\n";
std::cout << "Escena Joc: Inicialitzant...\n";
// Inicialitzar estat del joc
inicialitzar();
// Inicialitzar estat del joc
inicialitzar();
SDL_Event event;
Uint64 last_time = SDL_GetTicks();
SDL_Event event;
Uint64 last_time = SDL_GetTicks();
while (GestorEscenes::actual == GestorEscenes::Escena::JOC) {
// Calcular delta_time real
Uint64 current_time = SDL_GetTicks();
float delta_time = (current_time - last_time) / 1000.0f;
last_time = current_time;
while (GestorEscenes::actual == GestorEscenes::Escena::JOC) {
// Calcular delta_time real
Uint64 current_time = SDL_GetTicks();
float delta_time = (current_time - last_time) / 1000.0f;
last_time = current_time;
// Limitar delta_time per evitar grans salts
if (delta_time > 0.05f) {
delta_time = 0.05f;
// Limitar delta_time per evitar grans salts
if (delta_time > 0.05f) {
delta_time = 0.05f;
}
// Processar events SDL
while (SDL_PollEvent(&event)) {
// Manejo de finestra
if (sdl_.handleWindowEvent(event)) {
continue;
}
// Events globals (F1/F2/F3/ESC/QUIT)
if (GlobalEvents::handle(event, sdl_)) {
continue;
}
// Processament específic del joc (SPACE per disparar)
processar_input(event);
}
// Actualitzar física del joc amb delta_time real
actualitzar(delta_time);
// Actualitzar colors oscil·lats
sdl_.updateColors(delta_time);
// Netejar pantalla (usa color oscil·lat)
sdl_.neteja(0, 0, 0);
// Dibuixar joc
dibuixar();
// Presentar renderer (swap buffers)
sdl_.presenta();
}
// Processar events SDL
while (SDL_PollEvent(&event)) {
// Manejo de finestra
if (sdl_.handleWindowEvent(event)) {
continue;
}
// Events globals (F1/F2/F3/ESC/QUIT)
if (GlobalEvents::handle(event, sdl_)) {
continue;
}
// Processament específic del joc (SPACE per disparar)
processar_input(event);
}
// Actualitzar física del joc amb delta_time real
actualitzar(delta_time);
// Actualitzar colors oscil·lats
sdl_.updateColors(delta_time);
// Netejar pantalla (usa color oscil·lat)
sdl_.neteja(0, 0, 0);
// Dibuixar joc
dibuixar();
// Presentar renderer (swap buffers)
sdl_.presenta();
}
std::cout << "Escena Joc: Finalitzant...\n";
std::cout << "Escena Joc: Finalitzant...\n";
}
void EscenaJoc::inicialitzar() {
// Inicialitzar generador de números aleatoris
// Basat en el codi Pascal original: line 376
std::srand(static_cast<unsigned>(std::time(nullptr)));
// Inicialitzar generador de números aleatoris
// Basat en el codi Pascal original: line 376
std::srand(static_cast<unsigned>(std::time(nullptr)));
// Inicialitzar estat de col·lisió
itocado_ = 0;
// Inicialitzar estat de col·lisió
itocado_ = 0;
// Inicialitzar nau
nau_.inicialitzar();
// Inicialitzar nau
nau_.inicialitzar();
// Inicialitzar enemics (ORNIs)
for (auto &enemy : orni_) {
enemy.inicialitzar();
}
// Inicialitzar enemics (ORNIs)
for (auto& enemy : orni_) {
enemy.inicialitzar();
}
// Inicialitzar bales
for (auto &bala : bales_) {
bala.inicialitzar();
}
// Inicialitzar bales
for (auto& bala : bales_) {
bala.inicialitzar();
}
}
void EscenaJoc::actualitzar(float delta_time) {
// Actualitzar nau (input + física)
nau_.processar_input(delta_time);
nau_.actualitzar(delta_time);
// Actualitzar nau (input + física)
nau_.processar_input(delta_time);
nau_.actualitzar(delta_time);
// Actualitzar moviment i rotació dels enemics (ORNIs)
for (auto &enemy : orni_) {
enemy.actualitzar(delta_time);
}
// Actualitzar moviment i rotació dels enemics (ORNIs)
for (auto& enemy : orni_) {
enemy.actualitzar(delta_time);
}
// Actualitzar moviment de bales (Fase 9)
for (auto &bala : bales_) {
bala.actualitzar(delta_time);
}
// Actualitzar moviment de bales (Fase 9)
for (auto& bala : bales_) {
bala.actualitzar(delta_time);
}
// Actualitzar fragments d'explosions
debris_manager_.actualitzar(delta_time);
// Actualitzar fragments d'explosions
debris_manager_.actualitzar(delta_time);
}
void EscenaJoc::dibuixar() {
// Dibuixar marges de la zona de joc
dibuixar_marges();
// Dibuixar marges de la zona de joc
dibuixar_marges();
// Dibuixar nau
nau_.dibuixar();
// Dibuixar nau
nau_.dibuixar();
// Dibuixar ORNIs (enemics)
for (const auto &enemy : orni_) {
enemy.dibuixar();
}
// Dibuixar ORNIs (enemics)
for (const auto& enemy : orni_) {
enemy.dibuixar();
}
// Dibuixar bales (Fase 9)
for (const auto &bala : bales_) {
bala.dibuixar();
}
// Dibuixar bales (Fase 9)
for (const auto& bala : bales_) {
bala.dibuixar();
}
// Dibuixar fragments d'explosions (després d'altres objectes)
debris_manager_.dibuixar();
// Dibuixar fragments d'explosions (després d'altres objectes)
debris_manager_.dibuixar();
// Dibuixar marcador
dibuixar_marcador();
// Dibuixar marcador
dibuixar_marcador();
}
void EscenaJoc::processar_input(const SDL_Event &event) {
// Processament d'input per events puntuals (no continus)
// L'input continu (fletxes) es processa en actualitzar() amb
// SDL_GetKeyboardState()
void EscenaJoc::processar_input(const SDL_Event& event) {
// Processament d'input per events puntuals (no continus)
// L'input continu (fletxes) es processa en actualitzar() amb
// SDL_GetKeyboardState()
if (event.type == SDL_EVENT_KEY_DOWN) {
switch (event.key.key) {
case SDLK_SPACE: {
// TEMPORAL: Explotar enemic aleatori (per testing)
// TODO: Restaurar dispars quan el sistema d'explosions estiga validat
if (event.type == SDL_EVENT_KEY_DOWN) {
switch (event.key.key) {
case SDLK_SPACE: {
// TEMPORAL: Explotar enemic aleatori (per testing)
// TODO: Restaurar dispars quan el sistema d'explosions estiga validat
// Buscar tots els enemics actius
std::vector<int> enemics_actius;
for (int i = 0; i < Constants::MAX_ORNIS; i++) {
if (orni_[i].esta_actiu()) {
enemics_actius.push_back(i);
// Buscar tots els enemics actius
std::vector<int> enemics_actius;
for (int i = 0; i < Constants::MAX_ORNIS; i++) {
if (orni_[i].esta_actiu()) {
enemics_actius.push_back(i);
}
}
if (!enemics_actius.empty()) {
// Seleccionar enemic aleatori
int idx = enemics_actius[std::rand() % enemics_actius.size()];
// Crear explosió
debris_manager_.explotar(orni_[idx].get_forma(),
orni_[idx].get_centre(),
0.0f, // angle (enemics no roten físicament)
1.0f, // escala
Defaults::Physics::Debris::VELOCITAT_BASE);
// Desactivar enemic
orni_[idx].destruir();
std::cout << "[TEST] Enemic " << idx << " explotat!\n";
}
break;
}
default:
break;
}
}
if (!enemics_actius.empty()) {
// Seleccionar enemic aleatori
int idx = enemics_actius[std::rand() % enemics_actius.size()];
// Crear explosió
debris_manager_.explotar(orni_[idx].get_forma(),
orni_[idx].get_centre(),
0.0f, // angle (enemics no roten físicament)
1.0f, // escala
Defaults::Physics::Debris::VELOCITAT_BASE);
// Desactivar enemic
orni_[idx].destruir();
std::cout << "[TEST] Enemic " << idx << " explotat!\n";
}
break;
}
default:
break;
}
}
}
void EscenaJoc::tocado() {
// TODO: Implementar seqüència de mort
// TODO: Implementar seqüència de mort
}
void EscenaJoc::dibuixar_marges() const {
// Dibuixar rectangle de la zona de joc
const SDL_FRect &zona = Defaults::Zones::PLAYAREA;
// Dibuixar rectangle de la zona de joc
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
// Coordenades dels cantons
int x1 = static_cast<int>(zona.x);
int y1 = static_cast<int>(zona.y);
int x2 = static_cast<int>(zona.x + zona.w);
int y2 = static_cast<int>(zona.y + zona.h);
// Coordenades dels cantons
int x1 = static_cast<int>(zona.x);
int y1 = static_cast<int>(zona.y);
int x2 = static_cast<int>(zona.x + zona.w);
int y2 = static_cast<int>(zona.y + zona.h);
// 4 línies per formar el rectangle
Rendering::linea(sdl_.obte_renderer(), x1, y1, x2, y1, true); // Top
Rendering::linea(sdl_.obte_renderer(), x1, y2, x2, y2, true); // Bottom
Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2, true); // Left
Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2, true); // Right
// 4 línies per formar el rectangle
Rendering::linea(sdl_.obte_renderer(), x1, y1, x2, y1, true); // Top
Rendering::linea(sdl_.obte_renderer(), x1, y2, x2, y2, true); // Bottom
Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2, true); // Left
Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2, true); // Right
}
void EscenaJoc::dibuixar_marcador() {
// Text estàtic (hardcoded)
const std::string text = "SCORE: 01000 LIFE: 3 LEVEL: 01";
// Text estàtic (hardcoded)
const std::string text = "SCORE: 01000 LIFE: 3 LEVEL: 01";
// Paràmetres de renderització
const float escala = 0.85f;
const float spacing = 0.0f;
// Paràmetres de renderització
const float escala = 0.85f;
const float spacing = 0.0f;
// Calcular dimensions del text
float text_width = text_.get_text_width(text, escala, spacing);
float text_height = text_.get_text_height(escala);
// Calcular dimensions del text
float text_width = text_.get_text_width(text, escala, spacing);
float text_height = text_.get_text_height(escala);
// Centrat horitzontal dins de la zona del marcador
float x = (Defaults::Zones::SCOREBOARD.w - text_width) / 2.0f;
// Centrat horitzontal dins de la zona del marcador
float x = (Defaults::Zones::SCOREBOARD.w - text_width) / 2.0f;
// Centrat vertical dins de la zona del marcador
float y = Defaults::Zones::SCOREBOARD.y +
(Defaults::Zones::SCOREBOARD.h - text_height) / 2.0f;
// Centrat vertical dins de la zona del marcador
float y = Defaults::Zones::SCOREBOARD.y +
(Defaults::Zones::SCOREBOARD.h - text_height) / 2.0f;
// Renderitzar
text_.render(text, {x, y}, escala, spacing);
// Renderitzar
text_.render(text, {x, y}, escala, spacing);
}