2 Commits

Author SHA1 Message Date
79964732ef Implementar sistema de auto-reinicio con temporizador de inactividad
- Añadir getter isStopped() en Ball para detectar pelotas quietas
- Sistema de temporizador de 5 segundos que detecta cuando todas las pelotas están paradas
- Auto-reinicio aleatorio cuando se cumple el tiempo de inactividad:
  * Escenario aleatorio usando test_.size() (1 a 100,000 pelotas)
  * Tema aleatorio usando sizeof(themes_) (5 temas disponibles)
  * Reset inteligente del temporizador si alguna pelota se mueve
- Integración no intrusiva en update() del bucle principal
- Usa infraestructura existente (SDL_GetTicks, initBalls, rand)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-27 22:21:30 +02:00
7ac29f899b Implementar impulso direccional adaptativo para tecla ESPACIO
- Renombrar pushUpBalls() → pushBallsAwayFromGravity() con lógica direccional
- ESPACIO ahora impulsa en dirección opuesta a gravedad actual:
  * Gravedad DOWN → impulsa ARRIBA (comportamiento original)
  * Gravedad UP → impulsa ABAJO
  * Gravedad LEFT → impulsa DERECHA
  * Gravedad RIGHT → impulsa IZQUIERDA
- Corregir modVel() para aplicar impulso horizontal a todas las pelotas
- Actualizar documentación de controles en README.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-27 22:10:33 +02:00
6 changed files with 90 additions and 13 deletions

View File

@@ -50,7 +50,11 @@ El nombre refleja su proposito: **ViBe** (vibe-coding experimental) + **Physics*
|-------|--------|
| `1-8` | Cambiar numero de pelotas (1, 10, 100, 500, 1K, 10K, 50K, 100K) |
| `ESPACIO` | Impulsar todas las pelotas hacia arriba |
| `G` | Alternar direccion de la gravedad (↓↑←→) |
| `` | **Gravedad hacia ARRIBA** |
| `↓` | **Gravedad hacia ABAJO** |
| `←` | **Gravedad hacia IZQUIERDA** |
| `→` | **Gravedad hacia DERECHA** |
| `G` | **Alternar gravedad ON/OFF (mantiene direccion)** |
## 📊 Informacion en Pantalla

View File

@@ -207,9 +207,7 @@ void Ball::render() {
// Modifica la velocidad (convierte de frame-based a time-based)
void Ball::modVel(float vx, float vy) {
if (stopped_) {
vx_ = vx_ + (vx * 60.0f); // Convertir a píxeles/segundo
}
vx_ = vx_ + (vx * 60.0f); // Convertir a píxeles/segundo
vy_ = vy_ + (vy * 60.0f); // Convertir a píxeles/segundo
on_surface_ = false;
stopped_ = false;

View File

@@ -55,6 +55,7 @@ class Ball {
float getLossCoefficient() const { return loss_; }
GravityDirection getGravityDirection() const { return gravity_direction_; }
bool isOnSurface() const { return on_surface_; }
bool isStopped() const { return stopped_; }
// Getters para batch rendering
SDL_FRect getPosition() const { return pos_; }

View File

@@ -3,9 +3,9 @@
// Configuración de ventana y pantalla
constexpr char WINDOW_CAPTION[] = "vibe3_physics";
constexpr int SCREEN_WIDTH = 640; // Ancho de la pantalla lógica (píxeles)
constexpr int SCREEN_HEIGHT = 360; // Alto de la pantalla lógica (píxeles)
constexpr int WINDOW_ZOOM = 2; // Zoom inicial de la ventana
constexpr int SCREEN_WIDTH = 320; // Ancho de la pantalla lógica (píxeles)
constexpr int SCREEN_HEIGHT = 240; // Alto de la pantalla lógica (píxeles)
constexpr int WINDOW_ZOOM = 3; // Zoom inicial de la ventana
constexpr int BALL_SIZE = 10; // Tamaño de las pelotas (píxeles)
// Configuración de zoom dinámico de ventana

View File

@@ -147,6 +147,9 @@ void Engine::update() {
if (show_text_) {
show_text_ = !(SDL_GetTicks() - text_init_time_ > TEXT_DURATION);
}
// Verificar auto-reinicio cuando todas las pelotas están quietas
checkAutoRestart();
}
void Engine::handleEvents() {
@@ -166,7 +169,7 @@ void Engine::handleEvents() {
break;
case SDLK_SPACE:
pushUpBalls();
pushBallsAwayFromGravity();
break;
case SDLK_G:
@@ -426,12 +429,32 @@ void Engine::setText() {
text_init_time_ = SDL_GetTicks();
}
void Engine::pushUpBalls() {
void Engine::pushBallsAwayFromGravity() {
for (auto &ball : balls_) {
const int SIGNO = ((rand() % 2) * 2) - 1;
const float VX = (((rand() % 20) + 10) * 0.1f) * SIGNO;
const float VY = ((rand() % 40) * 0.1f) + 5;
ball->modVel(VX, -VY); // Modifica la velocidad de la bola
const float LATERAL = (((rand() % 20) + 10) * 0.1f) * SIGNO;
const float MAIN = ((rand() % 40) * 0.1f) + 5;
float vx = 0, vy = 0;
switch (current_gravity_) {
case GravityDirection::DOWN: // Impulsar ARRIBA
vx = LATERAL;
vy = -MAIN;
break;
case GravityDirection::UP: // Impulsar ABAJO
vx = LATERAL;
vy = MAIN;
break;
case GravityDirection::LEFT: // Impulsar DERECHA
vx = MAIN;
vy = LATERAL;
break;
case GravityDirection::RIGHT: // Impulsar IZQUIERDA
vx = -MAIN;
vy = LATERAL;
break;
}
ball->modVel(vx, vy); // Modifica la velocidad según dirección de gravedad
}
}
@@ -749,4 +772,48 @@ void Engine::initializeThemes() {
{255, 0, 64} // 345° - Magenta claro-Rojo
}
};
}
void Engine::checkAutoRestart() {
// Verificar si TODAS las pelotas están paradas
bool all_stopped = true;
for (const auto &ball : balls_) {
if (!ball->isStopped()) {
all_stopped = false;
break;
}
}
if (all_stopped) {
if (!all_balls_were_stopped_) {
// Primera vez que se detecta que todas están paradas
all_balls_stopped_start_time_ = SDL_GetTicks();
all_balls_were_stopped_ = true;
} else {
// Ya estaban paradas, verificar tiempo transcurrido
Uint64 current_time = SDL_GetTicks();
if (current_time - all_balls_stopped_start_time_ >= AUTO_RESTART_DELAY) {
performRandomRestart();
}
}
} else {
// Al menos una pelota se está moviendo - resetear temporizador
all_balls_were_stopped_ = false;
all_balls_stopped_start_time_ = 0;
}
}
void Engine::performRandomRestart() {
// Escenario aleatorio usando tamaño del array
scenario_ = rand() % test_.size();
// Tema aleatorio usando tamaño del array de temas
current_theme_ = static_cast<ColorTheme>(rand() % (sizeof(themes_) / sizeof(themes_[0])));
// Reinicializar pelotas con nuevo escenario y tema
initBalls(scenario_);
// Resetear temporizador
all_balls_were_stopped_ = false;
all_balls_stopped_start_time_ = 0;
}

View File

@@ -58,6 +58,11 @@ private:
bool fullscreen_enabled_ = false;
bool real_fullscreen_enabled_ = false;
// Auto-restart system
Uint64 all_balls_stopped_start_time_ = 0; // Momento cuando todas se pararon
bool all_balls_were_stopped_ = false; // Flag de estado anterior
static constexpr Uint64 AUTO_RESTART_DELAY = 5000; // 5 segundos en ms
// Resolución dinámica para modo real fullscreen
int current_screen_width_ = SCREEN_WIDTH;
int current_screen_height_ = SCREEN_HEIGHT;
@@ -88,7 +93,7 @@ private:
// Métodos auxiliares
void initBalls(int value);
void setText();
void pushUpBalls();
void pushBallsAwayFromGravity();
void switchBallsGravity();
void changeGravityDirection(GravityDirection direction);
void toggleVSync();
@@ -96,6 +101,8 @@ private:
void toggleRealFullscreen();
std::string gravityDirectionToString(GravityDirection direction) const;
void initializeThemes();
void checkAutoRestart();
void performRandomRestart();
// Sistema de zoom dinámico
int calculateMaxWindowZoom() const;