[SFML] Abriendo y trabajando con una ventana

Topic created · 1 Mensajes · 1551 Visitas
  • Abriendo y trabajando con una ventana

    Introducción

    Este tutorial solo describe como abrir y trabajar con una ventana. Dibujar cosas esta fuera de este módulo. De igual manera leer este tutorial es de vital importancia para generar cualquier aplicación.

    Abriendo una ventana

    Las ventanas son definidas por la clase sf::Window. Una ventana puede ser creada y abierta directamente en la construcción:
    #include
    int main()
    {
    sf::Window window(sf::VideoMode(800, 600), "My window");
    ...
    return 0;
    }

    El primer argumento, VideoMode, define el tamaño de la ventana (el tamaño interno, sin la barra de título y los bordes). Aqui, hemos creado una ventana de 800x600 pixeles.

    El segundo argumento es simplemente el nombre de la ventana.

    Además este constructor acepta un tercer argumento opcional: el estilo, que nos dará a escoger la decoración y las características que buscas:
    sf::Style::None : Sin decoración (útil para pantallas de inicio); este estilo no puede ser combinado con otros
    sf::Style::Titlebar : La ventana posee una barra de título
    sf::Style::Resize : La ventana puede ser cambiada de tamaño y posee un botón de maximizar
    sf::Style::Close : La ventana tiene un botón de cerrar
    sf::Style::Fullscreen : La ventana se muestra en modo pantalla completa; este estilo no puede ser combinado con otros
    sf::Style::Default : El estilo por defecto (Titlebar, Resize y Close)
    Si buscas crear la ventana despues de la instancia de construcción de sf::Window, o recrearla con un modo diferente de video o con otro título, puedes usar la función create que toma exactamente los mismos argumentos:
    #include
    int main()
    {
    sf::Window window;
    window.create(sf::VideoMode(800, 600), "My window");
    ...
    return 0;
    }

    Trayendo la ventana a la vida

    Si tratas de ejecutar el código de arriba sin colocar nada en el lugar de "...", dificilmente podrás ver algo. Primero, por que el programa termina inmediatamente. Segundo, por que no existe hay control de eventos, con lo que incluso añadiendo un bucle se verá una ventana muerta, incapaz de moverse o siquiera de cambiar tamaño.

    Vamos a añadir un poco de código para que este programa sea mas interesante:
    #include

    int main()
    {
    sf::Window window(sf::VideoMode(800, 600), "My window");
    //Bucle de aplicación
    while (window.isOpen())
    {
    //Revisa si algun evento de sf::Window se ha activado
    sf::Event event;
    while (window.pollEvent(event))
    {
    //Si se solicita cerrar la ventana, esta se cierra
    if (event.type == sf::Event::Closed)
    window.close();
    }
    }
    return 0;
    }

    El código de arriba puede abrir una ventana, la termina cuando el usuario la cierra. Veamos como funciona en detalle.

    Primero, hemos agregado un loop que se asegura que la aplicación se actualice hasta que la ventana se cierre. La mayoría (no todos) de los programas en SFML tienen este tipo de loop, a veces son llamados main loop o game loop.

    Luego lo primera que hacemos dentro de nuestro game loop es ver si algún evento ha sido desencadenado. Noten que utilizamos un bucle while para que todos los eventos se procesen, en caso de que hubiera alguno pendiente. La función pollEvent devuelve true si un evento está pendiente, o false si no hay eventos pendientes.

    Siempre que exista un evento desencadenado, debemos comprobar el tipo de evento (cerrar ventana, tecla pulsada, mouse en movimiento, joystick conectado) y reaccionar si esque estamos interesados en dicho evento. En este caso, solo nos preocupamos por el evento Event::Closed, que se desencadena cuando el usuario quiere cerrar la ventana. En este punto, la ventana esta aún abierta y tenemos que cerrarla de forma explícita con la función close. Esto permite hacer algo antes de que la ventana sea cerrada, como guardar el estado actual de la aplicacion, o mostrar un mensaje.

    Despues que la ventana ha sido cerrada, el programa sale del game loop y termina.

    Hasta ahora, probablemente te has dado cuenta que no hemos hablado acerca de dibujar algo en la ventana. Esto no es trabajo del modulo window, tendrás que saltar al modulo de gráficos si quieres dibujar algo como un sprite, textos o formas.

    Por lo tanto, no esperes ver algo interesante en esta ventana: lo mas probable es que veas un color uniforme (negro o blanco).

    Jugando con la ventana

    Por supuesto, SFML te deja jugar un poco con la ventana creada. Existen operaciones basicas con la ventana, como cambiar el tamaño, la posicion, el título o el ícono.
    // Cambia la posición de la ventana.
    window.setPosition(sf::Vector2i(10, 50));
    // Cambia el tamaño de la ventana
    window.setSize(sf::Vector2u(640, 480));
    // Cambia el título de la ventana
    window.setTitle("SFML window");
    // Obtiene el tamaño de la ventana
    sf::Vector2u size = window.getSize();
    unsigned int width = size.x;
    unsigned int height = size.y;
    ...

    Controlando el framerate

    A veces, cuando la aplicación se ejecuta, puedes notar defectos visuales como lagrimeos. La razón es que la frecuencia de actualización de tu aplicación no está sincronizada con la frecuencia vertical del monitos, y como resultado, la parte inferior de la trama se mezcla con la siguiente.
    La solución a este problema es activar la sincronización vertical utilizando la función setVerticalSyncEnabled:
    // Activa la sincronización, después de crear la ventana.
    window.setVerticalSyncEnabled(true);

    Después de llamar esta función, tu aplicación correrá a la misma frecuencia del monitor, aproximadamente 60 cuadros por segundo.