Programación de videojuegos - Mostrar mensajes

En el transcurso de un juego vamos a necesitar mostrar mensajes por pantalla, al crear menús de opciones, mostrar el score, o cualquier otra información que queramos transmitir al usuario. Para poder escribir el texto en la ventana SDL necesitamos el uso de fuentes (fonts). SDL_ttf nos permite cargar cualquier fuente TrueType (.ttf), renderizarla con los parámetros que necesitemos y utilizarla como cualquier otra textura.

Lo primero que tenemos que hacer es inicializar la biblioteca con SDLTTF.init(). Un buen lugar para hacerlo es justo después de la inicialización de SDL.

if (SDLTTF.init() == -1) { 
    critical ("Couldn't initialize SDLTTF: %s\n", SDL.get_error()); 
} 

Comprobamos que la inicialización es correcta, si hay algún error (retorno = -1) podemos obtener el error con SDL.get_error().

Luego tenemos que cargar el font. Esto se hace creando una instancia de la clase Font, en la que se le pasa el path del fichero .ttf con el font TrueType y el tamaño que queremos darle:

this.font = new Font (path, size); 

Una vez cargado tenemos tres formas de renderizar el texto para mostrarlo en pantalla:

  • El renderizado Solid es rápido, pero "sucio". Tiene la velocidad de renderizado más rápida de todos los modos de renderizado. El texto no se muestra integrado de forma suave con el fondo, de ahí que se diga que es "sucio". Este modo se utiliza cuando el texto cambia y se tiene que actualizar muy rápidamente.
    Font Render Solid
  • El renderizado Blended es lo opuesto al Solid. De buena calidad, pero lento. La fuente se difumina con el fondo produciendo una combinación agradable sobre otra imagen. Es el modo a usar cuando el texto no cambie demasiado rápido y se desee una alta calidad en el resultado.
    Font Render Blended
  • El tercero, Shaded, se encuentra a camino entre los otros dos en velocidad de renderizado y calidad. El renderizado Shaded agrega un fondo al texto renderizado. Debido a esto, esta función de renderizado toma un color adicional más que los otros estilos para usar como color de fondo. Se usa cuando se necesita buena calidad y se puede asumir el cuadro que se crea.
    Font Render Shaded

Cada uno de estos tres métodos llama a una de las funciones para renderizar solid - shaded - blended:

public void set_text_solid (string text = "Demo") { 
    info_s = this.font.render (text, this._color); 
    texture_info_s = Video.Texture.create_from_surface (wsdl.renderer, 
                                                            info_s); 
} 
 
public void set_text_shaded (string text = "Demo") { 
    info_s = this.font.render_shaded (text, this._color, 
                                            this._background_color); 
    texture_info_s = Video.Texture.create_from_surface (wsdl.renderer, 
                                                            info_s); 
} 
 
public void set_text_blended (string text = "Demo", int wrap_length = 200) { 
    info_s = this.font 
                .render_blended_wrapped (text, this._color, wrap_length); 
    texture_info_s = Video.Texture.create_from_surface (wsdl.renderer, 
                                                            info_s); 
} 

Ejemplo

Vamos a ver un ejemplo en el que ponemos un fondo y escribimos un texto con cada uno de los sistemas de renderizado.

El código referente al uso de fonts se encuentra en la clase RFont que nos permite cargar un font, renderizarlo usando alguno de los tres métodos que hemos visto y copiar la textura resultante a un punto.

Con el fin de ver mejor las diferentes formas en que se renderizan los fonts, dibujo primero un fondo animado.

Tenemos el ejemplo completo en el repositorio git:

$ git clone https://git.clibre.io/gaming/demofonts2.git

Para construir e instalar:

$ cd demofonts2
$ meson build
$ cd build
$ ninja
$ ninja install

Demo Render Fonts

Font metrics

En la clase RFont he añadido un método llamado print_metric (), que imprime las medidas de un carácter que le pasamos como parámetro con en el font seleccionado:

public void print_metric (uchar letter) { 
    int minx, maxx, miny, maxy, advance, res; 
    res = this.font.get_metrics (letter, out minx, out maxx, out miny, 
                                    out maxy, out advance); 
    if (res == -1) { 
        warning ("Error in get_metrics: %s\n", SDL.get_error ()); 
    } else { 
        int fontheight = this.font.get_height (); 
        int fontascent = this.font.get_ascent (); 
        int fontdescent = this.font.get_descent (); 
        int fontlineskip = this.font.get_lineskip (); 
 
        print ("minx\t\t:%d\n", minx); 
        print ("maxx\t\t:%d\n", maxx); 
        print ("miny\t\t:%d\n", miny); 
        print ("maxy\t\t:%d\n", maxy); 
        print ("advance\t\t:%d\n", advance); 
        print ("font height\t:%d\n", fontheight); 
        print ("font ascent\t:%d\n", fontascent); 
        print ("font descent\t:%d\n", fontdescent); 
        print ("font line skip\t:%d\n", fontlineskip); 
    } 
} 

Podemos ver las correspondencias de las medidas en el siguiente diagrama (imagen incluida en la documentación de la librería SDL_ttf):

Glyph Metrics

Esta información nos puede resultar de utilidad para conocer las medidas de la textura que vamos a crear y poder posicionara de forma correcta.

Por hoy es todo, espero que pueda resultar de utilidad.

(2 votos)
Etiquetado como :

Deja un comentario

Asegúrese de introducir toda la información requerida, indicada por un asterisco (*). No se permite código HTML.