Funciones avanzadas de dibujo

Esta funcionalidad sólo está disponible en la versión registrada de Game Maker

En los capítulos anteriores hemos descrito las funciones básicas de dibujo. En este capítulo veremos funciones más avanzadas que te otorgan muchas más posibilidades para crear los gráficos de tus juegos. Primero, hay unas funciones que sirven para dibujar formas coloreadas con gradientes o efectos de difuminado. Después veremos las funciones que sirven para dibujar polígonos básicos y por último veremos la forma de dibujar polígonos texturizados.

Las siguientes funciones son versiones extendidas de las funciones de dibujo básicas. Todas ellas admiten parámetros para el color, por lo que ninguna de estas funciones usará el color general de dibujo.

draw_point_color(x,y,col1) Dibuja un punto en la posición (x,y) con el color indicado.
draw_line_color(x1,y1,x2,y2,col1,col2) Dibuja una línea desde (x1,y1) hasta (x2,y2), interpolando el color entre col1 y col2.
draw_rectangle_color(x1,y1,x2,y2,col1,col2,col3,col4,outline) Dibuja un rectángulo. Los cuatro colores indican los colores de los vértices superior-izquierdo, superior-derecho, inferior-derecho e inferior-izquierdo respectivamente. outline indica si sólo debe dibujarse el contorno del rectángulo (true) o si éste debe estar relleno (false).
draw_roundrect_color(x1,y1,x2,y2,col1,col2,outline) Dibuja un rectángulo redondeado. col1 es el color en el centro del rectángulo y col2 en el borde. outline indica si sólo debe dibujarse el contorno del rectángulo (true) o si éste debe estar relleno (false).
draw_triangle_color(x1,y1,x2,y2,x3,y3,col1,col2,col3,outline) Dibuja un triángulo. Los tres colores son los colores en los vértices del triángulo (el color se interpola en las demás zonas entre estos tres colores). outline indica si sólo debe dibujarse el contorno del triángulo (true) o si éste debe estar relleno (false).
draw_circle_color(x,y,r,col1,col2,outline) Dibuja un círculo en (x,y) con radio r. col1 es el color en el centro y col2 en el borde. outline indica si sólo debe dibujarse el contorno del círculo (true) o si éste debe estar relleno (false).
draw_ellipse_color(x1,y1,x2,y2,col1,col2,outline) Dibuja una elipse. col1 es el color en el centro y col2 en el borde. outline indica si sólo debe dibujarse el contorno de la elipse (true) o si éste debe estar rellena (false).

 

También puedes dibujar primitivas más complicadas, pero esto se hace de forma diferente. Primero debes especificar el tipo de primitiva que quieres dibujar. Después especificas los vértices y finalmente la terminas. En este momento se dibuja la primitiva. Existen seis tipos de primitivas:

pr_pointlist Los vértices son un grupo de puntos.
pr_linelist Los vértices son un grupo de líneas. Cada pareja de puntos forma una línea, por lo que debe haber un número par de puntos.
pr_linestrip Los vértices forman una poli-línea de forma que el primer punto se conecta al segundo, el segundo al tercero, etc...El último punto no se conecta al primero. Para conseguir esto, debes especificar otra vez el primer punto al final de la primitiva.
pr_trianglelist Los vértices son un grupo de triángulos. Cada trena de puntos forma un triángulo, luego el número de puntos debe ser un múltiplo de 3.
pr_trianglestrip Los vértices son un grupo de triángulos, pero esta vez  de forma distinta. Los tres primeros puntos forman el primer triángulo. Los dos últimos puntos de este triángulo junto con el siguiente punto forman el segundo triángulo y así sucesivamente. Es decir, cada nuevo punto especifica un nuevo triángulo conectado por un lado al triángulo anterior.
pr_trianglefan Similar a la función anterior, pero esta vez el primer punto forma parte de todos los triángulos. Cada nuevo punto especifica un nuevo triángulo formado también por el punto anterior y por el primer punto, que ya hemos dicho que está presente en todos los triángulos.

Para dibujar primitivas disponemos de las siguientes funciones:

draw_primitive_begin(kind) Comenzar a definir una primitiva del tipo indicado.
draw_vertex(x,y) Añade el vértice (x,y) a la primitiva, usando los valores generales de dibujo de color y transparencia.
draw_vertex_color(x,y,col,alpha) Añade el vértice (x,y) a la primitiva, con los valores de color y transparencia especificados. De esta forma puedes crear primitivas que cambian gradualmente de color u opacidad.
draw_primitive_end() Terminar la definición de la primitiva. En este momento es cuando se dibuja la primitiva.

Finalmente, es posible dibujar primitivas usando sprites o fondos como texturas. Cuando usas una textura la imagen se sitúa sobre la primitiva y se escala para que su tamaño encaje con el de la primitiva. Las texturas se usan para dar detalle a las primitivas, como por ejemplo, una pared de ladrillos. Para usar una textura, primero debes obtener su id. Esto se realiza con las funciones siguientes:

sprite_get_texture(spr,subimg) Devuelve la id de la textura correspondiente a la subimagen subimg del sprite indicado.
background_get_texture(back) Devuelve la id de la textura correspondiente al fondo indicado.

Una textura seleccionada puede que no esté cargada en la memoria de video. Normalmente el sistema se encarga de hacerlo automáticamente pero puede ser que a veces decidas encargarte tú mismo de esto. Puedes hacerlo con las funciones siguientes:

texture_preload(texid) Carga la textura en la memoria de video inmediatamente.
texture_set_priority(texid,prio) Cuando no hay memoria gráfica suficiente algunas texturas se eliminarán temporalmente para hacer sitio a otras que se necesiten. Las texturas con menor prioridad se eliminarán primero. Por defecto todas las texturas tienen prioridad 0 pero con esta función puedes especificar una prioridad distinta para cada una (usa sólo valores positivos).

Para añadir una textura a una primitiva debes especificar dónde se situará cada parte de la textura sobre la primitiva. Las posiciones en la textura se indican con valores entre 0 y 1, pero esto nos presenta un problema. Los tamaños de las texturas siempre deben ser potencias de 2 (por ejemplo, 32x32 o 64x64). Si quieres usar sprites o fondos como texturas debes asegurarte de que cumplan esta restricción. Si no, la textura será completamente blanca. Para hallar qué parte de la textura se está utilizando puedes utilizar las dos siguientes funciones. Ambas devuelven un valor entre 0 y 1 que indica la anchura o altura de la parte de la textura que se está usando. Usando este valor como coordenada de textura indicará el lado derecho o inferior de la textura.

texture_get_width(texid) Devuelve la anchura de la textura con la id especificada. Esta anchura será un valor comprendido entre 0 y 1.
texture_get_height(texid) Devuelve la altura de la textura con la id especificada. Esta altura será un valor comprendido entre 0 y 1.

Para dibujar texturas puedes usar las siguientes funciones:

draw_primitive_begin_texture(kind,texid) Comienza la definición de una primitiva del tipo indicado con la textura indicada.
draw_vertex_texture(x,y,xtex,ytex) Añade el vértice (x,y) a la primitiva con la posición (xtex,ytex) en la textura, usando los valores generales de dibujo de color y transparencia. xtex e ytex deben estar comprendidos entre 0 y 1 pero también pueden usarse valores mayores para hacer que la textura se repita (ver más abajo).
draw_vertex_texture_color(x,y,xtex,ytex,col,alpha) Añade el vértice (x,y) a la primitiva con la posición (xtex,ytex) en la textura, usando le color de teñido y transparencia indicados.
draw_primitive_end() Termina la descripción de la primitiva, dibujándola.

Existen tres funciones que influencian la forma en que se dibujan las texturas:

texture_set_interpolation(linear) Indica si debe usarse interpolación lineal (true) o utilizar el píxel más cercano (false). La interpolación lineal suele conseguir texturas más suaves pero a veces pueden parecer un poco borrosas o hacer que le juego se ralentice. Esta propiedad también afecta a la forma en que se dibujan los sprites y fondos. Por defecto es false (esta propiedad también puede cambiarse desde las opciones globales del juego).
texture_set_blending(blend) Indica si debe usarse blending para el color y la transparencia. Blending es la capacidad para que se mezclen. Así por ejemplo, un sprite puede teñirse de un color. Por defecto es true. Activándola se puede conseguir que el juego vaya más rápido en máquina más viejas. Esta propiedad también afecta a la forma en que se dibujan los sprites y fondos.
texture_set_repeat(repeat) Indica si se permite que la textura se repita. Como hemos dicho las coordenadas de textura deben indicarse en el rango 0-1. Si se especifica un valor mayor que 1, el resto no se dibuja. Sin embargo, si ponemos esta propiedad a true la textura se repetirá hasta llenar la primitiva por completo. Observa que los sprites y fondos siempre se dibujan sin repetición, luego cuando se dibuje un sprite o un fondo este valor volverá a ponerse a false (valor por defecto).

Hay dos funciones más que son muy útiles para dibujar texturas. Normalmente, las primitivas se mezclan con el fondo usando el factor de transparencia. Pero puedes controlar la forma en que sucede esto. Por ejemplo, puedes indicar si los colores de la primitiva deben sumarse a los del fondo o restarse. De esta forma puedes crear puntos de luz o sombras. También es posible elegir el máximo entre el nuevo color y el color original para evitar efectos de saturación que ocurren al sumar varios colores. Observa que ni al restar, ni al calcular el máximo se toma en cuenta el valor de transparencia totalmente (DirectX no lo permite), así que debes asegurarte de que el área alrededor es negra. Como ya hemos dicho, hay dos funciones para esto. La primera te da las cuatro opciones ya descritas. La segunda te da muchas más opciones. Es muy recomendable que experimentes con estas funciones ya que se pueden crear efectos muy espectaculares como explosiones, sombras, efectos de luz, halos...

draw_set_blend_mode(mode) Indica el modo de mezcla a usar de entre los siguientes: bm_normal, bm_add (suma), bm_subtract (resta), y bm_max (máximo). No olvides volver a poner el modo normal cuando termines lo que estás haciendo por que esto afectará a la forma en que se dibujan los sprites y fondos.
draw_set_blend_mode_ext(src,dest) Indica el modo de mezcla que se debe usar para la fuente y el destino. El color resultante se calcula aplicando a cada color (fuente y destino) un factor diferente. Estos factores de mezcla se especifican con esta función. Los colores de fuente y el destino están formados por las componentes de rojo, verde, azul y transparencia. Así, llamamos a los componentes de la fuente (Rf,Gf,Bf,Af) y a los del destino (Rd, Gd, Bd, Ad). Todos estos factores se encuentran entre 0 y 1. Los factores de mezcla que puede usar en esta función son:

Por ejemplo, el modo de mezcla normal pone la fuente a bm_src_alpha y el destino a bm_inv_src_alpha. No olvides volver a poner el modo normal cuando termines porque si no los sprites y fondos se dibujarán con el nuevo modo.

Dibujar primitivas texturizadas es un poco complicado pero se consiguen resultados geniales. Puedes incluso crear juegos en falso 3D.