granera con sarna no pica
This commit is contained in:
@@ -115,15 +115,6 @@ categories:
|
||||
- name: GAME
|
||||
scope: game
|
||||
commands:
|
||||
- keyword: PLAYER
|
||||
handler: cmd_player
|
||||
description: "Player skin and color"
|
||||
usage: "PLAYER SKIN <name> | PLAYER COLOR <0-15>|DEFAULT"
|
||||
completions:
|
||||
PLAYER: [SKIN, COLOR]
|
||||
PLAYER SKIN: [DEFAULT, ABAD, BATMAN, CHIP, CONGO, JEANNINE, MUMMY, UPV_STUDENT]
|
||||
PLAYER COLOR: [DEFAULT]
|
||||
|
||||
- keyword: RESTART
|
||||
handler: cmd_restart
|
||||
description: Restart from the beginning
|
||||
|
||||
@@ -115,8 +115,8 @@ class Input {
|
||||
|
||||
private:
|
||||
// --- Constantes ---
|
||||
static constexpr Sint16 AXIS_THRESHOLD = 30000; // Umbral para ejes analógicos
|
||||
static constexpr Sint16 TRIGGER_THRESHOLD = 16384; // Umbral para triggers (50% del rango)
|
||||
static constexpr Sint16 AXIS_THRESHOLD = 20000; // Umbral on/off para ejes analógicos
|
||||
static constexpr Sint16 TRIGGER_THRESHOLD = 20000; // Umbral on/off para triggers
|
||||
static constexpr std::array<Action, 1> BUTTON_INPUTS = {Action::JUMP}; // Inputs que usan botones
|
||||
|
||||
// --- Métodos ---
|
||||
|
||||
@@ -108,7 +108,7 @@ void RenderInfo::render() const {
|
||||
|
||||
// Constantes visuales
|
||||
static constexpr Uint8 MSG_COLOR = 9; // PaletteColor::BRIGHT_GREEN
|
||||
static constexpr int TEXT_SIZE = 6;
|
||||
static constexpr int TEXT_SIZE = Console::TEXT_SIZE;
|
||||
static constexpr int PADDING_V = (TEXT_SIZE / 2) - 1;
|
||||
|
||||
// Fuente: preferir la de la consola si está disponible
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Defaults::Video {
|
||||
constexpr const char* PALETTE_NAME = "resurrect-64"; // Paleta por defecto
|
||||
constexpr const char* PALETTE_SORT = "original"; // Modo de ordenación de paleta por defecto
|
||||
constexpr bool LINEAR_UPSCALE = false; // Upscale NEAREST por defecto
|
||||
constexpr int DOWNSCALE_ALGO = 1; // Downscale Lanczos2 por defecto
|
||||
constexpr int DOWNSCALE_ALGO = 1; // Downscale por defecto (0=Bilinear, 1=Lanczos2, 2=Lanczos3)
|
||||
constexpr bool GPU_ACCELERATION = true; // Aceleración GPU activada por defecto
|
||||
} // namespace Defaults::Video
|
||||
|
||||
@@ -50,11 +50,24 @@ namespace Defaults::Audio {
|
||||
namespace Defaults::Music {
|
||||
constexpr float VOLUME = 0.8F; // Volumen por defecto de la musica
|
||||
constexpr bool ENABLED = true; // Musica habilitada por defecto
|
||||
|
||||
namespace Files {
|
||||
constexpr const char* TITLE_TRACK = "574071_EA_DTV.ogg";
|
||||
constexpr const char* GAME_TRACK = "574070_KUVO_Farewell_to_school.ogg";
|
||||
} // namespace Files
|
||||
} // namespace Defaults::Music
|
||||
|
||||
namespace Defaults::Sound {
|
||||
constexpr float VOLUME = 1.0F; // Volumen por defecto de los efectos de sonido
|
||||
constexpr bool ENABLED = true; // Sonido habilitado por defecto
|
||||
|
||||
namespace Files {
|
||||
constexpr const char* JUMP = "jump.wav";
|
||||
constexpr const char* LAND = "land.wav";
|
||||
constexpr const char* DEATH = "death.wav";
|
||||
constexpr const char* ITEM = "item.wav";
|
||||
constexpr const char* NOTIFY = "notify.wav";
|
||||
} // namespace Files
|
||||
} // namespace Defaults::Sound
|
||||
|
||||
namespace Defaults::Cheat {
|
||||
@@ -75,6 +88,7 @@ namespace Defaults::Controls {
|
||||
constexpr int GAMEPAD_BUTTON_LEFT = SDL_GAMEPAD_BUTTON_DPAD_LEFT; // Botón izquierda por defecto
|
||||
constexpr int GAMEPAD_BUTTON_RIGHT = SDL_GAMEPAD_BUTTON_DPAD_RIGHT; // Botón derecha por defecto
|
||||
constexpr int GAMEPAD_BUTTON_JUMP = SDL_GAMEPAD_BUTTON_WEST; // Botón salto por defecto
|
||||
constexpr Sint16 JOYSTICK_AXIS_THRESHOLD = 20000; // Umbral para ejes y triggers del gamepad
|
||||
} // namespace Defaults::Controls
|
||||
|
||||
namespace Defaults::Kiosk {
|
||||
@@ -98,12 +112,14 @@ namespace Defaults::Localization {
|
||||
|
||||
namespace Defaults::Game::Room {
|
||||
constexpr const char* INITIAL = "03.yaml"; // Habitación de inicio
|
||||
constexpr Uint8 ITEM_COLOR1 = 12; // Color principal de los items por defecto
|
||||
constexpr Uint8 ITEM_COLOR2 = 6; // Color secundario de los items por defecto
|
||||
} // namespace Defaults::Game::Room
|
||||
|
||||
namespace Defaults::Game::Player {
|
||||
constexpr int SPAWN_X = 25 * Tile::SIZE; // Posición X inicial
|
||||
constexpr int SPAWN_Y = 13 * Tile::SIZE; // Posición Y inicial
|
||||
constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial
|
||||
constexpr const char* SKIN = "default"; // Skin del jugador por defecto
|
||||
constexpr int COLOR = -1; // Color del jugador (-1 = automático según cheats)
|
||||
constexpr int SPAWN_X = 25 * Tile::SIZE; // Posición X inicial
|
||||
constexpr int SPAWN_Y = 13 * Tile::SIZE; // Posición Y inicial
|
||||
constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial
|
||||
constexpr const char* SKIN = "default"; // Skin del jugador por defecto
|
||||
constexpr const char* DEFAULT_ANIMATION = "player.yaml"; // Animación del skin por defecto
|
||||
} // namespace Defaults::Game::Player
|
||||
|
||||
@@ -204,7 +204,6 @@ void MapEditor::enter(std::shared_ptr<Room> room, std::shared_ptr<Player> player
|
||||
|
||||
// Forzar invencibilidad
|
||||
Options::cheats.invincible = Options::Cheat::State::ENABLED;
|
||||
player_->setColor();
|
||||
|
||||
// Aplicar el setting de render_info del editor
|
||||
if (settings_.show_render_info != RenderInfo::get()->isActive()) {
|
||||
@@ -246,7 +245,6 @@ void MapEditor::exit() {
|
||||
if (!reenter_) {
|
||||
// Solo restaurar en el exit final (no en cambio de room)
|
||||
Options::cheats.invincible = invincible_before_editor_;
|
||||
player_->setColor();
|
||||
|
||||
if (RenderInfo::get()->isActive() != render_info_before_editor_) {
|
||||
RenderInfo::get()->toggle();
|
||||
@@ -969,7 +967,7 @@ void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitiv
|
||||
auto dot = anim.rfind('.');
|
||||
if (dot != std::string::npos) { anim = anim.substr(0, dot); }
|
||||
|
||||
line2 = "enemy " + std::to_string(selected_enemy_) + ": " + anim + " c:" + std::to_string(e.color);
|
||||
line2 = "enemy " + std::to_string(selected_enemy_) + ": " + anim;
|
||||
line3 = "vx:" + std::to_string(static_cast<int>(e.vx)) +
|
||||
" vy:" + std::to_string(static_cast<int>(e.vy));
|
||||
if (e.flip) { line3 += " flip"; }
|
||||
@@ -1032,7 +1030,7 @@ auto MapEditor::getSetCompletions() const -> std::vector<std::string> {
|
||||
return {"TILE", "COUNTER"};
|
||||
}
|
||||
// Room
|
||||
return {"BGCOLOR", "ITEMCOLOR1", "ITEMCOLOR2", "CONVEYOR", "TILESET", "UP", "DOWN", "LEFT", "RIGHT"};
|
||||
return {"ITEMCOLOR1", "ITEMCOLOR2", "CONVEYOR", "TILESET", "UP", "DOWN", "LEFT", "RIGHT"};
|
||||
}
|
||||
|
||||
// Modifica una propiedad del enemigo seleccionado
|
||||
@@ -1062,21 +1060,7 @@ auto MapEditor::setEnemyProperty(const std::string& property, const std::string&
|
||||
}
|
||||
|
||||
if (property == "COLOR") {
|
||||
auto color = static_cast<Uint8>(safeStoi(value, 14));
|
||||
|
||||
// Intentar recrear el enemigo con el nuevo color
|
||||
Uint8 old_color = enemy.color;
|
||||
enemy.color = color;
|
||||
try {
|
||||
auto* enemy_mgr = room_->getEnemyManager();
|
||||
enemy_mgr->getEnemy(selected_enemy_) = std::make_shared<Enemy>(enemy);
|
||||
} catch (const std::exception& e) {
|
||||
enemy.color = old_color;
|
||||
return std::string("Error: ") + e.what();
|
||||
}
|
||||
|
||||
autosave();
|
||||
return "color: " + std::to_string(color);
|
||||
return "color property removed (legacy)";
|
||||
}
|
||||
|
||||
if (property == "VX") {
|
||||
@@ -1154,7 +1138,6 @@ auto MapEditor::addEnemy() -> std::string {
|
||||
new_enemy.y1 = static_cast<int>(CENTER_Y);
|
||||
new_enemy.x2 = static_cast<int>(CENTER_X + ROUTE_HALF);
|
||||
new_enemy.y2 = static_cast<int>(CENTER_Y);
|
||||
new_enemy.color = 14;
|
||||
new_enemy.flip = true;
|
||||
new_enemy.frame = -1;
|
||||
|
||||
|
||||
@@ -127,9 +127,6 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r
|
||||
out << " position1: {x: " << b1_x << ", y: " << b1_y << "}\n";
|
||||
out << " position2: {x: " << b2_x << ", y: " << b2_y << "}\n";
|
||||
|
||||
if (enemy.color != 14) {
|
||||
out << " color: " << static_cast<int>(enemy.color) << "\n";
|
||||
}
|
||||
if (enemy.flip) { out << " flip: true\n"; }
|
||||
if (enemy.mirror) { out << " mirror: true\n"; }
|
||||
if (enemy.frame != -1) { out << " frame: " << enemy.frame << "\n"; }
|
||||
|
||||
@@ -23,21 +23,17 @@ Enemy::Enemy(const Data& enemy)
|
||||
sprite_->setVelX(enemy.vx);
|
||||
sprite_->setVelY(enemy.vy);
|
||||
|
||||
const int FLIP = (should_flip_ && enemy.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) SDL flags are designed for bitwise OR
|
||||
applyFlipMirror(enemy.vx);
|
||||
|
||||
collider_ = getRect();
|
||||
|
||||
color_ = enemy.color;
|
||||
|
||||
// Coloca un frame al azar o el designado
|
||||
sprite_->setCurrentAnimationFrame((enemy.frame == -1) ? (rand() % sprite_->getCurrentAnimationSize()) : enemy.frame);
|
||||
}
|
||||
|
||||
// Pinta el enemigo en pantalla
|
||||
void Enemy::render() {
|
||||
sprite_->render(1, color_);
|
||||
sprite_->render();
|
||||
}
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
@@ -60,9 +56,7 @@ void Enemy::resetToInitialPosition(const Data& data) {
|
||||
sprite_->setVelX(data.vx);
|
||||
sprite_->setVelY(data.vy);
|
||||
|
||||
const int FLIP = (should_flip_ && data.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
applyFlipMirror(data.vx);
|
||||
|
||||
collider_ = getRect();
|
||||
}
|
||||
@@ -105,6 +99,13 @@ void Enemy::checkPath() { // NOLINT(readability-make-member-function-const)
|
||||
}
|
||||
}
|
||||
|
||||
// Aplica flip horizontal y/o mirror vertical al sprite
|
||||
void Enemy::applyFlipMirror(float vx) {
|
||||
const int FLIP = (should_flip_ && vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) SDL flags are designed for bitwise OR
|
||||
}
|
||||
|
||||
// Devuelve el rectangulo que contiene al enemigo
|
||||
auto Enemy::getRect() -> SDL_FRect {
|
||||
return sprite_->getRect();
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <string> // Para string
|
||||
class AnimatedSprite; // lines 7-7
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <string> // Para string
|
||||
|
||||
class AnimatedSprite;
|
||||
|
||||
class Enemy {
|
||||
public:
|
||||
@@ -21,7 +22,6 @@ class Enemy {
|
||||
bool flip{false}; // Indica si el enemigo hace flip al terminar su ruta
|
||||
bool mirror{false}; // Indica si el enemigo está volteado verticalmente
|
||||
int frame{0}; // Frame inicial para la animación del enemigo
|
||||
Uint8 color{14}; // Color del enemigo (default: white=14)
|
||||
};
|
||||
|
||||
explicit Enemy(const Data& enemy); // Constructor
|
||||
@@ -38,12 +38,12 @@ class Enemy {
|
||||
auto getCollider() -> SDL_FRect&; // Obtiene el rectangulo de colision del enemigo
|
||||
|
||||
private:
|
||||
void checkPath(); // Comprueba si ha llegado al limite del recorrido para darse media vuelta
|
||||
void applyFlipMirror(float vx); // Aplica flip horizontal y/o mirror vertical al sprite
|
||||
void checkPath(); // Comprueba si ha llegado al limite del recorrido para darse media vuelta
|
||||
|
||||
std::shared_ptr<AnimatedSprite> sprite_; // Sprite del enemigo
|
||||
|
||||
// Variables
|
||||
Uint8 color_{0}; // Color del enemigo
|
||||
int x1_{0}; // Limite izquierdo de la ruta en el eje X
|
||||
int x2_{0}; // Limite derecho de la ruta en el eje X
|
||||
int y1_{0}; // Limite superior de la ruta en el eje Y
|
||||
|
||||
@@ -8,7 +8,7 @@ Item::Item(const Data& item)
|
||||
: sprite_(std::make_shared<Sprite>(Resource::Cache::get()->getSurface(item.tile_set_file), item.x, item.y, ITEM_SIZE, ITEM_SIZE)),
|
||||
time_accumulator_(static_cast<float>(item.counter) * COLOR_CHANGE_INTERVAL) {
|
||||
// Inicia variables
|
||||
sprite_->setClip((item.tile % 10) * ITEM_SIZE, (item.tile / 10) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE);
|
||||
sprite_->setClip((item.tile % TILESET_COLUMNS) * ITEM_SIZE, (item.tile / TILESET_COLUMNS) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE);
|
||||
collider_ = sprite_->getRect();
|
||||
|
||||
// Inicializa los colores
|
||||
@@ -52,7 +52,7 @@ void Item::setPosition(float x, float y) {
|
||||
#ifdef _DEBUG
|
||||
// Cambia el tile del item (para editor)
|
||||
void Item::setTile(int tile) {
|
||||
sprite_->setClip((tile % 10) * ITEM_SIZE, (tile / 10) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE);
|
||||
sprite_->setClip((tile % TILESET_COLUMNS) * ITEM_SIZE, (tile / TILESET_COLUMNS) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ class Item {
|
||||
|
||||
private:
|
||||
static constexpr float ITEM_SIZE = 8.0F; // Tamaño del item en pixels
|
||||
static constexpr int TILESET_COLUMNS = 10; // Columnas en la textura del tileset de items
|
||||
static constexpr float COLOR_CHANGE_INTERVAL = 0.06F; // Intervalo de cambio de color en segundos (4 frames a 66.67fps)
|
||||
|
||||
std::shared_ptr<Sprite> sprite_; // SSprite del objeto
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "core/input/input.hpp" // Para Input, InputAction
|
||||
#include "core/rendering/sprite/animated_sprite.hpp" // Para AnimatedSprite
|
||||
#include "core/resources/resource_cache.hpp" // Para Resource
|
||||
#include "game/defaults.hpp" // Para Defaults::Game::Player, Defaults::Sound::Files
|
||||
#include "game/gameplay/room.hpp" // Para Room
|
||||
#include "game/gameplay/tile_collider.hpp" // Para TileCollider
|
||||
#include "game/options.hpp" // Para Cheat, Options
|
||||
@@ -24,7 +25,6 @@
|
||||
Player::Player(const Data& player)
|
||||
: room_(player.room) {
|
||||
initSprite(player.animations_path);
|
||||
setColor();
|
||||
applySpawnValues(player.spawn_data);
|
||||
placeSprite();
|
||||
initSounds();
|
||||
@@ -36,7 +36,7 @@ Player::Player(const Data& player)
|
||||
// ============================================================================
|
||||
|
||||
void Player::render() {
|
||||
sprite_->render(1, color_);
|
||||
sprite_->render();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -560,35 +560,14 @@ void Player::animate(float delta_time) { // NOLINT(readability-make-member-func
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Color y skin
|
||||
// Skin
|
||||
// ============================================================================
|
||||
|
||||
void Player::setColor(Uint8 color) {
|
||||
if (color != 0) {
|
||||
color_ = color;
|
||||
return;
|
||||
}
|
||||
if (Options::game.player_color >= 0) {
|
||||
color_ = static_cast<Uint8>(Options::game.player_color);
|
||||
} else {
|
||||
color_ = 14;
|
||||
}
|
||||
if (room_ != nullptr && color_ == room_->getBGColor()) {
|
||||
color_ = (room_->getBGColor() != 14) ? 14 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
auto Player::skinToAnimationPath(const std::string& skin_name) -> std::string {
|
||||
if (skin_name == "default") { return "player.yaml"; }
|
||||
if (skin_name == Defaults::Game::Player::SKIN) { return Defaults::Game::Player::DEFAULT_ANIMATION; }
|
||||
return skin_name + ".yaml";
|
||||
}
|
||||
|
||||
void Player::setSkin(const std::string& skin_name) {
|
||||
const auto FLIP = sprite_->getFlip();
|
||||
initSprite(skinToAnimationPath(skin_name));
|
||||
sprite_->setFlip(FLIP);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Inicialización
|
||||
// ============================================================================
|
||||
@@ -602,8 +581,8 @@ void Player::initSprite(const std::string& animations_path) { // NOLINT(readabi
|
||||
}
|
||||
|
||||
void Player::initSounds() { // NOLINT(readability-convert-member-functions-to-static)
|
||||
jump_sound_ = Resource::Cache::get()->getSound("jump.wav");
|
||||
land_sound_ = Resource::Cache::get()->getSound("land.wav");
|
||||
jump_sound_ = Resource::Cache::get()->getSound(Defaults::Sound::Files::JUMP);
|
||||
land_sound_ = Resource::Cache::get()->getSound(Defaults::Sound::Files::LAND);
|
||||
}
|
||||
|
||||
void Player::applySpawnValues(const SpawnData& spawn) {
|
||||
|
||||
@@ -67,8 +67,6 @@ class Player {
|
||||
auto getRect() -> SDL_FRect { return {.x = x_, .y = y_, .w = WIDTH, .h = HEIGHT}; }
|
||||
auto getCollider() -> SDL_FRect& { return collider_box_; }
|
||||
auto getSpawnParams() -> SpawnData { return {.x = x_, .y = y_, .vx = vx_, .vy = vy_, .last_grounded_position = last_grounded_position_, .state = state_, .flip = sprite_->getFlip()}; }
|
||||
void setColor(Uint8 color = 0);
|
||||
void setSkin(const std::string& skin_name);
|
||||
static auto skinToAnimationPath(const std::string& skin_name) -> std::string;
|
||||
void setRoom(std::shared_ptr<Room> room) { room_ = std::move(room); }
|
||||
void setAdjacentRoom(std::shared_ptr<Room> room, Room::Border direction);
|
||||
@@ -134,7 +132,6 @@ class Player {
|
||||
int last_grounded_position_ = 0;
|
||||
|
||||
// --- Renderizado y sonido ---
|
||||
Uint8 color_ = 0;
|
||||
JA_Sound_t* jump_sound_ = nullptr;
|
||||
JA_Sound_t* land_sound_ = nullptr;
|
||||
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace GameControl {
|
||||
// Disponible en todos los builds — cambia la skin del jugador ("default" o nombre de enemigo)
|
||||
inline std::function<void(const std::string&)> change_player_skin;
|
||||
// Disponible en todos los builds — cambia el color del jugador (-1 = automático, 0-15 = color fijo)
|
||||
inline std::function<void(int)> change_player_color;
|
||||
} // namespace GameControl
|
||||
|
||||
#ifdef _DEBUG
|
||||
namespace GameControl {
|
||||
// Registrada por Game::Game() — cambia la habitación activa
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "item_manager.hpp"
|
||||
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "game/defaults.hpp" // Para Defaults::Sound::Files
|
||||
#include "game/entities/item.hpp" // Para Item
|
||||
#include "game/options.hpp" // Para Options
|
||||
#include "item_tracker.hpp" // Para ItemTracker
|
||||
@@ -55,7 +56,7 @@ auto ItemManager::checkCollision(SDL_FRect& rect) -> bool { // NOLINT(readabili
|
||||
items_.erase(items_.begin() + i);
|
||||
|
||||
// Reproduce el sonido de pickup
|
||||
Audio::get()->playSound("item.wav", Audio::Group::GAME);
|
||||
Audio::get()->playSound(Defaults::Sound::Files::ITEM, Audio::Group::GAME);
|
||||
|
||||
// Actualiza el scoreboard y estadísticas
|
||||
data_->items++;
|
||||
|
||||
@@ -115,13 +115,6 @@ void Room::setTile(int index, int tile_value) {
|
||||
}
|
||||
}
|
||||
|
||||
// Cambia color de fondo y redibuja el mapa (para editor)
|
||||
void Room::setBgColor(Uint8 color) {
|
||||
bg_color_ = color;
|
||||
tilemap_renderer_->setBgColor(color);
|
||||
tilemap_renderer_->redrawMap(collision_map_->getCollisionTileMap());
|
||||
}
|
||||
|
||||
// Cambia colores de items en vivo (para editor)
|
||||
void Room::setItemColors(Uint8 color1, Uint8 color2) {
|
||||
item_color1_ = color1;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <string> // Para string
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "game/defaults.hpp" // Para Defaults::Game::Room
|
||||
#include "game/entities/enemy.hpp" // Para EnemyData
|
||||
#include "game/entities/item.hpp" // Para ItemData
|
||||
#include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data
|
||||
@@ -31,8 +32,8 @@ class Room {
|
||||
struct Data {
|
||||
std::string number;
|
||||
Uint8 bg_color{0};
|
||||
Uint8 item_color1{12};
|
||||
Uint8 item_color2{6};
|
||||
Uint8 item_color1{Defaults::Game::Room::ITEM_COLOR1};
|
||||
Uint8 item_color2{Defaults::Game::Room::ITEM_COLOR2};
|
||||
std::string upper_room;
|
||||
std::string lower_room;
|
||||
std::string left_room;
|
||||
@@ -61,7 +62,6 @@ class Room {
|
||||
void resetEnemyPositions(const std::vector<Enemy::Data>& enemy_data);
|
||||
auto getEnemyManager() -> EnemyManager* { return enemy_manager_.get(); }
|
||||
auto getItemManager() -> ItemManager* { return item_manager_.get(); }
|
||||
void setBgColor(Uint8 color);
|
||||
void setItemColors(Uint8 color1, Uint8 color2);
|
||||
void setTile(int index, int tile_value);
|
||||
[[nodiscard]] auto getTileSetFile() const -> const std::string& { return tile_set_file_; }
|
||||
@@ -92,8 +92,8 @@ class Room {
|
||||
|
||||
std::string number_;
|
||||
Uint8 bg_color_{0};
|
||||
Uint8 item_color1_{12};
|
||||
Uint8 item_color2_{6};
|
||||
Uint8 item_color1_{Defaults::Game::Room::ITEM_COLOR1};
|
||||
Uint8 item_color2_{Defaults::Game::Room::ITEM_COLOR2};
|
||||
std::string upper_room_;
|
||||
std::string lower_room_;
|
||||
std::string left_room_;
|
||||
|
||||
@@ -236,11 +236,6 @@ auto RoomLoader::parseEnemyData(const fkyaml::node& enemy_node) -> Enemy::Data {
|
||||
parseEnemyBoundaries(enemy_node["boundaries"], enemy);
|
||||
}
|
||||
|
||||
// Color
|
||||
if (enemy_node.contains("color")) {
|
||||
enemy.color = readColorNode(enemy_node["color"]);
|
||||
}
|
||||
|
||||
// Optional fields
|
||||
enemy.flip = enemy_node.contains("flip")
|
||||
? enemy_node["flip"].get_value_or<bool>(false)
|
||||
|
||||
@@ -62,8 +62,7 @@ void TilemapRenderer::setTile(int index, int tile_value) {
|
||||
map_surface_->fillRect(&cell, bg_color_);
|
||||
|
||||
if (tile_value > -1) {
|
||||
const bool IS_ANIMATED = (tile_value >= 18 * tile_set_width_) && (tile_value < 19 * tile_set_width_);
|
||||
if (!IS_ANIMATED) {
|
||||
if (!isAnimatedTile(tile_value)) {
|
||||
SDL_FRect clip = {.x = static_cast<float>((tile_value % tile_set_width_) * TILE_SIZE),
|
||||
.y = static_cast<float>((tile_value / tile_set_width_) * TILE_SIZE),
|
||||
.w = static_cast<float>(TILE_SIZE),
|
||||
@@ -107,11 +106,10 @@ void TilemapRenderer::fillMapTexture(const std::vector<int>& collision_tile_map)
|
||||
for (int y = 0; y < MAP_HEIGHT; ++y) {
|
||||
for (int x = 0; x < MAP_WIDTH; ++x) {
|
||||
const int INDEX = (y * MAP_WIDTH) + x;
|
||||
// Los tiles animados (fila 18 del tileset) no se pintan en la textura estática
|
||||
const bool IS_ANIMATED = (tile_map_[INDEX] >= 18 * tile_set_width_) && (tile_map_[INDEX] < 19 * tile_set_width_);
|
||||
// Los tiles animados no se pintan en la textura estática
|
||||
const bool HAS_TILE = tile_map_[INDEX] > -1;
|
||||
|
||||
if (HAS_TILE && !IS_ANIMATED) {
|
||||
if (HAS_TILE && !isAnimatedTile(tile_map_[INDEX])) {
|
||||
clip.x = (tile_map_[INDEX] % tile_set_width_) * TILE_SIZE;
|
||||
clip.y = (tile_map_[INDEX] / tile_set_width_) * TILE_SIZE;
|
||||
#ifdef _DEBUG
|
||||
@@ -145,8 +143,8 @@ void TilemapRenderer::setAnimatedTiles(const std::vector<int>& collision_tile_ma
|
||||
const int YC = (tile_map_[i] / tile_set_width_) * TILE_SIZE;
|
||||
|
||||
AnimatedTile at;
|
||||
at.sprite = std::make_shared<Sprite>(tileset_surface_, X, Y, 8, 8);
|
||||
at.sprite->setClip(XC, YC, 8, 8);
|
||||
at.sprite = std::make_shared<Sprite>(tileset_surface_, X, Y, TILE_SIZE, TILE_SIZE);
|
||||
at.sprite->setClip(XC, YC, TILE_SIZE, TILE_SIZE);
|
||||
at.x_orig = XC;
|
||||
animated_tiles_.push_back(at);
|
||||
}
|
||||
@@ -176,3 +174,7 @@ void TilemapRenderer::renderAnimatedTiles() {
|
||||
a.sprite->render();
|
||||
}
|
||||
}
|
||||
|
||||
auto TilemapRenderer::isAnimatedTile(int tile_value) const -> bool {
|
||||
return (tile_value >= ANIMATED_TILE_ROW * tile_set_width_) && (tile_value < (ANIMATED_TILE_ROW + 1) * tile_set_width_);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ class TilemapRenderer {
|
||||
|
||||
#ifdef _DEBUG
|
||||
void redrawMap(const std::vector<int>& collision_tile_map);
|
||||
void setBgColor(Uint8 color) { bg_color_ = color; }
|
||||
void setTile(int index, int tile_value);
|
||||
#endif
|
||||
|
||||
@@ -46,6 +45,9 @@ class TilemapRenderer {
|
||||
static constexpr int PLAY_AREA_HEIGHT = PlayArea::HEIGHT;
|
||||
static constexpr float CONVEYOR_FRAME_DURATION = 0.05F;
|
||||
static constexpr int COLLISION_ANIMATED = 6; // Valor del tile de conveyor en el collision tilemap
|
||||
static constexpr int ANIMATED_TILE_ROW = 18; // Fila del tileset que contiene los tiles animados
|
||||
|
||||
[[nodiscard]] auto isAnimatedTile(int tile_value) const -> bool;
|
||||
|
||||
std::vector<int> tile_map_;
|
||||
int tile_set_width_;
|
||||
|
||||
@@ -512,28 +512,6 @@ namespace Options {
|
||||
}
|
||||
}
|
||||
|
||||
// Carga configuración del jugador desde YAML
|
||||
void loadPlayerConfigFromYaml(const fkyaml::node& yaml) {
|
||||
if (yaml.contains("player")) {
|
||||
const auto& player_node = yaml["player"];
|
||||
if (player_node.contains("skin")) {
|
||||
try {
|
||||
game.player_skin = player_node["skin"].get_value<std::string>();
|
||||
} catch (...) {
|
||||
game.player_skin = Defaults::Game::Player::SKIN;
|
||||
}
|
||||
}
|
||||
if (player_node.contains("color")) {
|
||||
try {
|
||||
int color = player_node["color"].get_value<int>();
|
||||
game.player_color = (color >= 0 && color <= 15) ? color : Defaults::Game::Player::COLOR;
|
||||
} catch (...) {
|
||||
game.player_color = Defaults::Game::Player::COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Carga configuración del modo kiosko desde YAML
|
||||
void loadKioskConfigFromYaml(const fkyaml::node& yaml) {
|
||||
if (yaml.contains("kiosk")) {
|
||||
@@ -670,7 +648,6 @@ namespace Options {
|
||||
loadAudioConfigFromYaml(yaml);
|
||||
loadKeyboardControlsFromYaml(yaml);
|
||||
loadGamepadControlsFromYaml(yaml);
|
||||
loadPlayerConfigFromYaml(yaml);
|
||||
loadKioskConfigFromYaml(yaml);
|
||||
loadLocalizationFromYaml(yaml);
|
||||
|
||||
@@ -792,11 +769,6 @@ namespace Options {
|
||||
|
||||
// KIOSK
|
||||
file << "\n";
|
||||
file << "# PLAYER\n";
|
||||
file << "player:\n";
|
||||
file << " skin: \"" << game.player_skin << "\"\n";
|
||||
file << " color: " << game.player_color << "\n";
|
||||
file << "\n";
|
||||
|
||||
file << "# KIOSK MODE\n";
|
||||
file << "kiosk:\n";
|
||||
|
||||
@@ -134,10 +134,8 @@ namespace Options {
|
||||
|
||||
// Estructura para las opciones de juego
|
||||
struct Game {
|
||||
float width{Defaults::Canvas::WIDTH}; // Ancho de la resolucion del juego
|
||||
float height{Defaults::Canvas::HEIGHT}; // Alto de la resolucion del juego
|
||||
std::string player_skin{Defaults::Game::Player::SKIN}; // Skin del jugador ("default" o nombre de enemigo)
|
||||
int player_color{Defaults::Game::Player::COLOR}; // Color del jugador (-1 = automático, 0-15 = color fijo)
|
||||
float width{Defaults::Canvas::WIDTH}; // Ancho de la resolucion del juego
|
||||
float height{Defaults::Canvas::HEIGHT}; // Alto de la resolucion del juego
|
||||
};
|
||||
|
||||
// Estructura para un preset de PostFX
|
||||
|
||||
@@ -80,15 +80,6 @@ Game::Game(Mode mode)
|
||||
Console::get()->on_toggle = [this](bool open) { player_->setIgnoreInput(open); };
|
||||
if (Console::get()->isActive()) { player_->setIgnoreInput(true); }
|
||||
}
|
||||
GameControl::change_player_skin = [this](const std::string& skin_name) -> void {
|
||||
Options::game.player_skin = skin_name;
|
||||
player_->setSkin(skin_name);
|
||||
};
|
||||
GameControl::change_player_color = [this](int color) -> void {
|
||||
Options::game.player_color = color;
|
||||
player_->setColor();
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
GameControl::change_room = [this](const std::string& r) -> bool { return this->changeRoom(r); };
|
||||
GameControl::get_current_room = [this]() -> std::string { return current_room_; };
|
||||
@@ -108,7 +99,6 @@ Game::Game(Mode mode)
|
||||
} else {
|
||||
Options::cheats.invincible = invincible_before_debug_ ? Options::Cheat::State::ENABLED : Options::Cheat::State::DISABLED;
|
||||
}
|
||||
player_->setColor();
|
||||
scoreboard_data_->music = !Debug::get()->isEnabled();
|
||||
scoreboard_data_->music ? Audio::get()->resumeMusic() : Audio::get()->pauseMusic();
|
||||
};
|
||||
@@ -172,8 +162,6 @@ Game::~Game() {
|
||||
|
||||
ItemTracker::destroy();
|
||||
|
||||
GameControl::change_player_skin = nullptr;
|
||||
GameControl::change_player_color = nullptr;
|
||||
if (Console::get() != nullptr) { Console::get()->on_toggle = nullptr; }
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -646,12 +634,10 @@ void Game::handleDebugEvents(const SDL_Event& event) { // NOLINT(readability-co
|
||||
|
||||
case SDLK_1:
|
||||
toggleCheat(Options::cheats.infinite_lives, Locale::get()->get("game.cheat_infinite_lives")); // NOLINT(readability-static-accessed-through-instance)
|
||||
player_->setColor();
|
||||
break;
|
||||
|
||||
case SDLK_2:
|
||||
toggleCheat(Options::cheats.invincible, Locale::get()->get("game.cheat_invincible")); // NOLINT(readability-static-accessed-through-instance)
|
||||
player_->setColor();
|
||||
break;
|
||||
|
||||
case SDLK_7:
|
||||
@@ -671,7 +657,6 @@ void Game::handleDebugEvents(const SDL_Event& event) { // NOLINT(readability-co
|
||||
} else {
|
||||
Options::cheats.invincible = invincible_before_debug_ ? Options::Cheat::State::ENABLED : Options::Cheat::State::DISABLED;
|
||||
}
|
||||
player_->setColor();
|
||||
scoreboard_data_->music = !Debug::get()->isEnabled();
|
||||
scoreboard_data_->music ? Audio::get()->resumeMusic() : Audio::get()->pauseMusic();
|
||||
break;
|
||||
@@ -779,9 +764,6 @@ auto Game::changeRoom(const std::string& room_path) -> bool {
|
||||
// Pasa la nueva habitación al jugador
|
||||
player_->setRoom(room_);
|
||||
|
||||
// Recalcula el color del jugador (evita coincidir con el fondo)
|
||||
player_->setColor();
|
||||
|
||||
// Cambia la habitación actual
|
||||
current_room_ = room_path;
|
||||
|
||||
@@ -938,7 +920,7 @@ void Game::killPlayer() {
|
||||
}
|
||||
|
||||
// Sonido
|
||||
Audio::get()->playSound("death.wav", Audio::Group::GAME);
|
||||
Audio::get()->playSound(Defaults::Sound::Files::DEATH, Audio::Group::GAME);
|
||||
|
||||
// Transicionar al estado BLACK_SCREEN (el respawn ocurre en transitionToState)
|
||||
transitionToState(State::BLACK_SCREEN);
|
||||
@@ -956,7 +938,7 @@ void Game::togglePause() {
|
||||
// Inicializa al jugador
|
||||
void Game::initPlayer(const Player::SpawnData& spawn_point, std::shared_ptr<Room> room) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
const bool IGNORE_INPUT = player_ != nullptr && player_->getIgnoreInput();
|
||||
std::string player_animations = Player::skinToAnimationPath(Options::game.player_skin);
|
||||
std::string player_animations = Player::skinToAnimationPath(Defaults::Game::Player::SKIN);
|
||||
const Player::Data PLAYER{.spawn_data = spawn_point, .animations_path = player_animations, .room = std::move(room)};
|
||||
player_ = std::make_shared<Player>(PLAYER);
|
||||
if (IGNORE_INPUT) { player_->setIgnoreInput(true); }
|
||||
@@ -964,7 +946,7 @@ void Game::initPlayer(const Player::SpawnData& spawn_point, std::shared_ptr<Room
|
||||
|
||||
// Hace sonar la música
|
||||
void Game::keepMusicPlaying() {
|
||||
const std::string MUSIC_PATH = mode_ == Mode::GAME ? "574070_KUVO_Farewell_to_school.ogg" : "574071_EA_DTV.ogg";
|
||||
const std::string MUSIC_PATH = mode_ == Mode::GAME ? Defaults::Music::Files::GAME_TRACK : Defaults::Music::Files::TITLE_TRACK;
|
||||
|
||||
// Si la música no está sonando
|
||||
if (Audio::get()->getMusicState() == Audio::MusicState::STOPPED) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "core/resources/resource_list.hpp" // Para Asset
|
||||
#include "core/system/event_buffer.hpp" // Para EventBuffer
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "game/defaults.hpp" // Para Defaults::Music::Files
|
||||
#include "game/options.hpp" // Para Options, options, SectionState, Section
|
||||
#include "game/scene_manager.hpp" // Para SceneManager
|
||||
#include "game/ui/console.hpp" // Para Console
|
||||
@@ -41,8 +42,8 @@ Title::Title()
|
||||
SceneManager::options = SceneManager::Options::NONE;
|
||||
|
||||
// Acciones iniciales
|
||||
Screen::get()->setBorderColor(0); // Cambia el color del borde
|
||||
Audio::get()->playMusic("574071_EA_DTV.ogg"); // Inicia la musica
|
||||
Screen::get()->setBorderColor(0); // Cambia el color del borde
|
||||
Audio::get()->playMusic(Defaults::Music::Files::TITLE_TRACK); // Inicia la musica
|
||||
}
|
||||
|
||||
// Destructor
|
||||
@@ -260,10 +261,6 @@ void Title::renderMainMenu() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Zona central del menu
|
||||
constexpr int MENU_ZONE_Y = 73;
|
||||
constexpr int MENU_ZONE_HEIGHT = 102;
|
||||
|
||||
// Menú principal normal con 3 opciones centradas verticalmente en la zona
|
||||
const Uint8 COLOR = 8;
|
||||
const int TEXT_SIZE = menu_text_->getCharacterSize();
|
||||
@@ -394,9 +391,6 @@ void Title::applyKeyboardRemap() { // NOLINT(readability-convert-member-functio
|
||||
// Dibuja la pantalla de redefinir teclado
|
||||
void Title::renderKeyboardRemap() const {
|
||||
// Zona central del menu
|
||||
constexpr int MENU_ZONE_Y = 73;
|
||||
constexpr int MENU_ZONE_HEIGHT = 102;
|
||||
|
||||
const Uint8 COLOR = 8;
|
||||
const Uint8 ERROR_COLOR = 4;
|
||||
const int TEXT_SIZE = menu_text_->getCharacterSize();
|
||||
@@ -441,10 +435,6 @@ void Title::renderKeyboardRemap() const {
|
||||
|
||||
// Dibuja la pantalla de redefinir joystick
|
||||
void Title::renderJoystickRemap() const {
|
||||
// Zona central del menu
|
||||
constexpr int MENU_ZONE_Y = 73;
|
||||
constexpr int MENU_ZONE_HEIGHT = 102;
|
||||
|
||||
const Uint8 COLOR = 8;
|
||||
const Uint8 ERROR_COLOR = 4;
|
||||
const int TEXT_SIZE = menu_text_->getCharacterSize();
|
||||
@@ -502,23 +492,20 @@ void Title::handleJoystickRemap(const SDL_Event& event) {
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr Sint16 TRIGGER_THRESHOLD = 20000;
|
||||
constexpr Sint16 AXIS_THRESHOLD = 20000;
|
||||
|
||||
// Capturar triggers como botones (usando valores especiales 100/101)
|
||||
if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) {
|
||||
if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER && event.gaxis.value > Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) {
|
||||
captured_button = Input::TRIGGER_L2_AS_BUTTON; // 100
|
||||
axis_cooldown_ = 0.5F; // Cooldown de medio segundo
|
||||
} else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) {
|
||||
} else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER && event.gaxis.value > Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) {
|
||||
captured_button = Input::TRIGGER_R2_AS_BUTTON; // 101
|
||||
axis_cooldown_ = 0.5F;
|
||||
}
|
||||
// Capturar ejes del stick analógico (usando valores especiales 200+)
|
||||
else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFTX) {
|
||||
if (event.gaxis.value < -AXIS_THRESHOLD) {
|
||||
if (event.gaxis.value < -Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) {
|
||||
captured_button = 200; // Left stick izquierda
|
||||
axis_cooldown_ = 0.5F;
|
||||
} else if (event.gaxis.value > AXIS_THRESHOLD) {
|
||||
} else if (event.gaxis.value > Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) {
|
||||
captured_button = 201; // Left stick derecha
|
||||
axis_cooldown_ = 0.5F;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ class Title {
|
||||
static constexpr float FADE_STEP_INTERVAL = 0.05F; // Intervalo entre pasos de fade (antes cada 4 frames)
|
||||
static constexpr float POST_FADE_DELAY = 1.0F; // Delay después del fade (pantalla en negro)
|
||||
static constexpr float KEYBOARD_REMAP_DISPLAY_DELAY = 2.0F; // Tiempo mostrando teclas definidas antes de guardar
|
||||
|
||||
// --- Constantes de layout del menú ---
|
||||
static constexpr int MENU_ZONE_Y = 73; // Coordenada Y de la zona de menú
|
||||
static constexpr int MENU_ZONE_HEIGHT = 102; // Alto de la zona de menú
|
||||
// --- Métodos ---
|
||||
void handleEvents(); // Comprueba el manejador de eventos
|
||||
void handleMainMenuKeyPress(SDL_Keycode key); // Maneja las teclas del menu principal
|
||||
|
||||
@@ -42,14 +42,13 @@ static auto parseTokens(const std::string& input) -> std::vector<std::string> {
|
||||
|
||||
// Calcula la altura total de la consola para N líneas de mensaje (+ 1 línea de input)
|
||||
static auto calcTargetHeight(int num_msg_lines) -> float {
|
||||
constexpr int TEXT_SIZE = 6;
|
||||
constexpr int PADDING_IN_V = TEXT_SIZE / 2;
|
||||
return static_cast<float>((TEXT_SIZE * (num_msg_lines + 1)) + (PADDING_IN_V * 2));
|
||||
constexpr int PADDING_IN_V = Console::TEXT_SIZE / 2;
|
||||
return static_cast<float>((Console::TEXT_SIZE * (num_msg_lines + 1)) + (PADDING_IN_V * 2));
|
||||
}
|
||||
|
||||
// Divide text en líneas respetando los \n existentes y haciendo word-wrap por ancho en píxeles
|
||||
auto Console::wrapText(const std::string& text) const -> std::vector<std::string> {
|
||||
constexpr int PADDING_IN_H = 6; // TEXT_SIZE; simétrico a ambos lados
|
||||
constexpr int PADDING_IN_H = TEXT_SIZE; // Simétrico a ambos lados
|
||||
const int MAX_PX = static_cast<int>(Options::game.width) - (2 * PADDING_IN_H);
|
||||
|
||||
std::vector<std::string> result;
|
||||
@@ -132,7 +131,6 @@ void Console::buildSurface() {
|
||||
// Redibuja el texto dinámico sobre la surface (fondo + borde + líneas)
|
||||
void Console::redrawText() {
|
||||
const float WIDTH = Options::game.width;
|
||||
constexpr int TEXT_SIZE = 6;
|
||||
constexpr int PADDING_IN_H = TEXT_SIZE;
|
||||
constexpr int PADDING_IN_V = TEXT_SIZE / 2;
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ class Console {
|
||||
void toggle();
|
||||
void handleEvent(const SDL_Event& event);
|
||||
|
||||
// Constantes públicas
|
||||
static constexpr int TEXT_SIZE = 6; // Tamaño de carácter del font de la consola
|
||||
|
||||
// Consultas
|
||||
auto isActive() -> bool; // true si RISING, ACTIVE o VANISHING
|
||||
auto getVisibleHeight() -> int; // Píxeles visibles actuales (0 = oculta, height_ = totalmente visible)
|
||||
|
||||
@@ -857,41 +857,6 @@ static auto cmdCheat(const std::vector<std::string>& args) -> std::string { //
|
||||
return "usage: cheat [infinite lives|invincibility]";
|
||||
}
|
||||
|
||||
// PLAYER SKIN / PLAYER COLOR
|
||||
static auto cmdPlayer(const std::vector<std::string>& args) -> std::string {
|
||||
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
|
||||
|
||||
// PLAYER SKIN <name>
|
||||
if (args.size() >= 2 && args[0] == "SKIN") {
|
||||
if (!GameControl::change_player_skin) { return "Game not initialized"; }
|
||||
std::string skin_name = args[1];
|
||||
std::ranges::transform(skin_name, skin_name.begin(), ::tolower);
|
||||
GameControl::change_player_skin(skin_name);
|
||||
return "Player skin: " + skin_name;
|
||||
}
|
||||
|
||||
// PLAYER COLOR DEFAULT
|
||||
if (args.size() >= 2 && args[0] == "COLOR" && args[1] == "DEFAULT") {
|
||||
if (!GameControl::change_player_color) { return "Game not initialized"; }
|
||||
GameControl::change_player_color(-1);
|
||||
return "Player color: default";
|
||||
}
|
||||
|
||||
// PLAYER COLOR <0-15>
|
||||
if (args.size() >= 2 && args[0] == "COLOR") {
|
||||
int color = -1;
|
||||
try {
|
||||
color = std::stoi(args[1]);
|
||||
} catch (...) {}
|
||||
if (color < 0 || color > 15) { return "usage: player color <0-15>|default"; }
|
||||
if (!GameControl::change_player_color) { return "Game not initialized"; }
|
||||
GameControl::change_player_color(color);
|
||||
return "Player color: " + std::to_string(color);
|
||||
}
|
||||
|
||||
return "usage: player skin <name> | player color <0-15>|default";
|
||||
}
|
||||
|
||||
// RESTART
|
||||
static auto cmdRestart(const std::vector<std::string>& /*unused*/) -> std::string {
|
||||
SceneManager::current = SceneManager::Scene::LOGO;
|
||||
@@ -954,7 +919,6 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni
|
||||
handlers_["cmd_show"] = cmdShow;
|
||||
handlers_["cmd_hide"] = cmdHide;
|
||||
handlers_["cmd_cheat"] = cmdCheat;
|
||||
handlers_["cmd_player"] = cmdPlayer;
|
||||
handlers_["cmd_restart"] = cmdRestart;
|
||||
handlers_["cmd_kiosk"] = cmdKiosk;
|
||||
handlers_["cmd_exit"] = cmdExit;
|
||||
@@ -1006,8 +970,6 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni
|
||||
}
|
||||
return result;
|
||||
};
|
||||
dynamic_providers_["SET COLOR"] = color_provider;
|
||||
dynamic_providers_["SET BGCOLOR"] = color_provider;
|
||||
dynamic_providers_["EDIT MAPBG"] = color_provider;
|
||||
dynamic_providers_["EDIT MAPCONN"] = color_provider;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ const Notifier::Style Notifier::Style::DEFAULT = {
|
||||
.shape = Notifier::Shape::SQUARED,
|
||||
.text_align = Notifier::TextAlign::CENTER,
|
||||
.duration = 2.0F,
|
||||
.sound_file = "notify.wav",
|
||||
.sound_file = Defaults::Sound::Files::NOTIFY,
|
||||
.play_sound = false};
|
||||
|
||||
const Notifier::Style Notifier::Style::CHEEVO = {
|
||||
@@ -40,7 +40,7 @@ const Notifier::Style Notifier::Style::CHEEVO = {
|
||||
.shape = Notifier::Shape::SQUARED,
|
||||
.text_align = Notifier::TextAlign::CENTER,
|
||||
.duration = 4.0F,
|
||||
.sound_file = "notify.wav",
|
||||
.sound_file = Defaults::Sound::Files::NOTIFY,
|
||||
.play_sound = true};
|
||||
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
@@ -160,7 +160,7 @@ void Notifier::show(std::vector<std::string> texts, const Style& style, int icon
|
||||
}
|
||||
|
||||
// Inicializa variables
|
||||
const int TEXT_SIZE = 6;
|
||||
constexpr float TEXT_SIZE = LINE_HEIGHT;
|
||||
const auto PADDING_IN_H = TEXT_SIZE;
|
||||
const auto PADDING_IN_V = TEXT_SIZE / 2;
|
||||
const int ICON_SPACE = icon >= 0 ? ICON_SIZE + PADDING_IN_H : 0;
|
||||
@@ -205,16 +205,16 @@ void Notifier::show(std::vector<std::string> texts, const Style& style, int icon
|
||||
// Dibuja el fondo de la notificación
|
||||
SDL_FRect rect;
|
||||
if (SHAPE == Shape::ROUNDED) {
|
||||
rect = {.x = 4, .y = 0, .w = WIDTH - (4 * 2), .h = HEIGHT};
|
||||
rect = {.x = static_cast<float>(CORNER_RADIUS), .y = 0, .w = WIDTH - (CORNER_RADIUS * 2), .h = HEIGHT};
|
||||
n.surface->fillRect(&rect, style.bg_color);
|
||||
|
||||
rect = {.x = 4 / 2, .y = 1, .w = WIDTH - 4, .h = HEIGHT - 2};
|
||||
rect = {.x = static_cast<float>(CORNER_RADIUS / 2), .y = static_cast<float>(BORDER_INSET), .w = WIDTH - CORNER_RADIUS, .h = HEIGHT - (BORDER_INSET * 2)};
|
||||
n.surface->fillRect(&rect, style.bg_color);
|
||||
|
||||
rect = {.x = 1, .y = 4 / 2, .w = WIDTH - 2, .h = HEIGHT - 4};
|
||||
rect = {.x = static_cast<float>(BORDER_INSET), .y = static_cast<float>(CORNER_RADIUS / 2), .w = WIDTH - (BORDER_INSET * 2), .h = HEIGHT - CORNER_RADIUS};
|
||||
n.surface->fillRect(&rect, style.bg_color);
|
||||
|
||||
rect = {.x = 0, .y = 4, .w = WIDTH, .h = HEIGHT - (4 * 2)};
|
||||
rect = {.x = 0, .y = static_cast<float>(CORNER_RADIUS), .w = WIDTH, .h = HEIGHT - (CORNER_RADIUS * 2)};
|
||||
n.surface->fillRect(&rect, style.bg_color);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,9 @@ class Notifier {
|
||||
static constexpr float ICON_SIZE = 16.0F;
|
||||
static constexpr float PADDING_OUT = 0.0F;
|
||||
static constexpr float SLIDE_SPEED = 120.0F; // Pixels per second for slide animations
|
||||
static constexpr float LINE_HEIGHT = 6.0F; // Alto de línea fijo para el layout de notificaciones
|
||||
static constexpr int CORNER_RADIUS = 4; // Radio de las esquinas redondeadas
|
||||
static constexpr int BORDER_INSET = 1; // Inset del borde interior
|
||||
|
||||
// [SINGLETON] Objeto notifier
|
||||
static Notifier* notifier;
|
||||
|
||||
Reference in New Issue
Block a user