afegit i parametritzat outline per als textos dels items
This commit is contained in:
@@ -2,17 +2,18 @@
|
||||
# Formato: PARAMETRO VALOR
|
||||
|
||||
# --- GAME ---
|
||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||
game.height 240 # Alto de la resolución nativa del juego (en píxeles)
|
||||
game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||
game.play_area.rect.h 200 # Alto de la zona jugable
|
||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||
game.item_text_outline_color E0E0E0F0 # Color del outline del texto de los items (RGBA hex)
|
||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||
game.height 240 # Alto de la resolución nativa del juego (en píxeles)
|
||||
game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||
game.play_area.rect.h 200 # Alto de la zona jugable
|
||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||
|
||||
# --- FADE ---
|
||||
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
||||
|
||||
@@ -2,17 +2,18 @@
|
||||
# Formato: PARAMETRO VALOR
|
||||
|
||||
# --- GAME ---
|
||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
||||
game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||
game.play_area.rect.h 216 # Alto de la zona jugable
|
||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||
game.item_text_outline_color E0E0E0F0 # Color del outline del texto de los items (RGBA hex)
|
||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
||||
game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||
game.play_area.rect.h 216 # Alto de la zona jugable
|
||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||
|
||||
# --- FADE ---
|
||||
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
|
||||
// Constructor
|
||||
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
|
||||
void BalloonManager::init() {
|
||||
@@ -291,7 +289,7 @@ auto BalloonManager::destroyAllBalloons() -> int {
|
||||
}
|
||||
|
||||
balloon_deploy_counter_ = 300;
|
||||
Screen::get()->flash(FLASH_COLOR, 3);
|
||||
Screen::get()->flash(Colors::FLASH, 3);
|
||||
Screen::get()->shake();
|
||||
|
||||
return score;
|
||||
|
||||
130
source/color.cpp
130
source/color.cpp
@@ -42,22 +42,8 @@ auto Color::fromHex(const std::string &hex_str) -> Color {
|
||||
return Color(r, g, b, a);
|
||||
}
|
||||
|
||||
// Obtiene un color del vector de colores imitando al Coche Fantástico
|
||||
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color {
|
||||
int cycle_length = (colors.size() * 2) - 2;
|
||||
size_t n = counter % cycle_length;
|
||||
|
||||
size_t index;
|
||||
if (n < colors.size()) {
|
||||
index = n; // Avanza: 0,1,2,3
|
||||
} else {
|
||||
index = 2 * (colors.size() - 1) - n; // Retrocede: 2,1
|
||||
}
|
||||
|
||||
return colors[index];
|
||||
}
|
||||
|
||||
constexpr auto rgbToHsv(Color color) -> HSV {
|
||||
// Implementaciones de métodos estáticos de Color
|
||||
constexpr auto Color::rgbToHsv(Color color) -> HSV {
|
||||
float r = color.r / 255.0F;
|
||||
float g = color.g / 255.0F;
|
||||
float b = color.b / 255.0F;
|
||||
@@ -87,7 +73,7 @@ constexpr auto rgbToHsv(Color color) -> HSV {
|
||||
return {.h = h, .s = s, .v = v};
|
||||
}
|
||||
|
||||
constexpr auto hsvToRgb(HSV hsv) -> Color {
|
||||
constexpr auto Color::hsvToRgb(HSV hsv) -> Color {
|
||||
float c = hsv.v * hsv.s;
|
||||
float x = c * (1 - std::abs(std::fmod(hsv.h / 60.0F, 2) - 1));
|
||||
float m = hsv.v - c;
|
||||
@@ -128,55 +114,73 @@ constexpr auto hsvToRgb(HSV hsv) -> Color {
|
||||
static_cast<uint8_t>(roundf((b + m) * 255)));
|
||||
}
|
||||
|
||||
auto generateMirroredCycle(Color base, ColorCycleStyle style) -> ColorCycle {
|
||||
ColorCycle result{};
|
||||
HSV base_hsv = rgbToHsv(base);
|
||||
// Implementaciones del namespace Colors
|
||||
namespace Colors {
|
||||
// Obtiene un color del vector de colores imitando al Coche Fantástico
|
||||
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color {
|
||||
int cycle_length = (colors.size() * 2) - 2;
|
||||
size_t n = counter % cycle_length;
|
||||
|
||||
for (size_t i = 0; i < COLOR_CYCLE_SIZE; ++i) {
|
||||
float t = static_cast<float>(i) / (COLOR_CYCLE_SIZE - 1); // 0 → 1
|
||||
float hue_shift = 0.0F;
|
||||
float sat_shift = 0.0F;
|
||||
float val_shift = 0.0F;
|
||||
|
||||
switch (style) {
|
||||
case ColorCycleStyle::SUBTLE_PULSE:
|
||||
// Solo brillo suave
|
||||
val_shift = 0.07F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::HUE_WAVE:
|
||||
// Oscilación leve de tono
|
||||
hue_shift = 15.0F * (t - 0.5F) * 2.0F;
|
||||
val_shift = 0.05F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::VIBRANT:
|
||||
// Cambios fuertes en tono y brillo
|
||||
hue_shift = 35.0F * sinf(t * M_PI);
|
||||
val_shift = 0.2F * sinf(t * M_PI);
|
||||
sat_shift = -0.2F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::DARKEN_GLOW:
|
||||
// Se oscurece al centro
|
||||
val_shift = -0.15F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::LIGHT_FLASH:
|
||||
// Se ilumina al centro
|
||||
val_shift = 0.25F * sinf(t * M_PI);
|
||||
break;
|
||||
size_t index;
|
||||
if (n < colors.size()) {
|
||||
index = n; // Avanza: 0,1,2,3
|
||||
} else {
|
||||
index = 2 * (colors.size() - 1) - n; // Retrocede: 2,1
|
||||
}
|
||||
|
||||
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 = hsvToRgb(adjusted);
|
||||
result[i] = c;
|
||||
result[(2 * COLOR_CYCLE_SIZE) - 1 - i] = c; // espejo
|
||||
return colors[index];
|
||||
}
|
||||
|
||||
return result;
|
||||
auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle {
|
||||
Cycle result{};
|
||||
HSV base_hsv = Color::rgbToHsv(base);
|
||||
|
||||
for (size_t i = 0; i < CYCLE_SIZE; ++i) {
|
||||
float t = static_cast<float>(i) / (CYCLE_SIZE - 1); // 0 → 1
|
||||
float hue_shift = 0.0F;
|
||||
float sat_shift = 0.0F;
|
||||
float val_shift = 0.0F;
|
||||
|
||||
switch (style) {
|
||||
case ColorCycleStyle::SUBTLE_PULSE:
|
||||
// Solo brillo suave
|
||||
val_shift = 0.07F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::HUE_WAVE:
|
||||
// Oscilación leve de tono
|
||||
hue_shift = 15.0F * (t - 0.5F) * 2.0F;
|
||||
val_shift = 0.05F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::VIBRANT:
|
||||
// Cambios fuertes en tono y brillo
|
||||
hue_shift = 35.0F * sinf(t * M_PI);
|
||||
val_shift = 0.2F * sinf(t * M_PI);
|
||||
sat_shift = -0.2F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::DARKEN_GLOW:
|
||||
// Se oscurece al centro
|
||||
val_shift = -0.15F * sinf(t * M_PI);
|
||||
break;
|
||||
|
||||
case ColorCycleStyle::LIGHT_FLASH:
|
||||
// Se ilumina al centro
|
||||
val_shift = 0.25F * sinf(t * M_PI);
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,12 @@
|
||||
#include <string> // Para string
|
||||
#include <vector> // Para vector
|
||||
|
||||
// --- Constantes ---
|
||||
constexpr size_t COLOR_CYCLE_SIZE = 6; // Mitad del ciclo espejado
|
||||
// --- Estructura HSV: define un color en formato HSV ---
|
||||
struct HSV {
|
||||
float h; // Matiz (Hue)
|
||||
float s; // Saturación (Saturation)
|
||||
float v; // Valor (Value)
|
||||
};
|
||||
|
||||
// --- Estructura Color: define un color RGBA ---
|
||||
struct Color {
|
||||
@@ -60,6 +64,10 @@ struct Color {
|
||||
// Método estático para crear Color desde string hexadecimal
|
||||
static auto fromHex(const std::string &hex_str) -> Color;
|
||||
|
||||
// Conversiones de formato de color
|
||||
[[nodiscard]] constexpr static auto rgbToHsv(Color color) -> HSV;
|
||||
[[nodiscard]] constexpr static auto hsvToRgb(HSV hsv) -> Color;
|
||||
|
||||
[[nodiscard]] constexpr auto IS_EQUAL_TO(const Color &other) const -> bool {
|
||||
return r == other.r && g == other.g && b == other.b && a == other.a;
|
||||
}
|
||||
@@ -89,13 +97,6 @@ struct Color {
|
||||
}
|
||||
};
|
||||
|
||||
// --- Estructura HSV: define un color en formato HSV ---
|
||||
struct HSV {
|
||||
float h; // Matiz (Hue)
|
||||
float s; // Saturación (Saturation)
|
||||
float v; // Valor (Value)
|
||||
};
|
||||
|
||||
// --- Enum ColorCycleStyle: define estilos de ciclo de color ---
|
||||
enum class ColorCycleStyle {
|
||||
SUBTLE_PULSE, // Variación leve en brillo (por defecto)
|
||||
@@ -105,23 +106,27 @@ enum class ColorCycleStyle {
|
||||
LIGHT_FLASH // Ilumina hacia el centro y regresa
|
||||
};
|
||||
|
||||
// --- Alias ---
|
||||
using ColorCycle = std::array<Color, 2 * COLOR_CYCLE_SIZE>;
|
||||
// --- Namespace Colors: constantes y utilidades de color ---
|
||||
namespace Colors {
|
||||
// --- Constantes ---
|
||||
constexpr size_t CYCLE_SIZE = 6; // Mitad del ciclo espejado
|
||||
|
||||
// --- Colores predefinidos ---
|
||||
constexpr Color NO_TEXT_COLOR = Color(0XFF, 0XFF, 0XFF);
|
||||
constexpr Color SHADOW_TEXT_COLOR = Color(0X43, 0X43, 0X4F);
|
||||
constexpr Color TITLE_SHADOW_TEXT_COLOR = Color(0x14, 0x87, 0xc4);
|
||||
constexpr Color ORANGE_TEXT_COLOR = Color(0XFF, 0X7A, 0X00);
|
||||
// --- Alias ---
|
||||
using Cycle = std::array<Color, 2 * CYCLE_SIZE>;
|
||||
|
||||
constexpr Color FLASH_COLOR = Color(0XFF, 0XFF, 0XFF);
|
||||
// --- Colores predefinidos ---
|
||||
constexpr Color NO_COLOR_MOD = Color(0XFF, 0XFF, 0XFF);
|
||||
constexpr Color SHADOW_TEXT = Color(0X43, 0X43, 0X4F);
|
||||
constexpr Color TITLE_SHADOW_TEXT = Color(0x14, 0x87, 0xc4);
|
||||
constexpr Color ORANGE_TEXT = Color(0XFF, 0X7A, 0X00);
|
||||
|
||||
constexpr Color BLUE_SKY_COLOR = Color(0X02, 0X88, 0XD1);
|
||||
constexpr Color PINK_SKY_COLOR = Color(0XFF, 0X6B, 0X97);
|
||||
constexpr Color GREEN_SKY_COLOR = Color(0X00, 0X79, 0X6B);
|
||||
constexpr Color FLASH = Color(0XFF, 0XFF, 0XFF);
|
||||
|
||||
// --- Funciones ---
|
||||
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color;
|
||||
constexpr auto rgbToHsv(Color color) -> HSV;
|
||||
constexpr auto hsvToRgb(HSV hsv) -> Color;
|
||||
auto generateMirroredCycle(Color base, ColorCycleStyle style = ColorCycleStyle::SUBTLE_PULSE) -> ColorCycle;
|
||||
constexpr Color BLUE_SKY = Color(0X02, 0X88, 0XD1);
|
||||
constexpr Color PINK_SKY = Color(0XFF, 0X6B, 0X97);
|
||||
constexpr Color GREEN_SKY = Color(0X00, 0X79, 0X6B);
|
||||
|
||||
// --- Funciones ---
|
||||
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color;
|
||||
auto generateMirroredCycle(Color base, ColorCycleStyle style = ColorCycleStyle::SUBTLE_PULSE) -> Cycle;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ constexpr int NAME_ENTRY_IDLE_TIME = 10;
|
||||
constexpr int NAME_ENTRY_TOTAL_TIME = 60;
|
||||
constexpr bool HIT_STOP = false;
|
||||
constexpr int HIT_STOP_MS = 500;
|
||||
constexpr const char* ITEM_TEXT_OUTLINE_COLOR = "FFFFFF00"; // 255, 255, 255, 0
|
||||
|
||||
// Play area por defecto
|
||||
constexpr float PLAY_AREA_X = 0.0F;
|
||||
|
||||
@@ -136,6 +136,7 @@ auto setParams(const std::string& var, const std::string& value) -> bool {
|
||||
{"intro.shadow_color", [](const std::string& v) { param.intro.shadow_color = Color::fromHex(v); }},
|
||||
{"debug.color", [](const std::string& v) { param.debug.color = Color::fromHex(v); }},
|
||||
{"resource.color", [](const std::string& v) { param.resource.color = Color::fromHex(v); }},
|
||||
{"game.item_text_outline_color", [](const std::string& v) { param.game.item_text_outline_color = Color::fromHex(v); }},
|
||||
{"player.default_shirt[0].darkest", [](const std::string& v) { param.player.default_shirt[0].darkest = Color::fromHex(v); }},
|
||||
{"player.default_shirt[0].dark", [](const std::string& v) { param.player.default_shirt[0].dark = Color::fromHex(v); }},
|
||||
{"player.default_shirt[0].base", [](const std::string& v) { param.player.default_shirt[0].base = Color::fromHex(v); }},
|
||||
|
||||
@@ -22,6 +22,7 @@ struct ParamGame {
|
||||
Uint32 speed = 15; // Este valor no estaba en el archivo de configuración
|
||||
bool hit_stop = GameDefaults::Game::HIT_STOP;
|
||||
Uint32 hit_stop_ms = GameDefaults::Game::HIT_STOP_MS;
|
||||
Color item_text_outline_color;
|
||||
};
|
||||
|
||||
// --- Parámetros del fade ---
|
||||
|
||||
@@ -616,33 +616,42 @@ void Resource::createTextTextures() {
|
||||
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> CREATING TEXTURES");
|
||||
|
||||
// Texturas de tamaño normal
|
||||
std::vector<NameAndText> strings = {
|
||||
// Texturas de tamaño normal con outline
|
||||
std::vector<NameAndText> strings1 = {
|
||||
{"game_text_1000_points", "1.000"},
|
||||
{"game_text_2500_points", "2.500"},
|
||||
{"game_text_5000_points", "5.000"},
|
||||
{"game_text_powerup", Lang::getText("[GAME_TEXT] 4")},
|
||||
{"game_text_one_hit", Lang::getText("[GAME_TEXT] 5")},
|
||||
{"game_text_stop", Lang::getText("[GAME_TEXT] 6")},
|
||||
{"game_text_stop", Lang::getText("[GAME_TEXT] 6")}};
|
||||
|
||||
auto text1 = getText("04b_25_enhanced");
|
||||
for (const auto &s : strings1) {
|
||||
textures_.emplace_back(s.name, text1->writeDXToTexture(Text::STROKE, s.text, -2, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
|
||||
printWithDots("Texture : ", s.name, "[ DONE ]");
|
||||
}
|
||||
|
||||
// Texturas de tamaño normal
|
||||
std::vector<NameAndText> strings2 = {
|
||||
{"game_text_1000000_points", Lang::getText("[GAME_TEXT] 8")}};
|
||||
|
||||
auto text = getText("04b_25_enhanced");
|
||||
for (const auto &s : strings) {
|
||||
textures_.emplace_back(s.name, text->writeDXToTexture(Text::STROKE, s.text, -2, NO_TEXT_COLOR, 1, Color(255, 255, 0, 255)));
|
||||
auto text2 = getText("04b_25");
|
||||
for (const auto &s : strings2) {
|
||||
textures_.emplace_back(s.name, text2->writeDXToTexture(Text::STROKE, s.text, -2, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
|
||||
printWithDots("Texture : ", s.name, "[ DONE ]");
|
||||
}
|
||||
|
||||
// Texturas de tamaño doble
|
||||
std::vector<NameAndText> strings2_x = {
|
||||
std::vector<NameAndText> strings3 = {
|
||||
{"game_text_100000_points", "100.000"},
|
||||
{"game_text_get_ready", Lang::getText("[GAME_TEXT] 7")},
|
||||
{"game_text_last_stage", Lang::getText("[GAME_TEXT] 3")},
|
||||
{"game_text_congratulations", Lang::getText("[GAME_TEXT] 1")},
|
||||
{"game_text_game_over", "Game Over"}};
|
||||
|
||||
auto text2 = getText("04b_25_2x");
|
||||
for (const auto &s : strings2_x) {
|
||||
textures_.emplace_back(s.name, text2->writeToTexture(s.text, 1, -4));
|
||||
auto text3 = getText("04b_25_2x");
|
||||
for (const auto &s : strings3) {
|
||||
textures_.emplace_back(s.name, text3->writeToTexture(s.text, 1, -4));
|
||||
printWithDots("Texture : ", s.name, "[ DONE ]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ void Scoreboard::renderShowNameMode(size_t panel_index) {
|
||||
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
||||
|
||||
/* TEXTO CENTRADO */
|
||||
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y, record_name_.at(panel_index), 1, getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y, record_name_.at(panel_index), 1, Colors::getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||
}
|
||||
|
||||
void Scoreboard::renderGameCompletedMode(size_t panel_index) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "audio.h" // Para Audio
|
||||
#include "balloon_manager.h" // Para BalloonManager
|
||||
#include "color.h" // Para Zone, SHADOW_TEXT_COLOR, NO_TEXT_COLOR, Color
|
||||
#include "color.h" // Para Zone, Colors::SHADOW_TEXT, Colors::NO_COLOR_MOD, Color
|
||||
#include "fade.h" // Para Fade, FadeType, FadeMode
|
||||
#include "global_events.h" // Para check
|
||||
#include "global_inputs.h" // Para check
|
||||
@@ -35,12 +35,7 @@ constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner";
|
||||
|
||||
// Constructor
|
||||
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) {
|
||||
throw std::runtime_error("Failed to create SDL texture for text.");
|
||||
}
|
||||
@@ -173,7 +168,7 @@ void Credits::fillTextTexture() {
|
||||
const int TEXTS_HEIGHT = (1 * text->getCharacterSize()) + (8 * SPACE_POST_TITLE) + (3 * SPACE_PRE_TITLE);
|
||||
const int POS_X = static_cast<int>(param.game.game_area.center_x);
|
||||
credits_rect_dst_.h = credits_rect_src_.h = static_cast<float>(TEXTS_HEIGHT);
|
||||
auto text_style = Text::Style(Text::CENTER | Text::SHADOW, NO_TEXT_COLOR, SHADOW_TEXT_COLOR);
|
||||
auto text_style = Text::Style(Text::CENTER | Text::SHADOW, Colors::NO_COLOR_MOD, Colors::SHADOW_TEXT);
|
||||
|
||||
// PROGRAMMED_AND_DESIGNED_BY
|
||||
int y = 0;
|
||||
@@ -214,7 +209,7 @@ void Credits::fillTextTexture() {
|
||||
mini_logo_rect_src_.y = static_cast<float>(y);
|
||||
auto mini_logo_sprite = std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"));
|
||||
mini_logo_sprite->setPosition(1 + POS_X - (mini_logo_sprite->getWidth() / 2), 1 + y);
|
||||
Resource::get()->getTexture("logo_jailgames_mini.png")->setColor(SHADOW_TEXT_COLOR.r, SHADOW_TEXT_COLOR.g, SHADOW_TEXT_COLOR.b);
|
||||
Resource::get()->getTexture("logo_jailgames_mini.png")->setColor(Colors::SHADOW_TEXT.r, Colors::SHADOW_TEXT.g, Colors::SHADOW_TEXT.b);
|
||||
mini_logo_sprite->render();
|
||||
|
||||
mini_logo_sprite->setPosition(POS_X - (mini_logo_sprite->getWidth() / 2), y);
|
||||
@@ -223,7 +218,7 @@ void Credits::fillTextTexture() {
|
||||
|
||||
// Texto con el copyright
|
||||
y += mini_logo_sprite->getHeight() + 3;
|
||||
text->writeDX(Text::CENTER | Text::SHADOW, POS_X, y, std::string(TEXT_COPYRIGHT), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||
text->writeDX(Text::CENTER | Text::SHADOW, POS_X, y, std::string(TEXT_COPYRIGHT), 1, Colors::NO_COLOR_MOD, 1, Colors::SHADOW_TEXT);
|
||||
|
||||
// Resetea el renderizador
|
||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "balloon.h" // Para Balloon
|
||||
#include "balloon_manager.h" // Para BalloonManager
|
||||
#include "bullet.h" // Para Bullet, BulletType, BulletMoveStatus
|
||||
#include "color.h" // Para Color, FLASH_COLOR
|
||||
#include "color.h" // Para Color, Colors::FLASH
|
||||
#include "difficulty.h" // Para Code
|
||||
#include "fade.h" // Para Fade, FadeType, FadeMode
|
||||
#include "global_events.h" // Para check
|
||||
@@ -49,18 +49,7 @@
|
||||
|
||||
// Constructor
|
||||
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
|
||||
demo_.enabled = demo;
|
||||
|
||||
@@ -281,7 +270,7 @@ void Game::updateStage() {
|
||||
// Efectos de cambio de fase
|
||||
playSound("stage_change.wav");
|
||||
balloon_manager_->resetBalloonSpeed();
|
||||
screen_->flash(FLASH_COLOR, 3);
|
||||
screen_->flash(Colors::FLASH, 3);
|
||||
screen_->shake();
|
||||
|
||||
// Obtener datos de la nueva fase
|
||||
@@ -687,8 +676,7 @@ void Game::renderItems() {
|
||||
|
||||
// Devuelve un item al azar y luego segun sus probabilidades
|
||||
auto Game::dropItem() -> ItemType {
|
||||
//const auto LUCKY_NUMBER = rand() % 100;
|
||||
const auto LUCKY_NUMBER = 0;
|
||||
const auto LUCKY_NUMBER = rand() % 100;
|
||||
const auto ITEM = rand() % 6;
|
||||
|
||||
switch (ITEM) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "audio.h" // Para Audio
|
||||
#include "background.h" // Para Background
|
||||
#include "color.h" // Para Color, easeOutQuint, NO_TEXT_COLOR
|
||||
#include "color.h" // Para Color, easeOutQuint, Colors::NO_COLOR_MOD
|
||||
#include "fade.h" // Para Fade, FadeMode, FadeType
|
||||
#include "global_events.h" // Para check
|
||||
#include "global_inputs.h" // Para check
|
||||
@@ -29,14 +29,7 @@
|
||||
|
||||
// Constructor
|
||||
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
|
||||
Section::name = Section::Name::HI_SCORE_TABLE;
|
||||
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
||||
@@ -191,7 +184,7 @@ void HiScoreTable::createSprites() {
|
||||
// Crea los sprites para las entradas en la tabla de puntuaciones
|
||||
const int ANIMATION = rand() % 4;
|
||||
const std::string SAMPLE_LINE(ENTRY_LENGTH + 3, ' ');
|
||||
auto sample_entry = std::make_unique<Sprite>(entry_text->writeDXToTexture(Text::SHADOW, SAMPLE_LINE, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR));
|
||||
auto sample_entry = std::make_unique<Sprite>(entry_text->writeDXToTexture(Text::SHADOW, SAMPLE_LINE, 1, Colors::NO_COLOR_MOD, 1, Colors::SHADOW_TEXT));
|
||||
const auto ENTRY_WIDTH = sample_entry->getWidth();
|
||||
for (int i = 0; i < MAX_NAMES; ++i) {
|
||||
const auto TABLE_POSITION = format(i + 1) + ". ";
|
||||
@@ -204,7 +197,7 @@ void HiScoreTable::createSprites() {
|
||||
}
|
||||
const auto LINE = TABLE_POSITION + Options::settings.hi_score_table.at(i).name + dots + SCORE + ONE_CC;
|
||||
|
||||
entry_names_.emplace_back(std::make_shared<PathSprite>(entry_text->writeDXToTexture(Text::SHADOW, LINE, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR)));
|
||||
entry_names_.emplace_back(std::make_shared<PathSprite>(entry_text->writeDXToTexture(Text::SHADOW, LINE, 1, Colors::NO_COLOR_MOD, 1, Colors::SHADOW_TEXT)));
|
||||
const int DEFAULT_POS_X = (backbuffer_width - ENTRY_WIDTH) / 2;
|
||||
const int POS_X = (i < 9) ? DEFAULT_POS_X : DEFAULT_POS_X - entry_text->getCharacterSize();
|
||||
const int POS_Y = (i * SPACE_BETWEEN_LINES) + FIRST_LINE + SPACE_BETWEEN_HEADER;
|
||||
@@ -291,7 +284,7 @@ void HiScoreTable::initBackground() {
|
||||
background_->setTransition(0.0F);
|
||||
background_->setSunProgression(1.0F);
|
||||
background_->setMoonProgression(0.0F);
|
||||
background_fade_color_ = GREEN_SKY_COLOR;
|
||||
background_fade_color_ = Colors::GREEN_SKY;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -301,7 +294,7 @@ void HiScoreTable::initBackground() {
|
||||
background_->setTransition(0.0F);
|
||||
background_->setSunProgression(0.65F);
|
||||
background_->setMoonProgression(0.0F);
|
||||
background_fade_color_ = PINK_SKY_COLOR;
|
||||
background_fade_color_ = Colors::PINK_SKY;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -311,7 +304,7 @@ void HiScoreTable::initBackground() {
|
||||
background_->setTransition(0.0F);
|
||||
background_->setSunProgression(0.0F);
|
||||
background_->setMoonProgression(0.0F);
|
||||
background_fade_color_ = BLUE_SKY_COLOR;
|
||||
background_fade_color_ = Colors::BLUE_SKY;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "audio.h" // Para Audio
|
||||
#include "color.h" // Para Color, SHADOW_TEXT_COLOR, Zone, NO_TEXT_C...
|
||||
#include "color.h" // Para Color, Colors::SHADOW_TEXT, Zone, NO_TEXT_C...
|
||||
#include "fade.h" // Para Fade, FadeMode, FadeType
|
||||
#include "global_events.h" // Para check
|
||||
#include "global_inputs.h" // Para check
|
||||
@@ -26,12 +26,7 @@
|
||||
|
||||
// Constructor
|
||||
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
|
||||
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
|
||||
@@ -150,8 +145,8 @@ void Instructions::fillTexture() {
|
||||
}
|
||||
const int ANCHOR_ITEM = (param.game.width - (length + X_OFFSET)) / 2;
|
||||
|
||||
auto caption_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, ORANGE_TEXT_COLOR, SHADOW_TEXT_COLOR);
|
||||
auto text_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, NO_TEXT_COLOR, SHADOW_TEXT_COLOR);
|
||||
auto caption_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, Colors::ORANGE_TEXT, Colors::SHADOW_TEXT);
|
||||
auto text_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, Colors::NO_COLOR_MOD, Colors::SHADOW_TEXT);
|
||||
|
||||
// Escribe el texto de las instrucciones
|
||||
text_->writeStyle(param.game.game_area.center_x, FIRST_LINE, Lang::getText("[INSTRUCTIONS] 01"), caption_style);
|
||||
@@ -167,11 +162,11 @@ void Instructions::fillTexture() {
|
||||
text_->writeStyle(param.game.game_area.center_x, ANCHOR2, Lang::getText("[INSTRUCTIONS] 06"), caption_style);
|
||||
|
||||
const int ANCHOR3 = ANCHOR2 + SPACE_POST_HEADER;
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 0), Lang::getText("[INSTRUCTIONS] 07"), SHADOW_TEXT_COLOR);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 1), Lang::getText("[INSTRUCTIONS] 08"), SHADOW_TEXT_COLOR);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 2), Lang::getText("[INSTRUCTIONS] 09"), SHADOW_TEXT_COLOR);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 3), Lang::getText("[INSTRUCTIONS] 10"), SHADOW_TEXT_COLOR);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 4), Lang::getText("[INSTRUCTIONS] 11"), SHADOW_TEXT_COLOR);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 0), Lang::getText("[INSTRUCTIONS] 07"), Colors::SHADOW_TEXT);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 1), Lang::getText("[INSTRUCTIONS] 08"), Colors::SHADOW_TEXT);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 2), Lang::getText("[INSTRUCTIONS] 09"), Colors::SHADOW_TEXT);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 3), Lang::getText("[INSTRUCTIONS] 10"), Colors::SHADOW_TEXT);
|
||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 4), Lang::getText("[INSTRUCTIONS] 11"), Colors::SHADOW_TEXT);
|
||||
|
||||
// Deja el renderizador como estaba
|
||||
SDL_SetRenderTarget(renderer_, temp);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "audio.h" // Para Audio
|
||||
#include "color.h" // Para NO_TEXT_COLOR, TITLE_SHADOW_TEXT_COLOR
|
||||
#include "color.h" // Para Colors::NO_COLOR_MOD, Colors::TITLE_SHADOW_TEXT
|
||||
#include "fade.h" // Para Fade, FadeType
|
||||
#include "game_logo.h" // Para GameLogo
|
||||
#include "global_events.h" // Para check
|
||||
@@ -37,13 +37,7 @@ class Texture;
|
||||
|
||||
// Constructor
|
||||
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
|
||||
tiled_bg_->setColor(param.title.bg_color);
|
||||
game_logo_->enable();
|
||||
@@ -438,9 +432,9 @@ void Title::renderStartPrompt() {
|
||||
param.title.press_start_position,
|
||||
Lang::getText("[TITLE] PRESS_BUTTON_TO_PLAY"),
|
||||
1,
|
||||
NO_TEXT_COLOR,
|
||||
Colors::NO_COLOR_MOD,
|
||||
1,
|
||||
TITLE_SHADOW_TEXT_COLOR);
|
||||
Colors::TITLE_SHADOW_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,9 +449,9 @@ void Title::renderCopyright() {
|
||||
anchor_.copyright_text,
|
||||
std::string(TEXT_COPYRIGHT),
|
||||
1,
|
||||
NO_TEXT_COLOR,
|
||||
Colors::NO_COLOR_MOD,
|
||||
1,
|
||||
TITLE_SHADOW_TEXT_COLOR);
|
||||
Colors::TITLE_SHADOW_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -345,7 +345,7 @@ void MenuRenderer::updateColorCounter() {
|
||||
}
|
||||
}
|
||||
auto MenuRenderer::getAnimatedSelectedColor() const -> Color {
|
||||
static auto color_cycle_ = generateMirroredCycle(param.service_menu.selected_color, ColorCycleStyle::HUE_WAVE);
|
||||
static auto color_cycle_ = Colors::generateMirroredCycle(param.service_menu.selected_color, ColorCycleStyle::HUE_WAVE);
|
||||
return color_cycle_.at(color_counter_ % color_cycle_.size());
|
||||
}
|
||||
auto MenuRenderer::setRect(SDL_FRect rect) -> SDL_FRect {
|
||||
|
||||
Reference in New Issue
Block a user