#include #include "texture.h" #include "ball.h" #include "defines.h" #include "dbgtxt.h" #include #include // Variables globales SDL_Window *window = nullptr; SDL_Renderer *renderer = nullptr; Texture *texture = nullptr; std::vector balls; int test[8] = {1, 10, 100, 500, 1000, 10000, 50000, 100000}; bool shouldExit = false; // Controla si la aplicación debe cerrarse Uint32 ticks = 0; // Tiempo en milisegundos para controlar la actualización int scenario = 0; // Escenario actual basado en el número de bolas std::string text = ""; // Texto a mostrar en pantalla int textPos = 0; // Posición del texto en la pantalla bool showText = true; // Determina si el texto se debe mostrar int counter = 0; // Temporizador para mostrar el texto void deleteBalls(); // Declaración de una función para eliminar bolas // Establece el texto en pantalla mostrando el número de bolas actuales void setText() { const std::string text2 = test[scenario] == 1 ? " PELOTA" : " PELOTAS"; text = std::to_string(test[scenario]) + text2; const int size = text.size() * 8; textPos = SCREEN_WIDTH / 2 - size / 2; counter = TEXT_TIME; showText = true; } // Inicializa las bolas según el escenario seleccionado void initBalls(int value) { deleteBalls(); // Limpia las bolas actuales for (int i = 0; i < test[value]; ++i) { const int sign = ((rand() % 2) * 2) - 1; // Genera un signo aleatorio (+ o -) const float x = (rand() % (SCREEN_WIDTH / 2)) + (SCREEN_WIDTH / 4); // Posición inicial en X const float vx = (((rand() % 20) + 10) * 0.1f) * sign; // Velocidad en X const float vy = ((rand() % 60) - 30) * 0.1f; // Velocidad en Y const color_t color = {(rand() % 192) + 32, (rand() % 192) + 32, (rand() % 192) + 32}; // Color aleatorio Ball *b = new Ball(x, vx, vy, color, texture); balls.push_back(b); // Añadir la nueva bola al vector } setText(); // Actualizar el texto } // Aumenta la velocidad vertical de las bolas "hacia arriba" void pushUpBalls() { for (auto ball : balls) { const int sign = ((rand() % 2) * 2) - 1; const float vx = (((rand() % 20) + 10) * 0.1f) * sign; const float vy = ((rand() % 40) * 0.1f) + 5; ball->modVel(vx, -vy); // Modifica la velocidad de la bola } } // Cambia la gravedad de todas las bolas void switchBallsGravity() { for (auto ball : balls) { if (ball) { ball->switchGravity(); } } } // Elimina todas las bolas y libera memoria void deleteBalls() { for (auto ball : balls) { if (ball) { delete ball; ball = nullptr; } } balls.clear(); // Limpia el vector } // Inicializa SDL y configura los componentes principales bool init() { bool success = true; // Bandera de éxito // Inicializa SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("¡SDL no se pudo inicializar! Error de SDL: %s\n", SDL_GetError()); success = false; } else { // Crear ventana principal window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH * WINDOW_SIZE, SCREEN_HEIGHT * WINDOW_SIZE, SDL_WINDOW_SHOWN); if (window == nullptr) { printf("¡No se pudo crear la ventana! Error de SDL: %s\n", SDL_GetError()); success = false; } else { // Crear renderizador renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (renderer == nullptr) { printf("¡No se pudo crear el renderizador! Error de SDL: %s\n", SDL_GetError()); success = false; } else { // Establecer color inicial del renderizador SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); // Establecer tamaño lógico para el renderizado SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); } } } // Inicializar otros componentes texture = new Texture(renderer, "resources/pelota.png"); ticks = SDL_GetTicks(); srand(time(nullptr)); dbg_init(renderer); // Inicializar herramientas de depuración initBalls(scenario); return success; } // Limpia todos los recursos y cierra SDL void close() { SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); window = nullptr; renderer = nullptr; if (texture) { delete texture; texture = nullptr; } deleteBalls(); // Liberar memoria de las bolas SDL_Quit(); // Finalizar SDL } // Verifica los eventos en la cola void checkEvents() { SDL_Event event; while (SDL_PollEvent(&event) != 0) { // Evento de salida if (event.type == SDL_QUIT) { shouldExit = true; break; } // Procesar eventos de teclado if (event.type == SDL_KEYDOWN && event.key.repeat == 0) { switch (event.key.keysym.sym) { case SDLK_ESCAPE: shouldExit = true; break; case SDLK_SPACE: pushUpBalls(); break; case SDLK_g: switchBallsGravity(); break; case SDLK_1: scenario = 0; initBalls(scenario); break; case SDLK_2: scenario = 1; initBalls(scenario); break; case SDLK_3: scenario = 2; initBalls(scenario); break; case SDLK_4: scenario = 3; initBalls(scenario); break; case SDLK_5: scenario = 4; initBalls(scenario); break; case SDLK_6: scenario = 5; initBalls(scenario); break; case SDLK_7: scenario = 6; initBalls(scenario); break; case SDLK_8: scenario = 7; initBalls(scenario); break; } } } } // Actualiza la lógica del juego void update() { if (SDL_GetTicks() - ticks > 15) { ticks = SDL_GetTicks(); for (auto ball : balls) { ball->update(); } if (counter > 0) { counter--; } else { showText = false; } } } // Renderiza el contenido en la pantalla void render() { SDL_SetRenderDrawColor(renderer, 32, 32, 32, 255); SDL_RenderClear(renderer); for (auto ball : balls) { ball->render(); } if (showText) { dbg_print(textPos, 8, text.c_str(), 255, 255, 255); } SDL_RenderPresent(renderer); } // Función principal int main(int argc, char *args[]) { init(); while (!shouldExit) { update(); checkEvents(); render(); } close(); return 0; }