corregida la llista de inicialització en clang-format
creat Balloon::Config per a inicialitzar globos
This commit is contained in:
@@ -14,6 +14,8 @@ ContinuationIndentWidth: 4
|
|||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: true
|
||||||
BreakConstructorInitializers: BeforeComma
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
PackConstructorInitializers: Never
|
||||||
AllowAllArgumentsOnNextLine: false
|
AllowAllArgumentsOnNextLine: false
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <utility> // Para pair
|
#include <utility> // Para pair
|
||||||
|
|
||||||
#include "texture.h" // Para Texture
|
|
||||||
#include "resource_helper.h" // Para ResourceHelper
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
#include "utils.h" // Para printWithDots
|
#include "texture.h" // Para Texture
|
||||||
|
#include "utils.h" // Para printWithDots
|
||||||
|
|
||||||
// Carga las animaciones en un vector(Animations) desde un fichero
|
// Carga las animaciones en un vector(Animations) desde un fichero
|
||||||
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer {
|
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer {
|
||||||
@@ -19,13 +19,13 @@ auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffe
|
|||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
std::istringstream stream;
|
std::istringstream stream;
|
||||||
bool using_resource_data = false;
|
bool using_resource_data = false;
|
||||||
|
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
std::string content(resource_data.begin(), resource_data.end());
|
std::string content(resource_data.begin(), resource_data.end());
|
||||||
stream.str(content);
|
stream.str(content);
|
||||||
using_resource_data = true;
|
using_resource_data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback a archivo directo
|
// Fallback a archivo directo
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
if (!using_resource_data) {
|
if (!using_resource_data) {
|
||||||
@@ -35,7 +35,7 @@ auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffe
|
|||||||
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream& input_stream = using_resource_data ? stream : static_cast<std::istream&>(file);
|
std::istream& input_stream = using_resource_data ? stream : static_cast<std::istream&>(file);
|
||||||
|
|
||||||
printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
|
printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ class AnimatedSprite : public MovingSprite {
|
|||||||
// --- Constructores y destructor ---
|
// --- Constructores y destructor ---
|
||||||
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string& file_path);
|
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string& file_path);
|
||||||
AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer& animations);
|
AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer& animations);
|
||||||
explicit AnimatedSprite(std::shared_ptr<Texture> texture) : MovingSprite(std::move(texture)) {}
|
explicit AnimatedSprite(std::shared_ptr<Texture> texture)
|
||||||
|
: MovingSprite(std::move(texture)) {}
|
||||||
~AnimatedSprite() override = default;
|
~AnimatedSprite() override = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#include <sstream> // Para basic_istringstream
|
#include <sstream> // Para basic_istringstream
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
|
|
||||||
#include "utils.h" // Para getFileName
|
|
||||||
#include "resource_helper.h" // Para ResourceHelper
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
|
#include "utils.h" // Para getFileName
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
Asset *Asset::instance = nullptr;
|
Asset *Asset::instance = nullptr;
|
||||||
@@ -209,7 +209,7 @@ auto Asset::checkFile(const std::string &path) -> bool {
|
|||||||
// Intentar primero con ResourceHelper
|
// Intentar primero con ResourceHelper
|
||||||
auto data = ResourceHelper::loadFile(path);
|
auto data = ResourceHelper::loadFile(path);
|
||||||
bool success = !data.empty();
|
bool success = !data.empty();
|
||||||
|
|
||||||
// Si no se encuentra en el pack, intentar con filesystem directo
|
// Si no se encuentra en el pack, intentar con filesystem directo
|
||||||
if (!success) {
|
if (!success) {
|
||||||
std::ifstream file(path);
|
std::ifstream file(path);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <unordered_map> // Para unordered_map
|
#include <unordered_map> // Para unordered_map
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
#include <cstdint> // Para uint8_t
|
|
||||||
|
|
||||||
// --- Clase Asset: gestor optimizado de recursos (singleton) ---
|
// --- Clase Asset: gestor optimizado de recursos (singleton) ---
|
||||||
class Asset {
|
class Asset {
|
||||||
@@ -34,7 +34,7 @@ class Asset {
|
|||||||
void add(const std::string &file_path, Type type, bool required = true, bool absolute = false);
|
void add(const std::string &file_path, Type type, bool required = true, bool absolute = false);
|
||||||
void loadFromFile(const std::string &config_file_path, const std::string &prefix = "", const std::string &system_folder = ""); // Con soporte para variables
|
void loadFromFile(const std::string &config_file_path, const std::string &prefix = "", const std::string &system_folder = ""); // Con soporte para variables
|
||||||
[[nodiscard]] auto get(const std::string &filename) const -> std::string; // Mantener nombre original
|
[[nodiscard]] auto get(const std::string &filename) const -> std::string; // Mantener nombre original
|
||||||
[[nodiscard]] auto loadData(const std::string &filename) const -> std::vector<uint8_t>; // Carga datos del archivo
|
[[nodiscard]] auto loadData(const std::string &filename) const -> std::vector<uint8_t>; // Carga datos del archivo
|
||||||
[[nodiscard]] auto check() const -> bool;
|
[[nodiscard]] auto check() const -> bool;
|
||||||
[[nodiscard]] auto getListByType(Type type) const -> std::vector<std::string>;
|
[[nodiscard]] auto getListByType(Type type) const -> std::vector<std::string>;
|
||||||
[[nodiscard]] auto exists(const std::string &filename) const -> bool; // Nueva función para verificar existencia
|
[[nodiscard]] auto exists(const std::string &filename) const -> bool; // Nueva función para verificar existencia
|
||||||
@@ -47,7 +47,9 @@ class Asset {
|
|||||||
bool required; // Indica si el archivo es obligatorio
|
bool required; // Indica si el archivo es obligatorio
|
||||||
|
|
||||||
Item(std::string path, Type asset_type, bool is_required)
|
Item(std::string path, Type asset_type, bool is_required)
|
||||||
: file(std::move(path)), type(asset_type), required(is_required) {}
|
: file(std::move(path)),
|
||||||
|
type(asset_type),
|
||||||
|
required(is_required) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Variables internas ---
|
// --- Variables internas ---
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
#include "asset_integrated.h"
|
#include "asset_integrated.h"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
bool AssetIntegrated::resource_pack_enabled_ = false;
|
bool AssetIntegrated::resource_pack_enabled_ = false;
|
||||||
|
|
||||||
void AssetIntegrated::initWithResourcePack(const std::string &executable_path,
|
void AssetIntegrated::initWithResourcePack(const std::string &executable_path,
|
||||||
const std::string &resource_pack_path) {
|
const std::string &resource_pack_path) {
|
||||||
// Inicializar Asset normal
|
// Inicializar Asset normal
|
||||||
Asset::init(executable_path);
|
Asset::init(executable_path);
|
||||||
|
|
||||||
// Inicializar ResourceLoader
|
// Inicializar ResourceLoader
|
||||||
auto& loader = ResourceLoader::getInstance();
|
auto &loader = ResourceLoader::getInstance();
|
||||||
if (loader.initialize(resource_pack_path, true)) {
|
if (loader.initialize(resource_pack_path, true)) {
|
||||||
resource_pack_enabled_ = true;
|
resource_pack_enabled_ = true;
|
||||||
std::cout << "Asset system initialized with resource pack: " << resource_pack_path << std::endl;
|
std::cout << "Asset system initialized with resource pack: " << resource_pack_path << std::endl;
|
||||||
@@ -24,58 +25,58 @@ void AssetIntegrated::initWithResourcePack(const std::string &executable_path,
|
|||||||
std::vector<uint8_t> AssetIntegrated::loadFile(const std::string &filename) {
|
std::vector<uint8_t> AssetIntegrated::loadFile(const std::string &filename) {
|
||||||
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
|
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
|
||||||
// Intentar cargar del pack de recursos
|
// Intentar cargar del pack de recursos
|
||||||
auto& loader = ResourceLoader::getInstance();
|
auto &loader = ResourceLoader::getInstance();
|
||||||
|
|
||||||
// Convertir ruta completa a ruta relativa para el pack
|
// Convertir ruta completa a ruta relativa para el pack
|
||||||
std::string relativePath = filename;
|
std::string relativePath = filename;
|
||||||
|
|
||||||
// Si la ruta contiene "data/", extraer la parte relativa
|
// Si la ruta contiene "data/", extraer la parte relativa
|
||||||
size_t dataPos = filename.find("data/");
|
size_t dataPos = filename.find("data/");
|
||||||
if (dataPos != std::string::npos) {
|
if (dataPos != std::string::npos) {
|
||||||
relativePath = filename.substr(dataPos + 5); // +5 para saltar "data/"
|
relativePath = filename.substr(dataPos + 5); // +5 para saltar "data/"
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = loader.loadResource(relativePath);
|
auto data = loader.loadResource(relativePath);
|
||||||
if (!data.empty()) {
|
if (!data.empty()) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback: cargar del filesystem
|
// Fallback: cargar del filesystem
|
||||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
std::cerr << "Error: Could not open file: " << filename << std::endl;
|
std::cerr << "Error: Could not open file: " << filename << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::streamsize fileSize = file.tellg();
|
std::streamsize fileSize = file.tellg();
|
||||||
file.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
std::vector<uint8_t> data(fileSize);
|
std::vector<uint8_t> data(fileSize);
|
||||||
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
|
if (!file.read(reinterpret_cast<char *>(data.data()), fileSize)) {
|
||||||
std::cerr << "Error: Could not read file: " << filename << std::endl;
|
std::cerr << "Error: Could not read file: " << filename << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetIntegrated::fileExists(const std::string &filename) const {
|
bool AssetIntegrated::fileExists(const std::string &filename) const {
|
||||||
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
|
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
|
||||||
auto& loader = ResourceLoader::getInstance();
|
auto &loader = ResourceLoader::getInstance();
|
||||||
|
|
||||||
// Convertir ruta completa a ruta relativa para el pack
|
// Convertir ruta completa a ruta relativa para el pack
|
||||||
std::string relativePath = filename;
|
std::string relativePath = filename;
|
||||||
size_t dataPos = filename.find("data/");
|
size_t dataPos = filename.find("data/");
|
||||||
if (dataPos != std::string::npos) {
|
if (dataPos != std::string::npos) {
|
||||||
relativePath = filename.substr(dataPos + 5);
|
relativePath = filename.substr(dataPos + 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loader.resourceExists(relativePath)) {
|
if (loader.resourceExists(relativePath)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar en filesystem
|
// Verificar en filesystem
|
||||||
return std::filesystem::exists(filename);
|
return std::filesystem::exists(filename);
|
||||||
}
|
}
|
||||||
@@ -90,16 +91,16 @@ bool AssetIntegrated::shouldUseResourcePack(const std::string &filepath) const {
|
|||||||
// - Archivos de config/ (ahora están fuera de data/)
|
// - Archivos de config/ (ahora están fuera de data/)
|
||||||
// - Archivos con absolute=true en assets.txt
|
// - Archivos con absolute=true en assets.txt
|
||||||
// - Archivos de sistema (${SYSTEM_FOLDER})
|
// - Archivos de sistema (${SYSTEM_FOLDER})
|
||||||
|
|
||||||
if (filepath.find("/config/") != std::string::npos ||
|
if (filepath.find("/config/") != std::string::npos ||
|
||||||
filepath.find("config/") == 0) {
|
filepath.find("config/") == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filepath.find("/data/") != std::string::npos ||
|
if (filepath.find("/data/") != std::string::npos ||
|
||||||
filepath.find("data/") == 0) {
|
filepath.find("data/") == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,29 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "asset.h"
|
#include "asset.h"
|
||||||
#include "resource_loader.h"
|
#include "resource_loader.h"
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
// Extensión de Asset que integra ResourceLoader
|
// Extensión de Asset que integra ResourceLoader
|
||||||
class AssetIntegrated : public Asset {
|
class AssetIntegrated : public Asset {
|
||||||
public:
|
public:
|
||||||
// Inicializa Asset con ResourceLoader
|
// Inicializa Asset con ResourceLoader
|
||||||
static void initWithResourcePack(const std::string &executable_path,
|
static void initWithResourcePack(const std::string &executable_path,
|
||||||
const std::string &resource_pack_path = "resources.pack");
|
const std::string &resource_pack_path = "resources.pack");
|
||||||
|
|
||||||
// Carga un archivo usando ResourceLoader como primera opción
|
// Carga un archivo usando ResourceLoader como primera opción
|
||||||
std::vector<uint8_t> loadFile(const std::string &filename);
|
std::vector<uint8_t> loadFile(const std::string &filename);
|
||||||
|
|
||||||
// Verifica si un archivo existe (pack o filesystem)
|
// Verifica si un archivo existe (pack o filesystem)
|
||||||
bool fileExists(const std::string &filename) const;
|
bool fileExists(const std::string &filename) const;
|
||||||
|
|
||||||
// Obtiene la ruta completa para archivos del sistema/config
|
// Obtiene la ruta completa para archivos del sistema/config
|
||||||
std::string getSystemPath(const std::string &filename) const;
|
std::string getSystemPath(const std::string &filename) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool resource_pack_enabled_;
|
static bool resource_pack_enabled_;
|
||||||
|
|
||||||
// Determina si un archivo debe cargarse del pack o del filesystem
|
// Determina si un archivo debe cargarse del pack o del filesystem
|
||||||
bool shouldUseResourcePack(const std::string &filepath) const;
|
bool shouldUseResourcePack(const std::string &filepath) const;
|
||||||
};
|
};
|
||||||
@@ -75,11 +75,15 @@ class Audio {
|
|||||||
bool loop; // Indica si la última pista de música se debe reproducir en bucle
|
bool loop; // Indica si la última pista de música se debe reproducir en bucle
|
||||||
|
|
||||||
// Constructor para inicializar la música con valores predeterminados
|
// Constructor para inicializar la música con valores predeterminados
|
||||||
Music() : state(MusicState::STOPPED), loop(false) {}
|
Music()
|
||||||
|
: state(MusicState::STOPPED),
|
||||||
|
loop(false) {}
|
||||||
|
|
||||||
// Constructor para inicializar con valores específicos
|
// Constructor para inicializar con valores específicos
|
||||||
Music(MusicState init_state, std::string init_name, bool init_loop)
|
Music(MusicState init_state, std::string init_name, bool init_loop)
|
||||||
: state(init_state), name(std::move(init_name)), loop(init_loop) {}
|
: state(init_state),
|
||||||
|
name(std::move(init_name)),
|
||||||
|
loop(init_loop) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
|
|||||||
@@ -11,20 +11,21 @@
|
|||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float speed, Uint16 creation_timer, SDL_FRect play_area, const std::shared_ptr<Texture> &texture, const std::vector<std::string> &animation)
|
Balloon::Balloon(const Config& config)
|
||||||
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
|
: sprite_(std::make_unique<AnimatedSprite>(config.texture, config.animation)),
|
||||||
x_(x),
|
x_(config.x),
|
||||||
y_(y),
|
y_(config.y),
|
||||||
vx_(vel_x),
|
vx_(config.vel_x),
|
||||||
being_created_(creation_timer > 0),
|
being_created_(config.creation_counter > 0),
|
||||||
invulnerable_(creation_timer > 0),
|
invulnerable_(config.creation_counter > 0),
|
||||||
stopped_(creation_timer > 0),
|
stopped_(config.creation_counter > 0),
|
||||||
creation_counter_(creation_timer),
|
creation_counter_(config.creation_counter),
|
||||||
creation_counter_ini_(creation_timer),
|
creation_counter_ini_(config.creation_counter),
|
||||||
type_(type),
|
type_(config.type),
|
||||||
size_(size),
|
size_(config.size),
|
||||||
speed_(speed),
|
speed_(config.speed),
|
||||||
play_area_(play_area) {
|
play_area_(config.play_area),
|
||||||
|
sound_(config.sound) {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case Type::BALLOON: {
|
case Type::BALLOON: {
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
@@ -37,9 +38,8 @@ Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float spee
|
|||||||
power_ = POWER.at(INDEX);
|
power_ = POWER.at(INDEX);
|
||||||
menace_ = MENACE.at(INDEX);
|
menace_ = MENACE.at(INDEX);
|
||||||
score_ = SCORE.at(INDEX);
|
score_ = SCORE.at(INDEX);
|
||||||
bouncing_sound_ = BOUNCING_SOUND.at(INDEX);
|
sound_.bouncing_file = BOUNCING_SOUND.at(INDEX);
|
||||||
popping_sound_ = POPPING_SOUND.at(INDEX);
|
sound_.popping_file = POPPING_SOUND.at(INDEX);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,17 +52,16 @@ Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float spee
|
|||||||
power_ = POWER.at(INDEX);
|
power_ = POWER.at(INDEX);
|
||||||
menace_ = MENACE.at(INDEX);
|
menace_ = MENACE.at(INDEX);
|
||||||
score_ = SCORE.at(INDEX);
|
score_ = SCORE.at(INDEX);
|
||||||
bouncing_sound_ = BOUNCING_SOUND.at(INDEX);
|
sound_.bouncing_file = BOUNCING_SOUND.at(INDEX);
|
||||||
popping_sound_ = POPPING_SOUND.at(INDEX);
|
sound_.popping_file = POPPING_SOUND.at(INDEX);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::POWERBALL: {
|
case Type::POWERBALL: {
|
||||||
constexpr int INDEX = 3;
|
constexpr int INDEX = 3;
|
||||||
h_ = w_ = WIDTH.at(4);
|
h_ = w_ = WIDTH.at(4);
|
||||||
bouncing_sound_ = BOUNCING_SOUND.at(3);
|
sound_.bouncing_file = BOUNCING_SOUND.at(3);
|
||||||
popping_sound_ = "power_ball_explosion.wav";
|
sound_.popping_file = "power_ball_explosion.wav";
|
||||||
power_ = score_ = menace_ = 0;
|
power_ = score_ = menace_ = 0;
|
||||||
|
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
@@ -70,9 +69,8 @@ Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float spee
|
|||||||
gravity_ = param.balloon.settings.at(INDEX).grav;
|
gravity_ = param.balloon.settings.at(INDEX).grav;
|
||||||
default_vy_ = param.balloon.settings.at(INDEX).vel;
|
default_vy_ = param.balloon.settings.at(INDEX).vel;
|
||||||
|
|
||||||
sprite_->setRotate(creation_timer <= 0);
|
sprite_->setRotate(config.creation_counter <= 0);
|
||||||
sprite_->setRotateAmount(vx_ > 0.0F ? 2.0 : -2.0);
|
sprite_->setRotateAmount(vx_ > 0.0F ? 2.0 : -2.0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,8 +231,14 @@ void Balloon::applyGravity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Balloon::playBouncingSound() {
|
void Balloon::playBouncingSound() {
|
||||||
if (bouncing_sound_enabled_) {
|
if (sound_.enabled && sound_.bouncing_enabled) {
|
||||||
playSound(bouncing_sound_);
|
Audio::get()->playSound(sound_.bouncing_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Balloon::playPoppingSound() {
|
||||||
|
if (sound_.enabled && sound_.poping_enabled) {
|
||||||
|
Audio::get()->playSound(sound_.popping_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,23 +372,8 @@ void Balloon::useNormalColor() {
|
|||||||
setAnimation();
|
setAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reproduce sonido
|
|
||||||
void Balloon::playSound(const std::string &name) const {
|
|
||||||
if (!sound_enabled_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto *audio_ = Audio::get();
|
|
||||||
audio_->playSound(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Explota el globo
|
// Explota el globo
|
||||||
void Balloon::pop(bool should_sound) {
|
void Balloon::pop(bool should_sound) {
|
||||||
if (should_sound) {
|
if (should_sound) { playPoppingSound(); }
|
||||||
if (poping_sound_enabled_) {
|
|
||||||
playSound(popping_sound_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enabled_ = false;
|
enabled_ = false;
|
||||||
}
|
}
|
||||||
140
source/balloon.h
140
source/balloon.h
@@ -25,10 +25,16 @@ class Balloon {
|
|||||||
static constexpr std::array<int, 5> WIDTH = {10, 16, 26, 48, 49};
|
static constexpr std::array<int, 5> WIDTH = {10, 16, 26, 48, 49};
|
||||||
|
|
||||||
static constexpr std::array<std::string_view, 4> BOUNCING_SOUND = {
|
static constexpr std::array<std::string_view, 4> BOUNCING_SOUND = {
|
||||||
"balloon_bounce0.wav", "balloon_bounce1.wav", "balloon_bounce2.wav", "balloon_bounce3.wav"};
|
"balloon_bounce0.wav",
|
||||||
|
"balloon_bounce1.wav",
|
||||||
|
"balloon_bounce2.wav",
|
||||||
|
"balloon_bounce3.wav"};
|
||||||
|
|
||||||
static constexpr std::array<std::string_view, 4> POPPING_SOUND = {
|
static constexpr std::array<std::string_view, 4> POPPING_SOUND = {
|
||||||
"balloon_pop0.wav", "balloon_pop1.wav", "balloon_pop2.wav", "balloon_pop3.wav"};
|
"balloon_pop0.wav",
|
||||||
|
"balloon_pop1.wav",
|
||||||
|
"balloon_pop2.wav",
|
||||||
|
"balloon_pop3.wav"};
|
||||||
|
|
||||||
static constexpr float VELX_POSITIVE = 0.7F;
|
static constexpr float VELX_POSITIVE = 0.7F;
|
||||||
static constexpr float VELX_NEGATIVE = -0.7F;
|
static constexpr float VELX_NEGATIVE = -0.7F;
|
||||||
@@ -52,18 +58,32 @@ class Balloon {
|
|||||||
POWERBALL = 2, // Globo de poder
|
POWERBALL = 2, // Globo de poder
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --- Estructura para manejo de sonido ---
|
||||||
|
struct Sound {
|
||||||
|
std::string bouncing_file; // Archivo de sonido al rebotar
|
||||||
|
std::string popping_file; // Archivo de sonido al explotar
|
||||||
|
bool bouncing_enabled = false; // Si debe sonar el globo al rebotar
|
||||||
|
bool poping_enabled = true; // Si debe sonar el globo al explotar
|
||||||
|
bool enabled = true; // Indica si los globos deben hacer algun sonido
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Estructura de configuración para inicialización ---
|
||||||
|
struct Config {
|
||||||
|
float x = 0.0F;
|
||||||
|
float y = 0.0F;
|
||||||
|
Type type = Type::BALLOON;
|
||||||
|
Size size = Size::EXTRALARGE;
|
||||||
|
float vel_x = VELX_POSITIVE;
|
||||||
|
float speed = SPEED.at(0);
|
||||||
|
Uint16 creation_counter = 0;
|
||||||
|
SDL_FRect play_area = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
|
||||||
|
std::shared_ptr<Texture> texture = nullptr;
|
||||||
|
std::vector<std::string> animation;
|
||||||
|
Sound sound;
|
||||||
|
};
|
||||||
|
|
||||||
// --- Constructores y destructor ---
|
// --- Constructores y destructor ---
|
||||||
Balloon(
|
Balloon(const Config& config);
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
Type type,
|
|
||||||
Size size,
|
|
||||||
float vel_x,
|
|
||||||
float speed,
|
|
||||||
Uint16 creation_timer,
|
|
||||||
SDL_FRect play_area,
|
|
||||||
const std::shared_ptr<Texture>& texture,
|
|
||||||
const std::vector<std::string>& animation);
|
|
||||||
~Balloon() = default;
|
~Balloon() = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
@@ -102,9 +122,9 @@ class Balloon {
|
|||||||
void setVelY(float vel_y) { vy_ = vel_y; }
|
void setVelY(float vel_y) { vy_ = vel_y; }
|
||||||
void setSpeed(float speed) { speed_ = speed; }
|
void setSpeed(float speed) { speed_ = speed; }
|
||||||
void setInvulnerable(bool value) { invulnerable_ = value; }
|
void setInvulnerable(bool value) { invulnerable_ = value; }
|
||||||
void setBouncingSound(bool value) { bouncing_sound_enabled_ = value; }
|
void setBouncingSound(bool value) { sound_.bouncing_enabled = value; }
|
||||||
void setPoppingSound(bool value) { poping_sound_enabled_ = value; }
|
void setPoppingSound(bool value) { sound_.poping_enabled = value; }
|
||||||
void setSound(bool value) { sound_enabled_ = value; }
|
void setSound(bool value) { sound_.enabled = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Estructura para el efecto de rebote ---
|
// --- Estructura para el efecto de rebote ---
|
||||||
@@ -114,10 +134,28 @@ class Balloon {
|
|||||||
|
|
||||||
// Tablas de valores predefinidos para el efecto de rebote
|
// Tablas de valores predefinidos para el efecto de rebote
|
||||||
static constexpr std::array<float, BOUNCE_FRAMES> HORIZONTAL_ZOOM_VALUES = {
|
static constexpr std::array<float, BOUNCE_FRAMES> HORIZONTAL_ZOOM_VALUES = {
|
||||||
1.10F, 1.05F, 1.00F, 0.95F, 0.90F, 0.95F, 1.00F, 1.02F, 1.05F, 1.02F};
|
1.10F,
|
||||||
|
1.05F,
|
||||||
|
1.00F,
|
||||||
|
0.95F,
|
||||||
|
0.90F,
|
||||||
|
0.95F,
|
||||||
|
1.00F,
|
||||||
|
1.02F,
|
||||||
|
1.05F,
|
||||||
|
1.02F};
|
||||||
|
|
||||||
static constexpr std::array<float, BOUNCE_FRAMES> VERTICAL_ZOOM_VALUES = {
|
static constexpr std::array<float, BOUNCE_FRAMES> VERTICAL_ZOOM_VALUES = {
|
||||||
0.90F, 0.95F, 1.00F, 1.05F, 1.10F, 1.05F, 1.00F, 0.98F, 0.95F, 0.98F};
|
0.90F,
|
||||||
|
0.95F,
|
||||||
|
1.00F,
|
||||||
|
1.05F,
|
||||||
|
1.10F,
|
||||||
|
1.05F,
|
||||||
|
1.00F,
|
||||||
|
0.98F,
|
||||||
|
0.95F,
|
||||||
|
0.98F};
|
||||||
|
|
||||||
// Estado del efecto
|
// Estado del efecto
|
||||||
bool enabled_ = false; // Si el efecto está activo
|
bool enabled_ = false; // Si el efecto está activo
|
||||||
@@ -203,47 +241,43 @@ class Balloon {
|
|||||||
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
|
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
|
||||||
|
|
||||||
// --- Variables de estado y físicas ---
|
// --- Variables de estado y físicas ---
|
||||||
float x_; // Posición X
|
float x_; // Posición X
|
||||||
float y_; // Posición Y
|
float y_; // Posición Y
|
||||||
float w_; // Ancho
|
float w_; // Ancho
|
||||||
float h_; // Alto
|
float h_; // Alto
|
||||||
float vx_; // Velocidad X
|
float vx_; // Velocidad X
|
||||||
float vy_; // Velocidad Y
|
float vy_; // Velocidad Y
|
||||||
float gravity_; // Aceleración en Y
|
float gravity_; // Aceleración en Y
|
||||||
float default_vy_; // Velocidad inicial al rebotar
|
float default_vy_; // Velocidad inicial al rebotar
|
||||||
float max_vy_; // Máxima velocidad en Y
|
float max_vy_; // Máxima velocidad en Y
|
||||||
bool being_created_; // Si el globo se está creando
|
bool being_created_; // Si el globo se está creando
|
||||||
bool enabled_ = true; // Si el globo está activo
|
bool enabled_ = true; // Si el globo está activo
|
||||||
bool invulnerable_; // Si el globo es invulnerable
|
bool invulnerable_; // Si el globo es invulnerable
|
||||||
bool stopped_; // Si el globo está parado
|
bool stopped_; // Si el globo está parado
|
||||||
bool use_reversed_colors_ = false; // Si se usa el color alternativo
|
bool use_reversed_colors_ = false; // Si se usa el color alternativo
|
||||||
Circle collider_; // Círculo de colisión
|
Circle collider_; // Círculo de colisión
|
||||||
Uint16 creation_counter_; // Temporizador de creación
|
Uint16 creation_counter_; // Temporizador de creación
|
||||||
Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación
|
Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación
|
||||||
Uint16 score_; // Puntos al destruir el globo
|
Uint16 score_; // Puntos al destruir el globo
|
||||||
Type type_; // Tipo de globo
|
Type type_; // Tipo de globo
|
||||||
Size size_; // Tamaño de globo
|
Size size_; // Tamaño de globo
|
||||||
Uint8 menace_; // Amenaza que genera el globo
|
Uint8 menace_; // Amenaza que genera el globo
|
||||||
Uint32 counter_ = 0; // Contador interno
|
Uint32 counter_ = 0; // Contador interno
|
||||||
float travel_y_ = 1.0F; // Distancia a recorrer en Y antes de aplicar gravedad
|
float travel_y_ = 1.0F; // Distancia a recorrer en Y antes de aplicar gravedad
|
||||||
float speed_; // Velocidad del globo
|
float speed_; // Velocidad del globo
|
||||||
Uint8 power_; // Poder que alberga el globo
|
Uint8 power_; // Poder que alberga el globo
|
||||||
SDL_FRect play_area_; // Zona de movimiento del globo
|
SDL_FRect play_area_; // Zona de movimiento del globo
|
||||||
std::string bouncing_sound_; // Archivo de sonido al rebotar
|
Sound sound_; // Configuración de sonido del globo
|
||||||
std::string popping_sound_; // Archivo de sonido al explotar
|
BounceEffect bounce_effect_; // Efecto de rebote
|
||||||
bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar
|
|
||||||
bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar
|
|
||||||
bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido
|
|
||||||
BounceEffect bounce_effect_; // Efecto de rebote
|
|
||||||
|
|
||||||
// --- Posicionamiento y transformación ---
|
// --- Posicionamiento y transformación ---
|
||||||
void shiftColliders(); // Alinea el círculo de colisión con el sprite
|
void shiftColliders(); // Alinea el círculo de colisión con el sprite
|
||||||
void shiftSprite(); // Alinea el sprite en pantalla
|
void shiftSprite(); // Alinea el sprite en pantalla
|
||||||
|
|
||||||
// --- Animación y sonido ---
|
// --- Animación y sonido ---
|
||||||
void setAnimation(); // Establece la animación correspondiente
|
void setAnimation(); // Establece la animación correspondiente
|
||||||
void playSound(const std::string& name) const; // Reproduce un sonido por nombre
|
void playBouncingSound(); // Reproduce el sonido de rebote
|
||||||
void playBouncingSound(); // Reproduce el sonido de rebote
|
void playPoppingSound(); // Reproduce el sonido de reventar
|
||||||
|
|
||||||
// --- Movimiento y física ---
|
// --- Movimiento y física ---
|
||||||
void handleHorizontalMovement(); // Maneja el movimiento horizontal
|
void handleHorizontalMovement(); // Maneja el movimiento horizontal
|
||||||
|
|||||||
@@ -15,19 +15,24 @@ class BalloonFormations {
|
|||||||
public:
|
public:
|
||||||
// --- Estructuras ---
|
// --- Estructuras ---
|
||||||
struct SpawnParams {
|
struct SpawnParams {
|
||||||
int x = 0; // Posición en el eje X donde crear el globo
|
float x = 0; // Posición en el eje X donde crear el globo
|
||||||
int y = 0; // Posición en el eje Y donde crear el globo
|
float y = 0; // Posición en el eje Y donde crear el globo
|
||||||
float vel_x = 0.0F; // Velocidad inicial en el eje X
|
float vel_x = 0.0F; // Velocidad inicial en el eje X
|
||||||
Balloon::Type type = Balloon::Type::BALLOON; // Tipo de globo
|
Balloon::Type type = Balloon::Type::BALLOON; // Tipo de globo
|
||||||
Balloon::Size size = Balloon::Size::SMALL; // Tamaño de globo
|
Balloon::Size size = Balloon::Size::SMALL; // Tamaño de globo
|
||||||
int creation_counter = 0; // Temporizador para la creación del globo
|
Uint16 creation_counter = 0; // Temporizador para la creación del globo
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
SpawnParams() = default;
|
SpawnParams() = default;
|
||||||
|
|
||||||
// Constructor con parámetros
|
// Constructor con parámetros
|
||||||
SpawnParams(int x, int y, float vel_x, Balloon::Type type, Balloon::Size size, int creation_counter)
|
SpawnParams(float x, float y, float vel_x, Balloon::Type type, Balloon::Size size, Uint16 creation_counter)
|
||||||
: x(x), y(y), vel_x(vel_x), type(type), size(size), creation_counter(creation_counter) {}
|
: x(x),
|
||||||
|
y(y),
|
||||||
|
vel_x(vel_x),
|
||||||
|
type(type),
|
||||||
|
size(size),
|
||||||
|
creation_counter(creation_counter) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Formation {
|
struct Formation {
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
BalloonManager::BalloonManager(IStageInfo *stage_info)
|
BalloonManager::BalloonManager(IStageInfo *stage_info)
|
||||||
: explosions_(std::make_unique<Explosions>()), balloon_formations_(std::make_unique<BalloonFormations>()), stage_info_(stage_info) { init(); }
|
: explosions_(std::make_unique<Explosions>()),
|
||||||
|
balloon_formations_(std::make_unique<BalloonFormations>()),
|
||||||
|
stage_info_(stage_info) { init(); }
|
||||||
|
|
||||||
// Inicializa
|
// Inicializa
|
||||||
void BalloonManager::init() {
|
void BalloonManager::init() {
|
||||||
@@ -105,7 +107,15 @@ void BalloonManager::deployRandomFormation(int stage) {
|
|||||||
// Crea los globos de la formación
|
// Crea los globos de la formación
|
||||||
const auto BALLOONS = balloon_formations_->getFormationFromPool(stage, formation_id).balloons;
|
const auto BALLOONS = balloon_formations_->getFormationFromPool(stage, formation_id).balloons;
|
||||||
for (auto balloon : BALLOONS) {
|
for (auto balloon : BALLOONS) {
|
||||||
createBalloon(balloon.x, balloon.y, balloon.type, balloon.size, balloon.vel_x, balloon_speed_, (creation_time_enabled_) ? balloon.creation_counter : 0);
|
Balloon::Config config = {
|
||||||
|
.x = balloon.x,
|
||||||
|
.y = balloon.y,
|
||||||
|
.vel_x = balloon.vel_x,
|
||||||
|
.type = balloon.type,
|
||||||
|
.size = balloon.size,
|
||||||
|
.speed = balloon_speed_,
|
||||||
|
.creation_counter = static_cast<Uint16>(creation_time_enabled_ ? balloon.creation_counter : 0)};
|
||||||
|
createBalloon(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinicia el contador para el próximo despliegue
|
// Reinicia el contador para el próximo despliegue
|
||||||
@@ -118,15 +128,31 @@ void BalloonManager::deployRandomFormation(int stage) {
|
|||||||
void BalloonManager::deployFormation(int formation_id) {
|
void BalloonManager::deployFormation(int formation_id) {
|
||||||
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
||||||
for (auto balloon : BALLOONS) {
|
for (auto balloon : BALLOONS) {
|
||||||
createBalloon(balloon.x, balloon.y, balloon.type, balloon.size, balloon.vel_x, balloon_speed_, balloon.creation_counter);
|
Balloon::Config config = {
|
||||||
|
.x = balloon.x,
|
||||||
|
.y = balloon.y,
|
||||||
|
.vel_x = balloon.vel_x,
|
||||||
|
.type = balloon.type,
|
||||||
|
.size = balloon.size,
|
||||||
|
.speed = balloon_speed_,
|
||||||
|
.creation_counter = balloon.creation_counter};
|
||||||
|
createBalloon(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea una formación de globos específica a una altura determinada
|
// Crea una formación de globos específica a una altura determinada
|
||||||
void BalloonManager::deployFormation(int formation_id, int y) {
|
void BalloonManager::deployFormation(int formation_id, float y) {
|
||||||
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
||||||
for (auto balloon : BALLOONS) {
|
for (auto balloon : BALLOONS) {
|
||||||
createBalloon(balloon.x, y, balloon.type, balloon.size, balloon.vel_x, balloon_speed_, balloon.creation_counter);
|
Balloon::Config config = {
|
||||||
|
.x = balloon.x,
|
||||||
|
.y = y,
|
||||||
|
.vel_x = balloon.vel_x,
|
||||||
|
.type = balloon.type,
|
||||||
|
.size = balloon.size,
|
||||||
|
.speed = balloon_speed_,
|
||||||
|
.creation_counter = balloon.creation_counter};
|
||||||
|
createBalloon(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,13 +178,16 @@ auto BalloonManager::calculateScreenPower() -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crea un globo nuevo en el vector de globos
|
// Crea un globo nuevo en el vector de globos
|
||||||
auto BalloonManager::createBalloon(float x, int y, Balloon::Type type, Balloon::Size size, float velx, float speed, int creation_timer) -> std::shared_ptr<Balloon> {
|
auto BalloonManager::createBalloon(Balloon::Config config) -> std::shared_ptr<Balloon> {
|
||||||
if (can_deploy_balloons_) {
|
if (can_deploy_balloons_) {
|
||||||
const int INDEX = static_cast<int>(size);
|
const int INDEX = static_cast<int>(config.size);
|
||||||
balloons_.emplace_back(std::make_shared<Balloon>(x, y, type, size, velx, speed, creation_timer, play_area_, balloon_textures_.at(INDEX), balloon_animations_.at(INDEX)));
|
config.play_area = play_area_;
|
||||||
balloons_.back()->setSound(sound_enabled_);
|
config.texture = balloon_textures_.at(INDEX);
|
||||||
balloons_.back()->setBouncingSound(bouncing_sound_enabled_);
|
config.animation = balloon_animations_.at(INDEX);
|
||||||
balloons_.back()->setPoppingSound(poping_sound_enabled_);
|
config.sound.enabled = sound_enabled_;
|
||||||
|
config.sound.bouncing_enabled = bouncing_sound_enabled_;
|
||||||
|
config.sound.poping_enabled = poping_sound_enabled_;
|
||||||
|
balloons_.emplace_back(std::make_shared<Balloon>(config));
|
||||||
return balloons_.back();
|
return balloons_.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,19 +198,24 @@ auto BalloonManager::createBalloon(float x, int y, Balloon::Type type, Balloon::
|
|||||||
void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction) {
|
void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction) {
|
||||||
if (can_deploy_balloons_) {
|
if (can_deploy_balloons_) {
|
||||||
// Calcula parametros
|
// Calcula parametros
|
||||||
const float VX = direction == "LEFT" ? Balloon::VELX_NEGATIVE : Balloon::VELX_POSITIVE;
|
|
||||||
const auto SIZE = static_cast<Balloon::Size>(static_cast<int>(balloon->getSize()) - 1);
|
|
||||||
const int PARENT_HEIGHT = balloon->getHeight();
|
const int PARENT_HEIGHT = balloon->getHeight();
|
||||||
const int CHILD_HEIGHT = Balloon::WIDTH.at(static_cast<int>(balloon->getSize()) - 1);
|
const int CHILD_HEIGHT = Balloon::WIDTH.at(static_cast<int>(balloon->getSize()) - 1);
|
||||||
const int CHILD_WIDTH = CHILD_HEIGHT;
|
const int CHILD_WIDTH = CHILD_HEIGHT;
|
||||||
const float Y = balloon->getPosY() + ((PARENT_HEIGHT - CHILD_HEIGHT) / 2);
|
|
||||||
float x = direction == "LEFT" ? balloon->getPosX() + (balloon->getWidth() / 3) : balloon->getPosX() + (2 * (balloon->getWidth() / 3));
|
const float X = direction == "LEFT" ? balloon->getPosX() + (balloon->getWidth() / 3) : balloon->getPosX() + (2 * (balloon->getWidth() / 3));
|
||||||
const float MIN_X = play_area_.x;
|
const float MIN_X = play_area_.x;
|
||||||
const float MAX_X = play_area_.w - CHILD_WIDTH;
|
const float MAX_X = play_area_.w - CHILD_WIDTH;
|
||||||
x = std::clamp(x - (CHILD_WIDTH / 2), MIN_X, MAX_X);
|
|
||||||
|
Balloon::Config config = {
|
||||||
|
.x = std::clamp(X - (CHILD_WIDTH / 2), MIN_X, MAX_X),
|
||||||
|
.y = balloon->getPosY() + ((PARENT_HEIGHT - CHILD_HEIGHT) / 2),
|
||||||
|
.size = static_cast<Balloon::Size>(static_cast<int>(balloon->getSize()) - 1),
|
||||||
|
.vel_x = direction == "LEFT" ? Balloon::VELX_NEGATIVE : Balloon::VELX_POSITIVE,
|
||||||
|
.creation_counter = 0,
|
||||||
|
.speed = balloon_speed_};
|
||||||
|
|
||||||
// Crea el globo
|
// Crea el globo
|
||||||
auto b = createBalloon(x, Y, balloon->getType(), SIZE, VX, balloon_speed_, 0);
|
auto b = createBalloon(config);
|
||||||
|
|
||||||
// Establece parametros
|
// Establece parametros
|
||||||
b->setVelY(b->getType() == Balloon::Type::BALLOON ? -2.50F : Balloon::VELX_NEGATIVE * 2.0F);
|
b->setVelY(b->getType() == Balloon::Type::BALLOON ? -2.50F : Balloon::VELX_NEGATIVE * 2.0F);
|
||||||
@@ -196,22 +230,33 @@ void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon> &balloon,
|
|||||||
void BalloonManager::createPowerBall() {
|
void BalloonManager::createPowerBall() {
|
||||||
if (can_deploy_balloons_) {
|
if (can_deploy_balloons_) {
|
||||||
constexpr int VALUES = 6;
|
constexpr int VALUES = 6;
|
||||||
constexpr float POS_Y = -Balloon::WIDTH.at(4);
|
const int LUCK = rand() % VALUES;
|
||||||
constexpr int CREATION_TIME = 0;
|
|
||||||
|
|
||||||
const float LEFT = param.game.play_area.rect.x;
|
const float LEFT = param.game.play_area.rect.x;
|
||||||
const float CENTER = param.game.play_area.center_x - (Balloon::WIDTH.at(4) / 2);
|
const float CENTER = param.game.play_area.center_x - (Balloon::WIDTH.at(4) / 2);
|
||||||
const float RIGHT = param.game.play_area.rect.w - Balloon::WIDTH.at(4);
|
const float RIGHT = param.game.play_area.rect.w - Balloon::WIDTH.at(4);
|
||||||
|
|
||||||
const int LUCK = rand() % VALUES;
|
|
||||||
const std::array<float, VALUES> POS_X = {LEFT, LEFT, CENTER, CENTER, RIGHT, RIGHT};
|
const std::array<float, VALUES> POS_X = {LEFT, LEFT, CENTER, CENTER, RIGHT, RIGHT};
|
||||||
const std::array<float, VALUES> VEL_X = {Balloon::VELX_POSITIVE, Balloon::VELX_POSITIVE, Balloon::VELX_POSITIVE, Balloon::VELX_NEGATIVE, Balloon::VELX_NEGATIVE, Balloon::VELX_NEGATIVE};
|
const std::array<float, VALUES> VEL_X = {Balloon::VELX_POSITIVE, Balloon::VELX_POSITIVE, Balloon::VELX_POSITIVE, Balloon::VELX_NEGATIVE, Balloon::VELX_NEGATIVE, Balloon::VELX_NEGATIVE};
|
||||||
|
|
||||||
balloons_.emplace_back(std::make_unique<Balloon>(POS_X[LUCK], POS_Y, Balloon::Type::POWERBALL, Balloon::Size::EXTRALARGE, VEL_X[LUCK], balloon_speed_, CREATION_TIME, play_area_, balloon_textures_[4], balloon_animations_[4]));
|
Balloon::Config config = {
|
||||||
|
.x = POS_X.at(LUCK),
|
||||||
|
.y = -Balloon::WIDTH.at(4),
|
||||||
|
.type = Balloon::Type::POWERBALL,
|
||||||
|
.size = Balloon::Size::EXTRALARGE,
|
||||||
|
.vel_x = VEL_X.at(LUCK),
|
||||||
|
.speed = balloon_speed_,
|
||||||
|
.creation_counter = 0,
|
||||||
|
.play_area = play_area_,
|
||||||
|
.texture = balloon_textures_.at(4),
|
||||||
|
.animation = balloon_animations_.at(4),
|
||||||
|
.sound = {
|
||||||
|
.enabled = sound_enabled_,
|
||||||
|
.bouncing_enabled = bouncing_sound_enabled_,
|
||||||
|
.poping_enabled = poping_sound_enabled_}};
|
||||||
|
|
||||||
|
balloons_.emplace_back(std::make_unique<Balloon>(config));
|
||||||
balloons_.back()->setInvulnerable(true);
|
balloons_.back()->setInvulnerable(true);
|
||||||
balloons_.back()->setSound(sound_enabled_);
|
|
||||||
balloons_.back()->setBouncingSound(bouncing_sound_enabled_);
|
|
||||||
balloons_.back()->setPoppingSound(poping_sound_enabled_);
|
|
||||||
|
|
||||||
power_ball_enabled_ = true;
|
power_ball_enabled_ = true;
|
||||||
power_ball_counter_ = Balloon::POWERBALL_COUNTER;
|
power_ball_counter_ = Balloon::POWERBALL_COUNTER;
|
||||||
@@ -335,19 +380,6 @@ void BalloonManager::createTwoBigBalloons() {
|
|||||||
deployFormation(1);
|
deployFormation(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea una disposición de globos aleatoria
|
|
||||||
void BalloonManager::createRandomBalloons() {
|
|
||||||
const int NUM_BALLOONS = 2 + (rand() % 4);
|
|
||||||
for (int i = 0; i < NUM_BALLOONS; ++i) {
|
|
||||||
const float X = param.game.game_area.rect.x + (rand() % static_cast<int>(param.game.game_area.rect.w)) - Balloon::WIDTH.at(3);
|
|
||||||
const int Y = param.game.game_area.rect.y + (rand() % 50);
|
|
||||||
const auto SIZE = static_cast<Balloon::Size>(rand() % 4);
|
|
||||||
const float VEL_X = (rand() % 2 == 0) ? Balloon::VELX_POSITIVE : Balloon::VELX_NEGATIVE;
|
|
||||||
const int CREATION_COUNTER = 0;
|
|
||||||
createBalloon(X, Y, Balloon::Type::BALLOON, SIZE, VEL_X, balloon_speed_, CREATION_COUNTER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtiene el nivel de ameza actual generado por los globos
|
// Obtiene el nivel de ameza actual generado por los globos
|
||||||
auto BalloonManager::getMenace() -> int {
|
auto BalloonManager::getMenace() -> int {
|
||||||
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon) { return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
|
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon) { return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
|
||||||
|
|||||||
@@ -37,14 +37,13 @@ class BalloonManager {
|
|||||||
// --- Creación de formaciones enemigas ---
|
// --- Creación de formaciones enemigas ---
|
||||||
void deployRandomFormation(int stage); // Crea una formación de globos aleatoria
|
void deployRandomFormation(int stage); // Crea una formación de globos aleatoria
|
||||||
void deployFormation(int formation_id); // Crea una formación específica
|
void deployFormation(int formation_id); // Crea una formación específica
|
||||||
void deployFormation(int formation_id, int y); // Crea una formación específica con coordenadas
|
void deployFormation(int formation_id, float y); // Crea una formación específica con coordenadas
|
||||||
|
|
||||||
// --- Creación de globos ---
|
// --- Creación de globos ---
|
||||||
auto createBalloon(float x, int y, Balloon::Type type, Balloon::Size size, float velx, float speed, int creation_timer) -> std::shared_ptr<Balloon>; // Crea un nuevo globo
|
auto createBalloon(Balloon::Config config) -> std::shared_ptr<Balloon>; // Crea un nuevo globo
|
||||||
void createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction); // Crea un globo a partir de otro
|
void createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction); // Crea un globo a partir de otro
|
||||||
void createPowerBall(); // Crea una PowerBall
|
void createPowerBall(); // Crea una PowerBall
|
||||||
void createTwoBigBalloons(); // Crea dos globos grandes
|
void createTwoBigBalloons(); // Crea dos globos grandes
|
||||||
void createRandomBalloons(); // Crea una disposición aleatoria de globos
|
|
||||||
|
|
||||||
// --- Control de velocidad y despliegue ---
|
// --- Control de velocidad y despliegue ---
|
||||||
void setBalloonSpeed(float speed); // Ajusta la velocidad de los globos
|
void setBalloonSpeed(float speed); // Ajusta la velocidad de los globos
|
||||||
|
|||||||
110
source/color.cpp
110
source/color.cpp
@@ -116,71 +116,71 @@ constexpr auto Color::hsvToRgb(HSV hsv) -> Color {
|
|||||||
|
|
||||||
// Implementaciones del namespace Colors
|
// Implementaciones del namespace Colors
|
||||||
namespace Colors {
|
namespace Colors {
|
||||||
// Obtiene un color del vector de colores imitando al Coche Fantástico
|
// Obtiene un color del vector de colores imitando al Coche Fantástico
|
||||||
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color {
|
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color {
|
||||||
int cycle_length = (colors.size() * 2) - 2;
|
int cycle_length = (colors.size() * 2) - 2;
|
||||||
size_t n = counter % cycle_length;
|
size_t n = counter % cycle_length;
|
||||||
|
|
||||||
size_t index;
|
size_t index;
|
||||||
if (n < colors.size()) {
|
if (n < colors.size()) {
|
||||||
index = n; // Avanza: 0,1,2,3
|
index = n; // Avanza: 0,1,2,3
|
||||||
} else {
|
} else {
|
||||||
index = 2 * (colors.size() - 1) - n; // Retrocede: 2,1
|
index = 2 * (colors.size() - 1) - n; // Retrocede: 2,1
|
||||||
}
|
|
||||||
|
|
||||||
return colors[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle {
|
return colors[index];
|
||||||
Cycle result{};
|
}
|
||||||
HSV base_hsv = Color::rgbToHsv(base);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < CYCLE_SIZE; ++i) {
|
auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle {
|
||||||
float t = static_cast<float>(i) / (CYCLE_SIZE - 1); // 0 → 1
|
Cycle result{};
|
||||||
float hue_shift = 0.0F;
|
HSV base_hsv = Color::rgbToHsv(base);
|
||||||
float sat_shift = 0.0F;
|
|
||||||
float val_shift = 0.0F;
|
|
||||||
|
|
||||||
switch (style) {
|
for (size_t i = 0; i < CYCLE_SIZE; ++i) {
|
||||||
case ColorCycleStyle::SUBTLE_PULSE:
|
float t = static_cast<float>(i) / (CYCLE_SIZE - 1); // 0 → 1
|
||||||
// Solo brillo suave
|
float hue_shift = 0.0F;
|
||||||
val_shift = 0.07F * sinf(t * M_PI);
|
float sat_shift = 0.0F;
|
||||||
break;
|
float val_shift = 0.0F;
|
||||||
|
|
||||||
case ColorCycleStyle::HUE_WAVE:
|
switch (style) {
|
||||||
// Oscilación leve de tono
|
case ColorCycleStyle::SUBTLE_PULSE:
|
||||||
hue_shift = 15.0F * (t - 0.5F) * 2.0F;
|
// Solo brillo suave
|
||||||
val_shift = 0.05F * sinf(t * M_PI);
|
val_shift = 0.07F * sinf(t * M_PI);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ColorCycleStyle::VIBRANT:
|
case ColorCycleStyle::HUE_WAVE:
|
||||||
// Cambios fuertes en tono y brillo
|
// Oscilación leve de tono
|
||||||
hue_shift = 35.0F * sinf(t * M_PI);
|
hue_shift = 15.0F * (t - 0.5F) * 2.0F;
|
||||||
val_shift = 0.2F * sinf(t * M_PI);
|
val_shift = 0.05F * sinf(t * M_PI);
|
||||||
sat_shift = -0.2F * sinf(t * M_PI);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case ColorCycleStyle::DARKEN_GLOW:
|
case ColorCycleStyle::VIBRANT:
|
||||||
// Se oscurece al centro
|
// Cambios fuertes en tono y brillo
|
||||||
val_shift = -0.15F * sinf(t * M_PI);
|
hue_shift = 35.0F * sinf(t * M_PI);
|
||||||
break;
|
val_shift = 0.2F * sinf(t * M_PI);
|
||||||
|
sat_shift = -0.2F * sinf(t * M_PI);
|
||||||
|
break;
|
||||||
|
|
||||||
case ColorCycleStyle::LIGHT_FLASH:
|
case ColorCycleStyle::DARKEN_GLOW:
|
||||||
// Se ilumina al centro
|
// Se oscurece al centro
|
||||||
val_shift = 0.25F * sinf(t * M_PI);
|
val_shift = -0.15F * sinf(t * M_PI);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
HSV adjusted = {
|
case ColorCycleStyle::LIGHT_FLASH:
|
||||||
.h = fmodf(base_hsv.h + hue_shift + 360.0F, 360.0F),
|
// Se ilumina al centro
|
||||||
.s = fminf(1.0F, fmaxf(0.0F, base_hsv.s + sat_shift)),
|
val_shift = 0.25F * sinf(t * M_PI);
|
||||||
.v = fminf(1.0F, fmaxf(0.0F, base_hsv.v + val_shift))};
|
break;
|
||||||
|
|
||||||
Color c = Color::hsvToRgb(adjusted);
|
|
||||||
result[i] = c;
|
|
||||||
result[(2 * CYCLE_SIZE) - 1 - i] = c; // espejo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
HSV adjusted = {
|
||||||
|
.h = fmodf(base_hsv.h + hue_shift + 360.0F, 360.0F),
|
||||||
|
.s = fminf(1.0F, fmaxf(0.0F, base_hsv.s + sat_shift)),
|
||||||
|
.v = fminf(1.0F, fmaxf(0.0F, base_hsv.v + val_shift))};
|
||||||
|
|
||||||
|
Color c = Color::hsvToRgb(adjusted);
|
||||||
|
result[i] = c;
|
||||||
|
result[(2 * CYCLE_SIZE) - 1 - i] = c; // espejo
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace Colors
|
||||||
@@ -36,10 +36,17 @@ struct Color {
|
|||||||
|
|
||||||
Uint8 r, g, b, a;
|
Uint8 r, g, b, a;
|
||||||
|
|
||||||
constexpr Color() : r(MIN_COLOR_VALUE), g(MIN_COLOR_VALUE), b(MIN_COLOR_VALUE), a(DEFAULT_ALPHA) {}
|
constexpr Color()
|
||||||
|
: r(MIN_COLOR_VALUE),
|
||||||
|
g(MIN_COLOR_VALUE),
|
||||||
|
b(MIN_COLOR_VALUE),
|
||||||
|
a(DEFAULT_ALPHA) {}
|
||||||
|
|
||||||
explicit constexpr Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = DEFAULT_ALPHA)
|
explicit constexpr Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = DEFAULT_ALPHA)
|
||||||
: r(red), g(green), b(blue), a(alpha) {}
|
: r(red),
|
||||||
|
g(green),
|
||||||
|
b(blue),
|
||||||
|
a(alpha) {}
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto INVERSE() const -> Color {
|
[[nodiscard]] constexpr auto INVERSE() const -> Color {
|
||||||
return Color(MAX_COLOR_VALUE - r, MAX_COLOR_VALUE - g, MAX_COLOR_VALUE - b, a);
|
return Color(MAX_COLOR_VALUE - r, MAX_COLOR_VALUE - g, MAX_COLOR_VALUE - b, a);
|
||||||
@@ -108,25 +115,25 @@ enum class ColorCycleStyle {
|
|||||||
|
|
||||||
// --- Namespace Colors: constantes y utilidades de color ---
|
// --- Namespace Colors: constantes y utilidades de color ---
|
||||||
namespace Colors {
|
namespace Colors {
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
constexpr size_t CYCLE_SIZE = 6; // Mitad del ciclo espejado
|
constexpr size_t CYCLE_SIZE = 6; // Mitad del ciclo espejado
|
||||||
|
|
||||||
// --- Alias ---
|
// --- Alias ---
|
||||||
using Cycle = std::array<Color, 2 * CYCLE_SIZE>;
|
using Cycle = std::array<Color, 2 * CYCLE_SIZE>;
|
||||||
|
|
||||||
// --- Colores predefinidos ---
|
// --- Colores predefinidos ---
|
||||||
constexpr Color NO_COLOR_MOD = Color(0XFF, 0XFF, 0XFF);
|
constexpr Color NO_COLOR_MOD = Color(0XFF, 0XFF, 0XFF);
|
||||||
constexpr Color SHADOW_TEXT = Color(0X43, 0X43, 0X4F);
|
constexpr Color SHADOW_TEXT = Color(0X43, 0X43, 0X4F);
|
||||||
constexpr Color TITLE_SHADOW_TEXT = Color(0x14, 0x87, 0xc4);
|
constexpr Color TITLE_SHADOW_TEXT = Color(0x14, 0x87, 0xc4);
|
||||||
constexpr Color ORANGE_TEXT = Color(0XFF, 0X7A, 0X00);
|
constexpr Color ORANGE_TEXT = Color(0XFF, 0X7A, 0X00);
|
||||||
|
|
||||||
constexpr Color FLASH = Color(0XFF, 0XFF, 0XFF);
|
constexpr Color FLASH = Color(0XFF, 0XFF, 0XFF);
|
||||||
|
|
||||||
constexpr Color BLUE_SKY = Color(0X02, 0X88, 0XD1);
|
constexpr Color BLUE_SKY = Color(0X02, 0X88, 0XD1);
|
||||||
constexpr Color PINK_SKY = Color(0XFF, 0X6B, 0X97);
|
constexpr Color PINK_SKY = Color(0XFF, 0X6B, 0X97);
|
||||||
constexpr Color GREEN_SKY = Color(0X00, 0X79, 0X6B);
|
constexpr Color GREEN_SKY = Color(0X00, 0X79, 0X6B);
|
||||||
|
|
||||||
// --- Funciones ---
|
// --- Funciones ---
|
||||||
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color;
|
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color;
|
||||||
auto generateMirroredCycle(Color base, ColorCycleStyle style = ColorCycleStyle::SUBTLE_PULSE) -> Cycle;
|
auto generateMirroredCycle(Color base, ColorCycleStyle style = ColorCycleStyle::SUBTLE_PULSE) -> Cycle;
|
||||||
}
|
} // namespace Colors
|
||||||
@@ -76,7 +76,8 @@ struct BalloonSettings {
|
|||||||
float vel;
|
float vel;
|
||||||
float grav;
|
float grav;
|
||||||
constexpr BalloonSettings(float v, float g)
|
constexpr BalloonSettings(float v, float g)
|
||||||
: vel(v), grav(g) {}
|
: vel(v),
|
||||||
|
grav(g) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::array<BalloonSettings, 4> SETTINGS = {{
|
constexpr std::array<BalloonSettings, 4> SETTINGS = {{
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ class DefineButtons {
|
|||||||
int button;
|
int button;
|
||||||
|
|
||||||
Button(std::string label, Input::Action action, int button)
|
Button(std::string label, Input::Action action, int button)
|
||||||
: label(std::move(label)), action(action), button(button) {}
|
: label(std::move(label)),
|
||||||
|
action(action),
|
||||||
|
button(button) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
|
|||||||
@@ -18,9 +18,9 @@
|
|||||||
#include "manage_hiscore_table.h" // Para ManageHiScoreTable
|
#include "manage_hiscore_table.h" // Para ManageHiScoreTable
|
||||||
#include "options.h" // Para loadFromFile, saveToFile, Settings, settings, setConfigFile, setControllersFile
|
#include "options.h" // Para loadFromFile, saveToFile, Settings, settings, setConfigFile, setControllersFile
|
||||||
#include "param.h" // Para loadParamsFromFile
|
#include "param.h" // Para loadParamsFromFile
|
||||||
#include "resource_helper.h" // Para ResourceHelper
|
|
||||||
#include "player.h" // Para Player
|
#include "player.h" // Para Player
|
||||||
#include "resource.h" // Para Resource
|
#include "resource.h" // Para Resource
|
||||||
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode
|
#include "section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode
|
||||||
#include "sections/credits.h" // Para Credits
|
#include "sections/credits.h" // Para Credits
|
||||||
@@ -77,8 +77,8 @@ Director::~Director() {
|
|||||||
// Inicializa todo
|
// Inicializa todo
|
||||||
void Director::init() {
|
void Director::init() {
|
||||||
// Configuración inicial de parametros
|
// Configuración inicial de parametros
|
||||||
Asset::init(executable_path_); // Inicializa el sistema de gestión de archivos
|
Asset::init(executable_path_); // Inicializa el sistema de gestión de archivos
|
||||||
|
|
||||||
#ifdef MACOS_BUNDLE
|
#ifdef MACOS_BUNDLE
|
||||||
ResourceHelper::initializeResourceSystem(executable_path_ + "/../Resources/resources.pack");
|
ResourceHelper::initializeResourceSystem(executable_path_ + "/../Resources/resources.pack");
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ void EnterName::incPosition() {
|
|||||||
} else if (position_ > 0) // No es necesario verificar position_ < MAX_NAME_LENGTH
|
} else if (position_ > 0) // No es necesario verificar position_ < MAX_NAME_LENGTH
|
||||||
{
|
{
|
||||||
// Copiamos el índice del carácter anterior si es posible.
|
// Copiamos el índice del carácter anterior si es posible.
|
||||||
//character_index_[position_] = character_index_[position_ - 1];
|
// character_index_[position_] = character_index_[position_ - 1];
|
||||||
|
|
||||||
// Ponemos el caracter "espacio"
|
// Ponemos el caracter "espacio"
|
||||||
character_index_[position_] = 0;
|
character_index_[position_] = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -147,12 +147,19 @@ auto EnterName::findIndex(char character) const -> int {
|
|||||||
// Devuelve un nombre al azar
|
// Devuelve un nombre al azar
|
||||||
auto EnterName::getRandomName() -> std::string {
|
auto EnterName::getRandomName() -> std::string {
|
||||||
static constexpr std::array<std::string_view, 8> NAMES = {
|
static constexpr std::array<std::string_view, 8> NAMES = {
|
||||||
"BAL1", "TABE", "DOC", "MON", "SAM1", "JORDI", "JDES", "PEPE"};
|
"BAL1",
|
||||||
|
"TABE",
|
||||||
|
"DOC",
|
||||||
|
"MON",
|
||||||
|
"SAM1",
|
||||||
|
"JORDI",
|
||||||
|
"JDES",
|
||||||
|
"PEPE"};
|
||||||
return std::string(NAMES[rand() % NAMES.size()]);
|
return std::string(NAMES[rand() % NAMES.size()]);
|
||||||
}
|
}
|
||||||
// Obtiene el nombre final introducido
|
// Obtiene el nombre final introducido
|
||||||
auto EnterName::getFinalName() -> std::string {
|
auto EnterName::getFinalName() -> std::string {
|
||||||
auto name = trim(name_.substr(0, position_ + 1)); // Devuelve el texto intruducido incluyendo el del selector
|
auto name = trim(name_.substr(0, position_ + 1)); // Devuelve el texto intruducido incluyendo el del selector
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
name = getRandomName();
|
name = getRandomName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ struct ExplosionTexture {
|
|||||||
std::vector<std::string> animation; // Animación para la textura
|
std::vector<std::string> animation; // Animación para la textura
|
||||||
|
|
||||||
ExplosionTexture(int sz, std::shared_ptr<Texture> tex, const std::vector<std::string> &anim)
|
ExplosionTexture(int sz, std::shared_ptr<Texture> tex, const std::vector<std::string> &anim)
|
||||||
: size(sz), texture(std::move(tex)), animation(anim) {}
|
: size(sz),
|
||||||
|
texture(std::move(tex)),
|
||||||
|
animation(anim) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Clase Explosions: gestor de explosiones ---
|
// --- Clase Explosions: gestor de explosiones ---
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void Fade::init() {
|
|||||||
num_squares_width_ = param.fade.num_squares_width;
|
num_squares_width_ = param.fade.num_squares_width;
|
||||||
num_squares_height_ = param.fade.num_squares_height;
|
num_squares_height_ = param.fade.num_squares_height;
|
||||||
random_squares_duration_ = param.fade.random_squares_duration_ms; // Usar como duración en ms
|
random_squares_duration_ = param.fade.random_squares_duration_ms; // Usar como duración en ms
|
||||||
square_transition_duration_ = random_squares_duration_ / 4; // 25% del tiempo total para la transición individual
|
square_transition_duration_ = random_squares_duration_ / 4; // 25% del tiempo total para la transición individual
|
||||||
random_squares_start_time_ = 0;
|
random_squares_start_time_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ void Fade::render() {
|
|||||||
if (state_ == State::FINISHED && mode_ == Mode::IN) {
|
if (state_ == State::FINISHED && mode_ == Mode::IN) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RenderTexture(renderer_, backbuffer_, nullptr, nullptr);
|
SDL_RenderTexture(renderer_, backbuffer_, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ void Fade::update() {
|
|||||||
void Fade::updatePreState() {
|
void Fade::updatePreState() {
|
||||||
// Sistema basado en tiempo únicamente
|
// Sistema basado en tiempo únicamente
|
||||||
Uint32 elapsed_time = SDL_GetTicks() - pre_start_time_;
|
Uint32 elapsed_time = SDL_GetTicks() - pre_start_time_;
|
||||||
|
|
||||||
if (elapsed_time >= static_cast<Uint32>(pre_duration_)) {
|
if (elapsed_time >= static_cast<Uint32>(pre_duration_)) {
|
||||||
state_ = State::FADING;
|
state_ = State::FADING;
|
||||||
// CRÍTICO: Reinicializar tiempo de inicio para tipos que usan random_squares_start_time_
|
// CRÍTICO: Reinicializar tiempo de inicio para tipos que usan random_squares_start_time_
|
||||||
@@ -129,17 +129,17 @@ void Fade::changeToPostState() {
|
|||||||
void Fade::updatePostState() {
|
void Fade::updatePostState() {
|
||||||
// Sistema basado en tiempo únicamente
|
// Sistema basado en tiempo únicamente
|
||||||
Uint32 elapsed_time = SDL_GetTicks() - post_start_time_;
|
Uint32 elapsed_time = SDL_GetTicks() - post_start_time_;
|
||||||
|
|
||||||
if (elapsed_time >= static_cast<Uint32>(post_duration_)) {
|
if (elapsed_time >= static_cast<Uint32>(post_duration_)) {
|
||||||
state_ = State::FINISHED;
|
state_ = State::FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mantener el alpha final correcto para cada tipo de fade
|
// Mantener el alpha final correcto para cada tipo de fade
|
||||||
Uint8 post_alpha = a_;
|
Uint8 post_alpha = a_;
|
||||||
if (type_ == Type::RANDOM_SQUARE2 || type_ == Type::DIAGONAL) {
|
if (type_ == Type::RANDOM_SQUARE2 || type_ == Type::DIAGONAL) {
|
||||||
post_alpha = (mode_ == Mode::OUT) ? 255 : 0;
|
post_alpha = (mode_ == Mode::OUT) ? 255 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanBackbuffer(r_, g_, b_, post_alpha);
|
cleanBackbuffer(r_, g_, b_, post_alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,16 +204,16 @@ void Fade::updateRandomSquareFade() {
|
|||||||
|
|
||||||
void Fade::updateRandomSquare2Fade() {
|
void Fade::updateRandomSquare2Fade() {
|
||||||
Uint32 elapsed_time = SDL_GetTicks() - random_squares_start_time_;
|
Uint32 elapsed_time = SDL_GetTicks() - random_squares_start_time_;
|
||||||
|
|
||||||
int total_squares = num_squares_width_ * num_squares_height_;
|
int total_squares = num_squares_width_ * num_squares_height_;
|
||||||
|
|
||||||
// Calcula el tiempo de activación: total - tiempo que necesitan los últimos cuadrados
|
// Calcula el tiempo de activación: total - tiempo que necesitan los últimos cuadrados
|
||||||
int activation_time = random_squares_duration_ - square_transition_duration_;
|
int activation_time = random_squares_duration_ - square_transition_duration_;
|
||||||
activation_time = std::max(activation_time, square_transition_duration_); // Mínimo igual a la duración de transición
|
activation_time = std::max(activation_time, square_transition_duration_); // Mínimo igual a la duración de transición
|
||||||
|
|
||||||
// Lógica diferente según el modo
|
// Lógica diferente según el modo
|
||||||
int squares_to_activate = 0;
|
int squares_to_activate = 0;
|
||||||
|
|
||||||
if (mode_ == Mode::OUT) {
|
if (mode_ == Mode::OUT) {
|
||||||
// OUT: Activa cuadrados gradualmente
|
// OUT: Activa cuadrados gradualmente
|
||||||
if (elapsed_time < static_cast<Uint32>(activation_time)) {
|
if (elapsed_time < static_cast<Uint32>(activation_time)) {
|
||||||
@@ -222,7 +222,7 @@ void Fade::updateRandomSquare2Fade() {
|
|||||||
} else {
|
} else {
|
||||||
squares_to_activate = total_squares; // Activar todos
|
squares_to_activate = total_squares; // Activar todos
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activa nuevos cuadrados y guarda su tiempo de activación
|
// Activa nuevos cuadrados y guarda su tiempo de activación
|
||||||
for (int i = 0; i < squares_to_activate && i < total_squares; ++i) {
|
for (int i = 0; i < squares_to_activate && i < total_squares; ++i) {
|
||||||
if (square_age_[i] == -1) {
|
if (square_age_[i] == -1) {
|
||||||
@@ -232,22 +232,22 @@ void Fade::updateRandomSquare2Fade() {
|
|||||||
} else {
|
} else {
|
||||||
// IN: Todos los cuadrados empiezan activos desde el inicio
|
// IN: Todos los cuadrados empiezan activos desde el inicio
|
||||||
squares_to_activate = total_squares;
|
squares_to_activate = total_squares;
|
||||||
|
|
||||||
// Activa cuadrados gradualmente con tiempo de inicio escalonado
|
// Activa cuadrados gradualmente con tiempo de inicio escalonado
|
||||||
float activation_progress = static_cast<float>(elapsed_time) / activation_time;
|
float activation_progress = static_cast<float>(elapsed_time) / activation_time;
|
||||||
int squares_starting_transition = static_cast<int>(activation_progress * total_squares);
|
int squares_starting_transition = static_cast<int>(activation_progress * total_squares);
|
||||||
|
|
||||||
// Asegurar que al menos 1 cuadrado se active desde el primer frame
|
// Asegurar que al menos 1 cuadrado se active desde el primer frame
|
||||||
squares_starting_transition = std::max(squares_starting_transition, 1);
|
squares_starting_transition = std::max(squares_starting_transition, 1);
|
||||||
squares_starting_transition = std::min(squares_starting_transition, total_squares);
|
squares_starting_transition = std::min(squares_starting_transition, total_squares);
|
||||||
|
|
||||||
for (int i = 0; i < squares_starting_transition; ++i) {
|
for (int i = 0; i < squares_starting_transition; ++i) {
|
||||||
if (square_age_[i] == -1) {
|
if (square_age_[i] == -1) {
|
||||||
square_age_[i] = elapsed_time; // Empieza la transición a transparente
|
square_age_[i] = elapsed_time; // Empieza la transición a transparente
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawRandomSquares2();
|
drawRandomSquares2();
|
||||||
|
|
||||||
value_ = calculateValue(0, total_squares, squares_to_activate);
|
value_ = calculateValue(0, total_squares, squares_to_activate);
|
||||||
@@ -265,7 +265,7 @@ void Fade::updateRandomSquare2Fade() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all_completed) {
|
if (all_completed) {
|
||||||
// Pintar textura final: OUT opaca, IN transparente
|
// Pintar textura final: OUT opaca, IN transparente
|
||||||
Uint8 final_alpha = (mode_ == Mode::OUT) ? 255 : 0;
|
Uint8 final_alpha = (mode_ == Mode::OUT) ? 255 : 0;
|
||||||
@@ -277,17 +277,17 @@ void Fade::updateRandomSquare2Fade() {
|
|||||||
|
|
||||||
void Fade::updateDiagonalFade() {
|
void Fade::updateDiagonalFade() {
|
||||||
Uint32 elapsed_time = SDL_GetTicks() - random_squares_start_time_;
|
Uint32 elapsed_time = SDL_GetTicks() - random_squares_start_time_;
|
||||||
|
|
||||||
int total_squares = num_squares_width_ * num_squares_height_;
|
int total_squares = num_squares_width_ * num_squares_height_;
|
||||||
|
|
||||||
// Calcula el tiempo de activación: total - tiempo que necesitan los últimos cuadrados
|
// Calcula el tiempo de activación: total - tiempo que necesitan los últimos cuadrados
|
||||||
int activation_time = random_squares_duration_ - square_transition_duration_;
|
int activation_time = random_squares_duration_ - square_transition_duration_;
|
||||||
activation_time = std::max(activation_time, square_transition_duration_);
|
activation_time = std::max(activation_time, square_transition_duration_);
|
||||||
|
|
||||||
// Calcula cuántas diagonales deberían estar activas
|
// Calcula cuántas diagonales deberían estar activas
|
||||||
int max_diagonal = num_squares_width_ + num_squares_height_ - 1; // Número total de diagonales
|
int max_diagonal = num_squares_width_ + num_squares_height_ - 1; // Número total de diagonales
|
||||||
int active_diagonals = 0;
|
int active_diagonals = 0;
|
||||||
|
|
||||||
if (mode_ == Mode::OUT) {
|
if (mode_ == Mode::OUT) {
|
||||||
// OUT: Activa diagonales gradualmente desde esquina superior izquierda
|
// OUT: Activa diagonales gradualmente desde esquina superior izquierda
|
||||||
if (elapsed_time < static_cast<Uint32>(activation_time)) {
|
if (elapsed_time < static_cast<Uint32>(activation_time)) {
|
||||||
@@ -296,7 +296,7 @@ void Fade::updateDiagonalFade() {
|
|||||||
} else {
|
} else {
|
||||||
active_diagonals = max_diagonal; // Activar todas
|
active_diagonals = max_diagonal; // Activar todas
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activa cuadrados por diagonales
|
// Activa cuadrados por diagonales
|
||||||
for (int diagonal = 0; diagonal < active_diagonals; ++diagonal) {
|
for (int diagonal = 0; diagonal < active_diagonals; ++diagonal) {
|
||||||
activateDiagonal(diagonal, elapsed_time);
|
activateDiagonal(diagonal, elapsed_time);
|
||||||
@@ -304,12 +304,12 @@ void Fade::updateDiagonalFade() {
|
|||||||
} else {
|
} else {
|
||||||
// IN: Todas las diagonales empiezan activas, van desapareciendo
|
// IN: Todas las diagonales empiezan activas, van desapareciendo
|
||||||
active_diagonals = max_diagonal;
|
active_diagonals = max_diagonal;
|
||||||
|
|
||||||
// Activa diagonales gradualmente para transición
|
// Activa diagonales gradualmente para transición
|
||||||
if (elapsed_time < static_cast<Uint32>(activation_time)) {
|
if (elapsed_time < static_cast<Uint32>(activation_time)) {
|
||||||
float activation_progress = static_cast<float>(elapsed_time) / activation_time;
|
float activation_progress = static_cast<float>(elapsed_time) / activation_time;
|
||||||
int diagonals_starting_transition = static_cast<int>(activation_progress * max_diagonal);
|
int diagonals_starting_transition = static_cast<int>(activation_progress * max_diagonal);
|
||||||
|
|
||||||
for (int diagonal = 0; diagonal < diagonals_starting_transition; ++diagonal) {
|
for (int diagonal = 0; diagonal < diagonals_starting_transition; ++diagonal) {
|
||||||
activateDiagonal(diagonal, elapsed_time);
|
activateDiagonal(diagonal, elapsed_time);
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,7 @@ void Fade::updateDiagonalFade() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawDiagonal();
|
drawDiagonal();
|
||||||
|
|
||||||
value_ = calculateValue(0, total_squares, active_diagonals * (total_squares / max_diagonal));
|
value_ = calculateValue(0, total_squares, active_diagonals * (total_squares / max_diagonal));
|
||||||
@@ -338,7 +338,7 @@ void Fade::updateDiagonalFade() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all_completed) {
|
if (all_completed) {
|
||||||
// Pintar textura final: OUT opaca, IN transparente
|
// Pintar textura final: OUT opaca, IN transparente
|
||||||
Uint8 final_alpha = (mode_ == Mode::OUT) ? 255 : 0;
|
Uint8 final_alpha = (mode_ == Mode::OUT) ? 255 : 0;
|
||||||
@@ -354,15 +354,15 @@ void Fade::activateDiagonal(int diagonal_index, Uint32 current_time) {
|
|||||||
// Diagonal 1: (1,0), (0,1)
|
// Diagonal 1: (1,0), (0,1)
|
||||||
// Diagonal 2: (2,0), (1,1), (0,2)
|
// Diagonal 2: (2,0), (1,1), (0,2)
|
||||||
// etc.
|
// etc.
|
||||||
|
|
||||||
for (int x = 0; x < num_squares_width_; ++x) {
|
for (int x = 0; x < num_squares_width_; ++x) {
|
||||||
int y = diagonal_index - x;
|
int y = diagonal_index - x;
|
||||||
|
|
||||||
// Verificar que y está dentro de los límites
|
// Verificar que y está dentro de los límites
|
||||||
if (y >= 0 && y < num_squares_height_) {
|
if (y >= 0 && y < num_squares_height_) {
|
||||||
// Convertir coordenadas (x,y) a índice en el vector
|
// Convertir coordenadas (x,y) a índice en el vector
|
||||||
int index = y * num_squares_width_ + x;
|
int index = y * num_squares_width_ + x;
|
||||||
|
|
||||||
if (index >= 0 && index < static_cast<int>(square_age_.size())) {
|
if (index >= 0 && index < static_cast<int>(square_age_.size())) {
|
||||||
if (square_age_[index] == -1) {
|
if (square_age_[index] == -1) {
|
||||||
square_age_[index] = current_time; // Guarda el tiempo de activación
|
square_age_[index] = current_time; // Guarda el tiempo de activación
|
||||||
@@ -385,30 +385,30 @@ void Fade::drawDiagonal() {
|
|||||||
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); // Usar BLEND para alpha
|
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); // Usar BLEND para alpha
|
||||||
|
|
||||||
Uint32 current_time = SDL_GetTicks() - random_squares_start_time_;
|
Uint32 current_time = SDL_GetTicks() - random_squares_start_time_;
|
||||||
|
|
||||||
// Lógica unificada: sobre textura transparente, pintar cuadrados según su estado
|
// Lógica unificada: sobre textura transparente, pintar cuadrados según su estado
|
||||||
for (size_t i = 0; i < square_.size(); ++i) {
|
for (size_t i = 0; i < square_.size(); ++i) {
|
||||||
Uint8 current_alpha = 0;
|
Uint8 current_alpha = 0;
|
||||||
|
|
||||||
if (square_age_[i] == -1) {
|
if (square_age_[i] == -1) {
|
||||||
// Cuadrado no activado
|
// Cuadrado no activado
|
||||||
if (mode_ == Mode::OUT) {
|
if (mode_ == Mode::OUT) {
|
||||||
current_alpha = 0; // OUT: transparente si no activado
|
current_alpha = 0; // OUT: transparente si no activado
|
||||||
} else {
|
} else {
|
||||||
current_alpha = a_; // IN: opaco si no activado
|
current_alpha = a_; // IN: opaco si no activado
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Cuadrado activado - calculamos progreso
|
// Cuadrado activado - calculamos progreso
|
||||||
Uint32 square_elapsed = current_time - square_age_[i];
|
Uint32 square_elapsed = current_time - square_age_[i];
|
||||||
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f);
|
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f);
|
||||||
|
|
||||||
if (mode_ == Mode::OUT) {
|
if (mode_ == Mode::OUT) {
|
||||||
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
|
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
|
||||||
} else {
|
} else {
|
||||||
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0
|
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_alpha > 0) {
|
if (current_alpha > 0) {
|
||||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, current_alpha);
|
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, current_alpha);
|
||||||
SDL_RenderFillRect(renderer_, &square_[i]);
|
SDL_RenderFillRect(renderer_, &square_[i]);
|
||||||
@@ -450,30 +450,30 @@ void Fade::drawRandomSquares2() {
|
|||||||
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); // Usar BLEND para alpha
|
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); // Usar BLEND para alpha
|
||||||
|
|
||||||
Uint32 current_time = SDL_GetTicks() - random_squares_start_time_;
|
Uint32 current_time = SDL_GetTicks() - random_squares_start_time_;
|
||||||
|
|
||||||
// Lógica unificada: sobre textura transparente, pintar cuadrados según su estado
|
// Lógica unificada: sobre textura transparente, pintar cuadrados según su estado
|
||||||
for (size_t i = 0; i < square_.size(); ++i) {
|
for (size_t i = 0; i < square_.size(); ++i) {
|
||||||
Uint8 current_alpha = 0;
|
Uint8 current_alpha = 0;
|
||||||
|
|
||||||
if (square_age_[i] == -1) {
|
if (square_age_[i] == -1) {
|
||||||
// Cuadrado no activado
|
// Cuadrado no activado
|
||||||
if (mode_ == Mode::OUT) {
|
if (mode_ == Mode::OUT) {
|
||||||
current_alpha = 0; // OUT: transparente si no activado
|
current_alpha = 0; // OUT: transparente si no activado
|
||||||
} else {
|
} else {
|
||||||
current_alpha = a_; // IN: opaco si no activado
|
current_alpha = a_; // IN: opaco si no activado
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Cuadrado activado - calculamos progreso
|
// Cuadrado activado - calculamos progreso
|
||||||
Uint32 square_elapsed = current_time - square_age_[i];
|
Uint32 square_elapsed = current_time - square_age_[i];
|
||||||
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f);
|
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f);
|
||||||
|
|
||||||
if (mode_ == Mode::OUT) {
|
if (mode_ == Mode::OUT) {
|
||||||
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
|
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
|
||||||
} else {
|
} else {
|
||||||
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0
|
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_alpha > 0) {
|
if (current_alpha > 0) {
|
||||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, current_alpha);
|
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, current_alpha);
|
||||||
SDL_RenderFillRect(renderer_, &square_[i]);
|
SDL_RenderFillRect(renderer_, &square_[i]);
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ class Fade {
|
|||||||
public:
|
public:
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class Type : Uint8 {
|
enum class Type : Uint8 {
|
||||||
FULLSCREEN = 0, // Fundido de pantalla completa
|
FULLSCREEN = 0, // Fundido de pantalla completa
|
||||||
CENTER = 1, // Fundido desde el centro
|
CENTER = 1, // Fundido desde el centro
|
||||||
RANDOM_SQUARE = 2, // Fundido con cuadrados aleatorios
|
RANDOM_SQUARE = 2, // Fundido con cuadrados aleatorios
|
||||||
RANDOM_SQUARE2 = 3, // Fundido con cuadrados aleatorios (variante 2)
|
RANDOM_SQUARE2 = 3, // Fundido con cuadrados aleatorios (variante 2)
|
||||||
DIAGONAL = 4, // Fundido diagonal desde esquina superior izquierda
|
DIAGONAL = 4, // Fundido diagonal desde esquina superior izquierda
|
||||||
VENETIAN = 5, // Fundido tipo persiana veneciana
|
VENETIAN = 5, // Fundido tipo persiana veneciana
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Mode : Uint8 {
|
enum class Mode : Uint8 {
|
||||||
@@ -104,10 +104,10 @@ class Fade {
|
|||||||
void calculateVenetianProgress(); // Calcula el progreso del efecto veneciano
|
void calculateVenetianProgress(); // Calcula el progreso del efecto veneciano
|
||||||
|
|
||||||
// --- Dibujo de efectos visuales ---
|
// --- Dibujo de efectos visuales ---
|
||||||
void drawCenterFadeRectangles(); // Dibuja los rectángulos del fundido central
|
void drawCenterFadeRectangles(); // Dibuja los rectángulos del fundido central
|
||||||
void drawRandomSquares(int active_count = -1); // Dibuja los cuadrados aleatorios del fundido
|
void drawRandomSquares(int active_count = -1); // Dibuja los cuadrados aleatorios del fundido
|
||||||
void drawRandomSquares2(); // Dibuja los cuadrados con transición de color (RANDOM_SQUARE2)
|
void drawRandomSquares2(); // Dibuja los cuadrados con transición de color (RANDOM_SQUARE2)
|
||||||
void drawDiagonal(); // Dibuja los cuadrados con patrón diagonal
|
void drawDiagonal(); // Dibuja los cuadrados con patrón diagonal
|
||||||
void activateDiagonal(int diagonal_index, Uint32 current_time); // Activa una diagonal específica
|
void activateDiagonal(int diagonal_index, Uint32 current_time); // Activa una diagonal específica
|
||||||
void drawVenetianBlinds(); // Dibuja las persianas venecianas del fundido
|
void drawVenetianBlinds(); // Dibuja las persianas venecianas del fundido
|
||||||
};
|
};
|
||||||
@@ -43,7 +43,12 @@ class GameLogo {
|
|||||||
|
|
||||||
Shake() = default;
|
Shake() = default;
|
||||||
Shake(int d, int de, int l, int o)
|
Shake(int d, int de, int l, int o)
|
||||||
: desp(d), delay(de), length(l), remaining(l), counter(de), origin(o) {}
|
: desp(d),
|
||||||
|
delay(de),
|
||||||
|
length(l),
|
||||||
|
remaining(l),
|
||||||
|
counter(de),
|
||||||
|
origin(o) {}
|
||||||
|
|
||||||
void init(int d, int de, int l, int o) {
|
void init(int d, int de, int l, int o) {
|
||||||
desp = d;
|
desp = d;
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ class Input {
|
|||||||
bool just_pressed; // Se acaba de pulsar en este fotograma
|
bool just_pressed; // Se acaba de pulsar en este fotograma
|
||||||
|
|
||||||
KeyState(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false)
|
KeyState(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false)
|
||||||
: scancode(scancode), is_held(is_held), just_pressed(just_pressed) {}
|
: scancode(scancode),
|
||||||
|
is_held(is_held),
|
||||||
|
just_pressed(just_pressed) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ButtonState {
|
struct ButtonState {
|
||||||
@@ -43,7 +45,10 @@ class Input {
|
|||||||
bool trigger_active{false}; // Estado del trigger como botón digital
|
bool trigger_active{false}; // Estado del trigger como botón digital
|
||||||
|
|
||||||
ButtonState(int btn = static_cast<int>(SDL_GAMEPAD_BUTTON_INVALID), bool is_held = false, bool just_pressed = false, bool axis_act = false)
|
ButtonState(int btn = static_cast<int>(SDL_GAMEPAD_BUTTON_INVALID), bool is_held = false, bool just_pressed = false, bool axis_act = false)
|
||||||
: button(btn), is_held(is_held), just_pressed(just_pressed), axis_active(axis_act) {}
|
: button(btn),
|
||||||
|
is_held(is_held),
|
||||||
|
just_pressed(just_pressed),
|
||||||
|
axis_active(axis_act) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Keyboard {
|
struct Keyboard {
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
class Texture; // lines 6-6
|
class Texture; // lines 6-6
|
||||||
|
|
||||||
Item::Item(ItemType type, float x, float y, SDL_FRect &play_area, const std::shared_ptr<Texture> &texture, const std::vector<std::string> &animation)
|
Item::Item(ItemType type, float x, float y, SDL_FRect &play_area, const std::shared_ptr<Texture> &texture, const std::vector<std::string> &animation)
|
||||||
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)), play_area_(play_area), type_(type) {
|
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
|
||||||
|
play_area_(play_area),
|
||||||
|
type_(type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ItemType::COFFEE_MACHINE: {
|
case ItemType::COFFEE_MACHINE: {
|
||||||
width_ = COFFEE_MACHINE_WIDTH;
|
width_ = COFFEE_MACHINE_WIDTH;
|
||||||
@@ -90,7 +92,7 @@ void Item::move() {
|
|||||||
|
|
||||||
// Si toca el borde lateral
|
// Si toca el borde lateral
|
||||||
if (pos_x_ == MIN_X || pos_x_ == MAX_X) {
|
if (pos_x_ == MIN_X || pos_x_ == MAX_X) {
|
||||||
vel_x_ = -vel_x_; // Invierte la velocidad horizontal
|
vel_x_ = -vel_x_; // Invierte la velocidad horizontal
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si colisiona por arriba, rebota (excepto la máquina de café)
|
// Si colisiona por arriba, rebota (excepto la máquina de café)
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ auto loadFromFile(const std::string &file_path) -> bool {
|
|||||||
|
|
||||||
// Intentar cargar desde ResourceHelper primero
|
// Intentar cargar desde ResourceHelper primero
|
||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
json j;
|
json j;
|
||||||
|
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
// Cargar desde datos del pack
|
// Cargar desde datos del pack
|
||||||
std::string content(resource_data.begin(), resource_data.end());
|
std::string content(resource_data.begin(), resource_data.end());
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ struct Language {
|
|||||||
std::string file_name; // Nombre del fichero con los textos
|
std::string file_name; // Nombre del fichero con los textos
|
||||||
|
|
||||||
Language(Code c, std::string n, std::string fn)
|
Language(Code c, std::string n, std::string fn)
|
||||||
: code(c), name(std::move(n)), file_name(std::move(fn)) {}
|
: code(c),
|
||||||
|
name(std::move(n)),
|
||||||
|
file_name(std::move(fn)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Funciones ---
|
// --- Funciones ---
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ struct HiScoreEntry {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
explicit HiScoreEntry(const std::string &n = "", int s = 0, bool occ = false)
|
explicit HiScoreEntry(const std::string &n = "", int s = 0, bool occ = false)
|
||||||
: name(n.substr(0, 6)), score(s), one_credit_complete(occ) {}
|
: name(n.substr(0, 6)),
|
||||||
|
score(s),
|
||||||
|
one_credit_complete(occ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Tipos ---
|
// --- Tipos ---
|
||||||
|
|||||||
@@ -196,46 +196,48 @@ auto setParams(const std::string& var, const std::string& value) -> bool {
|
|||||||
|
|
||||||
// Colores válidos para globos
|
// Colores válidos para globos
|
||||||
static const std::unordered_map<std::string, bool> VALID_BALLOON_COLORS = {
|
static const std::unordered_map<std::string, bool> VALID_BALLOON_COLORS = {
|
||||||
{"blue", true}, {"orange", true}, {"red", true}, {"green", true}
|
{"blue", true},
|
||||||
};
|
{"orange", true},
|
||||||
|
{"red", true},
|
||||||
|
{"green", true}};
|
||||||
|
|
||||||
auto validateBalloonColor = [](const std::string& color) -> bool {
|
auto validateBalloonColor = [](const std::string& color) -> bool {
|
||||||
return VALID_BALLOON_COLORS.find(color) != VALID_BALLOON_COLORS.end();
|
return VALID_BALLOON_COLORS.find(color) != VALID_BALLOON_COLORS.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::unordered_map<std::string, std::function<void(const std::string&)>> STRING_PARAMS = {
|
static const std::unordered_map<std::string, std::function<void(const std::string&)>> STRING_PARAMS = {
|
||||||
{"balloon.color[0]", [validateBalloonColor](const std::string& v) {
|
{"balloon.color[0]", [validateBalloonColor](const std::string& v) {
|
||||||
if (!validateBalloonColor(v)) {
|
if (!validateBalloonColor(v)) {
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'blue' por defecto.", v.c_str());
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'blue' por defecto.", v.c_str());
|
||||||
param.balloon.color.at(0) = "blue";
|
param.balloon.color.at(0) = "blue";
|
||||||
} else {
|
} else {
|
||||||
param.balloon.color.at(0) = v;
|
param.balloon.color.at(0) = v;
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"balloon.color[1]", [validateBalloonColor](const std::string& v) {
|
{"balloon.color[1]", [validateBalloonColor](const std::string& v) {
|
||||||
if (!validateBalloonColor(v)) {
|
if (!validateBalloonColor(v)) {
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'orange' por defecto.", v.c_str());
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'orange' por defecto.", v.c_str());
|
||||||
param.balloon.color.at(1) = "orange";
|
param.balloon.color.at(1) = "orange";
|
||||||
} else {
|
} else {
|
||||||
param.balloon.color.at(1) = v;
|
param.balloon.color.at(1) = v;
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"balloon.color[2]", [validateBalloonColor](const std::string& v) {
|
{"balloon.color[2]", [validateBalloonColor](const std::string& v) {
|
||||||
if (!validateBalloonColor(v)) {
|
if (!validateBalloonColor(v)) {
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'red' por defecto.", v.c_str());
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'red' por defecto.", v.c_str());
|
||||||
param.balloon.color.at(2) = "red";
|
param.balloon.color.at(2) = "red";
|
||||||
} else {
|
} else {
|
||||||
param.balloon.color.at(2) = v;
|
param.balloon.color.at(2) = v;
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"balloon.color[3]", [validateBalloonColor](const std::string& v) {
|
{"balloon.color[3]", [validateBalloonColor](const std::string& v) {
|
||||||
if (!validateBalloonColor(v)) {
|
if (!validateBalloonColor(v)) {
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'green' por defecto.", v.c_str());
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'green' por defecto.", v.c_str());
|
||||||
param.balloon.color.at(3) = "green";
|
param.balloon.color.at(3) = "green";
|
||||||
} else {
|
} else {
|
||||||
param.balloon.color.at(3) = v;
|
param.balloon.color.at(3) = v;
|
||||||
}
|
}
|
||||||
}}};
|
}}};
|
||||||
|
|
||||||
// Lambda para intentar cada mapa de parámetros
|
// Lambda para intentar cada mapa de parámetros
|
||||||
auto try_map = [&](const auto& param_map) -> bool {
|
auto try_map = [&](const auto& param_map) -> bool {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ struct ParamBalloon {
|
|||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
constexpr Settings(float grav_val = 0.0F, float vel_val = 0.0F)
|
constexpr Settings(float grav_val = 0.0F, float vel_val = 0.0F)
|
||||||
: grav(grav_val), vel(vel_val) {}
|
: grav(grav_val),
|
||||||
|
vel(vel_val) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inicialización con los valores por defecto desde GameDefaults
|
// Inicialización con los valores por defecto desde GameDefaults
|
||||||
@@ -164,7 +165,10 @@ struct ParamPlayer {
|
|||||||
|
|
||||||
// Constructor con tonalidades específicas
|
// Constructor con tonalidades específicas
|
||||||
Shirt(const Color& darkest_tone, const Color& dark_tone, const Color& base_tone, const Color& light_tone)
|
Shirt(const Color& darkest_tone, const Color& dark_tone, const Color& base_tone, const Color& light_tone)
|
||||||
: darkest(darkest_tone), dark(dark_tone), base(base_tone), light(light_tone) {}
|
: darkest(darkest_tone),
|
||||||
|
dark(dark_tone),
|
||||||
|
base(base_tone),
|
||||||
|
light(light_tone) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inicialización con valores por defecto
|
// Inicialización con valores por defecto
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ struct Path { // Define un recorrido para el sprite
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init)
|
Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init)
|
||||||
: spots(spots_init), waiting_counter(waiting_counter_init) {}
|
: spots(spots_init),
|
||||||
|
waiting_counter(waiting_counter_init) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Funciones ---
|
// --- Funciones ---
|
||||||
|
|||||||
@@ -22,7 +22,17 @@
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Player::Player(const Config &config)
|
Player::Player(const Config &config)
|
||||||
: player_sprite_(std::make_unique<AnimatedSprite>(config.texture.at(0), config.animations.at(0))), power_sprite_(std::make_unique<AnimatedSprite>(config.texture.at(4), config.animations.at(1))), enter_name_(std::make_unique<EnterName>()), hi_score_table_(config.hi_score_table), glowing_entry_(config.glowing_entry), stage_info_(config.stage_info), play_area_(*config.play_area), id_(config.id), default_pos_x_(config.x), default_pos_y_(config.y), demo_(config.demo) {
|
: player_sprite_(std::make_unique<AnimatedSprite>(config.texture.at(0), config.animations.at(0))),
|
||||||
|
power_sprite_(std::make_unique<AnimatedSprite>(config.texture.at(4), config.animations.at(1))),
|
||||||
|
enter_name_(std::make_unique<EnterName>()),
|
||||||
|
hi_score_table_(config.hi_score_table),
|
||||||
|
glowing_entry_(config.glowing_entry),
|
||||||
|
stage_info_(config.stage_info),
|
||||||
|
play_area_(*config.play_area),
|
||||||
|
id_(config.id),
|
||||||
|
default_pos_x_(config.x),
|
||||||
|
default_pos_y_(config.y),
|
||||||
|
demo_(config.demo) {
|
||||||
// Configura objetos
|
// Configura objetos
|
||||||
player_sprite_->addTexture(config.texture.at(1));
|
player_sprite_->addTexture(config.texture.at(1));
|
||||||
player_sprite_->addTexture(config.texture.at(2));
|
player_sprite_->addTexture(config.texture.at(2));
|
||||||
@@ -624,7 +634,7 @@ void Player::setPlayingState(State state) {
|
|||||||
|
|
||||||
switch (playing_state_) {
|
switch (playing_state_) {
|
||||||
case State::RECOVER: {
|
case State::RECOVER: {
|
||||||
score_ = 0; // Pon los puntos a cero para que no se vea en el marcador
|
score_ = 0; // Pon los puntos a cero para que no se vea en el marcador
|
||||||
score_multiplier_ = 1.0F;
|
score_multiplier_ = 1.0F;
|
||||||
setScoreboardMode(Scoreboard::Mode::SCORE);
|
setScoreboardMode(Scoreboard::Mode::SCORE);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2,57 +2,57 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event
|
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event
|
||||||
|
|
||||||
#include <algorithm> // Para find_if, max, find
|
#include <algorithm> // Para find_if, max, find
|
||||||
#include <array> // Para array
|
#include <array> // Para array
|
||||||
#include <cstdlib> // Para exit, getenv
|
#include <cstdlib> // Para exit, getenv
|
||||||
#include <filesystem> // Para filesystem::remove, filesystem::exists
|
#include <filesystem> // Para filesystem::remove, filesystem::exists
|
||||||
#include <fstream> // Para ofstream
|
#include <fstream> // Para ofstream
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
#include "asset.h" // Para Asset
|
#include "asset.h" // Para Asset
|
||||||
#include "color.h" // Para Color
|
#include "color.h" // Para Color
|
||||||
#ifndef NO_AUDIO
|
#ifndef NO_AUDIO
|
||||||
#include "external/jail_audio.h" // Para JA_LoadMusic, JA_LoadSound, JA_DeleteMusic, JA_DeleteSound
|
#include "external/jail_audio.h" // Para JA_LoadMusic, JA_LoadSound, JA_DeleteMusic, JA_DeleteSound
|
||||||
#endif
|
#endif
|
||||||
#include "lang.h" // Para getText
|
#include "lang.h" // Para getText
|
||||||
#include "param.h" // Para Param, param, ParamResource, ParamGame
|
#include "param.h" // Para Param, param, ParamResource, ParamGame
|
||||||
#include "screen.h" // Para Screen
|
|
||||||
#include "text.h" // Para Text
|
|
||||||
#include "resource_helper.h" // Para ResourceHelper
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
|
#include "screen.h" // Para Screen
|
||||||
|
#include "text.h" // Para Text
|
||||||
|
|
||||||
struct JA_Music_t; // lines 11-11
|
struct JA_Music_t; // lines 11-11
|
||||||
struct JA_Sound_t; // lines 12-12
|
struct JA_Sound_t; // lines 12-12
|
||||||
|
|
||||||
// Helper para cargar archivos de audio desde pack o filesystem
|
// Helper para cargar archivos de audio desde pack o filesystem
|
||||||
namespace {
|
namespace {
|
||||||
std::string createTempAudioFile(const std::string& file_path, std::vector<std::string>& temp_files_tracker) {
|
std::string createTempAudioFile(const std::string &file_path, std::vector<std::string> &temp_files_tracker) {
|
||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
// Crear archivo temporal
|
// Crear archivo temporal
|
||||||
std::string temp_dir;
|
std::string temp_dir;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
temp_dir = std::getenv("TEMP") ? std::getenv("TEMP") : "C:\\temp";
|
temp_dir = std::getenv("TEMP") ? std::getenv("TEMP") : "C:\\temp";
|
||||||
#else
|
#else
|
||||||
temp_dir = "/tmp";
|
temp_dir = "/tmp";
|
||||||
#endif
|
#endif
|
||||||
std::string temp_path = temp_dir + "/ccae_audio_" + std::to_string(std::hash<std::string>{}(file_path));
|
std::string temp_path = temp_dir + "/ccae_audio_" + std::to_string(std::hash<std::string>{}(file_path));
|
||||||
std::ofstream temp_file(temp_path, std::ios::binary);
|
std::ofstream temp_file(temp_path, std::ios::binary);
|
||||||
if (!temp_file) {
|
if (!temp_file) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Cannot create temp file %s", temp_path.c_str());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Cannot create temp file %s", temp_path.c_str());
|
||||||
return file_path;
|
return file_path;
|
||||||
}
|
|
||||||
temp_file.write(reinterpret_cast<const char*>(resource_data.data()), resource_data.size());
|
|
||||||
temp_file.close();
|
|
||||||
|
|
||||||
// Agregar a la lista de archivos temporales para limpieza posterior
|
|
||||||
temp_files_tracker.push_back(temp_path);
|
|
||||||
|
|
||||||
return temp_path;
|
|
||||||
}
|
}
|
||||||
return file_path; // Usar ruta original si no está en pack
|
temp_file.write(reinterpret_cast<const char *>(resource_data.data()), resource_data.size());
|
||||||
|
temp_file.close();
|
||||||
|
|
||||||
|
// Agregar a la lista de archivos temporales para limpieza posterior
|
||||||
|
temp_files_tracker.push_back(temp_path);
|
||||||
|
|
||||||
|
return temp_path;
|
||||||
}
|
}
|
||||||
|
return file_path; // Usar ruta original si no está en pack
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// Declaraciones de funciones que necesitas implementar en otros archivos
|
// Declaraciones de funciones que necesitas implementar en otros archivos
|
||||||
|
|
||||||
@@ -75,7 +75,8 @@ auto Resource::get() -> Resource * { return Resource::instance; }
|
|||||||
|
|
||||||
// Constructor con modo de carga
|
// Constructor con modo de carga
|
||||||
Resource::Resource(LoadingMode mode)
|
Resource::Resource(LoadingMode mode)
|
||||||
: loading_mode_(mode), loading_text_(nullptr) {
|
: loading_mode_(mode),
|
||||||
|
loading_text_(nullptr) {
|
||||||
if (loading_mode_ == LoadingMode::PRELOAD) {
|
if (loading_mode_ == LoadingMode::PRELOAD) {
|
||||||
loading_text_ = Screen::get()->getText();
|
loading_text_ = Screen::get()->getText();
|
||||||
load();
|
load();
|
||||||
@@ -649,7 +650,8 @@ void Resource::createTextTextures() {
|
|||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
NameAndText(std::string name_init, std::string text_init)
|
NameAndText(std::string name_init, std::string text_init)
|
||||||
: name(std::move(name_init)), text(std::move(text_init)) {}
|
: name(std::move(name_init)),
|
||||||
|
text(std::move(text_init)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> CREATING TEXTURES");
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> CREATING TEXTURES");
|
||||||
@@ -694,7 +696,10 @@ void Resource::createText() {
|
|||||||
std::string white_texture_file; // Textura blanca opcional
|
std::string white_texture_file; // Textura blanca opcional
|
||||||
|
|
||||||
ResourceInfo(std::string k, std::string t_file, std::string txt_file, std::string w_file = "")
|
ResourceInfo(std::string k, std::string t_file, std::string txt_file, std::string w_file = "")
|
||||||
: key(std::move(k)), texture_file(std::move(t_file)), text_file(std::move(txt_file)), white_texture_file(std::move(w_file)) {}
|
: key(std::move(k)),
|
||||||
|
texture_file(std::move(t_file)),
|
||||||
|
text_file(std::move(txt_file)),
|
||||||
|
white_texture_file(std::move(w_file)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> CREATING TEXT OBJECTS");
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> CREATING TEXT OBJECTS");
|
||||||
@@ -704,7 +709,7 @@ void Resource::createText() {
|
|||||||
{"04b_25_enhanced", "04b_25.png", "04b_25.txt", "04b_25_white.png"}, // Nueva fuente con textura blanca
|
{"04b_25_enhanced", "04b_25.png", "04b_25.txt", "04b_25_white.png"}, // Nueva fuente con textura blanca
|
||||||
{"04b_25_white", "04b_25_white.png", "04b_25.txt"},
|
{"04b_25_white", "04b_25_white.png", "04b_25.txt"},
|
||||||
{"04b_25_2x", "04b_25_2x.png", "04b_25_2x.txt"},
|
{"04b_25_2x", "04b_25_2x.png", "04b_25_2x.txt"},
|
||||||
{"04b_25_2x_enhanced", "04b_25_2x.png", "04b_25_2x.txt", "04b_25_2x_white.png"},// Nueva fuente con textura blanca
|
{"04b_25_2x_enhanced", "04b_25_2x.png", "04b_25_2x.txt", "04b_25_2x_white.png"}, // Nueva fuente con textura blanca
|
||||||
{"04b_25_metal", "04b_25_metal.png", "04b_25.txt"},
|
{"04b_25_metal", "04b_25_metal.png", "04b_25.txt"},
|
||||||
{"04b_25_grey", "04b_25_grey.png", "04b_25.txt"},
|
{"04b_25_grey", "04b_25_grey.png", "04b_25.txt"},
|
||||||
{"04b_25_flat", "04b_25_flat.png", "04b_25.txt"},
|
{"04b_25_flat", "04b_25_flat.png", "04b_25.txt"},
|
||||||
@@ -866,13 +871,13 @@ void Resource::updateProgressBar() {
|
|||||||
|
|
||||||
// Limpia archivos temporales de audio
|
// Limpia archivos temporales de audio
|
||||||
void Resource::cleanupTempAudioFiles() {
|
void Resource::cleanupTempAudioFiles() {
|
||||||
for (const auto& temp_path : temp_audio_files_) {
|
for (const auto &temp_path : temp_audio_files_) {
|
||||||
try {
|
try {
|
||||||
if (std::filesystem::exists(temp_path)) {
|
if (std::filesystem::exists(temp_path)) {
|
||||||
std::filesystem::remove(temp_path);
|
std::filesystem::remove(temp_path);
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Removed temp audio file: %s", temp_path.c_str());
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Removed temp audio file: %s", temp_path.c_str());
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception &e) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to remove temp audio file %s: %s", temp_path.c_str(), e.what());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to remove temp audio file %s: %s", temp_path.c_str(), e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ class Resource {
|
|||||||
JA_Sound_t *sound; // Objeto con el sonido
|
JA_Sound_t *sound; // Objeto con el sonido
|
||||||
|
|
||||||
ResourceSound(std::string name, JA_Sound_t *sound = nullptr)
|
ResourceSound(std::string name, JA_Sound_t *sound = nullptr)
|
||||||
: name(std::move(name)), sound(sound) {}
|
: name(std::move(name)),
|
||||||
|
sound(sound) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourceMusic {
|
struct ResourceMusic {
|
||||||
@@ -60,7 +61,8 @@ class Resource {
|
|||||||
JA_Music_t *music; // Objeto con la música
|
JA_Music_t *music; // Objeto con la música
|
||||||
|
|
||||||
ResourceMusic(std::string name, JA_Music_t *music = nullptr)
|
ResourceMusic(std::string name, JA_Music_t *music = nullptr)
|
||||||
: name(std::move(name)), music(music) {}
|
: name(std::move(name)),
|
||||||
|
music(music) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourceTexture {
|
struct ResourceTexture {
|
||||||
@@ -68,7 +70,8 @@ class Resource {
|
|||||||
std::shared_ptr<Texture> texture; // Objeto con la textura
|
std::shared_ptr<Texture> texture; // Objeto con la textura
|
||||||
|
|
||||||
ResourceTexture(std::string name, std::shared_ptr<Texture> texture = nullptr)
|
ResourceTexture(std::string name, std::shared_ptr<Texture> texture = nullptr)
|
||||||
: name(std::move(name)), texture(std::move(texture)) {}
|
: name(std::move(name)),
|
||||||
|
texture(std::move(texture)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourceTextFile {
|
struct ResourceTextFile {
|
||||||
@@ -76,7 +79,8 @@ class Resource {
|
|||||||
std::shared_ptr<Text::File> text_file; // Objeto con los descriptores de la fuente de texto
|
std::shared_ptr<Text::File> text_file; // Objeto con los descriptores de la fuente de texto
|
||||||
|
|
||||||
ResourceTextFile(std::string name, std::shared_ptr<Text::File> text_file = nullptr)
|
ResourceTextFile(std::string name, std::shared_ptr<Text::File> text_file = nullptr)
|
||||||
: name(std::move(name)), text_file(std::move(text_file)) {}
|
: name(std::move(name)),
|
||||||
|
text_file(std::move(text_file)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourceText {
|
struct ResourceText {
|
||||||
@@ -84,7 +88,8 @@ class Resource {
|
|||||||
std::shared_ptr<Text> text; // Objeto de texto
|
std::shared_ptr<Text> text; // Objeto de texto
|
||||||
|
|
||||||
ResourceText(std::string name, std::shared_ptr<Text> text = nullptr)
|
ResourceText(std::string name, std::shared_ptr<Text> text = nullptr)
|
||||||
: name(std::move(name)), text(std::move(text)) {}
|
: name(std::move(name)),
|
||||||
|
text(std::move(text)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourceAnimation {
|
struct ResourceAnimation {
|
||||||
@@ -92,7 +97,8 @@ class Resource {
|
|||||||
AnimationsFileBuffer animation; // Objeto con las animaciones
|
AnimationsFileBuffer animation; // Objeto con las animaciones
|
||||||
|
|
||||||
ResourceAnimation(std::string name, AnimationsFileBuffer animation = {})
|
ResourceAnimation(std::string name, AnimationsFileBuffer animation = {})
|
||||||
: name(std::move(name)), animation(std::move(animation)) {}
|
: name(std::move(name)),
|
||||||
|
animation(std::move(animation)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Estructura para el progreso de carga ---
|
// --- Estructura para el progreso de carga ---
|
||||||
@@ -100,8 +106,12 @@ class Resource {
|
|||||||
size_t total; // Número total de recursos
|
size_t total; // Número total de recursos
|
||||||
size_t loaded; // Número de recursos cargados
|
size_t loaded; // Número de recursos cargados
|
||||||
|
|
||||||
ResourceCount() : total(0), loaded(0) {}
|
ResourceCount()
|
||||||
ResourceCount(size_t total) : total(total), loaded(0) {}
|
: total(0),
|
||||||
|
loaded(0) {}
|
||||||
|
ResourceCount(size_t total)
|
||||||
|
: total(total),
|
||||||
|
loaded(0) {}
|
||||||
|
|
||||||
void add(size_t amount) { loaded += amount; }
|
void add(size_t amount) { loaded += amount; }
|
||||||
void increase() { loaded++; }
|
void increase() { loaded++; }
|
||||||
@@ -128,7 +138,7 @@ class Resource {
|
|||||||
std::string loading_resource_name_; // Nombre del recurso que se está cargando
|
std::string loading_resource_name_; // Nombre del recurso que se está cargando
|
||||||
SDL_FRect loading_wired_rect_;
|
SDL_FRect loading_wired_rect_;
|
||||||
SDL_FRect loading_full_rect_;
|
SDL_FRect loading_full_rect_;
|
||||||
|
|
||||||
// --- Archivos temporales ---
|
// --- Archivos temporales ---
|
||||||
std::vector<std::string> temp_audio_files_; // Rutas de archivos temporales de audio para limpieza
|
std::vector<std::string> temp_audio_files_; // Rutas de archivos temporales de audio para limpieza
|
||||||
|
|
||||||
|
|||||||
@@ -1,95 +1,96 @@
|
|||||||
#include "resource_helper.h"
|
#include "resource_helper.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace ResourceHelper {
|
namespace ResourceHelper {
|
||||||
static bool resource_system_initialized = false;
|
static bool resource_system_initialized = false;
|
||||||
|
|
||||||
bool initializeResourceSystem(const std::string& pack_file) {
|
bool initializeResourceSystem(const std::string& pack_file) {
|
||||||
|
auto& loader = ResourceLoader::getInstance();
|
||||||
|
resource_system_initialized = loader.initialize(pack_file, true);
|
||||||
|
|
||||||
|
if (resource_system_initialized) {
|
||||||
|
std::cout << "Resource system initialized with pack: " << pack_file << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Resource system using fallback mode (filesystem only)" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // Always return true as fallback is acceptable
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdownResourceSystem() {
|
||||||
|
if (resource_system_initialized) {
|
||||||
|
ResourceLoader::getInstance().shutdown();
|
||||||
|
resource_system_initialized = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> loadFile(const std::string& filepath) {
|
||||||
|
if (resource_system_initialized && shouldUseResourcePack(filepath)) {
|
||||||
auto& loader = ResourceLoader::getInstance();
|
auto& loader = ResourceLoader::getInstance();
|
||||||
resource_system_initialized = loader.initialize(pack_file, true);
|
std::string pack_path = getPackPath(filepath);
|
||||||
|
|
||||||
if (resource_system_initialized) {
|
auto data = loader.loadResource(pack_path);
|
||||||
std::cout << "Resource system initialized with pack: " << pack_file << std::endl;
|
if (!data.empty()) {
|
||||||
} else {
|
return data;
|
||||||
std::cout << "Resource system using fallback mode (filesystem only)" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true; // Always return true as fallback is acceptable
|
|
||||||
}
|
|
||||||
|
|
||||||
void shutdownResourceSystem() {
|
|
||||||
if (resource_system_initialized) {
|
|
||||||
ResourceLoader::getInstance().shutdown();
|
|
||||||
resource_system_initialized = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> loadFile(const std::string& filepath) {
|
// Fallback a filesystem
|
||||||
if (resource_system_initialized && shouldUseResourcePack(filepath)) {
|
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
|
||||||
auto& loader = ResourceLoader::getInstance();
|
if (!file) {
|
||||||
std::string pack_path = getPackPath(filepath);
|
return {};
|
||||||
|
|
||||||
auto data = loader.loadResource(pack_path);
|
|
||||||
if (!data.empty()) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback a filesystem
|
|
||||||
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
|
|
||||||
if (!file) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::streamsize fileSize = file.tellg();
|
|
||||||
file.seekg(0, std::ios::beg);
|
|
||||||
|
|
||||||
std::vector<uint8_t> data(fileSize);
|
|
||||||
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldUseResourcePack(const std::string& filepath) {
|
std::streamsize fileSize = file.tellg();
|
||||||
// Archivos que NO van al pack:
|
file.seekg(0, std::ios::beg);
|
||||||
// - config/ (ahora está fuera de data/)
|
|
||||||
// - archivos absolutos del sistema
|
std::vector<uint8_t> data(fileSize);
|
||||||
|
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
|
||||||
if (filepath.find("config/") != std::string::npos) {
|
return {};
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
return data;
|
||||||
// Si contiene "data/" es candidato para el pack
|
}
|
||||||
if (filepath.find("data/") != std::string::npos) {
|
|
||||||
return true;
|
bool shouldUseResourcePack(const std::string& filepath) {
|
||||||
}
|
// Archivos que NO van al pack:
|
||||||
|
// - config/ (ahora está fuera de data/)
|
||||||
|
// - archivos absolutos del sistema
|
||||||
|
|
||||||
|
if (filepath.find("config/") != std::string::npos) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getPackPath(const std::string& asset_path) {
|
// Si contiene "data/" es candidato para el pack
|
||||||
std::string pack_path = asset_path;
|
if (filepath.find("data/") != std::string::npos) {
|
||||||
|
return true;
|
||||||
// Normalizar separadores de path a '/'
|
|
||||||
std::replace(pack_path.begin(), pack_path.end(), '\\', '/');
|
|
||||||
|
|
||||||
// Remover prefijo "data/" si existe
|
|
||||||
size_t data_pos = pack_path.find("data/");
|
|
||||||
if (data_pos != std::string::npos) {
|
|
||||||
pack_path = pack_path.substr(data_pos + 5); // +5 para saltar "data/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remover cualquier prefijo de path absoluto
|
|
||||||
size_t last_data = pack_path.rfind("data/");
|
|
||||||
if (last_data != std::string::npos) {
|
|
||||||
pack_path = pack_path.substr(last_data + 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pack_path;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getPackPath(const std::string& asset_path) {
|
||||||
|
std::string pack_path = asset_path;
|
||||||
|
|
||||||
|
// Normalizar separadores de path a '/'
|
||||||
|
std::replace(pack_path.begin(), pack_path.end(), '\\', '/');
|
||||||
|
|
||||||
|
// Remover prefijo "data/" si existe
|
||||||
|
size_t data_pos = pack_path.find("data/");
|
||||||
|
if (data_pos != std::string::npos) {
|
||||||
|
pack_path = pack_path.substr(data_pos + 5); // +5 para saltar "data/"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remover cualquier prefijo de path absoluto
|
||||||
|
size_t last_data = pack_path.rfind("data/");
|
||||||
|
if (last_data != std::string::npos) {
|
||||||
|
pack_path = pack_path.substr(last_data + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pack_path;
|
||||||
|
}
|
||||||
|
} // namespace ResourceHelper
|
||||||
@@ -1,46 +1,47 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "resource_loader.h"
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "resource_loader.h"
|
||||||
|
|
||||||
// Helper functions para integrar ResourceLoader con el sistema existente
|
// Helper functions para integrar ResourceLoader con el sistema existente
|
||||||
namespace ResourceHelper {
|
namespace ResourceHelper {
|
||||||
// Inicializa ResourceLoader (llamar al inicio del programa)
|
// Inicializa ResourceLoader (llamar al inicio del programa)
|
||||||
bool initializeResourceSystem(const std::string& pack_file = "resources.pack");
|
bool initializeResourceSystem(const std::string& pack_file = "resources.pack");
|
||||||
|
|
||||||
// Cierra ResourceLoader
|
// Cierra ResourceLoader
|
||||||
void shutdownResourceSystem();
|
void shutdownResourceSystem();
|
||||||
|
|
||||||
// Carga un archivo usando ResourceLoader o fallback a filesystem
|
// Carga un archivo usando ResourceLoader o fallback a filesystem
|
||||||
std::vector<uint8_t> loadFile(const std::string& filepath);
|
std::vector<uint8_t> loadFile(const std::string& filepath);
|
||||||
|
|
||||||
// Verifica si un archivo debería cargarse del pack vs filesystem
|
// Verifica si un archivo debería cargarse del pack vs filesystem
|
||||||
bool shouldUseResourcePack(const std::string& filepath);
|
bool shouldUseResourcePack(const std::string& filepath);
|
||||||
|
|
||||||
// Convierte ruta Asset a ruta relativa para ResourceLoader
|
// Convierte ruta Asset a ruta relativa para ResourceLoader
|
||||||
std::string getPackPath(const std::string& asset_path);
|
std::string getPackPath(const std::string& asset_path);
|
||||||
|
|
||||||
// Wrappea la carga de archivos para mantener compatibilidad
|
// Wrappea la carga de archivos para mantener compatibilidad
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T* loadResourceFile(const std::string& asset_path, T* (*loader_func)(const char*)) {
|
T* loadResourceFile(const std::string& asset_path, T* (*loader_func)(const char*)) {
|
||||||
auto data = loadFile(asset_path);
|
auto data = loadFile(asset_path);
|
||||||
if (data.empty()) {
|
if (data.empty()) {
|
||||||
return loader_func(asset_path.c_str());
|
return loader_func(asset_path.c_str());
|
||||||
}
|
|
||||||
|
|
||||||
// Crear archivo temporal para funciones que esperan path
|
|
||||||
std::string temp_path = "/tmp/ccae_" + std::to_string(std::hash<std::string>{}(asset_path));
|
|
||||||
std::ofstream temp_file(temp_path, std::ios::binary);
|
|
||||||
temp_file.write(reinterpret_cast<const char*>(data.data()), data.size());
|
|
||||||
temp_file.close();
|
|
||||||
|
|
||||||
T* result = loader_func(temp_path.c_str());
|
|
||||||
std::filesystem::remove(temp_path);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Crear archivo temporal para funciones que esperan path
|
||||||
|
std::string temp_path = "/tmp/ccae_" + std::to_string(std::hash<std::string>{}(asset_path));
|
||||||
|
std::ofstream temp_file(temp_path, std::ios::binary);
|
||||||
|
temp_file.write(reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
temp_file.close();
|
||||||
|
|
||||||
|
T* result = loader_func(temp_path.c_str());
|
||||||
|
std::filesystem::remove(temp_path);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace ResourceHelper
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
#include "resource_loader.h"
|
#include "resource_loader.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
std::unique_ptr<ResourceLoader> ResourceLoader::instance = nullptr;
|
std::unique_ptr<ResourceLoader> ResourceLoader::instance = nullptr;
|
||||||
|
|
||||||
ResourceLoader::ResourceLoader()
|
ResourceLoader::ResourceLoader()
|
||||||
: resourcePack(nullptr), fallbackToFiles(true) {}
|
: resourcePack(nullptr),
|
||||||
|
fallbackToFiles(true) {}
|
||||||
|
|
||||||
ResourceLoader& ResourceLoader::getInstance() {
|
ResourceLoader& ResourceLoader::getInstance() {
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
@@ -22,10 +24,10 @@ ResourceLoader::~ResourceLoader() {
|
|||||||
|
|
||||||
bool ResourceLoader::initialize(const std::string& packFile, bool enableFallback) {
|
bool ResourceLoader::initialize(const std::string& packFile, bool enableFallback) {
|
||||||
shutdown();
|
shutdown();
|
||||||
|
|
||||||
fallbackToFiles = enableFallback;
|
fallbackToFiles = enableFallback;
|
||||||
packPath = packFile;
|
packPath = packFile;
|
||||||
|
|
||||||
if (std::filesystem::exists(packFile)) {
|
if (std::filesystem::exists(packFile)) {
|
||||||
resourcePack = new ResourcePack();
|
resourcePack = new ResourcePack();
|
||||||
if (resourcePack->loadPack(packFile)) {
|
if (resourcePack->loadPack(packFile)) {
|
||||||
@@ -38,12 +40,12 @@ bool ResourceLoader::initialize(const std::string& packFile, bool enableFallback
|
|||||||
std::cerr << "Failed to load resource pack: " << packFile << std::endl;
|
std::cerr << "Failed to load resource pack: " << packFile << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fallbackToFiles) {
|
if (fallbackToFiles) {
|
||||||
std::cout << "Using fallback mode: loading resources from data/ directory" << std::endl;
|
std::cout << "Using fallback mode: loading resources from data/ directory" << std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "Resource pack not found and fallback disabled: " << packFile << std::endl;
|
std::cerr << "Resource pack not found and fallback disabled: " << packFile << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -59,11 +61,11 @@ std::vector<uint8_t> ResourceLoader::loadResource(const std::string& filename) {
|
|||||||
if (resourcePack && resourcePack->hasResource(filename)) {
|
if (resourcePack && resourcePack->hasResource(filename)) {
|
||||||
return resourcePack->getResource(filename);
|
return resourcePack->getResource(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fallbackToFiles) {
|
if (fallbackToFiles) {
|
||||||
return loadFromFile(filename);
|
return loadFromFile(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "Resource not found: " << filename << std::endl;
|
std::cerr << "Resource not found: " << filename << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -72,33 +74,33 @@ bool ResourceLoader::resourceExists(const std::string& filename) {
|
|||||||
if (resourcePack && resourcePack->hasResource(filename)) {
|
if (resourcePack && resourcePack->hasResource(filename)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fallbackToFiles) {
|
if (fallbackToFiles) {
|
||||||
std::string fullPath = getDataPath(filename);
|
std::string fullPath = getDataPath(filename);
|
||||||
return std::filesystem::exists(fullPath);
|
return std::filesystem::exists(fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> ResourceLoader::loadFromFile(const std::string& filename) {
|
std::vector<uint8_t> ResourceLoader::loadFromFile(const std::string& filename) {
|
||||||
std::string fullPath = getDataPath(filename);
|
std::string fullPath = getDataPath(filename);
|
||||||
|
|
||||||
std::ifstream file(fullPath, std::ios::binary | std::ios::ate);
|
std::ifstream file(fullPath, std::ios::binary | std::ios::ate);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
std::cerr << "Error: Could not open file: " << fullPath << std::endl;
|
std::cerr << "Error: Could not open file: " << fullPath << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::streamsize fileSize = file.tellg();
|
std::streamsize fileSize = file.tellg();
|
||||||
file.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
std::vector<uint8_t> data(fileSize);
|
std::vector<uint8_t> data(fileSize);
|
||||||
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
|
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
|
||||||
std::cerr << "Error: Could not read file: " << fullPath << std::endl;
|
std::cerr << "Error: Could not read file: " << fullPath << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +119,7 @@ std::vector<std::string> ResourceLoader::getAvailableResources() const {
|
|||||||
if (resourcePack) {
|
if (resourcePack) {
|
||||||
return resourcePack->getResourceList();
|
return resourcePack->getResourceList();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
if (fallbackToFiles && std::filesystem::exists("data")) {
|
if (fallbackToFiles && std::filesystem::exists("data")) {
|
||||||
for (const auto& entry : std::filesystem::recursive_directory_iterator("data")) {
|
for (const auto& entry : std::filesystem::recursive_directory_iterator("data")) {
|
||||||
@@ -128,6 +130,6 @@ std::vector<std::string> ResourceLoader::getAvailableResources() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,38 @@
|
|||||||
#ifndef RESOURCE_LOADER_H
|
#ifndef RESOURCE_LOADER_H
|
||||||
#define RESOURCE_LOADER_H
|
#define RESOURCE_LOADER_H
|
||||||
|
|
||||||
#include "resource_pack.h"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "resource_pack.h"
|
||||||
|
|
||||||
class ResourceLoader {
|
class ResourceLoader {
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<ResourceLoader> instance;
|
static std::unique_ptr<ResourceLoader> instance;
|
||||||
ResourcePack* resourcePack;
|
ResourcePack* resourcePack;
|
||||||
std::string packPath;
|
std::string packPath;
|
||||||
bool fallbackToFiles;
|
bool fallbackToFiles;
|
||||||
|
|
||||||
ResourceLoader();
|
ResourceLoader();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ResourceLoader& getInstance();
|
static ResourceLoader& getInstance();
|
||||||
~ResourceLoader();
|
~ResourceLoader();
|
||||||
|
|
||||||
bool initialize(const std::string& packFile, bool enableFallback = true);
|
|
||||||
void shutdown();
|
|
||||||
|
|
||||||
std::vector<uint8_t> loadResource(const std::string& filename);
|
|
||||||
bool resourceExists(const std::string& filename);
|
|
||||||
|
|
||||||
void setFallbackToFiles(bool enable) { fallbackToFiles = enable; }
|
|
||||||
bool getFallbackToFiles() const { return fallbackToFiles; }
|
|
||||||
|
|
||||||
size_t getLoadedResourceCount() const;
|
|
||||||
std::vector<std::string> getAvailableResources() const;
|
|
||||||
|
|
||||||
private:
|
bool initialize(const std::string& packFile, bool enableFallback = true);
|
||||||
std::vector<uint8_t> loadFromFile(const std::string& filename);
|
void shutdown();
|
||||||
std::string getDataPath(const std::string& filename);
|
|
||||||
|
std::vector<uint8_t> loadResource(const std::string& filename);
|
||||||
|
bool resourceExists(const std::string& filename);
|
||||||
|
|
||||||
|
void setFallbackToFiles(bool enable) { fallbackToFiles = enable; }
|
||||||
|
bool getFallbackToFiles() const { return fallbackToFiles; }
|
||||||
|
|
||||||
|
size_t getLoadedResourceCount() const;
|
||||||
|
std::vector<std::string> getAvailableResources() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint8_t> loadFromFile(const std::string& filename);
|
||||||
|
std::string getDataPath(const std::string& filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
#include "resource_pack.h"
|
#include "resource_pack.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES_2024";
|
const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES_2024";
|
||||||
|
|
||||||
ResourcePack::ResourcePack() : loaded(false) {}
|
ResourcePack::ResourcePack()
|
||||||
|
: loaded(false) {}
|
||||||
|
|
||||||
ResourcePack::~ResourcePack() {
|
ResourcePack::~ResourcePack() {
|
||||||
clear();
|
clear();
|
||||||
@@ -22,7 +24,7 @@ uint32_t ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) {
|
|||||||
|
|
||||||
void ResourcePack::encryptData(std::vector<uint8_t>& data, const std::string& key) {
|
void ResourcePack::encryptData(std::vector<uint8_t>& data, const std::string& key) {
|
||||||
if (key.empty()) return;
|
if (key.empty()) return;
|
||||||
|
|
||||||
for (size_t i = 0; i < data.size(); ++i) {
|
for (size_t i = 0; i < data.size(); ++i) {
|
||||||
data[i] ^= key[i % key.length()];
|
data[i] ^= key[i % key.length()];
|
||||||
}
|
}
|
||||||
@@ -38,51 +40,51 @@ bool ResourcePack::loadPack(const std::string& packFile) {
|
|||||||
std::cerr << "Error: Could not open pack file: " << packFile << std::endl;
|
std::cerr << "Error: Could not open pack file: " << packFile << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char header[4];
|
char header[4];
|
||||||
file.read(header, 4);
|
file.read(header, 4);
|
||||||
if (std::string(header, 4) != "CCAE") {
|
if (std::string(header, 4) != "CCAE") {
|
||||||
std::cerr << "Error: Invalid pack file format" << std::endl;
|
std::cerr << "Error: Invalid pack file format" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
file.read(reinterpret_cast<char*>(&version), sizeof(version));
|
file.read(reinterpret_cast<char*>(&version), sizeof(version));
|
||||||
if (version != 1) {
|
if (version != 1) {
|
||||||
std::cerr << "Error: Unsupported pack version: " << version << std::endl;
|
std::cerr << "Error: Unsupported pack version: " << version << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t resourceCount;
|
uint32_t resourceCount;
|
||||||
file.read(reinterpret_cast<char*>(&resourceCount), sizeof(resourceCount));
|
file.read(reinterpret_cast<char*>(&resourceCount), sizeof(resourceCount));
|
||||||
|
|
||||||
resources.clear();
|
resources.clear();
|
||||||
resources.reserve(resourceCount);
|
resources.reserve(resourceCount);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < resourceCount; ++i) {
|
for (uint32_t i = 0; i < resourceCount; ++i) {
|
||||||
uint32_t filenameLength;
|
uint32_t filenameLength;
|
||||||
file.read(reinterpret_cast<char*>(&filenameLength), sizeof(filenameLength));
|
file.read(reinterpret_cast<char*>(&filenameLength), sizeof(filenameLength));
|
||||||
|
|
||||||
std::string filename(filenameLength, '\0');
|
std::string filename(filenameLength, '\0');
|
||||||
file.read(&filename[0], filenameLength);
|
file.read(&filename[0], filenameLength);
|
||||||
|
|
||||||
ResourceEntry entry;
|
ResourceEntry entry;
|
||||||
entry.filename = filename;
|
entry.filename = filename;
|
||||||
file.read(reinterpret_cast<char*>(&entry.offset), sizeof(entry.offset));
|
file.read(reinterpret_cast<char*>(&entry.offset), sizeof(entry.offset));
|
||||||
file.read(reinterpret_cast<char*>(&entry.size), sizeof(entry.size));
|
file.read(reinterpret_cast<char*>(&entry.size), sizeof(entry.size));
|
||||||
file.read(reinterpret_cast<char*>(&entry.checksum), sizeof(entry.checksum));
|
file.read(reinterpret_cast<char*>(&entry.checksum), sizeof(entry.checksum));
|
||||||
|
|
||||||
resources[filename] = entry;
|
resources[filename] = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t dataSize;
|
uint64_t dataSize;
|
||||||
file.read(reinterpret_cast<char*>(&dataSize), sizeof(dataSize));
|
file.read(reinterpret_cast<char*>(&dataSize), sizeof(dataSize));
|
||||||
|
|
||||||
data.resize(dataSize);
|
data.resize(dataSize);
|
||||||
file.read(reinterpret_cast<char*>(data.data()), dataSize);
|
file.read(reinterpret_cast<char*>(data.data()), dataSize);
|
||||||
|
|
||||||
decryptData(data, DEFAULT_ENCRYPT_KEY);
|
decryptData(data, DEFAULT_ENCRYPT_KEY);
|
||||||
|
|
||||||
loaded = true;
|
loaded = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -93,32 +95,32 @@ bool ResourcePack::savePack(const std::string& packFile) {
|
|||||||
std::cerr << "Error: Could not create pack file: " << packFile << std::endl;
|
std::cerr << "Error: Could not create pack file: " << packFile << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.write("CCAE", 4);
|
file.write("CCAE", 4);
|
||||||
|
|
||||||
uint32_t version = 1;
|
uint32_t version = 1;
|
||||||
file.write(reinterpret_cast<const char*>(&version), sizeof(version));
|
file.write(reinterpret_cast<const char*>(&version), sizeof(version));
|
||||||
|
|
||||||
uint32_t resourceCount = static_cast<uint32_t>(resources.size());
|
uint32_t resourceCount = static_cast<uint32_t>(resources.size());
|
||||||
file.write(reinterpret_cast<const char*>(&resourceCount), sizeof(resourceCount));
|
file.write(reinterpret_cast<const char*>(&resourceCount), sizeof(resourceCount));
|
||||||
|
|
||||||
for (const auto& [filename, entry] : resources) {
|
for (const auto& [filename, entry] : resources) {
|
||||||
uint32_t filenameLength = static_cast<uint32_t>(filename.length());
|
uint32_t filenameLength = static_cast<uint32_t>(filename.length());
|
||||||
file.write(reinterpret_cast<const char*>(&filenameLength), sizeof(filenameLength));
|
file.write(reinterpret_cast<const char*>(&filenameLength), sizeof(filenameLength));
|
||||||
file.write(filename.c_str(), filenameLength);
|
file.write(filename.c_str(), filenameLength);
|
||||||
|
|
||||||
file.write(reinterpret_cast<const char*>(&entry.offset), sizeof(entry.offset));
|
file.write(reinterpret_cast<const char*>(&entry.offset), sizeof(entry.offset));
|
||||||
file.write(reinterpret_cast<const char*>(&entry.size), sizeof(entry.size));
|
file.write(reinterpret_cast<const char*>(&entry.size), sizeof(entry.size));
|
||||||
file.write(reinterpret_cast<const char*>(&entry.checksum), sizeof(entry.checksum));
|
file.write(reinterpret_cast<const char*>(&entry.checksum), sizeof(entry.checksum));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> encryptedData = data;
|
std::vector<uint8_t> encryptedData = data;
|
||||||
encryptData(encryptedData, DEFAULT_ENCRYPT_KEY);
|
encryptData(encryptedData, DEFAULT_ENCRYPT_KEY);
|
||||||
|
|
||||||
uint64_t dataSize = encryptedData.size();
|
uint64_t dataSize = encryptedData.size();
|
||||||
file.write(reinterpret_cast<const char*>(&dataSize), sizeof(dataSize));
|
file.write(reinterpret_cast<const char*>(&dataSize), sizeof(dataSize));
|
||||||
file.write(reinterpret_cast<const char*>(encryptedData.data()), dataSize);
|
file.write(reinterpret_cast<const char*>(encryptedData.data()), dataSize);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,25 +130,25 @@ bool ResourcePack::addFile(const std::string& filename, const std::string& filep
|
|||||||
std::cerr << "Error: Could not open file: " << filepath << std::endl;
|
std::cerr << "Error: Could not open file: " << filepath << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::streamsize fileSize = file.tellg();
|
std::streamsize fileSize = file.tellg();
|
||||||
file.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
std::vector<uint8_t> fileData(fileSize);
|
std::vector<uint8_t> fileData(fileSize);
|
||||||
if (!file.read(reinterpret_cast<char*>(fileData.data()), fileSize)) {
|
if (!file.read(reinterpret_cast<char*>(fileData.data()), fileSize)) {
|
||||||
std::cerr << "Error: Could not read file: " << filepath << std::endl;
|
std::cerr << "Error: Could not read file: " << filepath << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceEntry entry;
|
ResourceEntry entry;
|
||||||
entry.filename = filename;
|
entry.filename = filename;
|
||||||
entry.offset = data.size();
|
entry.offset = data.size();
|
||||||
entry.size = fileData.size();
|
entry.size = fileData.size();
|
||||||
entry.checksum = calculateChecksum(fileData);
|
entry.checksum = calculateChecksum(fileData);
|
||||||
|
|
||||||
data.insert(data.end(), fileData.begin(), fileData.end());
|
data.insert(data.end(), fileData.begin(), fileData.end());
|
||||||
resources[filename] = entry;
|
resources[filename] = entry;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,20 +157,20 @@ bool ResourcePack::addDirectory(const std::string& directory) {
|
|||||||
std::cerr << "Error: Directory does not exist: " << directory << std::endl;
|
std::cerr << "Error: Directory does not exist: " << directory << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(directory)) {
|
for (const auto& entry : std::filesystem::recursive_directory_iterator(directory)) {
|
||||||
if (entry.is_regular_file()) {
|
if (entry.is_regular_file()) {
|
||||||
std::string filepath = entry.path().string();
|
std::string filepath = entry.path().string();
|
||||||
std::string filename = std::filesystem::relative(entry.path(), directory).string();
|
std::string filename = std::filesystem::relative(entry.path(), directory).string();
|
||||||
|
|
||||||
std::replace(filename.begin(), filename.end(), '\\', '/');
|
std::replace(filename.begin(), filename.end(), '\\', '/');
|
||||||
|
|
||||||
if (!addFile(filename, filepath)) {
|
if (!addFile(filename, filepath)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,21 +180,21 @@ std::vector<uint8_t> ResourcePack::getResource(const std::string& filename) {
|
|||||||
std::cerr << "Error: Resource not found: " << filename << std::endl;
|
std::cerr << "Error: Resource not found: " << filename << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResourceEntry& entry = it->second;
|
const ResourceEntry& entry = it->second;
|
||||||
if (entry.offset + entry.size > data.size()) {
|
if (entry.offset + entry.size > data.size()) {
|
||||||
std::cerr << "Error: Invalid resource data: " << filename << std::endl;
|
std::cerr << "Error: Invalid resource data: " << filename << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> result(data.begin() + entry.offset,
|
std::vector<uint8_t> result(data.begin() + entry.offset,
|
||||||
data.begin() + entry.offset + entry.size);
|
data.begin() + entry.offset + entry.size);
|
||||||
|
|
||||||
uint32_t checksum = calculateChecksum(result);
|
uint32_t checksum = calculateChecksum(result);
|
||||||
if (checksum != entry.checksum) {
|
if (checksum != entry.checksum) {
|
||||||
std::cerr << "Warning: Checksum mismatch for resource: " << filename << std::endl;
|
std::cerr << "Warning: Checksum mismatch for resource: " << filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,10 +215,10 @@ size_t ResourcePack::getResourceCount() const {
|
|||||||
std::vector<std::string> ResourcePack::getResourceList() const {
|
std::vector<std::string> ResourcePack::getResourceList() const {
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
result.reserve(resources.size());
|
result.reserve(resources.size());
|
||||||
|
|
||||||
for (const auto& [filename, entry] : resources) {
|
for (const auto& [filename, entry] : resources) {
|
||||||
result.push_back(filename);
|
result.push_back(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1,46 +1,46 @@
|
|||||||
#ifndef RESOURCE_PACK_H
|
#ifndef RESOURCE_PACK_H
|
||||||
#define RESOURCE_PACK_H
|
#define RESOURCE_PACK_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
struct ResourceEntry {
|
struct ResourceEntry {
|
||||||
std::string filename;
|
std::string filename;
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResourcePack {
|
class ResourcePack {
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, ResourceEntry> resources;
|
std::unordered_map<std::string, ResourceEntry> resources;
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
bool loaded;
|
bool loaded;
|
||||||
|
|
||||||
uint32_t calculateChecksum(const std::vector<uint8_t>& data);
|
|
||||||
void encryptData(std::vector<uint8_t>& data, const std::string& key);
|
|
||||||
void decryptData(std::vector<uint8_t>& data, const std::string& key);
|
|
||||||
|
|
||||||
public:
|
uint32_t calculateChecksum(const std::vector<uint8_t>& data);
|
||||||
ResourcePack();
|
void encryptData(std::vector<uint8_t>& data, const std::string& key);
|
||||||
~ResourcePack();
|
void decryptData(std::vector<uint8_t>& data, const std::string& key);
|
||||||
|
|
||||||
bool loadPack(const std::string& packFile);
|
public:
|
||||||
bool savePack(const std::string& packFile);
|
ResourcePack();
|
||||||
|
~ResourcePack();
|
||||||
bool addFile(const std::string& filename, const std::string& filepath);
|
|
||||||
bool addDirectory(const std::string& directory);
|
bool loadPack(const std::string& packFile);
|
||||||
|
bool savePack(const std::string& packFile);
|
||||||
std::vector<uint8_t> getResource(const std::string& filename);
|
|
||||||
bool hasResource(const std::string& filename) const;
|
bool addFile(const std::string& filename, const std::string& filepath);
|
||||||
|
bool addDirectory(const std::string& directory);
|
||||||
void clear();
|
|
||||||
size_t getResourceCount() const;
|
std::vector<uint8_t> getResource(const std::string& filename);
|
||||||
std::vector<std::string> getResourceList() const;
|
bool hasResource(const std::string& filename) const;
|
||||||
|
|
||||||
static const std::string DEFAULT_ENCRYPT_KEY;
|
void clear();
|
||||||
|
size_t getResourceCount() const;
|
||||||
|
std::vector<std::string> getResourceList() const;
|
||||||
|
|
||||||
|
static const std::string DEFAULT_ENCRYPT_KEY;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -37,7 +37,11 @@ auto Scoreboard::get() -> Scoreboard * {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Scoreboard::Scoreboard()
|
Scoreboard::Scoreboard()
|
||||||
: renderer_(Screen::get()->getRenderer()), game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")), power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)), text_(Resource::get()->getText("8bithud")), enter_name_text_(Resource::get()->getText("smb2")) {
|
: renderer_(Screen::get()->getRenderer()),
|
||||||
|
game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")),
|
||||||
|
power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)),
|
||||||
|
text_(Resource::get()->getText("8bithud")),
|
||||||
|
enter_name_text_(Resource::get()->getText("smb2")) {
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
for (size_t i = 0; i < static_cast<size_t>(Id::SIZE); ++i) {
|
for (size_t i = 0; i < static_cast<size_t>(Id::SIZE); ++i) {
|
||||||
name_.at(i).clear();
|
name_.at(i).clear();
|
||||||
|
|||||||
@@ -91,7 +91,11 @@ class Screen {
|
|||||||
Color color; // Color del flash
|
Color color; // Color del flash
|
||||||
|
|
||||||
explicit FlashEffect(bool enabled = false, int length = 0, int delay = 0, Color color = Color(0xFF, 0xFF, 0xFF))
|
explicit FlashEffect(bool enabled = false, int length = 0, int delay = 0, Color color = Color(0xFF, 0xFF, 0xFF))
|
||||||
: enabled(enabled), length(length), delay(delay), counter(length), color(color) {}
|
: enabled(enabled),
|
||||||
|
length(length),
|
||||||
|
delay(delay),
|
||||||
|
counter(length),
|
||||||
|
color(color) {}
|
||||||
|
|
||||||
void update() { (enabled && counter > 0) ? counter-- : static_cast<int>(enabled = false); }
|
void update() { (enabled && counter > 0) ? counter-- : static_cast<int>(enabled = false); }
|
||||||
[[nodiscard]] auto isRendarable() const -> bool { return enabled && counter < length - delay; }
|
[[nodiscard]] auto isRendarable() const -> bool { return enabled && counter < length - delay; }
|
||||||
@@ -109,7 +113,14 @@ class Screen {
|
|||||||
bool enabled; // Indica si el efecto está activo
|
bool enabled; // Indica si el efecto está activo
|
||||||
|
|
||||||
explicit ShakeEffect(bool en = false, int dp = 2, int dl = 3, int cnt = 0, int len = 8, int rem = 0, int orig_pos = 0, int orig_width = 800)
|
explicit ShakeEffect(bool en = false, int dp = 2, int dl = 3, int cnt = 0, int len = 8, int rem = 0, int orig_pos = 0, int orig_width = 800)
|
||||||
: desp(dp), delay(dl), counter(cnt), length(len), remaining(rem), original_pos(orig_pos), original_width(orig_width), enabled(en) {}
|
: desp(dp),
|
||||||
|
delay(dl),
|
||||||
|
counter(cnt),
|
||||||
|
length(len),
|
||||||
|
remaining(rem),
|
||||||
|
original_pos(orig_pos),
|
||||||
|
original_width(orig_width),
|
||||||
|
enabled(en) {}
|
||||||
|
|
||||||
// Activa el efecto de sacudida y guarda la posición y tamaño originales
|
// Activa el efecto de sacudida y guarda la posición y tamaño originales
|
||||||
void enable(SDL_FRect &src_rect, SDL_FRect &dst_rect, int new_desp = -1, int new_delay = -1, int new_length = -1) {
|
void enable(SDL_FRect &src_rect, SDL_FRect &dst_rect, int new_desp = -1, int new_delay = -1, int new_length = -1) {
|
||||||
|
|||||||
@@ -35,7 +35,12 @@ constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner";
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Credits::Credits()
|
Credits::Credits()
|
||||||
: balloon_manager_(std::make_unique<BalloonManager>(nullptr)), tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::DIAGONAL)), fade_in_(std::make_unique<Fade>()), fade_out_(std::make_unique<Fade>()), text_texture_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, static_cast<int>(param.game.width), static_cast<int>(param.game.height))), canvas_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, static_cast<int>(param.game.width), static_cast<int>(param.game.height))) {
|
: balloon_manager_(std::make_unique<BalloonManager>(nullptr)),
|
||||||
|
tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::DIAGONAL)),
|
||||||
|
fade_in_(std::make_unique<Fade>()),
|
||||||
|
fade_out_(std::make_unique<Fade>()),
|
||||||
|
text_texture_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, static_cast<int>(param.game.width), static_cast<int>(param.game.height))),
|
||||||
|
canvas_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, static_cast<int>(param.game.width), static_cast<int>(param.game.height))) {
|
||||||
if (text_texture_ == nullptr) {
|
if (text_texture_ == nullptr) {
|
||||||
throw std::runtime_error("Failed to create SDL texture for text.");
|
throw std::runtime_error("Failed to create SDL texture for text.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,18 @@
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Game::Game(Player::Id player_id, int current_stage, bool demo)
|
Game::Game(Player::Id player_id, int current_stage, bool demo)
|
||||||
: renderer_(Screen::get()->getRenderer()), screen_(Screen::get()), input_(Input::get()), canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)), pause_manager_(std::make_unique<PauseManager>([this](bool is_paused) { onPauseStateChanged(is_paused); })), stage_manager_(std::make_unique<StageManager>()), balloon_manager_(std::make_unique<BalloonManager>(stage_manager_.get())), background_(std::make_unique<Background>(stage_manager_->getPowerNeededToReachStage(stage_manager_->getTotalStages() - 1))), fade_in_(std::make_unique<Fade>()), fade_out_(std::make_unique<Fade>()), tabe_(std::make_unique<Tabe>()), hit_(Hit(Resource::get()->getTexture("hit.png"))) {
|
: renderer_(Screen::get()->getRenderer()),
|
||||||
|
screen_(Screen::get()),
|
||||||
|
input_(Input::get()),
|
||||||
|
canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)),
|
||||||
|
pause_manager_(std::make_unique<PauseManager>([this](bool is_paused) { onPauseStateChanged(is_paused); })),
|
||||||
|
stage_manager_(std::make_unique<StageManager>()),
|
||||||
|
balloon_manager_(std::make_unique<BalloonManager>(stage_manager_.get())),
|
||||||
|
background_(std::make_unique<Background>(stage_manager_->getPowerNeededToReachStage(stage_manager_->getTotalStages() - 1))),
|
||||||
|
fade_in_(std::make_unique<Fade>()),
|
||||||
|
fade_out_(std::make_unique<Fade>()),
|
||||||
|
tabe_(std::make_unique<Tabe>()),
|
||||||
|
hit_(Hit(Resource::get()->getTexture("hit.png"))) {
|
||||||
// Pasa variables
|
// Pasa variables
|
||||||
demo_.enabled = demo;
|
demo_.enabled = demo;
|
||||||
|
|
||||||
|
|||||||
@@ -254,8 +254,8 @@ class Game {
|
|||||||
|
|
||||||
// --- Sistema de globos y enemigos ---
|
// --- Sistema de globos y enemigos ---
|
||||||
void handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std::shared_ptr<Player> &player); // Procesa destrucción de globo
|
void handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std::shared_ptr<Player> &player); // Procesa destrucción de globo
|
||||||
void handleTabeHitEffects(); // Gestiona efectos al golpear a Tabe
|
void handleTabeHitEffects(); // Gestiona efectos al golpear a Tabe
|
||||||
void checkAndUpdateBalloonSpeed(); // Ajusta velocidad de globos según progreso
|
void checkAndUpdateBalloonSpeed(); // Ajusta velocidad de globos según progreso
|
||||||
|
|
||||||
// --- Gestión de fases y progresión ---
|
// --- Gestión de fases y progresión ---
|
||||||
void updateStage(); // Verifica y actualiza cambio de fase
|
void updateStage(); // Verifica y actualiza cambio de fase
|
||||||
|
|||||||
@@ -29,7 +29,14 @@
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
HiScoreTable::HiScoreTable()
|
HiScoreTable::HiScoreTable()
|
||||||
: renderer_(Screen::get()->getRenderer()), backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), fade_(std::make_unique<Fade>()), background_(std::make_unique<Background>()), ticks_(0), view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}), fade_mode_(Fade::Mode::IN), background_fade_color_(Color(0, 0, 0)) {
|
: renderer_(Screen::get()->getRenderer()),
|
||||||
|
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
||||||
|
fade_(std::make_unique<Fade>()),
|
||||||
|
background_(std::make_unique<Background>()),
|
||||||
|
ticks_(0),
|
||||||
|
view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}),
|
||||||
|
fade_mode_(Fade::Mode::IN),
|
||||||
|
background_fade_color_(Color(0, 0, 0)) {
|
||||||
// Inicializa el resto
|
// Inicializa el resto
|
||||||
Section::name = Section::Name::HI_SCORE_TABLE;
|
Section::name = Section::Name::HI_SCORE_TABLE;
|
||||||
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
||||||
|
|||||||
@@ -26,7 +26,12 @@
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Instructions::Instructions()
|
Instructions::Instructions()
|
||||||
: renderer_(Screen::get()->getRenderer()), texture_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), text_(Resource::get()->getText("smb2")), tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::STATIC)), fade_(std::make_unique<Fade>()) {
|
: renderer_(Screen::get()->getRenderer()),
|
||||||
|
texture_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
||||||
|
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
||||||
|
text_(Resource::get()->getText("smb2")),
|
||||||
|
tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::STATIC)),
|
||||||
|
fade_(std::make_unique<Fade>()) {
|
||||||
// Configura las texturas
|
// Configura las texturas
|
||||||
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
||||||
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ struct Line { // Almacena información de línea animada
|
|||||||
|
|
||||||
// Constructor de Line
|
// Constructor de Line
|
||||||
Line(int y, float x, int direction)
|
Line(int y, float x, int direction)
|
||||||
: y(y), x(x), direction(direction) {}
|
: y(y),
|
||||||
|
x(x),
|
||||||
|
direction(direction) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clase Instructions
|
// Clase Instructions
|
||||||
|
|||||||
@@ -37,7 +37,13 @@ class Texture;
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Title::Title()
|
Title::Title()
|
||||||
: text_(Resource::get()->getText("smb2_grad")), fade_(std::make_unique<Fade>()), tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::RANDOM)), game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)), mini_logo_sprite_(std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"))), state_(TitleState::LOGO_ANIMATING), num_controllers_(Input::get()->getNumGamepads()) {
|
: text_(Resource::get()->getText("smb2_grad")),
|
||||||
|
fade_(std::make_unique<Fade>()),
|
||||||
|
tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::RANDOM)),
|
||||||
|
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
|
||||||
|
mini_logo_sprite_(std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"))),
|
||||||
|
state_(TitleState::LOGO_ANIMATING),
|
||||||
|
num_controllers_(Input::get()->getNumGamepads()) {
|
||||||
// Configura objetos
|
// Configura objetos
|
||||||
tiled_bg_->setColor(param.title.bg_color);
|
tiled_bg_->setColor(param.title.bg_color);
|
||||||
game_logo_->enable();
|
game_logo_->enable();
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ class Sprite {
|
|||||||
[[nodiscard]] auto getTexture() const -> std::shared_ptr<Texture> { return textures_.at(texture_index_); }
|
[[nodiscard]] auto getTexture() const -> std::shared_ptr<Texture> { return textures_.at(texture_index_); }
|
||||||
void setTexture(std::shared_ptr<Texture> texture) { textures_.at(texture_index_) = std::move(texture); }
|
void setTexture(std::shared_ptr<Texture> texture) { textures_.at(texture_index_) = std::move(texture); }
|
||||||
void addTexture(const std::shared_ptr<Texture>& texture) { textures_.push_back(texture); }
|
void addTexture(const std::shared_ptr<Texture>& texture) { textures_.push_back(texture); }
|
||||||
auto setActiveTexture(size_t index) -> bool; // Cambia la textura activa por índice
|
auto setActiveTexture(size_t index) -> bool; // Cambia la textura activa por índice
|
||||||
[[nodiscard]] auto getActiveTexture() const -> size_t { return texture_index_; } // Alias para getActiveTextureIndex
|
[[nodiscard]] auto getActiveTexture() const -> size_t { return texture_index_; } // Alias para getActiveTextureIndex
|
||||||
[[nodiscard]] auto getTextureCount() const -> size_t { return textures_.size(); } // Obtiene el número total de texturas
|
[[nodiscard]] auto getTextureCount() const -> size_t { return textures_.size(); } // Obtiene el número total de texturas
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <string_view> // Para string_view
|
#include <string_view> // Para string_view
|
||||||
|
|
||||||
#include "color.h" // Para Color
|
#include "color.h" // Para Color
|
||||||
#include "screen.h" // Para Screen
|
|
||||||
#include "sprite.h" // Para Sprite
|
|
||||||
#include "texture.h" // Para Texture
|
|
||||||
#include "utils.h" // Para getFileName, printWithDots
|
|
||||||
#include "resource_helper.h" // Para ResourceHelper
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
|
#include "screen.h" // Para Screen
|
||||||
|
#include "sprite.h" // Para Sprite
|
||||||
|
#include "texture.h" // Para Texture
|
||||||
|
#include "utils.h" // Para getFileName, printWithDots
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Text::Text(const std::shared_ptr<Texture> &texture, const std::string &text_file) {
|
Text::Text(const std::shared_ptr<Texture> &texture, const std::string &text_file) {
|
||||||
@@ -157,7 +157,7 @@ auto Text::writeToTexture(const std::string &text, int zoom, int kerning, int le
|
|||||||
auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, Color text_color, Uint8 shadow_distance, Color shadow_color, int length) -> std::shared_ptr<Texture> {
|
auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, Color text_color, Uint8 shadow_distance, Color shadow_color, int length) -> std::shared_ptr<Texture> {
|
||||||
auto *renderer = Screen::get()->getRenderer();
|
auto *renderer = Screen::get()->getRenderer();
|
||||||
auto texture = std::make_shared<Texture>(renderer);
|
auto texture = std::make_shared<Texture>(renderer);
|
||||||
|
|
||||||
// Calcula las dimensiones considerando los efectos
|
// Calcula las dimensiones considerando los efectos
|
||||||
auto base_width = Text::length(text, kerning);
|
auto base_width = Text::length(text, kerning);
|
||||||
auto base_height = box_height_;
|
auto base_height = box_height_;
|
||||||
@@ -165,10 +165,10 @@ auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, C
|
|||||||
auto height = base_height;
|
auto height = base_height;
|
||||||
auto offset_x = 0;
|
auto offset_x = 0;
|
||||||
auto offset_y = 0;
|
auto offset_y = 0;
|
||||||
|
|
||||||
const auto STROKED = ((flags & Text::STROKE) == Text::STROKE);
|
const auto STROKED = ((flags & Text::STROKE) == Text::STROKE);
|
||||||
const auto SHADOWED = ((flags & Text::SHADOW) == Text::SHADOW);
|
const auto SHADOWED = ((flags & Text::SHADOW) == Text::SHADOW);
|
||||||
|
|
||||||
if (STROKED) {
|
if (STROKED) {
|
||||||
// Para stroke, el texto se expande en todas las direcciones por shadow_distance
|
// Para stroke, el texto se expande en todas las direcciones por shadow_distance
|
||||||
width = base_width + (shadow_distance * 2);
|
width = base_width + (shadow_distance * 2);
|
||||||
@@ -180,7 +180,7 @@ auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, C
|
|||||||
width = base_width + shadow_distance;
|
width = base_width + shadow_distance;
|
||||||
height = base_height + shadow_distance;
|
height = base_height + shadow_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *temp = SDL_GetRenderTarget(renderer);
|
auto *temp = SDL_GetRenderTarget(renderer);
|
||||||
|
|
||||||
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||||
@@ -200,18 +200,18 @@ void Text::writeColored(int x, int y, const std::string &text, Color color, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Escribe el texto con colores usando un sprite específico
|
// Escribe el texto con colores usando un sprite específico
|
||||||
void Text::writeColoredWithSprite(Sprite* sprite, int x, int y, const std::string &text, Color color, int kerning, int length) {
|
void Text::writeColoredWithSprite(Sprite *sprite, int x, int y, const std::string &text, Color color, int kerning, int length) {
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
const std::string_view VISIBLE_TEXT = (length == -1) ? std::string_view(text) : std::string_view(text).substr(0, length);
|
const std::string_view VISIBLE_TEXT = (length == -1) ? std::string_view(text) : std::string_view(text).substr(0, length);
|
||||||
|
|
||||||
auto *texture = sprite->getTexture().get();
|
auto *texture = sprite->getTexture().get();
|
||||||
|
|
||||||
// Guarda el alpha original y aplica el nuevo
|
// Guarda el alpha original y aplica el nuevo
|
||||||
Uint8 original_alpha;
|
Uint8 original_alpha;
|
||||||
SDL_GetTextureAlphaMod(texture->getSDLTexture(), &original_alpha);
|
SDL_GetTextureAlphaMod(texture->getSDLTexture(), &original_alpha);
|
||||||
texture->setAlpha(color.a);
|
texture->setAlpha(color.a);
|
||||||
texture->setColor(color.r, color.g, color.b);
|
texture->setColor(color.r, color.g, color.b);
|
||||||
|
|
||||||
sprite->setY(y);
|
sprite->setY(y);
|
||||||
for (const auto CH : VISIBLE_TEXT) {
|
for (const auto CH : VISIBLE_TEXT) {
|
||||||
const auto INDEX = static_cast<unsigned char>(CH);
|
const auto INDEX = static_cast<unsigned char>(CH);
|
||||||
@@ -223,7 +223,7 @@ void Text::writeColoredWithSprite(Sprite* sprite, int x, int y, const std::strin
|
|||||||
shift += offset_[INDEX].w + kerning;
|
shift += offset_[INDEX].w + kerning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restaura los valores originales
|
// Restaura los valores originales
|
||||||
texture->setColor(255, 255, 255);
|
texture->setColor(255, 255, 255);
|
||||||
texture->setAlpha(255);
|
texture->setAlpha(255);
|
||||||
@@ -233,26 +233,26 @@ void Text::writeColoredWithSprite(Sprite* sprite, int x, int y, const std::strin
|
|||||||
void Text::writeStrokeWithAlpha(int x, int y, const std::string &text, int kerning, Color stroke_color, Uint8 shadow_distance, int length) {
|
void Text::writeStrokeWithAlpha(int x, int y, const std::string &text, int kerning, Color stroke_color, Uint8 shadow_distance, int length) {
|
||||||
auto *renderer = Screen::get()->getRenderer();
|
auto *renderer = Screen::get()->getRenderer();
|
||||||
auto *original_target = SDL_GetRenderTarget(renderer);
|
auto *original_target = SDL_GetRenderTarget(renderer);
|
||||||
|
|
||||||
// Calcula dimensiones de la textura temporal
|
// Calcula dimensiones de la textura temporal
|
||||||
auto text_width = Text::length(text, kerning);
|
auto text_width = Text::length(text, kerning);
|
||||||
auto text_height = box_height_;
|
auto text_height = box_height_;
|
||||||
auto temp_width = text_width + (shadow_distance * 2);
|
auto temp_width = text_width + (shadow_distance * 2);
|
||||||
auto temp_height = text_height + (shadow_distance * 2);
|
auto temp_height = text_height + (shadow_distance * 2);
|
||||||
|
|
||||||
// Crea textura temporal
|
// Crea textura temporal
|
||||||
auto temp_texture = std::make_shared<Texture>(renderer);
|
auto temp_texture = std::make_shared<Texture>(renderer);
|
||||||
temp_texture->createBlank(temp_width, temp_height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
temp_texture->createBlank(temp_width, temp_height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||||
temp_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
temp_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
// Renderiza el stroke en la textura temporal
|
// Renderiza el stroke en la textura temporal
|
||||||
temp_texture->setAsRenderTarget(renderer);
|
temp_texture->setAsRenderTarget(renderer);
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
// Selecciona el sprite apropiado para el stroke
|
// Selecciona el sprite apropiado para el stroke
|
||||||
auto *stroke_sprite = white_sprite_ ? white_sprite_.get() : sprite_.get();
|
auto *stroke_sprite = white_sprite_ ? white_sprite_.get() : sprite_.get();
|
||||||
|
|
||||||
// Renderiza stroke sin alpha (sólido) en textura temporal
|
// Renderiza stroke sin alpha (sólido) en textura temporal
|
||||||
Color solid_color = Color(stroke_color.r, stroke_color.g, stroke_color.b, 255);
|
Color solid_color = Color(stroke_color.r, stroke_color.g, stroke_color.b, 255);
|
||||||
for (int dist = 1; dist <= shadow_distance; ++dist) {
|
for (int dist = 1; dist <= shadow_distance; ++dist) {
|
||||||
@@ -262,10 +262,10 @@ void Text::writeStrokeWithAlpha(int x, int y, const std::string &text, int kerni
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restaura render target original
|
// Restaura render target original
|
||||||
SDL_SetRenderTarget(renderer, original_target);
|
SDL_SetRenderTarget(renderer, original_target);
|
||||||
|
|
||||||
// Renderiza la textura temporal con el alpha deseado
|
// Renderiza la textura temporal con el alpha deseado
|
||||||
temp_texture->setAlpha(stroke_color.a);
|
temp_texture->setAlpha(stroke_color.a);
|
||||||
temp_texture->render(x - shadow_distance, y - shadow_distance);
|
temp_texture->render(x - shadow_distance, y - shadow_distance);
|
||||||
@@ -378,20 +378,20 @@ auto Text::loadFile(const std::string &file_path) -> std::shared_ptr<Text::File>
|
|||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
std::istringstream stream;
|
std::istringstream stream;
|
||||||
bool using_resource_data = false;
|
bool using_resource_data = false;
|
||||||
|
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
std::string content(resource_data.begin(), resource_data.end());
|
std::string content(resource_data.begin(), resource_data.end());
|
||||||
stream.str(content);
|
stream.str(content);
|
||||||
using_resource_data = true;
|
using_resource_data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback a archivo directo
|
// Fallback a archivo directo
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
if (!using_resource_data) {
|
if (!using_resource_data) {
|
||||||
file.open(file_path);
|
file.open(file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream& input_stream = using_resource_data ? stream : static_cast<std::istream&>(file);
|
std::istream &input_stream = using_resource_data ? stream : static_cast<std::istream &>(file);
|
||||||
|
|
||||||
if ((using_resource_data && stream.good()) || (!using_resource_data && file.is_open() && file.good())) {
|
if ((using_resource_data && stream.good()) || (!using_resource_data && file.is_open() && file.good())) {
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class Text {
|
|||||||
static auto loadFile(const std::string &file_path) -> std::shared_ptr<Text::File>; // Llena una estructura Text::File desde un fichero
|
static auto loadFile(const std::string &file_path) -> std::shared_ptr<Text::File>; // Llena una estructura Text::File desde un fichero
|
||||||
|
|
||||||
// --- Métodos privados ---
|
// --- Métodos privados ---
|
||||||
void writeColoredWithSprite(Sprite* sprite, int x, int y, const std::string &text, Color color, int kerning = 1, int length = -1); // Escribe con un sprite específico
|
void writeColoredWithSprite(Sprite *sprite, int x, int y, const std::string &text, Color color, int kerning = 1, int length = -1); // Escribe con un sprite específico
|
||||||
void writeStrokeWithAlpha(int x, int y, const std::string &text, int kerning, Color stroke_color, Uint8 shadow_distance, int length = -1); // Escribe stroke con alpha correcto
|
void writeStrokeWithAlpha(int x, int y, const std::string &text, int kerning, Color stroke_color, Uint8 shadow_distance, int length = -1); // Escribe stroke con alpha correcto
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -12,11 +12,11 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "color.h" // Para getFileName, Color, printWithDots
|
#include "color.h" // Para getFileName, Color, printWithDots
|
||||||
#include "external/gif.h" // Para Gif
|
#include "external/gif.h" // Para Gif
|
||||||
#include "stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_alpha
|
|
||||||
#include "utils.h"
|
|
||||||
#include "resource_helper.h" // Para ResourceHelper
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
|
#include "stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_alpha
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Texture::Texture(SDL_Renderer *renderer, std::string path)
|
Texture::Texture(SDL_Renderer *renderer, std::string path)
|
||||||
@@ -66,18 +66,18 @@ auto Texture::loadFromFile(const std::string &file_path) -> bool {
|
|||||||
int height;
|
int height;
|
||||||
int orig_format;
|
int orig_format;
|
||||||
unsigned char *data = nullptr;
|
unsigned char *data = nullptr;
|
||||||
|
|
||||||
// Intentar cargar desde ResourceHelper primero
|
// Intentar cargar desde ResourceHelper primero
|
||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
data = stbi_load_from_memory(resource_data.data(), resource_data.size(), &width, &height, &orig_format, req_format);
|
data = stbi_load_from_memory(resource_data.data(), resource_data.size(), &width, &height, &orig_format, req_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback a filesystem directo
|
// Fallback a filesystem directo
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format);
|
data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", getFileName(file_path).c_str());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", getFileName(file_path).c_str());
|
||||||
throw std::runtime_error("Fichero no encontrado: " + getFileName(file_path));
|
throw std::runtime_error("Fichero no encontrado: " + getFileName(file_path));
|
||||||
@@ -226,7 +226,7 @@ auto Texture::loadSurface(const std::string &file_path) -> std::shared_ptr<Surfa
|
|||||||
unloadSurface();
|
unloadSurface();
|
||||||
|
|
||||||
std::vector<Uint8> buffer;
|
std::vector<Uint8> buffer;
|
||||||
|
|
||||||
// Intentar cargar desde ResourceHelper primero
|
// Intentar cargar desde ResourceHelper primero
|
||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
@@ -305,7 +305,7 @@ auto Texture::loadPaletteFromFile(const std::string &file_path) -> Palette {
|
|||||||
Palette palette;
|
Palette palette;
|
||||||
|
|
||||||
std::vector<Uint8> buffer;
|
std::vector<Uint8> buffer;
|
||||||
|
|
||||||
// Intentar cargar desde ResourceHelper primero
|
// Intentar cargar desde ResourceHelper primero
|
||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
@@ -328,7 +328,7 @@ auto Texture::loadPaletteFromFile(const std::string &file_path) -> Palette {
|
|||||||
throw std::runtime_error("Error al leer el fichero: " + file_path);
|
throw std::runtime_error("Error al leer el fichero: " + file_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printWithDots("Palette : ", getFileName(file_path), "[ LOADED ]");
|
printWithDots("Palette : ", getFileName(file_path), "[ LOADED ]");
|
||||||
|
|
||||||
// Usar la nueva función loadPalette, que devuelve un vector<uint32_t>
|
// Usar la nueva función loadPalette, que devuelve un vector<uint32_t>
|
||||||
@@ -380,13 +380,13 @@ auto Texture::readPalFile(const std::string &file_path) -> Palette {
|
|||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
std::istringstream stream;
|
std::istringstream stream;
|
||||||
bool using_resource_data = false;
|
bool using_resource_data = false;
|
||||||
|
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
std::string content(resource_data.begin(), resource_data.end());
|
std::string content(resource_data.begin(), resource_data.end());
|
||||||
stream.str(content);
|
stream.str(content);
|
||||||
using_resource_data = true;
|
using_resource_data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback a archivo directo
|
// Fallback a archivo directo
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
if (!using_resource_data) {
|
if (!using_resource_data) {
|
||||||
@@ -395,8 +395,8 @@ auto Texture::readPalFile(const std::string &file_path) -> Palette {
|
|||||||
throw std::runtime_error("No se pudo abrir el archivo .pal");
|
throw std::runtime_error("No se pudo abrir el archivo .pal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream& input_stream = using_resource_data ? stream : static_cast<std::istream&>(file);
|
std::istream &input_stream = using_resource_data ? stream : static_cast<std::istream &>(file);
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
int line_number = 0;
|
int line_number = 0;
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ struct Surface {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels) // NOLINT(modernize-avoid-c-arrays)
|
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels) // NOLINT(modernize-avoid-c-arrays)
|
||||||
: data(std::move(pixels)), w(width), h(height) {}
|
: data(std::move(pixels)),
|
||||||
|
w(width),
|
||||||
|
h(height) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clase Texture: gestiona texturas, paletas y renderizado
|
// Clase Texture: gestiona texturas, paletas y renderizado
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ class MenuOption {
|
|||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
MenuOption(std::string caption, ServiceMenu::SettingsGroup group, bool hidden = false)
|
MenuOption(std::string caption, ServiceMenu::SettingsGroup group, bool hidden = false)
|
||||||
: caption_(std::move(caption)), group_(group), hidden_(hidden) {}
|
: caption_(std::move(caption)),
|
||||||
|
group_(group),
|
||||||
|
hidden_(hidden) {}
|
||||||
virtual ~MenuOption() = default;
|
virtual ~MenuOption() = default;
|
||||||
|
|
||||||
// --- Getters ---
|
// --- Getters ---
|
||||||
@@ -52,7 +54,8 @@ class MenuOption {
|
|||||||
class BoolOption : public MenuOption {
|
class BoolOption : public MenuOption {
|
||||||
public:
|
public:
|
||||||
BoolOption(const std::string &cap, ServiceMenu::SettingsGroup grp, bool *var)
|
BoolOption(const std::string &cap, ServiceMenu::SettingsGroup grp, bool *var)
|
||||||
: MenuOption(cap, grp), linked_variable_(var) {}
|
: MenuOption(cap, grp),
|
||||||
|
linked_variable_(var) {}
|
||||||
|
|
||||||
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
|
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
|
||||||
[[nodiscard]] auto getValueAsString() const -> std::string override {
|
[[nodiscard]] auto getValueAsString() const -> std::string override {
|
||||||
@@ -74,7 +77,11 @@ class BoolOption : public MenuOption {
|
|||||||
class IntOption : public MenuOption {
|
class IntOption : public MenuOption {
|
||||||
public:
|
public:
|
||||||
IntOption(const std::string &cap, ServiceMenu::SettingsGroup grp, int *var, int min, int max, int step)
|
IntOption(const std::string &cap, ServiceMenu::SettingsGroup grp, int *var, int min, int max, int step)
|
||||||
: MenuOption(cap, grp), linked_variable_(var), min_value_(min), max_value_(max), step_value_(step) {}
|
: MenuOption(cap, grp),
|
||||||
|
linked_variable_(var),
|
||||||
|
min_value_(min),
|
||||||
|
max_value_(max),
|
||||||
|
step_value_(step) {}
|
||||||
|
|
||||||
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
|
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
|
||||||
[[nodiscard]] auto getValueAsString() const -> std::string override { return std::to_string(*linked_variable_); }
|
[[nodiscard]] auto getValueAsString() const -> std::string override { return std::to_string(*linked_variable_); }
|
||||||
@@ -150,7 +157,8 @@ class ListOption : public MenuOption {
|
|||||||
class FolderOption : public MenuOption {
|
class FolderOption : public MenuOption {
|
||||||
public:
|
public:
|
||||||
FolderOption(const std::string &cap, ServiceMenu::SettingsGroup grp, ServiceMenu::SettingsGroup target)
|
FolderOption(const std::string &cap, ServiceMenu::SettingsGroup grp, ServiceMenu::SettingsGroup target)
|
||||||
: MenuOption(cap, grp), target_group_(target) {}
|
: MenuOption(cap, grp),
|
||||||
|
target_group_(target) {}
|
||||||
|
|
||||||
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
|
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
|
||||||
[[nodiscard]] auto getTargetGroup() const -> ServiceMenu::SettingsGroup override { return target_group_; }
|
[[nodiscard]] auto getTargetGroup() const -> ServiceMenu::SettingsGroup override { return target_group_; }
|
||||||
@@ -162,7 +170,8 @@ class FolderOption : public MenuOption {
|
|||||||
class ActionOption : public MenuOption {
|
class ActionOption : public MenuOption {
|
||||||
public:
|
public:
|
||||||
ActionOption(const std::string &cap, ServiceMenu::SettingsGroup grp, std::function<void()> action, bool hidden = false)
|
ActionOption(const std::string &cap, ServiceMenu::SettingsGroup grp, std::function<void()> action, bool hidden = false)
|
||||||
: MenuOption(cap, grp, hidden), action_(std::move(action)) {}
|
: MenuOption(cap, grp, hidden),
|
||||||
|
action_(std::move(action)) {}
|
||||||
|
|
||||||
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
|
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
|
||||||
void executeAction() override {
|
void executeAction() override {
|
||||||
@@ -183,7 +192,11 @@ class ActionListOption : public MenuOption {
|
|||||||
using ActionExecutor = std::function<void()>;
|
using ActionExecutor = std::function<void()>;
|
||||||
|
|
||||||
ActionListOption(const std::string &caption, ServiceMenu::SettingsGroup group, std::vector<std::string> options, ValueGetter getter, ValueSetter setter, ActionExecutor action_executor, bool hidden = false)
|
ActionListOption(const std::string &caption, ServiceMenu::SettingsGroup group, std::vector<std::string> options, ValueGetter getter, ValueSetter setter, ActionExecutor action_executor, bool hidden = false)
|
||||||
: MenuOption(caption, group, hidden), options_(std::move(options)), value_getter_(std::move(getter)), value_setter_(std::move(setter)), action_executor_(std::move(action_executor)) {
|
: MenuOption(caption, group, hidden),
|
||||||
|
options_(std::move(options)),
|
||||||
|
value_getter_(std::move(getter)),
|
||||||
|
value_setter_(std::move(setter)),
|
||||||
|
action_executor_(std::move(action_executor)) {
|
||||||
updateCurrentIndex();
|
updateCurrentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ void MenuRenderer::ShowHideAnimation::stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MenuRenderer::MenuRenderer(const ServiceMenu *menu_state, std::shared_ptr<Text> element_text, std::shared_ptr<Text> title_text)
|
MenuRenderer::MenuRenderer(const ServiceMenu *menu_state, std::shared_ptr<Text> element_text, std::shared_ptr<Text> title_text)
|
||||||
: element_text_(std::move(element_text)), title_text_(std::move(title_text)) {
|
: element_text_(std::move(element_text)),
|
||||||
|
title_text_(std::move(title_text)) {
|
||||||
initializeMaxSizes();
|
initializeMaxSizes();
|
||||||
setPosition(param.game.game_area.center_x, param.game.game_area.center_y, PositionMode::CENTERED);
|
setPosition(param.game.game_area.center_x, param.game.game_area.center_y, PositionMode::CENTERED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,9 @@ class Notifier {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
explicit Notification()
|
explicit Notification()
|
||||||
: texture(nullptr), sprite(nullptr), rect{0, 0, 0, 0} {}
|
: texture(nullptr),
|
||||||
|
sprite(nullptr),
|
||||||
|
rect{0, 0, 0, 0} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ void ServiceMenu::toggle() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!enabled_) { // Si está cerrado, abrir
|
if (!enabled_) { // Si está cerrado, abrir
|
||||||
reset();
|
reset();
|
||||||
Options::gamepad_manager.assignAndLinkGamepads();
|
Options::gamepad_manager.assignAndLinkGamepads();
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
|
|
||||||
// Constructor: inicializa el renderizador, el texto y el color del mensaje
|
// Constructor: inicializa el renderizador, el texto y el color del mensaje
|
||||||
UIMessage::UIMessage(std::shared_ptr<Text> text_renderer, std::string message_text, const Color &color)
|
UIMessage::UIMessage(std::shared_ptr<Text> text_renderer, std::string message_text, const Color &color)
|
||||||
: text_renderer_(std::move(text_renderer)), text_(std::move(message_text)), color_(color) {}
|
: text_renderer_(std::move(text_renderer)),
|
||||||
|
text_(std::move(message_text)),
|
||||||
|
color_(color) {}
|
||||||
|
|
||||||
// Muestra el mensaje en la posición base_x, base_y con animación de entrada desde arriba
|
// Muestra el mensaje en la posición base_x, base_y con animación de entrada desde arriba
|
||||||
void UIMessage::show() {
|
void UIMessage::show() {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <string> // Para basic_string, allocator, string, operator==, operator+, char_traits
|
#include <string> // Para basic_string, allocator, string, operator==, operator+, char_traits
|
||||||
|
|
||||||
#include "lang.h" // Para getText
|
#include "lang.h" // Para getText
|
||||||
#include "resource_helper.h" // Para ResourceHelper
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
@@ -325,7 +325,7 @@ auto loadDemoDataFromFile(const std::string &file_path) -> DemoData {
|
|||||||
DemoData dd;
|
DemoData dd;
|
||||||
|
|
||||||
SDL_IOStream *file = nullptr;
|
SDL_IOStream *file = nullptr;
|
||||||
|
|
||||||
// Intentar cargar desde ResourceHelper primero
|
// Intentar cargar desde ResourceHelper primero
|
||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
@@ -334,7 +334,7 @@ auto loadDemoDataFromFile(const std::string &file_path) -> DemoData {
|
|||||||
// Fallback a filesystem directo
|
// Fallback a filesystem directo
|
||||||
file = SDL_IOFromFile(file_path.c_str(), "r+b");
|
file = SDL_IOFromFile(file_path.c_str(), "r+b");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", file_path.c_str());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", file_path.c_str());
|
||||||
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
||||||
|
|||||||
@@ -22,9 +22,14 @@ struct Overrides {
|
|||||||
|
|
||||||
struct Circle {
|
struct Circle {
|
||||||
int x, y, r; // Coordenadas y radio
|
int x, y, r; // Coordenadas y radio
|
||||||
Circle() : x(0), y(0), r(0) {}
|
Circle()
|
||||||
|
: x(0),
|
||||||
|
y(0),
|
||||||
|
r(0) {}
|
||||||
Circle(int x_coord, int y_coord, int radius)
|
Circle(int x_coord, int y_coord, int radius)
|
||||||
: x(x_coord), y(y_coord), r(radius) {}
|
: x(x_coord),
|
||||||
|
y(y_coord),
|
||||||
|
r(radius) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DemoKeys {
|
struct DemoKeys {
|
||||||
@@ -36,7 +41,12 @@ struct DemoKeys {
|
|||||||
Uint8 fire_right;
|
Uint8 fire_right;
|
||||||
|
|
||||||
explicit DemoKeys(Uint8 l = 0, Uint8 r = 0, Uint8 ni = 0, Uint8 f = 0, Uint8 fl = 0, Uint8 fr = 0)
|
explicit DemoKeys(Uint8 l = 0, Uint8 r = 0, Uint8 ni = 0, Uint8 f = 0, Uint8 fl = 0, Uint8 fr = 0)
|
||||||
: left(l), right(r), no_input(ni), fire(f), fire_left(fl), fire_right(fr) {}
|
: left(l),
|
||||||
|
right(r),
|
||||||
|
no_input(ni),
|
||||||
|
fire(f),
|
||||||
|
fire_left(fl),
|
||||||
|
fire_right(fr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Tipos ---
|
// --- Tipos ---
|
||||||
@@ -49,9 +59,16 @@ struct Demo {
|
|||||||
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo
|
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo
|
||||||
std::vector<DemoData> data; // Vector con diferentes sets de datos con los movimientos para la demo
|
std::vector<DemoData> data; // Vector con diferentes sets de datos con los movimientos para la demo
|
||||||
|
|
||||||
Demo() : enabled(false), recording(false), counter(0) {}
|
Demo()
|
||||||
|
: enabled(false),
|
||||||
|
recording(false),
|
||||||
|
counter(0) {}
|
||||||
Demo(bool e, bool r, int c, const DemoKeys &k, const std::vector<DemoData> &d)
|
Demo(bool e, bool r, int c, const DemoKeys &k, const std::vector<DemoData> &d)
|
||||||
: enabled(e), recording(r), counter(c), keys(k), data(d) {}
|
: enabled(e),
|
||||||
|
recording(r),
|
||||||
|
counter(c),
|
||||||
|
keys(k),
|
||||||
|
data(d) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Zone {
|
struct Zone {
|
||||||
|
|||||||
Reference in New Issue
Block a user