style: aplicar todos los checks readability-* (225 fixes)
Cambios aplicados: - readability-braces-around-statements (añadir llaves en ifs/fors) - readability-implicit-bool-conversion (puntero → bool explícito) - readability-container-size-empty (.empty() en lugar de .size()==0) - readability-container-contains (.contains() C++20) - readability-make-member-function-const (métodos const) - readability-else-after-return (5 casos adicionales) - Añadido #include <cmath> en defaults.hpp Checks excluidos (justificados): - identifier-naming: Cascada de 300+ cambios - identifier-length: Nombres cortos son OK en este proyecto - magic-numbers: Demasiados falsos positivos - convert-member-functions-to-static: Rompe encapsulación - use-anyofallof: C++20 ranges no universal - function-cognitive-complexity: Complejidad aceptable - clang-analyzer-security.insecureAPI.rand: rand() suficiente para juegos
This commit is contained in:
18
.clang-tidy
18
.clang-tidy
@@ -6,15 +6,15 @@ Checks:
|
|||||||
# ✅ Check 4: readability-const-return-type (código ya cumple)
|
# ✅ Check 4: readability-const-return-type (código ya cumple)
|
||||||
# ✅ Check 5: readability-else-after-return (código ya cumple)
|
# ✅ Check 5: readability-else-after-return (código ya cumple)
|
||||||
# ✅ Check 6: readability-simplify-boolean-expr (código ya cumple)
|
# ✅ Check 6: readability-simplify-boolean-expr (código ya cumple)
|
||||||
- readability-uppercase-literal-suffix
|
# ✅ Check 7: readability-* (225 fixes aplicados)
|
||||||
- readability-math-missing-parentheses
|
- readability-*
|
||||||
#- readability-identifier-naming # TEMP DISABLED
|
- -readability-identifier-naming # Excluido (cascada de cambios)
|
||||||
- readability-const-return-type
|
- -readability-identifier-length # Excluido (nombres cortos son OK)
|
||||||
- readability-else-after-return
|
- -readability-magic-numbers # Excluido (muchos falsos positivos)
|
||||||
- readability-simplify-boolean-expr
|
- -readability-convert-member-functions-to-static # Excluido (rompe encapsulación)
|
||||||
|
- -readability-use-anyofallof # Excluido (C++20 ranges - no todos los compiladores)
|
||||||
# TODO: Habilitar gradualmente
|
- -readability-function-cognitive-complexity # Excluido (complejidad ciclomática aceptable)
|
||||||
# - readability-*
|
- -clang-analyzer-security.insecureAPI.rand # Excluido (rand() es suficiente para juegos)
|
||||||
# - modernize-*
|
# - modernize-*
|
||||||
# - performance-*
|
# - performance-*
|
||||||
# - bugprone-unchecked-optional-access
|
# - bugprone-unchecked-optional-access
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Defaults {
|
namespace Defaults {
|
||||||
@@ -441,13 +442,13 @@ constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // 240.0f
|
|||||||
// Nota: std::cos/sin no són constexpr en C++20, però funcionen en runtime
|
// Nota: std::cos/sin no són constexpr en C++20, però funcionen en runtime
|
||||||
// Les funcions inline són optimitzades pel compilador (zero overhead)
|
// Les funcions inline són optimitzades pel compilador (zero overhead)
|
||||||
inline float P1_TARGET_X() {
|
inline float P1_TARGET_X() {
|
||||||
return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE);
|
return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE));
|
||||||
}
|
}
|
||||||
inline float P1_TARGET_Y() {
|
inline float P1_TARGET_Y() {
|
||||||
return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO);
|
return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO);
|
||||||
}
|
}
|
||||||
inline float P2_TARGET_X() {
|
inline float P2_TARGET_X() {
|
||||||
return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE);
|
return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE));
|
||||||
}
|
}
|
||||||
inline float P2_TARGET_Y() {
|
inline float P2_TARGET_Y() {
|
||||||
return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO);
|
return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO);
|
||||||
|
|||||||
@@ -44,8 +44,9 @@ bool Shape::parsejar_fitxer(const std::string& contingut) {
|
|||||||
line = trim(line);
|
line = trim(line);
|
||||||
|
|
||||||
// Skip comments and blanks
|
// Skip comments and blanks
|
||||||
if (line.empty() || line[0] == '#')
|
if (line.empty() || line[0] == '#') {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse command
|
// Parse command
|
||||||
if (starts_with(line, "name:")) {
|
if (starts_with(line, "name:")) {
|
||||||
@@ -91,8 +92,9 @@ bool Shape::parsejar_fitxer(const std::string& contingut) {
|
|||||||
std::string Shape::trim(const std::string& str) const {
|
std::string Shape::trim(const std::string& str) const {
|
||||||
const char* whitespace = " \t\n\r";
|
const char* whitespace = " \t\n\r";
|
||||||
size_t start = str.find_first_not_of(whitespace);
|
size_t start = str.find_first_not_of(whitespace);
|
||||||
if (start == std::string::npos)
|
if (start == std::string::npos) {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
size_t end = str.find_last_not_of(whitespace);
|
size_t end = str.find_last_not_of(whitespace);
|
||||||
return str.substr(start, end - start + 1);
|
return str.substr(start, end - start + 1);
|
||||||
@@ -101,16 +103,18 @@ std::string Shape::trim(const std::string& str) const {
|
|||||||
// Helper: starts_with
|
// Helper: starts_with
|
||||||
bool Shape::starts_with(const std::string& str,
|
bool Shape::starts_with(const std::string& str,
|
||||||
const std::string& prefix) const {
|
const std::string& prefix) const {
|
||||||
if (str.length() < prefix.length())
|
if (str.length() < prefix.length()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return str.compare(0, prefix.length(), prefix) == 0;
|
return str.compare(0, prefix.length(), prefix) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper: extract value after ':'
|
// Helper: extract value after ':'
|
||||||
std::string Shape::extract_value(const std::string& line) const {
|
std::string Shape::extract_value(const std::string& line) const {
|
||||||
size_t colon = line.find(':');
|
size_t colon = line.find(':');
|
||||||
if (colon == std::string::npos)
|
if (colon == std::string::npos) {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
return line.substr(colon + 1);
|
return line.substr(colon + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ Starfield::Starfield(SDL_Renderer* renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inicialitzar una estrella (nova o regenerada)
|
// Inicialitzar una estrella (nova o regenerada)
|
||||||
void Starfield::inicialitzar_estrella(Estrella& estrella) {
|
void Starfield::inicialitzar_estrella(Estrella& estrella) const {
|
||||||
// Angle aleatori des del punt de fuga cap a fora
|
// Angle aleatori des del punt de fuga cap a fora
|
||||||
estrella.angle = (static_cast<float>(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI;
|
estrella.angle = (static_cast<float>(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI;
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class Starfield {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Inicialitzar una estrella (nova o regenerada)
|
// Inicialitzar una estrella (nova o regenerada)
|
||||||
void inicialitzar_estrella(Estrella& estrella);
|
void inicialitzar_estrella(Estrella& estrella) const;
|
||||||
|
|
||||||
// Verificar si una estrella està fora de l'àrea
|
// Verificar si una estrella està fora de l'àrea
|
||||||
bool fora_area(const Estrella& estrella) const;
|
bool fora_area(const Estrella& estrella) const;
|
||||||
|
|||||||
@@ -178,11 +178,11 @@ std::string VectorText::get_shape_filename(char c) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool VectorText::is_supported(char c) const {
|
bool VectorText::is_supported(char c) const {
|
||||||
return chars_.find(c) != chars_.end();
|
return chars_.contains(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorText::render(const std::string& text, const Punt& posicio, float escala, float spacing, float brightness) {
|
void VectorText::render(const std::string& text, const Punt& posicio, float escala, float spacing, float brightness) {
|
||||||
if (!renderer_) {
|
if (renderer_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ void Input::applyPlayer1BindingsFromOptions() {
|
|||||||
std::shared_ptr<Gamepad> gamepad = nullptr;
|
std::shared_ptr<Gamepad> gamepad = nullptr;
|
||||||
if (Options::player1.gamepad_name.empty()) {
|
if (Options::player1.gamepad_name.empty()) {
|
||||||
// Fallback: usar primer gamepad disponible
|
// Fallback: usar primer gamepad disponible
|
||||||
gamepad = (gamepads_.size() > 0) ? gamepads_[0] : nullptr;
|
gamepad = (!gamepads_.empty()) ? gamepads_[0] : nullptr;
|
||||||
} else {
|
} else {
|
||||||
// Buscar por nombre
|
// Buscar por nombre
|
||||||
gamepad = findAvailableGamepadByName(Options::player1.gamepad_name);
|
gamepad = findAvailableGamepadByName(Options::player1.gamepad_name);
|
||||||
|
|||||||
@@ -20,10 +20,12 @@ bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar
|
|||||||
|
|
||||||
// Helper function: retorna el signe d'un nombre
|
// Helper function: retorna el signe d'un nombre
|
||||||
auto sign = [](int x) -> int {
|
auto sign = [](int x) -> int {
|
||||||
if (x < 0)
|
if (x < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
if (x > 0)
|
}
|
||||||
|
if (x > 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@ bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar
|
|||||||
bool colisio = false;
|
bool colisio = false;
|
||||||
|
|
||||||
// Dibuixar amb SDL3 (més eficient que Bresenham píxel a píxel)
|
// Dibuixar amb SDL3 (més eficient que Bresenham píxel a píxel)
|
||||||
if (dibuixar && renderer) {
|
if (dibuixar && (renderer != nullptr)) {
|
||||||
// Transformar coordenades lògiques (640x480) a físiques (resolució real)
|
// Transformar coordenades lògiques (640x480) a físiques (resolució real)
|
||||||
float scale = g_current_scale_factor;
|
float scale = g_current_scale_factor;
|
||||||
int px1 = transform_x(x1, scale);
|
int px1 = transform_x(x1, scale);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ SDLManager::SDLManager()
|
|||||||
SDL_WINDOW_RESIZABLE // Permetre resize manual també
|
SDL_WINDOW_RESIZABLE // Permetre resize manual també
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!finestra_) {
|
if (finestra_ == nullptr) {
|
||||||
std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl;
|
std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl;
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return;
|
return;
|
||||||
@@ -59,7 +59,7 @@ SDLManager::SDLManager()
|
|||||||
// Crear renderer amb acceleració
|
// Crear renderer amb acceleració
|
||||||
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
|
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
|
||||||
|
|
||||||
if (!renderer_) {
|
if (renderer_ == nullptr) {
|
||||||
std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl;
|
std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl;
|
||||||
SDL_DestroyWindow(finestra_);
|
SDL_DestroyWindow(finestra_);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
@@ -114,7 +114,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
|
|||||||
// Crear finestra
|
// Crear finestra
|
||||||
finestra_ = SDL_CreateWindow(window_title.c_str(), current_width_, current_height_, flags);
|
finestra_ = SDL_CreateWindow(window_title.c_str(), current_width_, current_height_, flags);
|
||||||
|
|
||||||
if (!finestra_) {
|
if (finestra_ == nullptr) {
|
||||||
std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl;
|
std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl;
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return;
|
return;
|
||||||
@@ -128,7 +128,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
|
|||||||
// Crear renderer amb acceleració
|
// Crear renderer amb acceleració
|
||||||
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
|
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
|
||||||
|
|
||||||
if (!renderer_) {
|
if (renderer_ == nullptr) {
|
||||||
std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl;
|
std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl;
|
||||||
SDL_DestroyWindow(finestra_);
|
SDL_DestroyWindow(finestra_);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
@@ -157,12 +157,12 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDLManager::~SDLManager() {
|
SDLManager::~SDLManager() {
|
||||||
if (renderer_) {
|
if (renderer_ != nullptr) {
|
||||||
SDL_DestroyRenderer(renderer_);
|
SDL_DestroyRenderer(renderer_);
|
||||||
renderer_ = nullptr;
|
renderer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finestra_) {
|
if (finestra_ != nullptr) {
|
||||||
SDL_DestroyWindow(finestra_);
|
SDL_DestroyWindow(finestra_);
|
||||||
finestra_ = nullptr;
|
finestra_ = nullptr;
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ void SDLManager::calculateMaxWindowSize() {
|
|||||||
SDL_DisplayID display = SDL_GetPrimaryDisplay();
|
SDL_DisplayID display = SDL_GetPrimaryDisplay();
|
||||||
const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(display);
|
const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(display);
|
||||||
|
|
||||||
if (mode) {
|
if (mode != nullptr) {
|
||||||
// Deixar marge de 100px per a decoracions de l'OS
|
// Deixar marge de 100px per a decoracions de l'OS
|
||||||
max_width_ = mode->w - 100;
|
max_width_ = mode->w - 100;
|
||||||
max_height_ = mode->h - 100;
|
max_height_ = mode->h - 100;
|
||||||
@@ -282,14 +282,15 @@ void SDLManager::updateViewport() {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLManager::updateRenderingContext() {
|
void SDLManager::updateRenderingContext() const {
|
||||||
// Actualitzar el factor d'escala global per a totes les funcions de renderitzat
|
// Actualitzar el factor d'escala global per a totes les funcions de renderitzat
|
||||||
Rendering::g_current_scale_factor = zoom_factor_;
|
Rendering::g_current_scale_factor = zoom_factor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLManager::increaseWindowSize() {
|
void SDLManager::increaseWindowSize() {
|
||||||
if (is_fullscreen_)
|
if (is_fullscreen_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float new_zoom = zoom_factor_ + Defaults::Window::ZOOM_INCREMENT;
|
float new_zoom = zoom_factor_ + Defaults::Window::ZOOM_INCREMENT;
|
||||||
applyZoom(new_zoom);
|
applyZoom(new_zoom);
|
||||||
@@ -298,8 +299,9 @@ void SDLManager::increaseWindowSize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SDLManager::decreaseWindowSize() {
|
void SDLManager::decreaseWindowSize() {
|
||||||
if (is_fullscreen_)
|
if (is_fullscreen_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float new_zoom = zoom_factor_ - Defaults::Window::ZOOM_INCREMENT;
|
float new_zoom = zoom_factor_ - Defaults::Window::ZOOM_INCREMENT;
|
||||||
applyZoom(new_zoom);
|
applyZoom(new_zoom);
|
||||||
@@ -309,7 +311,8 @@ void SDLManager::decreaseWindowSize() {
|
|||||||
|
|
||||||
void SDLManager::applyWindowSize(int new_width, int new_height) {
|
void SDLManager::applyWindowSize(int new_width, int new_height) {
|
||||||
// Obtenir posició actual ABANS del resize
|
// Obtenir posició actual ABANS del resize
|
||||||
int old_x, old_y;
|
int old_x;
|
||||||
|
int old_y;
|
||||||
SDL_GetWindowPosition(finestra_, &old_x, &old_y);
|
SDL_GetWindowPosition(finestra_, &old_x, &old_y);
|
||||||
|
|
||||||
int old_width = current_width_;
|
int old_width = current_width_;
|
||||||
@@ -396,8 +399,9 @@ bool SDLManager::handleWindowEvent(const SDL_Event& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) {
|
void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) {
|
||||||
if (!renderer_)
|
if (renderer_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// [MODIFICAT] Usar color oscil·lat del fons en lloc dels paràmetres
|
// [MODIFICAT] Usar color oscil·lat del fons en lloc dels paràmetres
|
||||||
(void)r;
|
(void)r;
|
||||||
@@ -409,8 +413,9 @@ void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SDLManager::presenta() {
|
void SDLManager::presenta() {
|
||||||
if (!renderer_)
|
if (renderer_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_RenderPresent(renderer_);
|
SDL_RenderPresent(renderer_);
|
||||||
}
|
}
|
||||||
@@ -444,7 +449,7 @@ void SDLManager::updateFPS(float delta_time) {
|
|||||||
fps_display_,
|
fps_display_,
|
||||||
vsync_state);
|
vsync_state);
|
||||||
|
|
||||||
if (finestra_) {
|
if (finestra_ != nullptr) {
|
||||||
SDL_SetWindowTitle(finestra_, title.c_str());
|
SDL_SetWindowTitle(finestra_, title.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -452,7 +457,7 @@ void SDLManager::updateFPS(float delta_time) {
|
|||||||
|
|
||||||
// [NUEVO] Actualitzar títol de la finestra
|
// [NUEVO] Actualitzar títol de la finestra
|
||||||
void SDLManager::setWindowTitle(const std::string& title) {
|
void SDLManager::setWindowTitle(const std::string& title) {
|
||||||
if (finestra_) {
|
if (finestra_ != nullptr) {
|
||||||
SDL_SetWindowTitle(finestra_, title.c_str());
|
SDL_SetWindowTitle(finestra_, title.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -463,7 +468,7 @@ void SDLManager::toggleVSync() {
|
|||||||
Options::rendering.vsync = (Options::rendering.vsync == 1) ? 0 : 1;
|
Options::rendering.vsync = (Options::rendering.vsync == 1) ? 0 : 1;
|
||||||
|
|
||||||
// Aplicar a SDL
|
// Aplicar a SDL
|
||||||
if (renderer_) {
|
if (renderer_ != nullptr) {
|
||||||
SDL_SetRenderVSync(renderer_, Options::rendering.vsync);
|
SDL_SetRenderVSync(renderer_, Options::rendering.vsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class SDLManager {
|
|||||||
void setWindowTitle(const std::string& title);
|
void setWindowTitle(const std::string& title);
|
||||||
|
|
||||||
// [NUEVO] Actualitzar context de renderitzat (factor d'escala global)
|
// [NUEVO] Actualitzar context de renderitzat (factor d'escala global)
|
||||||
void updateRenderingContext();
|
void updateRenderingContext() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Window* finestra_;
|
SDL_Window* finestra_;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P
|
|||||||
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 && rotation_3d->has_rotation()) {
|
if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) {
|
||||||
Punt rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d);
|
Punt 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;
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ bool Pack::loadPack(const std::string& pack_file) {
|
|||||||
file.read(reinterpret_cast<char*>(&name_len), sizeof(name_len));
|
file.read(reinterpret_cast<char*>(&name_len), sizeof(name_len));
|
||||||
|
|
||||||
std::string filename(name_len, '\0');
|
std::string filename(name_len, '\0');
|
||||||
file.read(&filename[0], name_len);
|
file.read(filename.data(), name_len);
|
||||||
|
|
||||||
// Offset, mida, checksum
|
// Offset, mida, checksum
|
||||||
ResourceEntry entry;
|
ResourceEntry entry;
|
||||||
@@ -258,7 +258,7 @@ std::vector<uint8_t> Pack::getResource(const std::string& filename) {
|
|||||||
|
|
||||||
// Comprovar si existeix un recurs
|
// Comprovar si existeix un recurs
|
||||||
bool Pack::hasResource(const std::string& filename) const {
|
bool Pack::hasResource(const std::string& filename) const {
|
||||||
return resources_.find(filename) != resources_.end();
|
return resources_.contains(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtenir llista de tots els recursos
|
// Obtenir llista de tots els recursos
|
||||||
|
|||||||
@@ -42,8 +42,12 @@ struct ConfigPartida {
|
|||||||
// Retorna l'ID de l'únic jugador actiu (0 o 1)
|
// Retorna l'ID de l'únic jugador actiu (0 o 1)
|
||||||
// Només vàlid si es_un_jugador() retorna true
|
// Només vàlid si es_un_jugador() retorna true
|
||||||
[[nodiscard]] uint8_t id_unic_jugador() const {
|
[[nodiscard]] uint8_t id_unic_jugador() const {
|
||||||
if (jugador1_actiu && !jugador2_actiu) return 0;
|
if (jugador1_actiu && !jugador2_actiu) {
|
||||||
if (!jugador1_actiu && jugador2_actiu) return 1;
|
return 0;
|
||||||
|
}
|
||||||
|
if (!jugador1_actiu && jugador2_actiu) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0; // Fallback (cal comprovar es_un_jugador() primer)
|
return 0; // Fallback (cal comprovar es_un_jugador() primer)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ static std::string executable_directory_;
|
|||||||
|
|
||||||
// Inicialitzar el sistema de rutes amb argv[0]
|
// Inicialitzar el sistema de rutes amb argv[0]
|
||||||
void initializePathSystem(const char* argv0) {
|
void initializePathSystem(const char* argv0) {
|
||||||
if (!argv0) {
|
if (argv0 == nullptr) {
|
||||||
std::cerr << "[PathUtils] ADVERTÈNCIA: argv[0] és nullptr\n";
|
std::cerr << "[PathUtils] ADVERTÈNCIA: argv[0] és nullptr\n";
|
||||||
executable_path_ = "";
|
executable_path_ = "";
|
||||||
executable_directory_ = ".";
|
executable_directory_ = ".";
|
||||||
@@ -65,11 +65,9 @@ std::string getResourceBasePath() {
|
|||||||
// Bundle de macOS: recursos a ../Resources des de MacOS/
|
// Bundle de macOS: recursos a ../Resources des de MacOS/
|
||||||
std::cout << "[PathUtils] Detectat bundle de macOS\n";
|
std::cout << "[PathUtils] Detectat bundle de macOS\n";
|
||||||
return exe_dir + "/../Resources";
|
return exe_dir + "/../Resources";
|
||||||
} else {
|
} // Executable normal: recursos al mateix directori
|
||||||
// Executable normal: recursos al mateix directori
|
|
||||||
return exe_dir;
|
return exe_dir;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Normalitzar ruta (convertir barres, etc.)
|
// Normalitzar ruta (convertir barres, etc.)
|
||||||
std::string normalizePath(const std::string& path) {
|
std::string normalizePath(const std::string& path) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "debris_manager.hpp"
|
#include "debris_manager.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -90,7 +91,7 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
|||||||
|
|
||||||
// 2. Trobar slot lliure
|
// 2. Trobar slot lliure
|
||||||
Debris* debris = trobar_slot_lliure();
|
Debris* debris = trobar_slot_lliure();
|
||||||
if (!debris) {
|
if (debris == nullptr) {
|
||||||
std::cerr << "[DebrisManager] Warning: no debris slots disponibles\n";
|
std::cerr << "[DebrisManager] Warning: no debris slots disponibles\n";
|
||||||
return; // Pool ple
|
return; // Pool ple
|
||||||
}
|
}
|
||||||
@@ -205,8 +206,9 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
|||||||
|
|
||||||
void DebrisManager::actualitzar(float delta_time) {
|
void DebrisManager::actualitzar(float delta_time) {
|
||||||
for (auto& debris : debris_pool_) {
|
for (auto& debris : debris_pool_) {
|
||||||
if (!debris.actiu)
|
if (!debris.actiu) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. Actualitzar temps de vida
|
// 1. Actualitzar temps de vida
|
||||||
debris.temps_vida += delta_time;
|
debris.temps_vida += delta_time;
|
||||||
@@ -229,8 +231,7 @@ void DebrisManager::actualitzar(float delta_time) {
|
|||||||
|
|
||||||
// Aplicar acceleració negativa (fricció)
|
// Aplicar acceleració negativa (fricció)
|
||||||
float nova_speed = speed + (debris.acceleracio * delta_time);
|
float nova_speed = speed + (debris.acceleracio * delta_time);
|
||||||
if (nova_speed < 0.0F)
|
nova_speed = std::max(nova_speed, 0.0F);
|
||||||
nova_speed = 0.0F;
|
|
||||||
|
|
||||||
debris.velocitat.x = dir_x * nova_speed;
|
debris.velocitat.x = dir_x * nova_speed;
|
||||||
debris.velocitat.y = dir_y * nova_speed;
|
debris.velocitat.y = dir_y * nova_speed;
|
||||||
@@ -303,8 +304,9 @@ void DebrisManager::actualitzar(float delta_time) {
|
|||||||
|
|
||||||
void DebrisManager::dibuixar() const {
|
void DebrisManager::dibuixar() const {
|
||||||
for (const auto& debris : debris_pool_) {
|
for (const auto& debris : debris_pool_) {
|
||||||
if (!debris.actiu)
|
if (!debris.actiu) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Dibuixar segment de línia amb brightness heretat
|
// Dibuixar segment de línia amb brightness heretat
|
||||||
Rendering::linea(renderer_,
|
Rendering::linea(renderer_,
|
||||||
@@ -372,9 +374,10 @@ void DebrisManager::reiniciar() {
|
|||||||
int DebrisManager::get_num_actius() const {
|
int DebrisManager::get_num_actius() const {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (const auto& debris : debris_pool_) {
|
for (const auto& debris : debris_pool_) {
|
||||||
if (debris.actiu)
|
if (debris.actiu) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ GestorPuntuacioFlotant::GestorPuntuacioFlotant(SDL_Renderer* renderer)
|
|||||||
void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) {
|
void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) {
|
||||||
// 1. Trobar slot lliure
|
// 1. Trobar slot lliure
|
||||||
PuntuacioFlotant* pf = trobar_slot_lliure();
|
PuntuacioFlotant* pf = trobar_slot_lliure();
|
||||||
if (!pf)
|
if (pf == nullptr) {
|
||||||
return; // Pool ple (improbable)
|
return; // Pool ple (improbable)
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Inicialitzar puntuació flotant
|
// 2. Inicialitzar puntuació flotant
|
||||||
pf->text = std::to_string(punts);
|
pf->text = std::to_string(punts);
|
||||||
@@ -34,8 +35,9 @@ void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) {
|
|||||||
|
|
||||||
void GestorPuntuacioFlotant::actualitzar(float delta_time) {
|
void GestorPuntuacioFlotant::actualitzar(float delta_time) {
|
||||||
for (auto& pf : pool_) {
|
for (auto& pf : pool_) {
|
||||||
if (!pf.actiu)
|
if (!pf.actiu) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. Actualitzar posició (deriva cap amunt)
|
// 1. Actualitzar posició (deriva cap amunt)
|
||||||
pf.posicio.x += pf.velocitat.x * delta_time;
|
pf.posicio.x += pf.velocitat.x * delta_time;
|
||||||
@@ -57,8 +59,9 @@ void GestorPuntuacioFlotant::actualitzar(float delta_time) {
|
|||||||
|
|
||||||
void GestorPuntuacioFlotant::dibuixar() {
|
void GestorPuntuacioFlotant::dibuixar() {
|
||||||
for (const auto& pf : pool_) {
|
for (const auto& pf : pool_) {
|
||||||
if (!pf.actiu)
|
if (!pf.actiu) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Renderitzar centrat amb brightness (fade)
|
// Renderitzar centrat amb brightness (fade)
|
||||||
constexpr float escala = Defaults::FloatingScore::SCALE;
|
constexpr float escala = Defaults::FloatingScore::SCALE;
|
||||||
@@ -77,17 +80,19 @@ void GestorPuntuacioFlotant::reiniciar() {
|
|||||||
int GestorPuntuacioFlotant::get_num_actius() const {
|
int GestorPuntuacioFlotant::get_num_actius() const {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (const auto& pf : pool_) {
|
for (const auto& pf : pool_) {
|
||||||
if (pf.actiu)
|
if (pf.actiu) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
PuntuacioFlotant* GestorPuntuacioFlotant::trobar_slot_lliure() {
|
PuntuacioFlotant* GestorPuntuacioFlotant::trobar_slot_lliure() {
|
||||||
for (auto& pf : pool_) {
|
for (auto& pf : pool_) {
|
||||||
if (!pf.actiu)
|
if (!pf.actiu) {
|
||||||
return &pf;
|
return &pf;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nullptr; // Pool ple
|
return nullptr; // Pool ple
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "game/entities/bala.hpp"
|
#include "game/entities/bala.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -71,9 +72,7 @@ void Bala::actualitzar(float delta_time) {
|
|||||||
// Decrementar grace timer
|
// Decrementar grace timer
|
||||||
if (grace_timer_ > 0.0F) {
|
if (grace_timer_ > 0.0F) {
|
||||||
grace_timer_ -= delta_time;
|
grace_timer_ -= delta_time;
|
||||||
if (grace_timer_ < 0.0F) {
|
grace_timer_ = std::max(grace_timer_, 0.0F);
|
||||||
grace_timer_ = 0.0F;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mou(delta_time);
|
mou(delta_time);
|
||||||
@@ -107,7 +106,10 @@ void Bala::mou(float delta_time) {
|
|||||||
|
|
||||||
// Desactivar si surt de la zona de joc (no rebota com els ORNIs)
|
// Desactivar si surt de la zona de joc (no rebota com els ORNIs)
|
||||||
// CORRECCIÓ: Usar límits segurs amb radi de la bala
|
// CORRECCIÓ: Usar límits segurs amb radi de la bala
|
||||||
float min_x, max_x, min_y, max_y;
|
float min_x;
|
||||||
|
float max_x;
|
||||||
|
float min_y;
|
||||||
|
float max_y;
|
||||||
Constants::obtenir_limits_zona_segurs(Defaults::Entities::BULLET_RADIUS,
|
Constants::obtenir_limits_zona_segurs(Defaults::Entities::BULLET_RADIUS,
|
||||||
min_x,
|
min_x,
|
||||||
max_x,
|
max_x,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "game/entities/enemic.hpp"
|
#include "game/entities/enemic.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -37,7 +38,8 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) {
|
|||||||
|
|
||||||
// Carregar forma segons el tipus
|
// Carregar forma segons el tipus
|
||||||
const char* shape_file;
|
const char* shape_file;
|
||||||
float drotacio_min, drotacio_max;
|
float drotacio_min;
|
||||||
|
float drotacio_max;
|
||||||
|
|
||||||
switch (tipus_) {
|
switch (tipus_) {
|
||||||
case TipusEnemic::PENTAGON:
|
case TipusEnemic::PENTAGON:
|
||||||
@@ -70,7 +72,10 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [MODIFIED] Posició aleatòria amb comprovació de seguretat
|
// [MODIFIED] Posició aleatòria amb comprovació de seguretat
|
||||||
float min_x, max_x, min_y, max_y;
|
float min_x;
|
||||||
|
float max_x;
|
||||||
|
float min_y;
|
||||||
|
float max_y;
|
||||||
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
||||||
min_x,
|
min_x,
|
||||||
max_x,
|
max_x,
|
||||||
@@ -82,7 +87,8 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) {
|
|||||||
bool found_safe_position = false;
|
bool found_safe_position = false;
|
||||||
|
|
||||||
for (int attempt = 0; attempt < Defaults::Enemies::Spawn::MAX_SPAWN_ATTEMPTS; attempt++) {
|
for (int attempt = 0; attempt < Defaults::Enemies::Spawn::MAX_SPAWN_ATTEMPTS; attempt++) {
|
||||||
float candidate_x, candidate_y;
|
float candidate_x;
|
||||||
|
float candidate_y;
|
||||||
|
|
||||||
if (intent_spawn_safe(*ship_pos, candidate_x, candidate_y)) {
|
if (intent_spawn_safe(*ship_pos, candidate_x, candidate_y)) {
|
||||||
centre_.x = candidate_x;
|
centre_.x = candidate_x;
|
||||||
@@ -138,9 +144,7 @@ void Enemic::actualitzar(float delta_time) {
|
|||||||
if (timer_invulnerabilitat_ > 0.0F) {
|
if (timer_invulnerabilitat_ > 0.0F) {
|
||||||
timer_invulnerabilitat_ -= delta_time;
|
timer_invulnerabilitat_ -= delta_time;
|
||||||
|
|
||||||
if (timer_invulnerabilitat_ < 0.0F) {
|
timer_invulnerabilitat_ = std::max(timer_invulnerabilitat_, 0.0F);
|
||||||
timer_invulnerabilitat_ = 0.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [NEW] Update brightness with LERP during invulnerability
|
// [NEW] Update brightness with LERP during invulnerability
|
||||||
float t_inv = timer_invulnerabilitat_ / Defaults::Enemies::Spawn::INVULNERABILITY_DURATION;
|
float t_inv = timer_invulnerabilitat_ / Defaults::Enemies::Spawn::INVULNERABILITY_DURATION;
|
||||||
@@ -202,7 +206,10 @@ void Enemic::comportament_pentagon(float delta_time) {
|
|||||||
float new_x = centre_.x + dx;
|
float new_x = centre_.x + dx;
|
||||||
|
|
||||||
// Obtenir límits segurs
|
// Obtenir límits segurs
|
||||||
float min_x, max_x, min_y, max_y;
|
float min_x;
|
||||||
|
float max_x;
|
||||||
|
float min_y;
|
||||||
|
float max_y;
|
||||||
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
||||||
min_x,
|
min_x,
|
||||||
max_x,
|
max_x,
|
||||||
@@ -242,7 +249,7 @@ void Enemic::comportament_quadrat(float delta_time) {
|
|||||||
if (tracking_timer_ >= Defaults::Enemies::Quadrat::TRACKING_INTERVAL) {
|
if (tracking_timer_ >= Defaults::Enemies::Quadrat::TRACKING_INTERVAL) {
|
||||||
tracking_timer_ = 0.0F;
|
tracking_timer_ = 0.0F;
|
||||||
|
|
||||||
if (ship_position_) {
|
if (ship_position_ != nullptr) {
|
||||||
// Calculate angle to ship
|
// Calculate angle to ship
|
||||||
float dx = ship_position_->x - centre_.x;
|
float dx = ship_position_->x - centre_.x;
|
||||||
float dy = ship_position_->y - centre_.y;
|
float dy = ship_position_->y - centre_.y;
|
||||||
@@ -252,8 +259,12 @@ void Enemic::comportament_quadrat(float delta_time) {
|
|||||||
float angle_diff = target_angle - angle_;
|
float angle_diff = target_angle - angle_;
|
||||||
|
|
||||||
// Normalize angle difference to [-π, π]
|
// Normalize angle difference to [-π, π]
|
||||||
while (angle_diff > Constants::PI) angle_diff -= 2.0F * Constants::PI;
|
while (angle_diff > Constants::PI) {
|
||||||
while (angle_diff < -Constants::PI) angle_diff += 2.0F * Constants::PI;
|
angle_diff -= 2.0F * Constants::PI;
|
||||||
|
}
|
||||||
|
while (angle_diff < -Constants::PI) {
|
||||||
|
angle_diff += 2.0F * Constants::PI;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply tracking strength (uses member variable, defaults to 0.5)
|
// Apply tracking strength (uses member variable, defaults to 0.5)
|
||||||
angle_ += angle_diff * tracking_strength_;
|
angle_ += angle_diff * tracking_strength_;
|
||||||
@@ -269,7 +280,10 @@ void Enemic::comportament_quadrat(float delta_time) {
|
|||||||
float new_x = centre_.x + dx;
|
float new_x = centre_.x + dx;
|
||||||
|
|
||||||
// Obtenir límits segurs
|
// Obtenir límits segurs
|
||||||
float min_x, max_x, min_y, max_y;
|
float min_x;
|
||||||
|
float max_x;
|
||||||
|
float min_y;
|
||||||
|
float max_y;
|
||||||
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
||||||
min_x,
|
min_x,
|
||||||
max_x,
|
max_x,
|
||||||
@@ -294,7 +308,7 @@ void Enemic::comportament_molinillo(float delta_time) {
|
|||||||
// Molinillo: agressiu (fast, straight lines, proximity spin-up)
|
// Molinillo: agressiu (fast, straight lines, proximity spin-up)
|
||||||
|
|
||||||
// Check proximity to ship for spin-up effect
|
// Check proximity to ship for spin-up effect
|
||||||
if (ship_position_) {
|
if (ship_position_ != nullptr) {
|
||||||
float dx = ship_position_->x - centre_.x;
|
float dx = ship_position_->x - centre_.x;
|
||||||
float dy = ship_position_->y - centre_.y;
|
float dy = ship_position_->y - centre_.y;
|
||||||
float distance = std::sqrt((dx * dx) + (dy * dy));
|
float distance = std::sqrt((dx * dx) + (dy * dy));
|
||||||
@@ -318,7 +332,10 @@ void Enemic::comportament_molinillo(float delta_time) {
|
|||||||
float new_x = centre_.x + dx;
|
float new_x = centre_.x + dx;
|
||||||
|
|
||||||
// Obtenir límits segurs
|
// Obtenir límits segurs
|
||||||
float min_x, max_x, min_y, max_y;
|
float min_x;
|
||||||
|
float max_x;
|
||||||
|
float min_y;
|
||||||
|
float max_y;
|
||||||
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
||||||
min_x,
|
min_x,
|
||||||
max_x,
|
max_x,
|
||||||
@@ -491,7 +508,10 @@ 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 Punt& ship_pos, float& out_x, float& out_y) {
|
||||||
// Generate random position within safe bounds
|
// Generate random position within safe bounds
|
||||||
float min_x, max_x, min_y, max_y;
|
float min_x;
|
||||||
|
float max_x;
|
||||||
|
float min_y;
|
||||||
|
float max_y;
|
||||||
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS,
|
||||||
min_x,
|
min_x,
|
||||||
max_x,
|
max_x,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -40,12 +41,13 @@ void Nau::inicialitzar(const Punt* spawn_point, bool activar_invulnerabilitat) {
|
|||||||
// fitxer Només inicialitzem l'estat de la instància
|
// fitxer Només inicialitzem l'estat de la instància
|
||||||
|
|
||||||
// Use custom spawn point if provided, otherwise use center
|
// Use custom spawn point if provided, otherwise use center
|
||||||
if (spawn_point) {
|
if (spawn_point != nullptr) {
|
||||||
centre_.x = spawn_point->x;
|
centre_.x = spawn_point->x;
|
||||||
centre_.y = spawn_point->y;
|
centre_.y = spawn_point->y;
|
||||||
} else {
|
} else {
|
||||||
// Default: center of play area
|
// Default: center of play area
|
||||||
float centre_x, centre_y;
|
float centre_x;
|
||||||
|
float centre_y;
|
||||||
Constants::obtenir_centre_zona(centre_x, centre_y);
|
Constants::obtenir_centre_zona(centre_x, centre_y);
|
||||||
centre_.x = static_cast<int>(centre_x);
|
centre_.x = static_cast<int>(centre_x);
|
||||||
centre_.y = static_cast<int>(centre_y);
|
centre_.y = static_cast<int>(centre_y);
|
||||||
@@ -69,8 +71,9 @@ void Nau::processar_input(float delta_time, uint8_t player_id) {
|
|||||||
// Processar input continu (com teclapuls() del Pascal original)
|
// Processar input continu (com teclapuls() del Pascal original)
|
||||||
// Basat en joc_asteroides.cpp línies 66-85
|
// Basat en joc_asteroides.cpp línies 66-85
|
||||||
// Només processa input si la nau està viva
|
// Només processa input si la nau està viva
|
||||||
if (esta_tocada_)
|
if (esta_tocada_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto* input = Input::get();
|
auto* input = Input::get();
|
||||||
|
|
||||||
@@ -88,9 +91,7 @@ void Nau::processar_input(float delta_time, uint8_t player_id) {
|
|||||||
if (input->checkActionPlayer1(InputAction::THRUST, Input::ALLOW_REPEAT)) {
|
if (input->checkActionPlayer1(InputAction::THRUST, Input::ALLOW_REPEAT)) {
|
||||||
if (velocitat_ < Defaults::Physics::MAX_VELOCITY) {
|
if (velocitat_ < Defaults::Physics::MAX_VELOCITY) {
|
||||||
velocitat_ += Defaults::Physics::ACCELERATION * delta_time;
|
velocitat_ += Defaults::Physics::ACCELERATION * delta_time;
|
||||||
if (velocitat_ > Defaults::Physics::MAX_VELOCITY) {
|
velocitat_ = std::min(velocitat_, Defaults::Physics::MAX_VELOCITY);
|
||||||
velocitat_ = Defaults::Physics::MAX_VELOCITY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -106,9 +107,7 @@ void Nau::processar_input(float delta_time, uint8_t player_id) {
|
|||||||
if (input->checkActionPlayer2(InputAction::THRUST, Input::ALLOW_REPEAT)) {
|
if (input->checkActionPlayer2(InputAction::THRUST, Input::ALLOW_REPEAT)) {
|
||||||
if (velocitat_ < Defaults::Physics::MAX_VELOCITY) {
|
if (velocitat_ < Defaults::Physics::MAX_VELOCITY) {
|
||||||
velocitat_ += Defaults::Physics::ACCELERATION * delta_time;
|
velocitat_ += Defaults::Physics::ACCELERATION * delta_time;
|
||||||
if (velocitat_ > Defaults::Physics::MAX_VELOCITY) {
|
velocitat_ = std::min(velocitat_, Defaults::Physics::MAX_VELOCITY);
|
||||||
velocitat_ = Defaults::Physics::MAX_VELOCITY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,15 +115,14 @@ void Nau::processar_input(float delta_time, uint8_t player_id) {
|
|||||||
|
|
||||||
void Nau::actualitzar(float delta_time) {
|
void Nau::actualitzar(float delta_time) {
|
||||||
// Només actualitzar si la nau està viva
|
// Només actualitzar si la nau està viva
|
||||||
if (esta_tocada_)
|
if (esta_tocada_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Decrementar timer de invulnerabilidad
|
// Decrementar timer de invulnerabilidad
|
||||||
if (invulnerable_timer_ > 0.0F) {
|
if (invulnerable_timer_ > 0.0F) {
|
||||||
invulnerable_timer_ -= delta_time;
|
invulnerable_timer_ -= delta_time;
|
||||||
if (invulnerable_timer_ < 0.0F) {
|
invulnerable_timer_ = std::max(invulnerable_timer_, 0.0F);
|
||||||
invulnerable_timer_ = 0.0F;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aplicar física (moviment + fricció)
|
// Aplicar física (moviment + fricció)
|
||||||
@@ -133,8 +131,9 @@ void Nau::actualitzar(float delta_time) {
|
|||||||
|
|
||||||
void Nau::dibuixar() const {
|
void Nau::dibuixar() const {
|
||||||
// Només dibuixar si la nau està viva
|
// Només dibuixar si la nau està viva
|
||||||
if (esta_tocada_)
|
if (esta_tocada_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Si invulnerable, parpadear (toggle on/off)
|
// Si invulnerable, parpadear (toggle on/off)
|
||||||
if (es_invulnerable()) {
|
if (es_invulnerable()) {
|
||||||
@@ -149,8 +148,9 @@ void Nau::dibuixar() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forma_)
|
if (!forma_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Escalar velocitat per l'efecte visual (200 px/s → ~6 px d'efecte)
|
// Escalar velocitat per l'efecte visual (200 px/s → ~6 px d'efecte)
|
||||||
// El codi Pascal original sumava velocitat (0-6) al radi per donar
|
// El codi Pascal original sumava velocitat (0-6) al radi per donar
|
||||||
@@ -182,7 +182,10 @@ void Nau::aplicar_fisica(float delta_time) {
|
|||||||
|
|
||||||
// Boundary checking amb radi de la nau
|
// Boundary checking amb radi de la nau
|
||||||
// CORRECCIÓ: Usar límits segurs i inequalitats inclusives
|
// CORRECCIÓ: Usar límits segurs i inequalitats inclusives
|
||||||
float min_x, max_x, min_y, max_y;
|
float min_x;
|
||||||
|
float max_x;
|
||||||
|
float min_y;
|
||||||
|
float max_y;
|
||||||
Constants::obtenir_limits_zona_segurs(Defaults::Entities::SHIP_RADIUS,
|
Constants::obtenir_limits_zona_segurs(Defaults::Entities::SHIP_RADIUS,
|
||||||
min_x,
|
min_x,
|
||||||
max_x,
|
max_x,
|
||||||
@@ -201,8 +204,6 @@ void Nau::aplicar_fisica(float delta_time) {
|
|||||||
// Fricció - desacceleració gradual (time-based)
|
// Fricció - desacceleració gradual (time-based)
|
||||||
if (velocitat_ > 0.1F) {
|
if (velocitat_ > 0.1F) {
|
||||||
velocitat_ -= Defaults::Physics::FRICTION * delta_time;
|
velocitat_ -= Defaults::Physics::FRICTION * delta_time;
|
||||||
if (velocitat_ < 0.0F) {
|
velocitat_ = std::max(velocitat_, 0.0F);
|
||||||
velocitat_ = 0.0F;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "escena_joc.hpp"
|
#include "escena_joc.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
@@ -76,9 +77,7 @@ void EscenaJoc::executar() {
|
|||||||
last_time = current_time;
|
last_time = current_time;
|
||||||
|
|
||||||
// Limitar delta_time per evitar grans salts
|
// Limitar delta_time per evitar grans salts
|
||||||
if (delta_time > 0.05F) {
|
delta_time = std::min(delta_time, 0.05F);
|
||||||
delta_time = 0.05F;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actualitzar comptador de FPS
|
// Actualitzar comptador de FPS
|
||||||
sdl_.updateFPS(delta_time);
|
sdl_.updateFPS(delta_time);
|
||||||
@@ -1036,9 +1035,15 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() {
|
|||||||
// Check collision for BOTH players
|
// Check collision for BOTH players
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
// Skip collisions if player is dead or invulnerable
|
// Skip collisions if player is dead or invulnerable
|
||||||
if (itocado_per_jugador_[i] > 0.0F) continue;
|
if (itocado_per_jugador_[i] > 0.0F) {
|
||||||
if (!naus_[i].esta_viva()) continue;
|
continue;
|
||||||
if (naus_[i].es_invulnerable()) continue;
|
}
|
||||||
|
if (!naus_[i].esta_viva()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (naus_[i].es_invulnerable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const Punt& pos_nau = naus_[i].get_centre();
|
const Punt& pos_nau = naus_[i].get_centre();
|
||||||
|
|
||||||
@@ -1099,14 +1104,22 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() {
|
|||||||
// Check collision with BOTH players
|
// Check collision with BOTH players
|
||||||
for (uint8_t player_id = 0; player_id < 2; player_id++) {
|
for (uint8_t player_id = 0; player_id < 2; player_id++) {
|
||||||
// Skip if player is dead, invulnerable, or inactive
|
// Skip if player is dead, invulnerable, or inactive
|
||||||
if (itocado_per_jugador_[player_id] > 0.0F) continue;
|
if (itocado_per_jugador_[player_id] > 0.0F) {
|
||||||
if (!naus_[player_id].esta_viva()) continue;
|
continue;
|
||||||
if (naus_[player_id].es_invulnerable()) continue;
|
}
|
||||||
|
if (!naus_[player_id].esta_viva()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (naus_[player_id].es_invulnerable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip inactive players
|
// Skip inactive players
|
||||||
bool jugador_actiu = (player_id == 0) ? config_partida_.jugador1_actiu
|
bool jugador_actiu = (player_id == 0) ? config_partida_.jugador1_actiu
|
||||||
: config_partida_.jugador2_actiu;
|
: config_partida_.jugador2_actiu;
|
||||||
if (!jugador_actiu) continue;
|
if (!jugador_actiu) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const Punt& pos_nau = naus_[player_id].get_centre();
|
const Punt& pos_nau = naus_[player_id].get_centre();
|
||||||
|
|
||||||
@@ -1236,8 +1249,12 @@ Punt EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const {
|
|||||||
|
|
||||||
void EscenaJoc::disparar_bala(uint8_t player_id) {
|
void EscenaJoc::disparar_bala(uint8_t player_id) {
|
||||||
// Verificar que el jugador está vivo
|
// Verificar que el jugador está vivo
|
||||||
if (itocado_per_jugador_[player_id] > 0.0F) return;
|
if (itocado_per_jugador_[player_id] > 0.0F) {
|
||||||
if (!naus_[player_id].esta_viva()) return;
|
return;
|
||||||
|
}
|
||||||
|
if (!naus_[player_id].esta_viva()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 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 Punt& ship_centre = naus_[player_id].get_centre();
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ using Opcio = ContextEscenes::Opcio;
|
|||||||
// Helper: calcular el progrés individual d'una lletra
|
// Helper: calcular el progrés individual d'una lletra
|
||||||
// en funció del progrés global (efecte seqüencial)
|
// en funció del progrés global (efecte seqüencial)
|
||||||
static float calcular_progress_letra(size_t letra_index, size_t num_letras, float global_progress, float threshold) {
|
static float calcular_progress_letra(size_t letra_index, size_t num_letras, float global_progress, float threshold) {
|
||||||
if (num_letras == 0)
|
if (num_letras == 0) {
|
||||||
return 1.0F;
|
return 1.0F;
|
||||||
|
}
|
||||||
|
|
||||||
// Calcular temps per lletra
|
// Calcular temps per lletra
|
||||||
float duration_per_letra = 1.0F / static_cast<float>(num_letras);
|
float duration_per_letra = 1.0F / static_cast<float>(num_letras);
|
||||||
@@ -37,11 +38,11 @@ static float calcular_progress_letra(size_t letra_index, size_t num_letras, floa
|
|||||||
// Interpolar progrés
|
// Interpolar progrés
|
||||||
if (global_progress < start) {
|
if (global_progress < start) {
|
||||||
return 0.0F; // Encara no ha començat
|
return 0.0F; // Encara no ha començat
|
||||||
} else if (global_progress >= end) {
|
|
||||||
return 1.0F; // Completament apareguda
|
|
||||||
} else {
|
|
||||||
return (global_progress - start) / (end - start);
|
|
||||||
}
|
}
|
||||||
|
if (global_progress >= end) {
|
||||||
|
return 1.0F; // Completament apareguda
|
||||||
|
}
|
||||||
|
return (global_progress - start) / (end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
EscenaLogo::EscenaLogo(SDLManager& sdl, ContextEscenes& context)
|
EscenaLogo::EscenaLogo(SDLManager& sdl, ContextEscenes& context)
|
||||||
@@ -79,9 +80,7 @@ void EscenaLogo::executar() {
|
|||||||
last_time = current_time;
|
last_time = current_time;
|
||||||
|
|
||||||
// Limitar delta_time per evitar grans salts
|
// Limitar delta_time per evitar grans salts
|
||||||
if (delta_time > 0.05F) {
|
delta_time = std::min(delta_time, 0.05F);
|
||||||
delta_time = 0.05F;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actualitzar comptador de FPS
|
// Actualitzar comptador de FPS
|
||||||
sdl_.updateFPS(delta_time);
|
sdl_.updateFPS(delta_time);
|
||||||
@@ -395,7 +394,7 @@ void EscenaLogo::dibuixar() {
|
|||||||
|
|
||||||
// Dibuixar només lletres que NO han explotat
|
// Dibuixar només lletres que NO han explotat
|
||||||
for (size_t i = 0; i < lletres_.size(); i++) {
|
for (size_t i = 0; i < lletres_.size(); i++) {
|
||||||
if (explotades.find(i) == explotades.end()) {
|
if (!explotades.contains(i)) {
|
||||||
const auto& lletra = lletres_[i];
|
const auto& lletra = lletres_[i];
|
||||||
|
|
||||||
Rendering::render_shape(
|
Rendering::render_shape(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "escena_titol.hpp"
|
#include "escena_titol.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -265,9 +266,7 @@ void EscenaTitol::executar() {
|
|||||||
last_time = current_time;
|
last_time = current_time;
|
||||||
|
|
||||||
// Limitar delta_time per evitar grans salts
|
// Limitar delta_time per evitar grans salts
|
||||||
if (delta_time > 0.05F) {
|
delta_time = std::min(delta_time, 0.05F);
|
||||||
delta_time = 0.05F;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actualitzar comptador de FPS
|
// Actualitzar comptador de FPS
|
||||||
sdl_.updateFPS(delta_time);
|
sdl_.updateFPS(delta_time);
|
||||||
@@ -567,7 +566,7 @@ void EscenaTitol::dibuixar() {
|
|||||||
// === Calcular i renderitzar ombra (només si animació activa) ===
|
// === Calcular i renderitzar ombra (només si animació activa) ===
|
||||||
if (animacio_activa_) {
|
if (animacio_activa_) {
|
||||||
float temps_shadow = temps_animacio_ - SHADOW_DELAY;
|
float temps_shadow = temps_animacio_ - SHADOW_DELAY;
|
||||||
if (temps_shadow < 0.0F) temps_shadow = 0.0F; // Evitar temps negatiu
|
temps_shadow = std::max(temps_shadow, 0.0F); // Evitar temps negatiu
|
||||||
|
|
||||||
// Usar amplituds i freqüències completes per l'ombra
|
// Usar amplituds i freqüències completes per l'ombra
|
||||||
float amplitude_x_shadow = ORBIT_AMPLITUDE_X;
|
float amplitude_x_shadow = ORBIT_AMPLITUDE_X;
|
||||||
@@ -676,13 +675,17 @@ void EscenaTitol::dibuixar() {
|
|||||||
// Línea 1: Original (© 1999 Visente i Sergi)
|
// Línea 1: Original (© 1999 Visente i Sergi)
|
||||||
std::string copyright_original = Project::COPYRIGHT_ORIGINAL;
|
std::string copyright_original = Project::COPYRIGHT_ORIGINAL;
|
||||||
for (char& c : copyright_original) {
|
for (char& c : copyright_original) {
|
||||||
if (c >= 'a' && c <= 'z') c = c - 32; // Uppercase
|
if (c >= 'a' && c <= 'z') {
|
||||||
|
c = c - 32; // Uppercase
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Línea 2: Port (© 2025 jaildesigner)
|
// Línea 2: Port (© 2025 jaildesigner)
|
||||||
std::string copyright_port = Project::COPYRIGHT_PORT;
|
std::string copyright_port = Project::COPYRIGHT_PORT;
|
||||||
for (char& c : copyright_port) {
|
for (char& c : copyright_port) {
|
||||||
if (c >= 'a' && c <= 'z') c = c - 32; // Uppercase
|
if (c >= 'a' && c <= 'z') {
|
||||||
|
c = c - 32; // Uppercase
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcular posicions (anclatge des del top + separació)
|
// Calcular posicions (anclatge des del top + separació)
|
||||||
|
|||||||
@@ -448,77 +448,99 @@ static void loadAudioConfigFromYaml(const fkyaml::node& yaml) {
|
|||||||
|
|
||||||
// Carregar controls del jugador 1 des de YAML
|
// Carregar controls del jugador 1 des de YAML
|
||||||
static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) {
|
static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) {
|
||||||
if (!yaml.contains("player1")) return;
|
if (!yaml.contains("player1")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto& p1 = yaml["player1"];
|
const auto& p1 = yaml["player1"];
|
||||||
|
|
||||||
// Carregar controls de teclat
|
// Carregar controls de teclat
|
||||||
if (p1.contains("keyboard")) {
|
if (p1.contains("keyboard")) {
|
||||||
const auto& kb = p1["keyboard"];
|
const auto& kb = p1["keyboard"];
|
||||||
if (kb.contains("key_left"))
|
if (kb.contains("key_left")) {
|
||||||
player1.keyboard.key_left = stringToScancode(kb["key_left"].get_value<std::string>());
|
player1.keyboard.key_left = stringToScancode(kb["key_left"].get_value<std::string>());
|
||||||
if (kb.contains("key_right"))
|
}
|
||||||
|
if (kb.contains("key_right")) {
|
||||||
player1.keyboard.key_right = stringToScancode(kb["key_right"].get_value<std::string>());
|
player1.keyboard.key_right = stringToScancode(kb["key_right"].get_value<std::string>());
|
||||||
if (kb.contains("key_thrust"))
|
}
|
||||||
|
if (kb.contains("key_thrust")) {
|
||||||
player1.keyboard.key_thrust = stringToScancode(kb["key_thrust"].get_value<std::string>());
|
player1.keyboard.key_thrust = stringToScancode(kb["key_thrust"].get_value<std::string>());
|
||||||
if (kb.contains("key_shoot"))
|
}
|
||||||
|
if (kb.contains("key_shoot")) {
|
||||||
player1.keyboard.key_shoot = stringToScancode(kb["key_shoot"].get_value<std::string>());
|
player1.keyboard.key_shoot = stringToScancode(kb["key_shoot"].get_value<std::string>());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Carregar controls de gamepad
|
// Carregar controls de gamepad
|
||||||
if (p1.contains("gamepad")) {
|
if (p1.contains("gamepad")) {
|
||||||
const auto& gp = p1["gamepad"];
|
const auto& gp = p1["gamepad"];
|
||||||
if (gp.contains("button_left"))
|
if (gp.contains("button_left")) {
|
||||||
player1.gamepad.button_left = stringToButton(gp["button_left"].get_value<std::string>());
|
player1.gamepad.button_left = stringToButton(gp["button_left"].get_value<std::string>());
|
||||||
if (gp.contains("button_right"))
|
}
|
||||||
|
if (gp.contains("button_right")) {
|
||||||
player1.gamepad.button_right = stringToButton(gp["button_right"].get_value<std::string>());
|
player1.gamepad.button_right = stringToButton(gp["button_right"].get_value<std::string>());
|
||||||
if (gp.contains("button_thrust"))
|
}
|
||||||
|
if (gp.contains("button_thrust")) {
|
||||||
player1.gamepad.button_thrust = stringToButton(gp["button_thrust"].get_value<std::string>());
|
player1.gamepad.button_thrust = stringToButton(gp["button_thrust"].get_value<std::string>());
|
||||||
if (gp.contains("button_shoot"))
|
}
|
||||||
|
if (gp.contains("button_shoot")) {
|
||||||
player1.gamepad.button_shoot = stringToButton(gp["button_shoot"].get_value<std::string>());
|
player1.gamepad.button_shoot = stringToButton(gp["button_shoot"].get_value<std::string>());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Carregar nom del gamepad
|
// Carregar nom del gamepad
|
||||||
if (p1.contains("gamepad_name"))
|
if (p1.contains("gamepad_name")) {
|
||||||
player1.gamepad_name = p1["gamepad_name"].get_value<std::string>();
|
player1.gamepad_name = p1["gamepad_name"].get_value<std::string>();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Carregar controls del jugador 2 des de YAML
|
// Carregar controls del jugador 2 des de YAML
|
||||||
static void loadPlayer2ControlsFromYaml(const fkyaml::node& yaml) {
|
static void loadPlayer2ControlsFromYaml(const fkyaml::node& yaml) {
|
||||||
if (!yaml.contains("player2")) return;
|
if (!yaml.contains("player2")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto& p2 = yaml["player2"];
|
const auto& p2 = yaml["player2"];
|
||||||
|
|
||||||
// Carregar controls de teclat
|
// Carregar controls de teclat
|
||||||
if (p2.contains("keyboard")) {
|
if (p2.contains("keyboard")) {
|
||||||
const auto& kb = p2["keyboard"];
|
const auto& kb = p2["keyboard"];
|
||||||
if (kb.contains("key_left"))
|
if (kb.contains("key_left")) {
|
||||||
player2.keyboard.key_left = stringToScancode(kb["key_left"].get_value<std::string>());
|
player2.keyboard.key_left = stringToScancode(kb["key_left"].get_value<std::string>());
|
||||||
if (kb.contains("key_right"))
|
}
|
||||||
|
if (kb.contains("key_right")) {
|
||||||
player2.keyboard.key_right = stringToScancode(kb["key_right"].get_value<std::string>());
|
player2.keyboard.key_right = stringToScancode(kb["key_right"].get_value<std::string>());
|
||||||
if (kb.contains("key_thrust"))
|
}
|
||||||
|
if (kb.contains("key_thrust")) {
|
||||||
player2.keyboard.key_thrust = stringToScancode(kb["key_thrust"].get_value<std::string>());
|
player2.keyboard.key_thrust = stringToScancode(kb["key_thrust"].get_value<std::string>());
|
||||||
if (kb.contains("key_shoot"))
|
}
|
||||||
|
if (kb.contains("key_shoot")) {
|
||||||
player2.keyboard.key_shoot = stringToScancode(kb["key_shoot"].get_value<std::string>());
|
player2.keyboard.key_shoot = stringToScancode(kb["key_shoot"].get_value<std::string>());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Carregar controls de gamepad
|
// Carregar controls de gamepad
|
||||||
if (p2.contains("gamepad")) {
|
if (p2.contains("gamepad")) {
|
||||||
const auto& gp = p2["gamepad"];
|
const auto& gp = p2["gamepad"];
|
||||||
if (gp.contains("button_left"))
|
if (gp.contains("button_left")) {
|
||||||
player2.gamepad.button_left = stringToButton(gp["button_left"].get_value<std::string>());
|
player2.gamepad.button_left = stringToButton(gp["button_left"].get_value<std::string>());
|
||||||
if (gp.contains("button_right"))
|
}
|
||||||
|
if (gp.contains("button_right")) {
|
||||||
player2.gamepad.button_right = stringToButton(gp["button_right"].get_value<std::string>());
|
player2.gamepad.button_right = stringToButton(gp["button_right"].get_value<std::string>());
|
||||||
if (gp.contains("button_thrust"))
|
}
|
||||||
|
if (gp.contains("button_thrust")) {
|
||||||
player2.gamepad.button_thrust = stringToButton(gp["button_thrust"].get_value<std::string>());
|
player2.gamepad.button_thrust = stringToButton(gp["button_thrust"].get_value<std::string>());
|
||||||
if (gp.contains("button_shoot"))
|
}
|
||||||
|
if (gp.contains("button_shoot")) {
|
||||||
player2.gamepad.button_shoot = stringToButton(gp["button_shoot"].get_value<std::string>());
|
player2.gamepad.button_shoot = stringToButton(gp["button_shoot"].get_value<std::string>());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Carregar nom del gamepad
|
// Carregar nom del gamepad
|
||||||
if (p2.contains("gamepad_name"))
|
if (p2.contains("gamepad_name")) {
|
||||||
player2.gamepad_name = p2["gamepad_name"].get_value<std::string>();
|
player2.gamepad_name = p2["gamepad_name"].get_value<std::string>();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Carregar configuració des del fitxer YAML
|
// Carregar configuració des del fitxer YAML
|
||||||
auto loadFromFile() -> bool {
|
auto loadFromFile() -> bool {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ struct GamepadControls {
|
|||||||
struct PlayerControls {
|
struct PlayerControls {
|
||||||
KeyboardControls keyboard{};
|
KeyboardControls keyboard{};
|
||||||
GamepadControls gamepad{};
|
GamepadControls gamepad{};
|
||||||
std::string gamepad_name{""}; // Buit = auto-assignar per índex
|
std::string gamepad_name; // Buit = auto-assignar per índex
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variables globals (inline per evitar ODR violations)
|
// Variables globals (inline per evitar ODR violations)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ void SpawnController::configurar(const ConfigStage* config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpawnController::iniciar() {
|
void SpawnController::iniciar() {
|
||||||
if (!config_) {
|
if (config_ == nullptr) {
|
||||||
std::cerr << "[SpawnController] Error: config_ és null" << std::endl;
|
std::cerr << "[SpawnController] Error: config_ és null" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ void SpawnController::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpawnController::actualitzar(float delta_time, std::array<Enemic, 15>& orni_array, bool pausar) {
|
void SpawnController::actualitzar(float delta_time, std::array<Enemic, 15>& orni_array, bool pausar) {
|
||||||
if (!config_ || spawn_queue_.empty()) {
|
if ((config_ == nullptr) || spawn_queue_.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ uint8_t SpawnController::get_enemics_spawnejats() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpawnController::generar_spawn_events() {
|
void SpawnController::generar_spawn_events() {
|
||||||
if (!config_) {
|
if (config_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ void SpawnController::generar_spawn_events() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TipusEnemic SpawnController::seleccionar_tipus_aleatori() const {
|
TipusEnemic SpawnController::seleccionar_tipus_aleatori() const {
|
||||||
if (!config_) {
|
if (config_ == nullptr) {
|
||||||
return TipusEnemic::PENTAGON;
|
return TipusEnemic::PENTAGON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,11 +135,11 @@ TipusEnemic SpawnController::seleccionar_tipus_aleatori() const {
|
|||||||
|
|
||||||
if (rand_val < config_->distribucio.pentagon) {
|
if (rand_val < config_->distribucio.pentagon) {
|
||||||
return TipusEnemic::PENTAGON;
|
return TipusEnemic::PENTAGON;
|
||||||
} else if (rand_val < config_->distribucio.pentagon + config_->distribucio.quadrat) {
|
|
||||||
return TipusEnemic::QUADRAT;
|
|
||||||
} else {
|
|
||||||
return TipusEnemic::MOLINILLO;
|
|
||||||
}
|
}
|
||||||
|
if (rand_val < config_->distribucio.pentagon + config_->distribucio.quadrat) {
|
||||||
|
return TipusEnemic::QUADRAT;
|
||||||
|
}
|
||||||
|
return TipusEnemic::MOLINILLO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos) {
|
void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos) {
|
||||||
@@ -151,7 +151,7 @@ void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpawnController::aplicar_multiplicadors(Enemic& enemic) const {
|
void SpawnController::aplicar_multiplicadors(Enemic& enemic) const {
|
||||||
if (!config_) {
|
if (config_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -212,16 +212,17 @@ bool StageLoader::parse_multipliers(const fkyaml::node& yaml, MultiplicadorsDifi
|
|||||||
ModeSpawn StageLoader::parse_spawn_mode(const std::string& mode_str) {
|
ModeSpawn StageLoader::parse_spawn_mode(const std::string& mode_str) {
|
||||||
if (mode_str == "progressive") {
|
if (mode_str == "progressive") {
|
||||||
return ModeSpawn::PROGRESSIVE;
|
return ModeSpawn::PROGRESSIVE;
|
||||||
} else if (mode_str == "immediate") {
|
}
|
||||||
|
if (mode_str == "immediate") {
|
||||||
return ModeSpawn::IMMEDIATE;
|
return ModeSpawn::IMMEDIATE;
|
||||||
} else if (mode_str == "wave") {
|
}
|
||||||
|
if (mode_str == "wave") {
|
||||||
return ModeSpawn::WAVE;
|
return ModeSpawn::WAVE;
|
||||||
} else {
|
}
|
||||||
std::cerr << "[StageLoader] Warning: mode de spawn desconegut '" << mode_str
|
std::cerr << "[StageLoader] Warning: mode de spawn desconegut '" << mode_str
|
||||||
<< "', usant PROGRESSIVE" << std::endl;
|
<< "', usant PROGRESSIVE" << std::endl;
|
||||||
return ModeSpawn::PROGRESSIVE;
|
return ModeSpawn::PROGRESSIVE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool StageLoader::validar_config(const ConfigSistemaStages& config) {
|
bool StageLoader::validar_config(const ConfigSistemaStages& config) {
|
||||||
if (config.stages.empty()) {
|
if (config.stages.empty()) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ StageManager::StageManager(const ConfigSistemaStages* config)
|
|||||||
estat_(EstatStage::LEVEL_START),
|
estat_(EstatStage::LEVEL_START),
|
||||||
stage_actual_(1),
|
stage_actual_(1),
|
||||||
timer_transicio_(0.0F) {
|
timer_transicio_(0.0F) {
|
||||||
if (!config_) {
|
if (config_ == nullptr) {
|
||||||
std::cerr << "[StageManager] Error: config és null" << std::endl;
|
std::cerr << "[StageManager] Error: config és null" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ void StageManager::processar_level_completed(float delta_time) {
|
|||||||
|
|
||||||
void StageManager::carregar_stage(uint8_t stage_id) {
|
void StageManager::carregar_stage(uint8_t stage_id) {
|
||||||
const ConfigStage* stage_config = config_->obte_stage(stage_id);
|
const ConfigStage* stage_config = config_->obte_stage(stage_id);
|
||||||
if (!stage_config) {
|
if (stage_config == nullptr) {
|
||||||
std::cerr << "[StageManager] Error: no es pot trobar stage " << static_cast<int>(stage_id)
|
std::cerr << "[StageManager] Error: no es pot trobar stage " << static_cast<int>(stage_id)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ void ShipAnimator::inicialitzar() {
|
|||||||
void ShipAnimator::actualitzar(float delta_time) {
|
void ShipAnimator::actualitzar(float delta_time) {
|
||||||
// Dispatcher segons estat de cada nau
|
// Dispatcher segons estat de cada nau
|
||||||
for (auto& nau : naus_) {
|
for (auto& nau : naus_) {
|
||||||
if (!nau.visible) continue;
|
if (!nau.visible) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (nau.estat) {
|
switch (nau.estat) {
|
||||||
case EstatNau::ENTERING:
|
case EstatNau::ENTERING:
|
||||||
@@ -52,7 +54,9 @@ void ShipAnimator::actualitzar(float delta_time) {
|
|||||||
|
|
||||||
void ShipAnimator::dibuixar() const {
|
void ShipAnimator::dibuixar() const {
|
||||||
for (const auto& nau : naus_) {
|
for (const auto& nau : naus_) {
|
||||||
if (!nau.visible) continue;
|
if (!nau.visible) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Renderitzar nau (perspectiva ja incorporada a la forma)
|
// Renderitzar nau (perspectiva ja incorporada a la forma)
|
||||||
Rendering::render_shape(
|
Rendering::render_shape(
|
||||||
|
|||||||
Reference in New Issue
Block a user