Implementar cambio de sprite dinámico con hot-swap (Tecla N)
Sistema de múltiples texturas: - Carga ball.png (10x10) y ball_small.png (6x6) al inicio - Variable current_ball_size_ obtiene tamaño desde texture->getWidth() - Eliminar constante BALL_SIZE hardcoded Cambio de tamaño con ajuste de posiciones: - updateBallSizes() ajusta pos según gravedad y superficie - DOWN: mueve Y hacia abajo si crece - UP: mueve Y hacia arriba si crece - LEFT/RIGHT: mueve X correspondiente - Solo ajusta pelotas en superficie (isOnSurface()) Ball class actualizada: - Constructor recibe ball_size como parámetro - updateSize(new_size): actualiza hitbox y sprite - setTexture(texture): cambia textura del sprite - setPosition() usa setRotoBallScreenPosition() Sprite class: - Añadido setTexture() inline para hot-swap Tecla N: - Cicla entre texturas disponibles - Actualiza todas las pelotas sin reiniciar física - Texto informativo "SPRITE: NORMAL" / "SPRITE: SMALL" Fix bug initBalls(): - Ahora usa current_ball_size_ en constructor - Pelotas nuevas tienen tamaño correcto según textura activa 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -80,10 +80,22 @@ bool Engine::initialize() {
|
||||
|
||||
// Inicializar otros componentes si SDL se inicializó correctamente
|
||||
if (success) {
|
||||
// Construir ruta absoluta a la imagen
|
||||
// Cargar todas las texturas disponibles
|
||||
std::string exe_dir = getExecutableDirectory();
|
||||
std::string texture_path = exe_dir + "/data/ball.png";
|
||||
texture_ = std::make_shared<Texture>(renderer_, texture_path);
|
||||
|
||||
// Textura 0: ball.png (10x10)
|
||||
std::string texture_path_normal = exe_dir + "/data/ball.png";
|
||||
textures_.push_back(std::make_shared<Texture>(renderer_, texture_path_normal));
|
||||
|
||||
// Textura 1: ball_small.png (6x6)
|
||||
std::string texture_path_small = exe_dir + "/data/ball_small.png";
|
||||
textures_.push_back(std::make_shared<Texture>(renderer_, texture_path_small));
|
||||
|
||||
// Establecer textura inicial (índice 0)
|
||||
current_texture_index_ = 0;
|
||||
texture_ = textures_[current_texture_index_];
|
||||
current_ball_size_ = texture_->getWidth(); // Obtener tamaño dinámicamente
|
||||
|
||||
srand(static_cast<unsigned>(time(nullptr)));
|
||||
dbg_init(renderer_);
|
||||
initializeThemes();
|
||||
@@ -337,6 +349,11 @@ void Engine::handleEvents() {
|
||||
startThemeTransition(ColorTheme::MONOCHROME);
|
||||
break;
|
||||
|
||||
// Cambio de sprite/textura dinámico
|
||||
case SDLK_N:
|
||||
switchTexture();
|
||||
break;
|
||||
|
||||
// Control de escala de figura (solo en modo SHAPE)
|
||||
case SDLK_KP_PLUS:
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
@@ -609,7 +626,7 @@ void Engine::initBalls(int value) {
|
||||
const Color COLOR = theme.ball_colors[color_index];
|
||||
// Generar factor de masa aleatorio (0.7 = ligera, 1.3 = pesada)
|
||||
float mass_factor = GRAVITY_MASS_MIN + (rand() % 1000) / 1000.0f * (GRAVITY_MASS_MAX - GRAVITY_MASS_MIN);
|
||||
balls_.emplace_back(std::make_unique<Ball>(X, VX, VY, COLOR, texture_, current_screen_width_, current_screen_height_, current_gravity_, mass_factor));
|
||||
balls_.emplace_back(std::make_unique<Ball>(X, VX, VY, COLOR, texture_, current_screen_width_, current_screen_height_, current_ball_size_, current_gravity_, mass_factor));
|
||||
}
|
||||
setText(); // Actualiza el texto
|
||||
}
|
||||
@@ -1113,6 +1130,80 @@ void Engine::performRandomRestart() {
|
||||
all_balls_stopped_start_time_ = 0;
|
||||
}
|
||||
|
||||
// Sistema de cambio de sprites dinámico
|
||||
void Engine::updateBallSizes(int old_size, int new_size) {
|
||||
float delta_size = static_cast<float>(new_size - old_size);
|
||||
|
||||
for (auto& ball : balls_) {
|
||||
SDL_FRect pos = ball->getPosition();
|
||||
|
||||
// Solo ajustar posición si la pelota está en superficie
|
||||
if (ball->isOnSurface()) {
|
||||
GravityDirection grav_dir = ball->getGravityDirection();
|
||||
|
||||
switch (grav_dir) {
|
||||
case GravityDirection::DOWN:
|
||||
// Superficie inferior: ajustar Y hacia abajo si crece
|
||||
pos.y += delta_size;
|
||||
break;
|
||||
|
||||
case GravityDirection::UP:
|
||||
// Superficie superior: ajustar Y hacia arriba si crece
|
||||
pos.y -= delta_size;
|
||||
break;
|
||||
|
||||
case GravityDirection::LEFT:
|
||||
// Superficie izquierda: ajustar X hacia izquierda si crece
|
||||
pos.x -= delta_size;
|
||||
break;
|
||||
|
||||
case GravityDirection::RIGHT:
|
||||
// Superficie derecha: ajustar X hacia derecha si crece
|
||||
pos.x += delta_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Actualizar tamaño del hitbox
|
||||
ball->updateSize(new_size);
|
||||
|
||||
// Si ajustamos posición, aplicarla ahora
|
||||
if (ball->isOnSurface()) {
|
||||
ball->setRotoBallScreenPosition(pos.x, pos.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::switchTexture() {
|
||||
if (textures_.empty()) return;
|
||||
|
||||
// Guardar tamaño antiguo
|
||||
int old_size = current_ball_size_;
|
||||
|
||||
// Cambiar a siguiente textura (ciclar)
|
||||
current_texture_index_ = (current_texture_index_ + 1) % textures_.size();
|
||||
texture_ = textures_[current_texture_index_];
|
||||
|
||||
// Obtener nuevo tamaño de la textura
|
||||
int new_size = texture_->getWidth();
|
||||
current_ball_size_ = new_size;
|
||||
|
||||
// Actualizar texturas y tamaños de todas las pelotas
|
||||
for (auto& ball : balls_) {
|
||||
ball->setTexture(texture_);
|
||||
}
|
||||
|
||||
// Ajustar posiciones según el cambio de tamaño
|
||||
updateBallSizes(old_size, new_size);
|
||||
|
||||
// Mostrar texto informativo
|
||||
std::string texture_name = (current_texture_index_ == 0) ? "NORMAL" : "SMALL";
|
||||
text_ = "SPRITE: " + texture_name;
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
|
||||
// Sistema de Figuras 3D - Alternar entre modo física y última figura (Toggle con tecla F)
|
||||
void Engine::toggleShapeMode(bool force_gravity_on_exit) {
|
||||
if (current_mode_ == SimulationMode::PHYSICS) {
|
||||
|
||||
Reference in New Issue
Block a user