SFML 2: Crear una ventana

Una vez preparado el entorno de trabajo como vimos en el artículo anterior es hora de ponerse manos a la obra. Vamos a empezar borrando el código fuente que hay en el archivo main.cpp para empezar de 0 e ir paso a paso. En este artículo el objetivo es obtener el código que se dio de prueba y crear una ventana.

SFML 2, una estructura modular

Una de las claves de SFML es su estructura modular que nos permite usar solo las partes de la biblioteca que nos interesa sin tener que depender de todos los módulos. Veamos la relación que existe entre los módulos de SFML.

Módulo Depende de
System -
Window System
Graphics System, Window
Audio System
Network System

Como vemos todas dependen de System (menos la propia System) y Graphics además depende de Window. Lo bueno que tiene es que al incluir una que depende de otra, ya la otra queda automáticamente incluida, así, al incluir el módulo Graphics este incluye automáticamente a Window y System.

Así que si lo que queremos es trabajar con el modo gráfico de SFML solo debemos hacer lo siguiente.

#include 

Con solo esta línea ya podemos usar los módulos System, Window y Graphics de SFML. Para usar además el de Audio y Network habría que incluir las siguientes líneas

#include 
#include 

Con esas tres líneas tendríamos acceso a toda las funcionalidades que nos aporta SFML.

Creando un programa base

Bien una vez conocida la relación de los módulos de SFML por ahora nos vamos a centrar en el módulo Window que es el encargado de crear la ventana de la aplicación y manejar todos los eventos que suceden en ella. Así que empezamos con el siguiente código.

#include <SFML/Window.hpp>
 
 int main()
 {
     // Crea una ventana de 640x480x32 con el título SFML window
     sf::Window window(sf::VideoMode(640, 480, 32), "SFML window");

     // Activa la sincronización vertical (60 fps)
     window.setVerticalSyncEnabled(true);
 
     // Game Loop mientras la ventana esté abierta
     while (window.isOpen())
     {
         // Creamos un objeto evento
         sf::Event event;
         // Procesamos la pila de eventos
         while (window.pollEvent(event))
         {
             // Si el evento es de tipo Closed cerramos la ventana
             if (event.type == sf::Event::Closed)
                 window.close();
         }
 
         // Actualizamos la ventana
         window.display();
     }
 
     return 0;
 }

Después de incluir el módulo Window (Recuerda ahora podemos usar Window y System) procedemos a crear nuestra función main que ejecuta el programa.

El espacio de nombre sf

Una cosa importante es que todas las clases, funciones y tipos de datos de SFML están incluidos dentro del espacio de nombre sf, así para acceder a cualquier elemento que proporciona SFML hay que anteponer sf::.

Recomiendo encarecidamente no usar la famosa sentencia using namespace sf porque sería reducir a casi nula la funcionalidad de los espacios de nombre que nos permite con un simple vistazo ver a que colección pertenece nuestro elemento y evitar sobreescribirlo con un elemento propio.

Creando una ventana

Una vez aclarado esto lo primero que hay que hacer en un programa SFML es crear una ventana, esto se hace creando un objeto sf::Window como vemos que recibe como parámetros un objeto sf::VideoMode que no es más que una clase que almacena las dimensiones y la profundidad de color de un modo de vídeo, una cadena de caracteres que representa al título de la ventana y como parámetro opcional aceptaría el estilo de la ventana que define si es a pantalla completa, si se puede redimensionar o cerrar. Para ver todos los constructores y funciones que admite un objeto sf::Window lo mejor es irse a la documentación oficial de la clase.

Después de crear la ventana de la aplicación lo siguiente que hacemos es activar la sincronización vertical mediante el método setVerticalSyncEnabled esto lo que hace es que la aplicación vaya a 60 frames por segundo que es la taza de sincronización de los monitores evitando un molesto parpadeo. Si se quiere otra taza de fps se puede usar el método setFramerateLimit, todo está muy bien documentado.

A continuación viene la parte más importante de todo videojuego, el Game Loop es el bucle que se repite constantemente durante la ejecución del juego y que nos permite actualizar y dibujar los elementos del mismo.

En nuestro caso la estructura es un while que se repite mientras la ventana de la aplicación esté abierta, esto se comprueba llamando al método isOpen de la ventana.

Ya dentro del bucle es donde debemos meter todo lo que queremos que se ejecute en cada ciclo del juego. Lo primero que debemos hacer es procesar los eventos.

Controlando los eventos

En SFML los eventos que llegan a la ventana se van almacenando en una pila de la que se van extrayendo para procesarlos mediante el método pollEvent. Este método lo que hace es extraer un evento de la pila y almacenarlo en el objeto sf::Event pasado como parámetro. El método devuelve true si hay elementos en la pila y false en caso contrario. Así para procesar todos los eventos de la pila debería llamarse al método desde un bucle.

 sf::Event event;
 while (window.pollEvent(event))
 {
    // procesar evento...
 }

Como vemos lo que hacemos es crear un objeto sf::Event llamado event al que vamos a ir asignando los objetos que sacamos de la pila en el bucle. Dentro del bucle procesamos el evento.

Tipos de eventos

SFML maneja los siguientes tipos de eventos, casa uno con sus propiedades y parámetros distintos.

  • Closed - Se cierra la ventana.

  • Resized - Se redimensiona la ventana

  • LostFocus - La ventana pierde el foco

  • GainedFocus - La ventana obtiene el foco

  • TextEntered - Entrada de texto.

  • KeyPressed - Tecla pulsada.

  • KeyReleased - Tecla liberada.

  • MouseWheelMoved - Se mueve la rueda del ratón.

  • MouseButtonPressed - Se pulsa botón del ratón.

  • MouseButtonReleased - Se libera botón del ratón

  • MouseMoved - Se mueve el ratón.

  • MouseEntered - El ratón entra en la ventana

  • MouseLeft - El ratón sale de la ventana

  • JoystickButtonPressed - Se presiona un botón del joystick

  • JoystickButtonReleased - Se libera un botón del joystick

  • JoystickMoved - Se mueve el joystick

  • JoystickConnected - Se conecta el joystick

  • JoystickDisconnected - Se desconecta el joystick

Como vemos cada uno tiene unas propiedades diferentes según el tipo de uno puede que tenga sentido que nos de sus coordenadas x, y como la de la posición del ratón y otro la tecla pulsada como KeyPressed. En la documentación de la clase se puede ver con que parámetros cuenta cada evento.

Ahora volvemos a nuestro código en el que comprenderemos el código que viene a continuación, nuestro procesador de eventos. En este caso solo queremos procesar si hay evento de cierre por lo que comprobamos la pila de eventos y si alguno es te cierre mandamos la orden de cerrar la ventana.

Por último en la ultima sentencia llamamos al método display que actualiza la ventana, esto será necesario cuando dibujemos en nuestra ventana ya que es la sentencia que refresca lo dibujado mostrando una nueva imagen.

Conclusión

Ya debemos entender los conceptos básicos de SFML 2, como crear una ventana y cómo procesar eventos. Puedes hacer pruebas comprobando otro tipo de eventos e imprimiendo sus valores por consola para ver como trabajan.

En el próximo artículo veremos como controlar el tiempo en SFML 2, una parte fundamental del desarrollo de videojuegos.

En Genbeta Dev | SFML 2, biblioteca para el desarrollo de videojuegos En Genbeta Dev | SFML 2: Crear un entorno de trabajo

Ver todos los comentarios en https://www.genbeta.com

VER 0 Comentario

Portada de Genbeta