From 535c397be259616cfe3bef4d373268f7b991807b Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 3 Oct 2025 19:34:33 +0200 Subject: [PATCH] =?UTF-8?q?Mejorar=20interacci=C3=B3n=20entre=20modos=20Ro?= =?UTF-8?q?toBall=20y=20f=C3=ADsica=20con=20gesti=C3=B3n=20de=20gravedad?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cambios principales: - Fix: Pelotas ahora caen correctamente al salir de RotoBall (resetear on_surface_/stopped_) - Fix: Al cambiar escenario en RotoBall, desactivar modo figura primero - Feature: Al entrar en RotoBall, gravedad se desactiva automáticamente - Feature: Tecla G desde RotoBall → Sale a física SIN gravedad (pelotas flotan) - Feature: Tecla C desde RotoBall → Sale a física CON gravedad (pelotas caen) - Feature: Cursores desde RotoBall → Sale a física CON gravedad + cambio dirección - Feature: Cursores desde física sin gravedad → Reactiva gravedad automáticamente Nuevos métodos: - Ball::enableGravityIfDisabled() - Reactiva solo si está desactivada - Ball::forceGravityOn() - Fuerza activación - Ball::forceGravityOff() - Fuerza desactivación - Engine::toggleRotoBallMode(bool force_gravity_on_exit) - Control de gravedad al salir Lógica de controles desde RotoBall: - C: Figura OFF → Física CON gravedad (caen) - ↑↓←→: Figura OFF → Física CON gravedad + dirección (caen hacia dirección) - G: Figura OFF → Física SIN gravedad (flotan) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- source/ball.cpp | 23 +++++++++++++++++ source/ball.h | 9 +++++++ source/engine.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++-- source/engine.h | 5 +++- 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/source/ball.cpp b/source/ball.cpp index fe0dc61..328f1c2 100644 --- a/source/ball.cpp +++ b/source/ball.cpp @@ -227,6 +227,23 @@ void Ball::switchGravity() { gravity_force_ = gravity_force_ == 0.0f ? (GRAVITY_FORCE * 60.0f * 60.0f) : 0.0f; } +// Reactiva la gravedad si está desactivada +void Ball::enableGravityIfDisabled() { + if (gravity_force_ == 0.0f) { + gravity_force_ = GRAVITY_FORCE * 60.0f * 60.0f; + } +} + +// Fuerza gravedad ON (siempre activa) +void Ball::forceGravityOn() { + gravity_force_ = GRAVITY_FORCE * 60.0f * 60.0f; +} + +// Fuerza gravedad OFF (siempre desactiva) +void Ball::forceGravityOff() { + gravity_force_ = 0.0f; +} + // Cambia la dirección de gravedad void Ball::setGravityDirection(GravityDirection direction) { gravity_direction_ = direction; @@ -283,6 +300,12 @@ void Ball::setDepthBrightness(float brightness) { // Activar/desactivar atracción física hacia esfera RotoBall void Ball::enableRotoBallAttraction(bool enable) { rotoball_attraction_active_ = enable; + + // Al activar atracción, resetear flags de superficie para permitir física completa + if (enable) { + on_surface_ = false; + stopped_ = false; + } } // Aplicar fuerza de resorte hacia punto objetivo en esfera rotante diff --git a/source/ball.h b/source/ball.h index 479332a..77110b3 100644 --- a/source/ball.h +++ b/source/ball.h @@ -48,6 +48,15 @@ class Ball { // Cambia la gravedad void switchGravity(); + // Reactiva la gravedad si está desactivada + void enableGravityIfDisabled(); + + // Fuerza gravedad ON (siempre activa) + void forceGravityOn(); + + // Fuerza gravedad OFF (siempre desactiva) + void forceGravityOff(); + // Cambia la direcci\u00f3n de gravedad void setGravityDirection(GravityDirection direction); diff --git a/source/engine.cpp b/source/engine.cpp index cb8d4c6..41fe635 100644 --- a/source/engine.cpp +++ b/source/engine.cpp @@ -180,23 +180,52 @@ void Engine::handleEvents() { break; case SDLK_G: - switchBallsGravity(); + // Si estamos en RotoBall, salir a modo física SIN GRAVEDAD + if (current_mode_ == SimulationMode::ROTOBALL) { + toggleRotoBallMode(false); // Desactivar RotoBall sin forzar gravedad ON + } else { + switchBallsGravity(); // Toggle normal en modo física + } break; // Controles de dirección de gravedad con teclas de cursor case SDLK_UP: + // Si estamos en RotoBall, salir a modo física CON gravedad + if (current_mode_ == SimulationMode::ROTOBALL) { + toggleRotoBallMode(); // Desactivar RotoBall (activa gravedad automáticamente) + } else { + enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF + } changeGravityDirection(GravityDirection::UP); break; case SDLK_DOWN: + // Si estamos en RotoBall, salir a modo física CON gravedad + if (current_mode_ == SimulationMode::ROTOBALL) { + toggleRotoBallMode(); // Desactivar RotoBall (activa gravedad automáticamente) + } else { + enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF + } changeGravityDirection(GravityDirection::DOWN); break; case SDLK_LEFT: + // Si estamos en RotoBall, salir a modo física CON gravedad + if (current_mode_ == SimulationMode::ROTOBALL) { + toggleRotoBallMode(); // Desactivar RotoBall (activa gravedad automáticamente) + } else { + enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF + } changeGravityDirection(GravityDirection::LEFT); break; case SDLK_RIGHT: + // Si estamos en RotoBall, salir a modo física CON gravedad + if (current_mode_ == SimulationMode::ROTOBALL) { + toggleRotoBallMode(); // Desactivar RotoBall (activa gravedad automáticamente) + } else { + enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF + } changeGravityDirection(GravityDirection::RIGHT); break; @@ -441,6 +470,13 @@ void Engine::render() { } void Engine::initBalls(int value) { + // Si estamos en modo RotoBall, desactivarlo antes de regenerar pelotas + if (current_mode_ == SimulationMode::ROTOBALL) { + current_mode_ = SimulationMode::PHYSICS; + rotoball_.transitioning = false; + rotoball_.transition_progress = 0.0f; + } + // Limpiar las bolas actuales balls_.clear(); @@ -514,6 +550,24 @@ void Engine::switchBallsGravity() { } } +void Engine::enableBallsGravityIfDisabled() { + for (auto &ball : balls_) { + ball->enableGravityIfDisabled(); + } +} + +void Engine::forceBallsGravityOn() { + for (auto &ball : balls_) { + ball->forceGravityOn(); + } +} + +void Engine::forceBallsGravityOff() { + for (auto &ball : balls_) { + ball->forceGravityOff(); + } +} + void Engine::changeGravityDirection(GravityDirection direction) { current_gravity_ = direction; for (auto &ball : balls_) { @@ -869,7 +923,7 @@ void Engine::performRandomRestart() { } // Sistema RotoBall - Alternar entre modo física y esfera 3D -void Engine::toggleRotoBallMode() { +void Engine::toggleRotoBallMode(bool force_gravity_on_exit) { if (current_mode_ == SimulationMode::PHYSICS) { // Cambiar a modo RotoBall current_mode_ = SimulationMode::ROTOBALL; @@ -878,6 +932,9 @@ void Engine::toggleRotoBallMode() { rotoball_.angle_y = 0.0f; rotoball_.angle_x = 0.0f; + // Desactivar gravedad al entrar en modo figura + forceBallsGravityOff(); + // Generar esfera 3D generateRotoBallSphere(); @@ -904,6 +961,11 @@ void Engine::toggleRotoBallMode() { ball->enableRotoBallAttraction(false); } + // Activar gravedad al salir (solo si se especifica) + if (force_gravity_on_exit) { + forceBallsGravityOn(); + } + // Mostrar texto informativo text_ = "MODO FISICA"; int text_width = static_cast(text_.length() * 8); diff --git a/source/engine.h b/source/engine.h index 09ae1cf..4f8b32c 100644 --- a/source/engine.h +++ b/source/engine.h @@ -105,6 +105,9 @@ private: void setText(); void pushBallsAwayFromGravity(); void switchBallsGravity(); + void enableBallsGravityIfDisabled(); + void forceBallsGravityOn(); + void forceBallsGravityOff(); void changeGravityDirection(GravityDirection direction); void toggleVSync(); void toggleFullscreen(); @@ -125,7 +128,7 @@ private: void addSpriteToBatch(float x, float y, float w, float h, int r, int g, int b); // Sistema RotoBall - void toggleRotoBallMode(); + void toggleRotoBallMode(bool force_gravity_on_exit = true); void generateRotoBallSphere(); void updateRotoBall(); }; \ No newline at end of file