Introducción a los objetos en Game Maker Studio
Hemos visto varios tipos de recursos hasta ahora, como los sprites para hacer algunas animaciones, o los sonidos para aportar riqueza a nuestro juego. Hemos añadido todas estas cosas, pero el juego no hace nada aún. ¿Por qué? Porque todavía no hemos usado el recurso más importante de todos: los objetos.
¿Qué es un objeto en Game Maker? Los objetos es un recurso que utilizamos para controlar todos los aspectos del juego, gracias a la programación de los diferentes comportamientos que pueden tener. Un objeto puede tener un sprite asociado para que podamos verlo y controlarlo mientras jugamos, pero también puede ser invisible y que haga otras cosas como controlar el tiempo, vidas, etc.
Diferencia entre instancias y objetos
En realidad, no colocamos los objetos en una room para que se ejecuten. Lo que colocamos son instancias de esos objetos. Y, ¿qué es una instancia en Game Maker? Podemos decir que una instancia es una copia de ese objeto, una plantilla con todas las características que pueden hacer. Lo comento porque hay cosas que se pueden hacer con objetos y cosas que se pueden hacer con instancias, ya que aunque lo parezca no es lo mismo.
¿Porqué es diferente? Cuando decimos que algo afecta a una instancia, afecta solo a esa copia en particular que se ha creado en la room. Si existen otras instancias del mismo objeto, a esas no les afecta en nada. Cuando decimos que algo afecta a un objeto, le afectará a todas las instancias que hay en la room en ese momento.
Creando un objeto nuevo
Para crear un objeto nuevo, hacemos como siempre: o desde el árbol de recursos, botón derecho o desde el menú Resources – Create Object. Aparecerá una ventana parecida a ésta:
Vemos que la ventana de propiedades del objeto tiene muchisimas opciones, pero no hay que asustarse, las explicaremos todas, y ya veréis que es muy fácil de usar cuando nos hemos acostumbrado. Vamos a ver cada una de las secciones que hay.
En la parte izquierda, podemos ver algunas propiedades del objeto: podemos darle un nombre, recomendable usar el prefijo obj_, y otras propiedades genéricas. En la parte central vemos una lista de eventos, que podemos añadir y cambiar una gran lista de ellos. En la parte de la derecha, vemos una sección sobre las acciones, que están relacionadas para cada uno de los eventos. Podemos añadir un gran número de acciones, que podemos seleccionarlas de las pestañas y botones que vemos en la derecha. Los eventos y las acciones las comentaremos en detalle en próximos capítulos, ya que es la parte más importante de Game Maker Studio y es la base sobre la que programaremos. Ahora veremos las propiedades más importantes de un objeto.
Propiedades de un objeto en Game Maker Studio
Como ya hemos comentado, debemos ponerle un nombre que identifique el objeto. Debajo de donde indicamos el nombre, podemos elegir, si queremos, el sprite que inicialmente asociaremos al objeto. Para hacerlo, hay que hacer click izquierdo en el cuadro de texto o en el botón de al lado del agrupador de sprites, y aparecerá un menú emergente con todos los sprites, con la misma estructura de subcarpetas que hay en el árbol de recursos. Elegimos un sprite, y aparecerá su nombre y una visualización en miniatura al lado. Vemos que hay dos botones dentro del cuadro, el botón Edit, que abriría la ventana de propiedades del sprite seleccionado, y el botón New, que abriría la misma ventana pero para crear un sprite nuevo. Así podemos acceder a los sprites rápidamente sin necesidad de buscarlo en el árbol de recursos.
Vamos a ver otras propiedades que aparecen más abajo.
Propiedad Visible
La propiedad visible indica si las instancias, recordemos que son las instancias las que se ven en la room y no los objetos, se van a ver cuando se inician en la room. Decimos cuando se inician porque esta propiedad la podemos cambiar en cualquier momento. Lo habitual es que en la gran mayoría de veces serán visibles, pero a veces es útil tenerlos como invisibles. Por ejemplo, podemos crear un objeto obj_wall, le asociamos un sprite cuadrado y ese objeto será el que delimitará hasta dónde puede llegar un jugador. definir límites de juego, movimientos de enemigos, acciones programadas, etc. Aunque los objetos sean invisibles, reaccionarán de la misma manera a los eventos y acciones. Aunque estos objetos sean invisibles, es importante también definir su sprite, ya que también podrá usar su máscara para los eventos de colisión con otros objetos.
Un tema importante es que el evento Draw, que se utiliza para pintar sprites y otras opciones, no se ejecutaría, así que si tenemos acciones en este evento y en algún momento ponemos la instancia a invisible, se dejará de ejecutar.
Propiedad Solid
Al marcar esta propiedad, definimos el objeto como Sólido. Es muy importante esta propiedad, sobretodo para los eventos de colisión con otros objetos, ya que funcionan de manera diferente, y la recomendación es que los objetos que sean sólidas no se muevan. Ya hablaremos en detalle cuando hablemos de colisiones.
Propiedad Depth / Profundidad
Podemos ajustar la profundidad de las instancias, para controlar cómo se ven cuando se solapan entre ellas. Así veremos cual va por debajo y cual va por encima de otros objetos en otras profundidades. Cuando mayor sea el número que pongamos en Depth, mayor será su profundidad y se verá por debajo de otras instancias. Vemos un ejemplo sacado de la ayuda on line:
¿Y qué ocurre en los objetos que tienen la misma profundidad? No hay ninguna garantía de cómo se pueden ver. Yo he visto que el orden de creación de las instancias influye en la profundidad, siendo las más nuevas creadas las que se colocan por encima. Pero si no queremos arriesgarnos, damos profundidad con números negativos para las instancias que queremos por encima, y con números positivios para las que queramos más por debajo.
Esta propiedad puede ser cambiada durante el juego, al igual que la propiedad anterior.
Objetos persistentes
Cuando cambiamos de una room a otra, todas las instancias de objetos que se han creado se destruyen y se crean de nuevas las que hemos indicado en la siguiente room. Si nos interesa que una instancia permanezca siempre, marcamos la propiedad Persistent. Solo desaparecerá si se lo indicamos nosotros de forma explícita, ya sea con la acción correspondiente o mediante código GML.
Un ejemplo de esto sería tener un personaje principal, con todas sus características, que se va moviendo de una room a otra.
Cosas a tener en cuenta con objetos persistentes
Tenemos que tener especial cuidado de crear y destruir objetos persistentes correctamente, ya que puede ser una fuente de errores. Por ejemplo, si estamos jugando con nuestro objeto persistente como personaje principal, pausamos el juego y tenemos una opción de volver al menú principal, obviamente ¡aparecerá nuestro personaje si no lo hemos destruido!
Otro tema son sus eventos: los eventos Game Start, Game End, Room Start y Room End se habrán desencadenado (comprobar si se desencadena eventos de room al cambiar de room). Si reiniciamos el juego, con la acción correspondiente o con la función game_restart()
, todos los objetos se destruyen, incluidos los objetos persistentes, así que tocaría crearlos de nuevo.
Si desactivamos un objeto persistente, éste no va a cambiar de una room a otra, a no ser que lo volvamos a activar antes que se ejecute el evento Room End.
Herencia entre objetos: propiedad parent
Una de las opciones más importantes que existen en Game Maker Studio es la posibilidad de herencia entre objetos. Si conoces otros lenguajes de programación, verás que existen similitudes, pero también cosas diferentes y particulares con Game Maker. En esta opción podemos definir un objeto padre al objeto que estamos modificando, de ahí el término de herencia.
Haremos un resumen rápido ahora para entender el concepto, y en el futuro ya iremos en detalle con estas características. Un objeto padre comparte código, acciones y eventos con el objeto hijo. Eso significa que si tenemos un evento Create en el objeto padre, las acciones que habrá también se ejecutarán en sus hijos. Pero además, si tenemos otros objetos que tienen un evento de colisión con un objeto padre, sería lo mismo que tenerlo para los hijos.
Podéis imaginar el ahorro en tiempo que supone esto. Imaginemos un personaje que puede tener una pistola, una escopeta, etc.. Cuando dispara, podemos tener diferentes objetos de bala. Si lo pensamos bien, ya sea una bala de pistola, escopeta, recortada, metralleta, etc, hará exactamente lo mismo: se moverá a una velocidad en una dirección, y si impacta en otro objeto le hará un daño y desaparecerá. ¿Cual es la diferencia entre cada una de las balas? Quizás la velocidad y seguramente el daño causado. Podríamos tener un objeto que hiciese todos los eventos y acciones, y luego en cada objeto hijo definir solamente el daño que hace. Así podemos tener muchos objetos y con un mínimo esfuerzo aplicarle sus características.
Si le damos al botón que tiene el texto Parent, abriremos automáticamente una nueva ventana de propiedades del objeto padre, sin necesidad de buscarlo en el árbol de recursos. Más abajo, también tenemos una lista de los objetos hijos que están asociados, pudiendo abrir cualquiera de ellos haciendo click en el nombre.
Máscaras en objetos
Ya hemos hablado anteriormente de las máscaras de sprites. Pueden tener la misma forma que el sprite, o definir una forma básica como un rectángulo o un óvalo. También podemos definir una máscara diferente para cada subimagen del sprite.
Cuando un objeto le hemos asociado un sprite, la máscara del objeto es la del sprite. Aunque es posible que nos interese que un objeto tengo una máscara diferente a la del sprite asociado, o incluso que no tenga sprite pero sí máscara. Se puede hacer gracias a esta propiedad del objeto.
Recordad, las máscaras son importantes para los eventos de colisión porque indicarán cuando se producen. Si un objeto no tiene máscara no se producirá su evento de colisión.
Información del objeto
Vemos un botón que pone Show Information, dónde mostraría un texto con una visión general de todo el objeto, con sus eventos y acciones. Así podemos imprimirlo o guardarlo como HTML, para poder echar una ojeada o depurar el código del objeto.
Usar Physics
Si marcamos este check, le decimos que el objeto debe ser parte de un mundo con elementos de físicas. Abrirá parte de la ventana del objeto con nuevas propiedades físicas para definir.
Estas propiedades se verán de esta manera:
- Forma de colisión: Con el sistema de colisiones normales, usamos la máscara asignada al objeto, pero con las físicas activadas, ya no ocurre así. Tenemos que asignar una máscara nueva nosotros mismos, que puede ser un círculo, un rectángulo o una forma poligonal. Si es una forma poligonal, tenemos que seleccionarla nosotros mismos, con el botón Modify collision Shape (modificar forma de colisión), y veremos la siguiente ventana:
Es muy parecida al editor de paths, que hablaremos próximamente, y funciona de una manera muy parecida, pero tiene una serie de condiciones:
- Si es una máscara circular, solo podemos modificar el diámetro para cambiar su tamaño.
- Si es una máscara rectangular, podemos modificar sus esquinas.
- Si es un polígono, tiene que tener entre 3 y 8 puntos y debe ser convexo.
- Densidad: la densidad podemos definirla como la masa que tiene dentro de un volumen, así que su equivalente es el peso que tendrá dentro del espacio que hemos definido. Por ejemplo, un globo tendrá una densidad baja, un bloque de piedra tendrá una densidad alta (aunque ocupe el mismo volumen). Como vemos, no podemos definir el peso de un objeto, definimos su densidad y Game Maker lo calculará dependiendo del volumen que ocupa.
- Restitución: es para definir el rebote de un objeto cuando choca. Podemos decir si un objeto rebota mucho o poco, aunque también dependerá de propiedades como la gravedad o la fricción.
- Grupo de colisiones: Por defecto su valor es 0, lo que significa que su interacción es normal, así que funcionará con un evento de colisión. Si le damos un valor positivo, le decimos que estas instancias de objetos siempre chocan, y si tiene valor negativo es que nunca chocan. Usar grupos implica mucho proceso de máquina, así que hay que utilizarlo lo menos posible.
- Amortiguación lineal: se utiliza para reducir la velocidad de una instancia, cuando no existe colisión.
- Amortiguación angular: igual que la anterior, pero se utiliza en movimiento circular y reducir su rotación. Así no giraría infinitamente.
- Fricción: es la resistencia del movimiento cuando hay colisión, es decir, cuando chocan dos objetos.
Tenemos además tres checks para activar o desactivar y cambiar su comportamiento. Estas opciones son:
- Sensor: diremos que ignore las propiedades físicas del objeto, pero que devuelva los eventos de colisión de los objetos de alrededor.
- Empezar despierto: está marcado por defecto, para que los objetos con físicas tenga sus propiedades activas desde el principio. Si no nos interesa, lo desmarcamos y no actuará hasta que algo actúe en el objeto.
- Cinemática: habrá algunos casos que tengamos objetos dentro del mundo físico que no nos interesa que actúe fuerzas como la gravedad, ni colisiones, como pueden ser plataformas móviles o el suelo. Podríamos definir su densidad a 0 para que no afecte, pero eso significaría que su física no reacciona a nada y sería un objeto estático. Si en cambio marcamos esta casilla, no reaccionará a colisiones ni gravedad, pero todavía podremos moverlo o girarlo usando las variables apropiadas (podríamos tener plataformas móviles).
Conclusión final
Hemos visto que es un objeto, para que sirve y las características más importantes que tiene. Antes de detallar los eventos y acciones que podemos asignar a un objeto, hablaremos un poco en detalle sobre la herencia en otro artículo y como podemos agrupar varios objetos que hagan lo mismo.
Excelente guía de Game Maker!! Muy buen trabajo!!!
10/10