GAME MAKER
Usando Game Maker
Esta sección describe el uso básico de Game Maker. Explica la idea global detrás del programa, cómo añadir sprites, fondos y sonidos y cómo definir objetos con eventos y acciones y añadirlos a los cuartos. En esta sección se cubren los siguientes temas: Introducción Instalación Registro La idea global Un ejemplo sencillo La interfaz global de usuario Definiendo los sprites Sonidos y música Fondos Definiendo objetos Eventos Acciones Creando rooms Distribuyendo tu juego
Usando Game Maker
Así que quieres crear tus propios videojuegos Jugar juegos de computadora es divertido. Pero es más divertido diseñar tus propios juegos y que otros los jueguen. Desafortunadamente, no es fácil crear videojuegos para computadora. Los juegos comerciales de hoy en día normalmente se llevan de uno a tres años de desarrollo con equipos de entre 10 a 50 personas. Sus presupuestos alcanzan fácilmente millones de dólares. Y todas estas personas tienen bastante experiencia: programadores, diseñadores de arte, técnicos de sonido, etc.
¿Quiere decir que es imposible crear tus propios juegos para computadora? Afortunadamente no. Por supuesto que no debes esperar que puedas crear tu propio Quake o Age of Empires en unas cuantas semanas. Pero tampoco es necesario. Juegos más simples, como Tetris, Pacman, Space Invaders, etc., también son divertidos y son mucho más fáciles de crear. Desafortunadamente aún requieren de buenas habilidades de programación para manejar los gráficos, sonidos, la interacción con el usuario, etc. Es aquí donde aparece el Game Maker. El Game Maker ha sido creado para hacer mucho más sencilla la creación de ese tipo de juegos. Sin ninguna necesidad de programar. Una sencilla e intuitiva interfaz de arrastrar y soltar te permite crear tus propios juegos rápidamente. Puedes importar y crear imágenes, sprites (imágenes animadas), sonidos y usarlos. Tú defines fácilmente los objetos en tu juego e indicas su comportamiento. Puedes definir niveles atractivos con fondos deslizables en donde tome lugar el juego. Y si quieres control total sobre el juego existe un sencillo lenguaje de programación dentro del Game Maker que te pone al mando de todo lo que sucede en el juego.
El Game Maker se enfoca a juegos bidimensionales. Así que nada de mundos 3D como en Quake, aunque Game Maker incluye una funcionalidad reducida para gráficos en 3D. Pero no te desanimes. Muchos juegos importantes, como Age of Empires, las series Command and Conquer y Diablo usan tecnología de sprites bidimensionales, aunque parecen tridimensionales. Y diseñar juegos bidimensionales es mucho más fácil y rápido. Probablemente la mejor parte es que el Game Maker puede usarse libre de cargo. Y no hay ninguna restricción en los juegos que creas con él. Ninguna pantalla de publicidad, e incluso puedes venderlos si así lo deseas. Chequea el acuerdo de licencia adjunto para más detalles.
Este documento te dirá todo lo que necesitas saber acerca del Game Maker y cómo puedes crear tus propios juegos con él. Por favor entiende que, incluso con un programa como Game Maker, el diseño de juegos para computadora no es completamente trivial. Hay muchísimos aspectos que son importantes: el game play, los gráficos, los sonidos, la interacción con el usuario, etc. Comienza con ejemplos fáciles y te darás cuenta de que crear juegos es bastante divertido. También chequea los sitios Web: http://www.gamemaker.nl http://www.zonamakers.com http://www.comunidadgm.com
Instalación Probablemente ya lo hiciste pero por si acaso, aquí tienes cómo instalar el Game Maker. Simplemente ejecuta el programa gmaker.exe. Sigue las instrucciones en pantalla. Puedes instalar el programa donde lo desees pero mejor deja las opciones por defecto. Una vez que finalice la instalación, en el menú Inicio encontrarás un nuevo grupo de programas
desde el que puedes ejecutar el Game Maker y leer la documentación. Además del programa Game Maker también se instala la documentación, junto con el archivo de ayuda.
La primera vez que ejecutes el Game Maker se te preguntará si quieres ejecutarlo en modo Simple o Advanced (avanzado). Si no has empleado un programa de creación de videojuegos antes y no tienes experiencia como programador, usa el modo simple (selecciona No) En el modo simple se muestran menos opciones. Puedes cambiar
fácilmente al modo avanzado usando la opción en el menú File.
Dentro de la carpeta de instalación (por defecto C:\Archivos de Programa\Game_Maker6) tenemos varias carpetas adicionales:
•
examples: contiene varios juegos de ejemplo, para que los revises y/o modifiques.
•
lib: contiene varias librerías de acciones. Si deseas instalar librerías adicionales debes colocarlas dentro de esta carpeta.
•
sprites: esta carpeta está dedicada a contener los sprites que uses. La instalación incluye algunos sprites, pero en el sitio del Game Maker (http://www.gamemaker.nl), puedes descargar varios paquetes de recursos que contienen sprites, sonidos, y fondos adicionales.
•
backgrounds, sounds: carpetas similares que contienen las imágenes para los fondos y los sonidos.
Requisitos El Game Maker requiere una PC moderna con procesador Pentium y sistema operativo Windows 98, NT, 2000, Me, XP o superior. Tarjeta gráfica compatible con DirectX 8 con al menos 16 MB de memoria, resolución de al menos 800x600 y 65000 (16-bit) colores. También se requieres una tarjeta de sonido compatible con DirectX 8.0 o superior y que la versión 8.0 o superior de DirectX esté instalada en tu ordenador (Puedes bajar la última versión de DirectX del sitio de Microsoft: http://www.microsoft.com/windows/directx/.)
Al desarrollar y testear los juegos los requerimientos de memoria son bastante altos (por lo menos 64 MB y preferentemente más, dependiendo también del sistema operativo). Para ejecutar los juegos los requerimientos son menos severos y dependen del tipo de juego.
Registro Game Maker se puede usar gratuitamente. Sin embargo, la versión gratuita tiene algunas limitaciones y muestra un logo al cargar el juego. Para disponer de la funcionalidad total del programa, eliminar el logo de carga y contribuir al desarrollo del programa se recomienda encarecidamente que registres tu copia de Game Maker. Al registrar el programa obtendrás las siguientes opciones:
•
Eliminación del logo de Game Maker al cargar un juego.
•
Rotación, color blending y translucidez de sprites.
•
Acciones adicionales para música desde un CD, rotar texto o formas coloreadas.
•
Efectos especiales de sonido y sonido posicional.
•
Funciones avanzadas de dibujo, como polígonos texturizados.
•
Sistema de partículas para crear efectos de fuego, lluvia, explosiones,...
•
Funciones para gráficos en 3D
•
Funciones para crear juegos multi jugador para jugar en red.
•
Funciones para crear y modificar recursos (sprites, backgrounds,...) durante el juego.
•
Funciones para usar estructuras de datos.
•
Funciones para planificación de movimiento.
•
Posibilidad de extender aún más la funcionalidad de Game Maker usando DLLs.
La cuota de registro del Game Maker es de US $20 o de 15 Euros. Hay varias formas en las que puedes llevar a cabo el registro de tu copia del programa. La más fácil es usar el registro online usando un sistema de pago seguro con tarjeta de crédito o una cuenta PayPal. Alternativamente puedes realizar una transferencia a nuestra cuenta bancaria, enviarnos una money order o enviar efectivo. Puedes encontrar los detalles en el sitio de registro del Game Maker: www.gamemaker.nl/registration.html
Para registrar tu copia del Game Maker usa el sitio de arriba o selecciona Registration desde el menú Help. En la parte inferior de la ventana que aparece haz clic en el botón Registration. Serás llevado a nuestra página Web donde se indican las diferentes opciones de registro, incluyendo el registro online.
Una vez que tu registro ha sido recibido se te enviará un email con el nombre, clave y la información sobre cómo introducir la clave en el programa. Para introducir la clave, selecciona nuevamente Registration desde el menú Help. En la parte inferior de la ventana presiona el botón Enter Key. Introduce el nombre y la clave, y presiona OK. Si seguiste estos pasos correctamente el programa ya estará registrado.
Si posees una copia registrada de la versión 5 de Game Maker en tu ordenador puedes cambiar tu clave por otra válida para la versión 6. Para ello selecciona Registration desde el menú Help. A la izquierda del formulario verás el botón Convert a Version 5 Key (si no aparece es que no posees una versión registrada de GM o es que ya has registrado tu versión 6) Un texto explicativo te orientará para convertir tu
.
clave: lee las instrucciones cuidadosamente y pulsa el botón
La idea global Antes de ahondar en las posibilidades del Game Maker, sería bueno tener una idea general acerca del programa. Los juegos creados con el Game Maker se llevan a cabo en una o más habitaciones (rooms). (Las habitaciones son planas, no 3D, pero pueden contener imágenes con apariencia 3D). En estas habitaciones es donde colocas los objetos, los cuales puedes definir en el programa. Los objetos típicos son las paredes, objetos móviles, el personaje principal, enemigos, etc. Algunos objetos, como las paredes, sólo se encuentran ahí y no realizan ninguna acción. Otros, como el personaje principal, se moverán y reaccionarán a los comandos del jugador (teclado, ratón, joystick). Por ejemplo, cuando el personaje principal toca un enemigo podría ser eliminado. Los objetos son los ingredientes más importantes de los juegos creados con el Game Maker, por lo que hablaremos un poco más sobre ellos.
Primero que nada, la mayoría de los objetos necesitan alguna imagen para hacerse visibles en la pantalla. Tales imágenes son llamadas sprites. Un sprite no siempre es una sola imagen sino una serie de ellas que se muestran una tras otra para crear una animación. De esta forma parece que el personaje camina, que una pelota rueda, que una nave explota, etc. Durante el juego el sprite de un objeto en particular puede cambiar. (Así el personaje puede lucir diferente cuando camina a la izquierda o a la derecha). Puedes crear tus propios sprites en el Game Maker o cargarlos de algún archivo (GIFs animados por ejemplo).
A los objetos les pueden ocurrir ciertas cosas. A estas cosas se les llama eventos. Los objetos pueden realizar ciertas acciones dependiendo del evento que ocurra. Hay una gran cantidad de eventos que pueden suceder y una gran cantidad de acciones diferentes que los objetos pueden realizar. Por ejemplo, hay un evento creación cuando el objeto es creado. (Para ser más precisos, cuando una instancia de un objeto es creada; puede haber múltiples instancias del mismo objeto). Por ejemplo, cuando un objeto pelota se crea, puedes darle alguna acción de movimiento para que empiece a moverse. Cuando dos objetos se encuentran se tiene el evento colisión. En tal caso puedes hacer que la pelota se detenga o que invierta su dirección. Puedes también reproducir un efecto de sonido. Para este propósito el Game Maker te permite definir sonidos. Cuando el jugador presiona una tecla en el teclado hay un evento teclado, y el objeto puede realizar la acción apropiada, como moverse en la dirección indicada. Espero que entiendas la idea. Para cada objeto que diseñes puedes indicarle acciones para varios eventos, de esta forma se define el comportamiento del objeto.
Una vez que has definido tus objetos es tiempo de definir las habitaciones en donde habitarán. Las habitaciones pueden ser empleadas como niveles en el juego o para mostrar diferentes lugares. Hay acciones para moverse de una habitación a otra. Las habitaciones deben tener primero un fondo. Este puede ser un simple color de relleno o una imagen. Tales imágenes pueden ser creadas en el Game Maker o puedes cargarlas de algún archivo. (El fondo puede hacer muchas cosas pero por el momento, solo considéralo como algo que hace que los niveles se vean bien). Ahora puedes colocar tus objetos en la habitación. Puedes colocar múltiples instancias del mismo objeto en una habitación. Así, por ejemplo, necesitas definir sólo un objeto de pared y usarlo en muchos lugares. También puedes tener múltiples instancias de los mismos enemigos, mientras requieran del mismo comportamiento.
Ahora estás listo para ejecutar el juego. Se mostrará la primera habitación y los objetos en ella tomarán vida por las acciones en sus eventos de creación. Empezarán a interactuar unos con otros debido a las acciones en sus eventos de colisión y pueden reaccionar a lo que haga el jugador usando las acciones en los eventos del teclado o del ratón. En resumen, los siguientes elementos (comúnmente llamados recursos) tienen un papel crucial en el juego: •
Objetos (objects): que son las entidades verdaderas en el juego.
•
Habitaciones (rooms): los lugares (niveles) en donde habitan los objetos.
•
Sprites: imágenes (animadas) que se emplean para representar a los objetos.
•
Sonidos (sounds): para emplearse en el juego, ya sea como música de fondo o como efectos.
•
Fondos (backgrounds): las imágenes usadas como fondo para los cuartos.
De hecho, hay otro tipo de recursos: paths, scripts, fuentes y time lines. Estos recursos son importantes para juegos más complicados. Solo los verás cuando ejecutas el Game Maker en modo avanzado. Se hablará de ellos más tarde en los capítulos avanzados de este documento.
Un ejemplo sencillo Sería bueno echar un vistazo de cómo crear un ejemplo muy simple. El primer paso es describir el juego que queremos hacer. (Siempre debieras empezar por esto; te ahorrará mucho trabajo después). El juego será muy simple: hay una pelota rebotando entre varias paredes. El jugador debe intentar hacer clic en la pelota con el ratón. Cada vez que lo logre obtiene un punto.
Como se puede ver, se requieren dos objetos diferentes: la pelota y la pared. También necesitaremos dos sprites diferentes: uno para el objeto pared y otro para el objeto pelota. Finalmente, queremos escuchar algún sonido cuando se logre hacer clic en la pelota con el ratón. Usaremos un sólo nivel en el que se lleve a cabo el juego. (Si no quieres hacer el juego tú mismo, puedes cargarlo de la carpeta Examples con el nombre hit the ball.gm6)
Hagamos primero los sprites. Del menú Add selecciona Add Sprite (puedes también usar el botón apropiado en la barra de herramientas). Aparecerá una ventana. En el campo Name escribe “wall”. Selecciona el botón Load Sprite y elige una imagen apropiada (puedes encontrar una en la carpeta maze). Eso es todo, puedes cerrar la ventana. De esta misma forma, crea un sprite para la pelota.
Ahora definiremos el sonido. Del menú Add selecciona Add Sound. Aparece una ventana diferente. Dale un nombre al sonido y selecciona Load Sound. Selecciona algo apropiado y checa si es un buen sonido presionando el botón reproducir. Si te gusta, cierra la ventana.
El siguiente paso es crear los dos objetos. Hagamos primero la pared. Nuevamente del menú Add selecciona Add Object. Se abrirá una ventana que se ve bastante más compleja que las que hemos visto hasta ahora. A la izquierda tenemos información global acerca del objeto. Dale al objeto un nombre apropiado y del menú desplegable selecciona el sprite wall. Como una pared es sólida deberías marcar la casilla llamada Solid. Eso es todo por el momento. Nuevamente crea un objeto, llámalo ball, y selecciónale un sprite. No haremos sólida a la pelota. Necesitamos definir algún comportamiento para la pelota. Debajo hay un botón marcado Add Event. Presiónalo y verás todos los eventos posibles. Selecciona el evento de creación (create). Ahora se ha agregado a la lista de eventos. En el extremo derecho puedes ver todas las acciones posibles, en varios grupos. Del grupo move selecciona la acción con las 8 flechas rojas y arrástrala a la lista de acciones en el medio. Esta acción hará al objeto moverse en una dirección particular. Una vez que la sueltes en la lista de acciones se mostrará un diálogo en el cual puedes indicar la dirección de movimiento. Selecciona las 8 flechas para seleccionar una dirección al azar. Cierra el diálogo. Ahora la pelota empezará a moverse en el momento en que sea creada. En segundo lugar debemos definir lo que sucederá en caso de que se colisione con la pared. De nuevo presiona Add Event. Haz clic en el botón de los eventos de colisión (collision) y del menú que aparece selecciona el objeto wall. Para este evento necesitamos la acción rebotar. (Puedes ver lo que cada acción hace colocando el ratón sobre el icono que la representa). Finalmente necesitamos definir lo que se hará cuando el usuario presione el botón izquierdo del ratón sobre la pelota. Agrega el evento correspondiente y selecciona el botón izquierdo del ratón (Left button) del menú que se despliega. Para este evento necesitamos unas cuantas acciones: una para reproducir un sonido (la puedes encontrar en el grupo de acciones main1), una para cambiar el marcador (se encuentra en el grupo score) y dos más para mover la pelota a una posición aleatoria y moverla
en una nueva dirección (de la misma forma que en el evento de creación). Para la acción de sonido, selecciona el sonido adecuado. Para la acción del marcador (score), introduce un valor de 1 y marca la opciónRelative. Esto significa que se agregará 1 al marcador actual. (Si cometes algún error puedes hacer doble click sobre la acción para modificar su configuración).
Nuestros objetos ahora están listos. Lo que queda es definir la habitación. Agrega un nuevo nivel al juego, de nuevo desde el menú Add. A la derecha verás la habitación vacía. A la izquierda verás algunas propiedades que puedes modificar, como el ancho y alto de la habitación. En la parte inferior izquierda puedes seleccionar un objeto del menú desplegable. Puedes colocar instancias de ese objeto haciendo clic en el cuarto. Puedes eliminar las instancias usando el botón derecho del ratón. Crea un espacio cerrado alrededor del nivel usando el objeto wall. Finalmente coloca 1 ó 2 objetos ball en el nivel. Nuestro juego está listo.
Es hora de probar nuestro juego. Presiona el botón Run y ve lo que pasa. Si no cometiste algún error la pelota empieza a moverse alrededor. Intenta hacer click en ella con el ratón y ve qué sucede. Puedes detener el juego presionando la tecla
. Ahora puedes hacer más cambios. Felicidades. Has creado tu primer juego. Pero creo que es hora de aprender un poco más sobre el Game Maker.
La interfaz global de usuario
Al iniciar el Game Maker se muestra la siguiente ventana:
(De hecho, esto es lo que ves cuando ejecutas el Game Maker en modo simple. En el modo avanzado se muestran algunas opciones más. Ve el capítulo correspondiente para más detalles). A la izquierda puedes ver los diferentes recursos, mencionados antes: Sprites, Sounds (Sonidos), Backgrounds (Fondos), Scripts, Objects (Objetos), Rooms (Habitaciones) y dos más: Game Information (Información del juego) y Game Options (Opciones del juego) En la parte superior está el ya conocido menú y la barra de herramientas. En este capítulo describiré brevemente las diferentes opciones del menú, los botones, etc. En capítulos posteriores trataremos varios de ellos con más detalle. Recuerda que muchas cosas se pueden lograr de diferentes maneras: seleccionando un comando del menú, haciendo click en un botón, o haciendo click derecho sobre un recurso.
Menú file En el menú file puedes encontrar los comandos usuales para cargar y guardar archivos, además de algunos especiales:
•
New. Selecciona este comando para empezar a crear un juego nuevo. Si el juego actual sufrió modificaciones se te pregunta si
quieres guardarlo. También hay un botón en la barra de herramientas para hacer esto.
•
Open. Abre un archivo de juego. Los archivos del Game Maker tienen la
•
extensión .gmd. Hay un botón en la barra de herramientas para este comando. Puedes también abrir un juego arrastrando el archivo a la ventana del Game Maker.
•
Recent Files. Usa este submenú para reabrir los archivos abiertos recientemente.
•
Save. Guarda el archivo de diseño del juego con el nombre actual. Si no se había especificado un nombre, se te pide dar uno. Puedes usar este comando solo cuando el archivo ha cambiado. Como con los anteriores, hay un botón en la barra de herramientas para realizar esta acción.
•
Save As. Guarda el diseño del juego con otro nombre. Se te pide un nuevo nombre.
•
Create Executable. Una vez que tu juego esté listo probablemente querrás distribuirlo. Mediante este comando puedes crear una versión ejecutable de tu juego. Es simplemente un ejecutable que puedes darle a otros para que jueguen tu juego. Encontrarás más información sobre la distribución de juegos en el tema correspondiente.
•
Advanced Mode. Al hacer clic en este comando el Game Maker cambiará entre los modos simple y avanzado. En el modo avanzado se tienen disponibles comandos y recursos adicionales.
•
Exit. Probablemente obvio. Presiónalo para cerrar el Game Maker. Si hiciste cambios al juego actual se te preguntará si quieres guardarlo.
Menú Edit El menú edit contiene varios comandos que se relacionan con el recurso seleccionado (objeto, sonido, etc.) o grupo de recursos. Dependiendo del tipo de recurso algunos de los comandos pueden no estar disponibles.
•
Insert resource. Inserta una nueva instancia del tipo de recurso actualmente seleccionado, se inserta antes del mismo. (Si seleccionaste un grupo de recursos el recurso es agregado al grupo). Se abrirá un cuadro de diálogo en el que puedes cambiar las propiedades del recurso. Esto se tratará con más detalle en los capítulos siguientes.
•
Duplicate. Crea y agrega una copia del recurso actual. Se abre una ventana en la que puedes modificar el recurso.
•
Delete. Borra el recurso seleccionado (o grupo de recursos). Ten cuidado. No puede deshacerse. Por lo que se te hará una advertencia.
•
Rename. Dale un nuevo nombre al recurso. Esto se puede hacer también en la ventana de propiedades del recurso. También puedes seleccionar el recurso y entonces hacer clic en el nombre.
•
Properties. Usa este comando para mostrar la ventana de edición de propiedades. Nota que todas las ventanas de propiedades se muestran en la ventana principal. Puedes editar muchas de ellas al mismo tiempo. Puedes también editar las propiedades haciendo doble clic en el recurso.
Observa que estos comandos puedes también aplicarse de otra forma. Haz clic derecho en un recurso o en un grupo de recursos, y aparecerá el menú apropiado.
Menú Add En este menú puedes agregar un nuevo recurso de cada uno de los diferentes tipos que hay. Nota que para cada uno de ellos hay también un botón en la barra de herramientas y un acceso directo con el teclado.
Menú Run Este menú se usa para ejecutar el juego. Hay dos formas de ejecutar el juego:
•
Run normally. Ejecuta el juego en modo normal. El juego se ejecuta de la manera más eficiente posible exactamente como si fuera un ejecutable.
•
Run in Debug mode. Ejecuta el juego en modo debug. En este modo puedes revisar ciertos aspectos del juego, pausarlo o avanzar paso a paso. Muy útil para detectar y solucionar errores.
Una vez que tu juego esté listo, puedes crear un ejecutable del juego usando la acción del menú file.
Menú Window En este menú puedes encontrar los comandos comunes para manejar las diferentes propiedades de las ventanas de la ventana principal:
•
Cascade. Coloca todas las ventanas en cascada de forma que cada una sea parcialmente visible.
•
Arrange Icons. Ordena todas las ventanas. (Útil en particular cuando cambias de tamaño la ventana principal).
•
Close All. Cierra todas las ventanas de propiedades, preguntando si se desea guardar o no los cambios realizados.
Menú Help Aquí encontrarás algunos comandos de ayuda:
•
Contents. Te permite acceder a la versión en formato de ayuda de este documento.
•
How to use help. En caso de que no sepas, algo de ayuda sobre cómo usar la ayuda.
•
Registration. Aún cuando el Game Maker puede ser usado libre de cargo, se te alienta a registrar el programa. De esta forma se eliminará la ventana publicitaria que en ocasiones aparece en la ventana de edición y ayudarás al futuro desarrollo del programa. Aquí puedes encontrar información sobre cómo registrar el programa. Si ya lo registraste puedes usar esta opción para introducir la clave de registro que recibiste.
•
Web site. Te conecta al sitio del Game Maker en donde puedes encontrar información sobre la versión más reciente del Game Maker y colecciones de juegos y recursos para el Game Maker. Te recomiendo que visites el sitio al menos una vez al mes para ver nueva información.
•
About Game Maker. Breve información sobre esta versión del Game Maker.
El explorador de recursos En la parte izquierda de la forma principal encontrarás el explorador de recursos. Aquí tienes una lista ramificada de todos los recursos de tu juego. Trabaja de la misma forma que el explorador de Windows con el cual muy probablemente ya estás familiarizado. Si un elemento tiene un signo + a su lado puedes hacer clic en el signo para ver los recursos
dentro de él. Haciendo clic en el signo – los oculta nuevamente. Puedes cambiar el nombre de un recurso (excepto los de más alto nivel) seleccionándolo (con un solo click) y luego haciendo clic en el nombre. Haz doble clic en un recurso para editar sus propiedades. Usa el botón derecho del ratón para acceder a los comandos del menú Edit.
Puedes cambiar el orden de los recursos haciendo click en ellos y manteniendo presionado el botón del ratón. Ahora arrastra el recurso (o grupo) al lugar apropiado. (Por supuesto que el lugar debe ser el apropiado. Por ejemplo no puedes arrastrar un sonido a la lista de sprites).
Definiendo los sprites
Los sprites son las representaciones visuales de todos los objetos en el juego. Un sprite es o una imagen simple, dibujada con cualquier programa que te guste, o un juego de varias imágenes que, pueden ser reproducidas una tras otra, creando un efecto de movimiento (animación). Por ejemplo, las siguientes cuatro imágenes forman un sprite para un Pacman moviéndose hacia la derecha.
Cuando haces un juego empiezas por reunir los distintos sprites para los objetos en tu juego. Con el Game Maker viene incluida una colección de sprites estáticos y animados. Puedes encontrar otros sprites en Internet, normalmente como archivos gif animados. Para agregar un sprite, selecciona el comando Add Sprite del menú Add, o usa el botón correspondiente de la barra de herramientas. Aparecerá la siguiente ventana:
En la parte superior puedes indicar el nombre del sprite. Todos los sprites (y todos los demás recursos) tienen un nombre. Será mejor que le des a cada sprite un nombre descriptivo y fácil de recordar. Asegúrate de que todos los recursos tengan diferentes nombres. Aunque no es estrictamente requerido, se recomienda firmemente usar sólo letras, dígitos y el guión bajo (_) en el nombre de un sprite (y de cualquier otro recurso) y empezar el nombre con una letra. En particular no hagas uso de espacios en los nombres. Esto pasará a ser parte importante una vez que empieces a usar código.
Para cargar un sprite, haz clic en el botón Load Sprite. Se muestra un diálogo de archivo en el que debes indicar el sprite. El Game Maker puede abrir varios tipos de archivos de imagen. Cuando cargas un gif animado, las diferentes subimágenes forman las imágenes del sprite. Una vez que el sprite es cargado, se muestra la primera subimagen a la derecha. Cuando hay múltiples subimágenes, puedes verlas usando los botones con las flechas.
La opción Transparent indica si el fondo deberá ser considerado como transparente. La mayoría de los sprites son transparentes. El fondo es determinado por el color del píxel que se encuentra en la esquina inferior izquierda de la imagen. Así que asegúrate de que ningún píxel de la imagen que se mostrará tenga este color. (Los archivos gif a menudo definen su color de transparencia, este color no es usado en el Game Maker).
Con el botón Edit Sprite puedes editar el sprite, o incluso crear un sprite completamente nuevo.
Música y sonido
La mayoría de los juegos tienen ciertos efectos de sonido y música de fondo. El Game Maker incluye algunos efectos de sonido de utilidad. Puedes encontrar muchos más en la Web.
Para agregar un recurso de sonido a tu juego, usa el comando Add Sound en el menú Add o usa el botón correspondiente en la barra de herramientas. Aparecerá la siguiente Ventana:
Para cargar un sonido, presiona el botón Load Sound. Aparece un diálogo de selección de archivo en el que debes especificar el archivo de sonido. Hay dos tipos de archivos de sonido, archivos wave (*.wav) y archivos midi (*.mid). (Para información sobre archivos mp3 ve el Capítulo 17). Los archivos wave son usados para efectos breves de sonido. Usan mucha memoria pero se reproducen instantáneamente. Úsalos para todos los efectos de sonido en el juego. Los archivos midi tratan la música en una forma diferente. Como resultado usan mucha menos memoria, pero están limitados a música instrumental de fondo. Además, sólo se puede reproducir un archivo midi a la vez.
Una vez que cargues un archivo se muestra su tipo y duración. Puedes escuchar el sonido usando el botón reproducir. También hay un botón Save Sound para guardar en un archivo el sonido actual. Este botón no es realmente requerido pero pudieras necesitarlo si perdieras el sonido original.
Fondos
El tercer tipo de recursos básicos son los fondos. Los fondos son normalmente imágenes grandes usadas como fondo para los niveles en los que se realiza el juego. A menudo las imágenes de fondo son hechas con tiles (mosaicos) de manera que pueden formar una imagen en un área sin errores visuales. De esta manera puedes llenar el fondo con un patrón. Varios tiles de fondo de este tipo vienen incluidos con el Game Maker. Puedes encontrar muchos más en la Web.
Para agregar un fondo a tu juego, usa el comando Add Background en el menú Add o usa el botón correspondiente de la barra de
:
herramientas. Aparecerá la siguiente ventana
Presiona el botón Load Background para cargar una imagen de fondo. El Game Maker soporta varios formatos de imagen. ¡Las imágenes de fondo no pueden ser animadas! La opción Transparent indica si el fondo será parcialmente transparente. La mayoría de los fondos no son transparentes, por lo que la opción por defecto es no. Como color transparente se usa el color del píxel en la esquina inferior izquierda.
.
Puedes cambiar el fondo o crear uno nuevo usando el botón Edit Background. Para más información, ve el Capítulo 18
Definiendo objetos
Hemos agregado imágenes y sonidos al juego, pero ninguno de ellos realiza ninguna acción. Ahora llegamos al recurso más importante dentro del Game Maker: los objetos. Los objetos son las entidades que hacen las cosas en el juego. La mayoría de las veces tienen un sprite como representación gráfica para que puedas verlos. Tienen un comportamiento porque pueden reaccionar a ciertos eventos. Todas las cosas que ves en el juego (excepto el fondo) son objetos. (O para ser más precisos, son instancias de objetos). Los personajes, los enemigos, las pelotas, las paredes, etc. Puede haber también ciertos objetos que no ves pero que controlan ciertos aspectos del juego.
Por favor nota la diferencia entre los sprites y los objetos. Los sprites son solo imágenes (animadas) que no tienen ningún comportamiento. Los objetos normalmente tienen un sprite que los representa pero también tienen un comportamiento. ¡Sin objetos no hay juego!
También nota la diferencia entre los objetos y las instancias. Un objeto describe cierta entidad, por ejemplo un enemigo. Puede haber múltiples instancias de este objeto en el juego. Cuando hablamos de instancia nos referimos a una instancia en particular del objeto. Cuando hablamos de un objeto nos referimos a todas las instancias de este objeto.
Para agregar un objeto al juego, selecciona el comando Add Object del menú Add. Aparecerá la siguiente ventana:
Este formulario es bastante complejo. A la izquierda hay cierta información general acerca del objeto. En el medio hay varios eventos posibles que pueden ocurrirle a un objeto. Ve el siguiente capítulo para más detalles. A la derecha hay varias acciones que puede realizar el objeto. Estas serán tratadas en el Capítulo 12.
Como siempre, puedes (y debes) agregar un nombre al objeto. Después puedes indicar el sprite para el objeto. Para hacerlo, haz clic con el botón izquierdo del ratón en la caja de sprite o en el botón de menú junto a esta. Aparecerá un menú con todos los sprites disponibles. Selecciona el que quieras usar para el objeto. Si todavía no tienes un sprite para el objeto, puedes hacer click en el botón New para añadir un sprite y cambiarlo. También verás un botón Edit para editar el sprite rápidamente.
Debajo hay dos opciones. La opción Visible indica si las instancias de este objeto serán visibles. Obviamente, la mayoría de los objetos son visibles, pero algunas veces es útil tener objetos invisibles. Por ejemplo, puedes usarlos como guías de movimiento para un enemigo. Los objetos invisibles reaccionan a eventos y otras instancias pueden colisionar con ellos. La opción Solid indica si se trata de un objeto sólido
(como una pared). Las colisiones con objetos sólidos se tratan de forma distinta a las colisiones con objetos no sólidos. Se recomienda usar la opción Solid únicamente para objetos que no se mueven.
Eventos
El Game Maker emplea lo que se conoce como programación orientada a eventos. Esto es, en todo tipo de situaciones las instancias de los objetos reciben eventos (como mensajes que indican que algo ha sucedido). Entonces los objetos pueden reaccionar a estos mensajes ejecutando ciertas acciones. Para cada objeto debes indicar a qué eventos responderá y qué acciones debe realizar. Puede parecer complicado pero en realidad es bastante sencillo. Primero que nada, para la mayoría de los eventos los objetos no tienen que hacer nada. Para los eventos donde algo suceda puedes usar muy simples comandos de arrastrar y soltar para indicar las acciones.
En medio de la ventana de propiedades de objeto hay una lista de los eventos a los cuales el objeto puede reaccionar. Al principio está vacía. Puedes agregar eventos presionando el botón Add Event. Aparecerá un pequeño menú con todos los diferentes tipos de eventos. Aquí debes seleccionar el evento que deseas agregar. En ocasiones se mostrará un nuevo menú con opciones extra. Por ejemplo, para el evento del teclado debes seleccionar la tecla. Más abajo encontrarás una completa lista con descripciones de los eventos. Seleccionaremos un evento de la lista. Este será el evento que modificaremos. Puedes cambiar el evento seleccionado haciendo clic sobre él. A la derecha están todas las acciones representadas por pequeños iconos. Se encuentran agrupadas en varias páginas / fichas de opciones. En el siguiente capítulo describiré todas las acciones y lo que realizan. Entre los eventos y las acciones se encuentra la lista. Esta lista contiene las acciones para el evento actual. Para agregar acciones a la lista, arrástralas desde la derecha a la lista. Serán colocadas una bajo la otra, con una breve descripción. Para cada acción se te pedirán algunos parámetros. Estos se describirán también en el siguiente capítulo. Después de agregar algunas acciones, tendrías algo como esto:
Ahora puedes agregar acciones a otro evento. Haz clic con el botón izquierdo del ratón sobre el evento adecuado para seleccionarlo y arrastra la acción a la lista. Puedes cambiar el orden de las acciones en la lista arrastrando los iconos. Si mantienes presionada la tecla mientras arrastras una acción, crearás una copia de dicha acción. Puedes inclusive arrastrar acciones entre diferentes listas de diferentes objetos. Cuando haces clic con el botón derecho sobre una acción, se muestra un menú desde el cual puedes eliminar la acción (también puedes hacer esto usando la tecla ), o copiar y pegar acciones. Cuando mantienes el cursor del ratón sobre una acción, se muestra una descripción más detallada sobre la misma. En el siguiente capítulo hay más información sobre las acciones.
Para eliminar el evento seleccionado y todas sus acciones, presiona el botón Delete. (Los eventos sin acciones son eliminados automáticamente cuando cierras la ventana por lo que no hay necesidad de que lo hagas tu mismo). Si deseas asignar las acciones a un evento diferente (porque por ejemplo, has decidido emplear una tecla diferente para las acciones) presiona el botón Change y selecciona el nuevo evento. (¡El nuevo evento no debe haber sido empleado antes!).
Como se mencionó arriba, para agregar un evento, presiona el botón Add Event. Se muestra la siguiente ventana:
Aquí seleccionas el evento que deseas agregar. Algunas veces aparece un menú con opciones extra. A continuación una descripción de los eventos. (Recuerda que normalmente sólo haces uso de algunos de ellos):
Evento
create
Este evento ocurre cuando se crea una instancia del objeto. Normalmente se usa para establecer el movimiento de la instancia y/o establecer ciertas variables de la misma
.
Evento Destroy Este evento ocurre cuando la instancia es destruida. Para ser precisos, ocurre justo antes de que sea destruida, ¡por lo que la instancia aún existe cuando el evento es ejecutado! La mayoría de las veces este evento no se usa pero puedes por ejemplo emplearlo para cambiar el marcador o para crear algún otro objeto.
Eventos alarm
Cada instancia tiene 12 relojes de alarma. Puedes configurar estos relojes usando ciertas acciones (ver el siguiente capítulo). El reloj de alarma hace una cuenta regresiva hasta que llega a 0, que es cuando se genera el evento de alarma. Para indicar las acciones para un reloj de alarma, necesitas primero seleccionarlo en el menú. Los relojes de alarma son muy útiles. Puedes usarlos para hacer que ciertas cosas sucedan de tiempo en tiempo. Por ejemplo un enemigo puede cambiar su dirección de movimiento cada 20 pasos. (En cuyo caso una de las acciones en el evento debe configurar nuevamente la alarma).
Eventos
step
El evento step sucede a cada paso/frame del juego. Aquí puedes colocar acciones que requieren ejecutarse continuamente. Por ejemplo, si el objeto debe seguir a otro, puedes adaptar aquí la dirección de movimiento hacia el objeto que se está siguiendo. Sin embargo ten cuidado con este evento. No coloques muchas acciones muy complicadas en el evento step. Esto podría alentar el juego. Para ser más preciso, hay tres diferentes eventos step. Normalmente solo necesitas el evento por defecto. Pero usando el menú puedes también seleccionar el inicio y el final del evento step. El inicio del evento step es ejecutado al inicio de cada paso, antes de que ocurra cualquier otro evento. El evento step normal es ejecutado justo antes de que se coloquen las instancias en sus nuevas posiciones. El final del evento step se ejecuta al final de cada paso, justo antes de que se dibuje la escena. Este evento se usa normalmente para, por ejemplo, cambiar el sprite dependiendo de la dirección actual.
Eventos
de
colisión
En el momento en que dos instancias colisionan (esto es, que sus sprites se sobreponen) ocurre un evento de colisión. Bien, para ser precisos, ocurren dos eventos de colisión, uno por cada instancia. La instancia puede reaccionar a este evento de colisión. Para este fin, selecciona en el menú el objeto con el cual quieres definir el evento de colisión. Después coloca las acciones. Hay una diferencia entre lo que sucede cuando la instancia colisiona con un objeto sólido y cuando lo hace con uno no sólido. Antes que nada, cuando no hay acciones en el evento de colisión, no sucede nada. La instancia actual simplemente continúa moviéndose; aún cuando el otro objeto sea sólido. Cuando el evento de colisión contiene acciones sucede lo siguiente: Cuando el otro objeto es sólido, la instancia se coloca de vuelta al lugar previo (antes de que ocurriera la colisión). Entonces se ejecuta el evento. Finalmente, la instancia es llevada a su nueva posición. Así que si por ejemplo, el evento invierte la dirección de movimiento, la instancia rebota contra la pared sin detenerse. Si hay una nueva colisión, la instancia se mantiene en su lugar previo. De manera que efectivamente deje de moverse. Cuando el otro objeto no es sólido, la instancia no se regresa. El evento simplemente se ejecuta con la instancia en su posición actual. Tampoco se checa una nueva colisión. Si lo piensas, esto es lo que debería ocurrir lógicamente. Porque cuando el objeto no es sólido, podemos simplemente movernos sobre él, o a través de él. El evento nos notifica lo que está sucediendo. Existen muchos usos para el evento de colisión. Las instancias pueden usarlo para rebotar contra las paredes. Puedes usarlo para destruir algún objeto cuando es tocado por una bala, etc.
Eventos
Keyboard
Cuando el usuario presiona una tecla, ocurre un evento keyboard para todas las instancias de todos los objetos. Hay un evento diferente para cada tecla. En el menú puedes seleccionar la tecla para la que quieres definir el evento de teclado y después arrastrar las acciones. Es claro que solo unos cuantos objetos necesitan eventos para unas cuantas teclas. Se tiene un evento en cada paso cuando el jugador presiona la tecla. Hay dos eventos de teclado especiales. Uno es el . Este evento ocurre en cada paso cuando no hay ninguna tecla presionada. El segundo se llama y ocurre cuando se presiona cualquier tecla. A propósito, cuando el usuario presiona varias teclas, ocurren los eventos para todas ellas. Las teclas en el teclado numérico solo producen sus eventos correspondientes cuando está activada. Eventos
mouse
Un evento mouse ocurre para una instancia cuando el cursor del ratón se encuentra sobre el sprite que representa a la instancia. Dependiendo de qué botón se presione, se obtienen los eventos no button (ningún botón), left button (botón izquierdo), right button (botón derecho), o middle button (botón central). Estos eventos son generados en cada paso mientras el jugador mantenga el botón del ratón presionado. Los eventos press se generan una sola vez cuando el botón es presionado. Los eventos release se generan una sola vez cuando se suelta el botón. Recuerda que estos eventos sólo ocurren cuando el ratón está sobre la instancia. Si el jugador presiona un botón del ratón en algún lugar donde no haya ninguna instancia, no se genera el evento. Pero en ocasiones es importante reaccionar a cualquier click del ratón. Esto puede conseguirse usando los eventos globales que aparecen en el submenú. También hay dos eventos especiales. El evnto
mouse enter ocurre cuando el ratón entra sobre el sprite de la instancia. El evento mouse leave ocurre cuando el ratón deja de estar encima de la instancia. Estos eventos se usan típicamente para cambiar el sprite o para hacer sonar algún sonido. Los eventos mouse wheel up y mouse wheel down ocurren cuando se usa la rueda del ratón. Por último, hay una serie de eventos para joysticks. Puedes indicar acciones para las cuatro direcciones del joystick (en una dirección diagonal se ejecutan ambos eventos) y para 8 botones del joystick. Puedes hacer esto para dos joysticks.
Eventos
other
Hay otros eventos que pueden ser útiles en ciertos juegos. Los encuentras en este menú. Los eventos que puedes encontrar son: •
Outside: Este evento ocurre cuando la instancia se encuentra completamente fuera del cuarto. Este es normalmente un buen momento para destruirla.
•
Boundary: Este evento ocurre cuando la instancia llega al borde del cuarto.
•
Game start: Este evento se genera para todas las instancias en el primer cuarto donde inicia el juego. Ocurre antes que el evento room start (ver abajo) y aún antes de los eventos create de las instancias en el cuarto. Este evento se define normalmente en un solo objeto “controlador” y se usa para reproducir alguna música de fondo y para dar valores iniciales a algunas variables, o para cargar información.
•
Game end: El evento ocurre para todas las instancias cuando termina el juego. De nuevo, es común que solo un objeto lo defina. Se emplea por ejemplo para guardar cierta información en un archivo.
•
Room start: Este evento se genera para todas las instancias (en el cuarto) cuando se inicia un cuarto. Ocurre antes que los eventos de creación.
•
Room end: Este evento se genera para todas las instancias existentes cuando finaliza el cuarto.
•
No more lives: El Game Maker tiene un sistema de vidas interno. Hay una acción para especificar y cambiar el número de vidas. En el momento que el número de vidas sea menor o igual a 0, se genera este evento. Normalmente empleado para terminar o reiniciar el juego.
•
No more health: El Game Maker tiene un sistema interno de energía. Hay una acción para especificar y cambiar el nivel de energía. En el momento que la energía sea menor o igual a 0, ocurre este evento. Normalmente se emplea para disminuir el número de vidas o para reiniciar el juego.
•
End of animation: Como se indicó antes, una animación consiste en varias imágenes que se muestran una después de otra. Después de que se muestra la última se inicia nuevamente con la primera. El evento ocurre en ese preciso momento. Esto se puede usar para por ejemplo cambiar la animación, o destruir la instancia.
•
End of path: Este evento ocurre cuando la instancia que sigue una trayectoria predeterminada (path) llega al final de la misma. Ve al Capítulo 18 para encontrar más información sobre las trayectorias.
•
User defined: Hay 16 de estos eventos. Normalmente nunca ocurren a menos que tú mismo los llames desde alguna pieza de código.
Evento
Drawing
Las instancias, cuando son visibles, dibujan su sprite en la pantalla en cada paso. Cuando especificas acciones en el evento de dibujo, no se
dibuja el sprite, sino que se ejecutan estas acciones en su lugar. Esto se puede usar para dibujar algo más que un sprite, o para primero hacer algunos cambios a los parámetros del sprite. Hay varias acciones de dibujo especialmente diseñadas para usarse en el evento drawing. Recuerda que el evento drawing se ejecuta solamente cuando el objeto es visible. También recuerda que, independientemente de lo que dibujes aquí, los eventos de colisión se basan en el sprite que está asociado a la instancia
Evento
Key
press
Este evento es similar al evento keyboard con la diferencia de que éste ocurre solo una vez cuando se presiona la tecla, y no continuamente. Este es útil cuando deseas que una acción ocurra solo una vez.
Key
release
events
Este evento es similar al evento keyboard, pero ocurre solo una vez cuando la tecla es liberada, en lugar de ocurrir continuamente.
En algunas situaciones es importante conocer el orden en el cual el Game Maker procesa los eventos. Como sigue. •
Eventos Begin Step
•
Eventos Alarm
•
Eventos Keyboard, Key press, y Key release
•
Eventos Mouse
•
Eventos Step normales
•
(ahora todas las instancias son colocadas en sus nuevas posiciones)
•
Eventos Collision
•
Eventos End Step
•
Eventos Drawing
Los eventos de creación (create), destruir (destroy) y otros son generados en el momento pertinente.
Acciones Las acciones indican lo que sucede en un juego creado con el Game Maker. Las acciones se colocan en los eventos de los objetos. Cuando el evento ocurre estas acciones se llevan a cabo, resultando en cierto comportamiento para las instancias del objeto. Hay una gran cantidad de
acciones disponibles y es importante que entiendas lo que hacen. En este capítulo describiré las acciones disponibles en modo simple. Nota: ciertas cantidad de acciones sólo estan disponible en la versión registrada de Game Maker. Estas serén indicadas.
Todas las acciones se encuentran en las páginas / fichas(pestañas) a la derecha de la ventana de propiedades de objeto. Hay siete grupos de acciones. Puedes ver el grupo haciendo clic en la ficha correcta. Cuando mantienes el ratón sobre una de las acciones, se muestra una breve descripción para recordar su función.
Permíteme repetir brevemente: Para colocar una acción en un evento, solo arrástrala de las páginas / fichas a la lista de acción. Puedes cambiar el orden de la lista, arrastrando y soltando los iconos. Si presionas la tecla mientras arrastras puedes hacer una copia de la acción. (Puedes arrastrar y copiar acciones entre las listas en diferentes ventanas de propiedades de objetos). Usa el botón derecho del ratón para borrar acciones (o usa la tecla ó ) o para copiar y pegar acciones.
Cuando colocas una acción, la mayoría de las veces aparece una ventana de diálogo, en la cual puedes especificar ciertos parámetros para la acción. Dos tipos de parámetros aparecen en muchas acciones. En la parte superior puedes indicar a qué instancia aplica la acción. El valor por defecto es self, que es la instancia para la cual se está realizando la acción. La mayoría de las veces esto es lo adecuado. En el caso de un evento collision, puedes especificar también si se aplica la acción a la otra instancia involucrada en la colisión. De esta forma puedes por ejemplo destruir la otra instancia.
Finalmente, puedes elegir si aplicas la acción a todas las instancias de un objeto. De esta manera puedes por ejemplo cambiar todas las pelotas rojas por azules. El segundo tipo de parámetro es la casilla marcada Relative. Al marcar esta casilla, los valores que introduzcas serán relativos a los valores actuales. Por ejemplo, de esta forma puedes agregar algo al marcador actual, en lugar de cambiar el marcador actual por su nuevo valor. Los otros parámetros se describen abajo. Puedes revisar después los parámetros haciendo doble clic en la acción.
La información sobre las acciones está disponible en los siguientes temas: Acciones de movimiento Acciones principales, grupo 1 Acciones principales, grupo 2 Acciones de control Acciones de score Acciones de dibujo Usando expresiones y variables
Acciones de movimiento El primer grupo de acciones consiste de aquellas relacionadas al movimiento de objetos. Tenemos las siguientes:
Start moving in a direction Usa esta acción para que la instancia empiece a moverse en una dirección en particular. Puedes indicar la dirección usando las flechas. Usa el botón del medio para detener el movimiento. También debes especificar la velocidad de movimiento. Esta velocidad está dada en pixels por paso. El valor por defecto es de 8. De preferencia no uses valores de velocidad negativos. Puedes especificar múltiples direcciones. En este caso se elige una al azar. De esta forma puedes por ejemplo hacer que un enemigo se mueva hacia la izquierda o hacia la derecha.
Set direction and speed of motion Esta es la segunda forma en la que puedes especificar un movimiento (con las flechas azules). Aquí puedes indicar una dirección con más precisión. Con un ángulo de entre 0 y 360 grados. 0 significa hacia la derecha. La dirección es contra las manecillas del reloj. Así por ejemplo 90 indica la dirección hacia arriba. Si quieres una dirección arbitraria, puedes poner random(360). Como verás más abajo la función random da un número al azar menor que el valor indicado. Como podrás haber notado hay una casilla llamada Relative. Si la seleccionas, el nuevo movimiento es sumado al anterior. Por ejemplo, si la instancia se está moviendo hacia arriba y le agregas un pequeño movimiento hacia la izquierda, el nuevo movimiento será hacia arriba y a la izquierda.
Move towards a point Esta acción da otra manera de especificar un movimiento. Usted indica una posición y una velocidad y la instancia comienza a moverse con la velocidad seleccionada hacia la posición establecida (la instancia no se detendrá en la posición!). Por ejemplo, tu quieres que una bala vuele hacia la posición de una nave espacial (llamada spaceship), puedes usar como posición spaceship.x, spaceship.y (Aprenderá más sobre el uso de variables como éstas más adelante). Si marcas la casillaRelative, puede especificar la posición relativa para la posición actual de la instancia. (La velocidad no es tomada como relativa!)
Set the horizontal speed La velocidad de una instancia consiste de una parte horizontal y otra vertical. Con esta acción puedes cambiar la velocidad horizontal. Una velocidad horizontal positiva representa movimiento hacia la derecha. Una negativa movimiento hacia la izquierda. La velocidad vertical permanecerá constante. Usa la opción Relative para incrementar la velocidad horizontal (o disminuirla introduciendo un valor negativo).
Set the vertical speed De manera similar, con esta acción puedes cambiar la velocidad vertical de la instancia
.
Set the gravity Con esta acción puedes especificar una gravedad para un objeto en particular. Especificas una dirección (un ángulo entre 0 y 360 grados) y una velocidad, y a cada paso esta cantidad de velocidad en la dirección especificada se aumenta al movimiento actual de la instancia del objeto. Normalmente necesitas un muy pequeño incremento de velocidad (como 0.01). Normalmente se emplea una dirección hacia abajo (270 grados). Si seleccionas la casilla Relative incrementas la velocidad de gravedad y la dirección. Nota que, contrario a la vida real, diferentes objetos pueden tener diferentes direcciones de gravedad.
Reverse horizontal direction Con esta acción inviertes el movimiento horizontal de la instancia. Esto lo puedes usar por ejemplo cuando el objeto colisiona con una pared vertical.
Reverse vertical direction Con esta acción inviertes el movimiento vertical de la instancia. Esto lo puedes usar por ejemplo cuando el objeto colisiona con una pared horizontal.
Set the friction La fricción disminuye la velocidad de las instancias cuando se mueven. Puedes especificar la cantidad de fricción. En cada paso esta cantidad se resta de la velocidad hasta llegar a 0. Normalmente usas un número muy pequeño (como 0.01).
Jump to a given position Usando esta acción puedes colocar una instancia en una posición en particular. Simplemente especificas las coordenadas ‘x’ e ‘y’, y la instancia es colocada con su punto de referencia en esa posición. Si la casilla Relative está marcada, la posición es relativa a la posición actual de la instancia. Esta acción es usada a menudo para continuamente mover la instancia. En cada pasa incrementaremos la posición un poco.
Jump to the start position Esta acción coloca la instancia de vuelta a la posición donde fue creada.
Jump to a random position Esta acción mueve la instancia a una posición aleatoria cuarto. Solo se usan posiciones en donde la instancia no intercepte ninguna instancia sólida. Puedes especificar la rapidez (snap) usada. Si especificas valores positivos, las coordenadas serán elegidas con múltiplos enteros de los valores indicados. Esto puede ser usado por ejemplo para mantener una instancia alineada con las celdas de tu juego (si la hay). Puedes especificar la rapidez horizontal y la vertical por separado.
Snap to grid Con esta acción puedes alinear la posición de una instancia a una cuadrícula. Puedes indicar los valores horizontal y vertical (esto es, el tamaño de las celdas de la cuadrícula). Esto puede ser muy útil para asegurarte que las instancias se mantengan en una cuadrícula.
Wrap when moving outside Con esta acción puedes hacer que cuando una instancia salga del room por un lado, aparezca por el lado contrario (teleportación). Normalmente esta acción se usa en el evento Outside room. Observa que la instancia debe tener una velocidad para que esta acción funcione, porque la dirección en la que reaperece se basa en la dirección de movimiento. Puedes indicar si quieres que la instancia se teleporte sólo horizontalmente, sólo verticalmente o en ambas direcciones a la vez.
Move to contact position Con esta acción puedes mover la instancia en una dirección dada hasta que se encuentre tocando a otro objeto. Si ya hay colisión en la posición actual la instancia no se mueve. En caso contrario, la instancia se coloca justo antes de que ocurra una colisión. Puedes especificar la dirección y la máxima distancia que se debe mover la instancia. Por ejemplo, cuando la instancia se está cayendo puedes moverla una distancia máxima hasta que encuentre un objeto. También puedes hacer que se tengan en cuenta sólo los objetos sólidos o todos. Normalmente esta acción se pone en el evento colisión para asegurarte de que la instancia deje de moverse al chocar con el otro objeto.
Bounce against objects Cuando colocas esta acción en el evento collision de algún objeto, la instancia rebota en este objeto de manera natural. Si configuras el parámetro precise como falso, sólo las paredes horizontales y verticales se tratan correctamente. Cuando configuras precise a verdadero también se tratan las paredes inclinadas (y aún las curvadas) de manera correcta. Sin embargo esto es más lento. También puedes indicar si el objeto rebotará solo contra objetos sólidos o contra todos los objetos. Por favor nota que el rebote no es completamente correcto porque depende de muchas propiedades. Pero en muchas situaciones el efecto es lo suficientemente bueno
.
Acciones principales, grupo 1 El siguiente grupo de acciones está relacionado con la creación, el cambio y la destrucción de las instancias de objetos.
Create an instance of an object Con esta acción puedes crear una instancia de un objeto. Debes especificar el objeto a crear y la posición para la nueva instancia. Si marcas la casilla Relative, la posición es relativa a la posición de la instancia actual. La creación de instancias durante el juego es muy útil. Una nave crea balas; una bomba puede crear una explosión, etc. En muchos juegos tendrás un objeto de control que cada cierto tiempo creará enemigos u otros objetos. El evento de creación es ejecutado para la nueva instancia al crearse.
Create an instance of an object with a speed and direction Esta acción es la misma que la anterior pero con dos campos adicionales. Puedes especificar la velocidad y dirección de la instancia que se creará. Si usas la opción Relative sólo afectará a la posición y no a la velocidad ni dirección. Por ejemplo, para hacer que una bala se mueva en la misma dirección que el personaje que la crea usa un pequeño truco: activa la opción Relative e introduce la posición 0,0. En el campo de dirección, introduce la palabra
direction, que es la dirección en la que se mueve el personaje que dispara la bala.
Create instance of random object Esta acción te permite crear una instancia de uno de hasta cuatro objetos elegidos aleatoriamente. Especificas los cuatro objetos y la posición y una instancia de uno de estos objetos se creará en la posición elegida. Si usas Relative, la posición será relativa a la instancia que ejecute la acción. Si no quieres usar 4 objetos, puedes seleccionar No Object para los demás campos. Esta acción se puede usar para crear un enemigo de un tipo aleatorio en una posición determinada.
Change the instance Con esta acción puedes cambiar la instancia actual por otro objeto. Por ejemplo, puedes cambiar una instancia de una bomba en una
explosión. Todos los parámetros, como el movimiento o los valores de variables, se mantendrán iguales. Puedes indicar si llevar a cabo o no el evento de destrucción para el objeto actual y el evento de creación para el nuevo.
Destroy the instance Con esta acción destruyes la instancia actual. Esa instancia ejecuta el evento de destrucción de la instancia.
Destroy instances at a position Con esta acción puedes destruir todas las instancias cuya caja límite contiene una posición dada. Esto es útil por ejemplo cuando empleas la explosión de una bomba. Cuando marcas la casilla Relative, la posición es relativa a la posición de la instancia actual.
Change the sprite Usa esta acción para cambiar el sprite de la instancia. Debes indicar un nuevo sprite. También puedes indicar un factor de escalado. Un factor de 1 significa que el sprite no es escalado. El factor de escalado debe ser mayor que 0. Por favor recuerda que el escalado reducirá la velocidad del dibujo. El cambio de sprites es una característica importante. Por ejemplo, a menudo querrás cambiar el sprite de un personaje de acuerdo a la dirección a la que se dirige. Esto se puede lograr haciendo diferentes sprites para cada una de las (cuatro) direcciones. En los eventos del teclado para las teclas del cursor estableces la dirección de movimiento y el sprite.
Transform the sprite Usa esta acción para cambiar el tamaño y orientación del sprite de la instancia. Usa los factores de escale para hacer el sprite más grande o pequeño. El ángulo (angle) indica la orientación en sentido anti horario del sprite. Por ejemplo, para hacer que el sprite se oriente en la dirección del movimiento usa el valor
direction. Esto es muy útil para un juego de coches, por ejemplo. Esta acción sólo está
disponible en la función registrada.
Set sprite blending Normalmente el sprie se dibuja como se ha definido. Usando esta función puedes cambiar el color del sprite. Este color se combina con los colores del sprite Si quieres dibujar un sprite en varios colores debes definir el sprite en blanco y negro y usar el color para definir la nueva apariencia del sprite. También puedes indicar una transparencia (alpha): 0 significa totalmente transparente y 1 totalmente opaco. Con un valor intermedio (Ej.: 0.5) conseguirás que se pueda ver el fondo a través del sprite. Esto es muy útil para explosiones. Esta acción sólo está disponible en la función registrada.
Play a sound Con esta acción reproduces uno de los recursos de sonido que agregaste al juego. Puedes indicar el sonido a reproducir y si debiera reproducirse solo una vez (el valor por defecto) o hacerlo continuamente Se pueden reproducir varios archivos wave al mismo tiempo, pero sólo puede reproducirse un midi a la vez. Así que si inicia el sonido de un midi, el midi actual se detiene. A menos que el sonido tenga múltiples buffers sólo se puede reproducir una instancia del sonido. Por lo que si el mismo sonido se está reproduciendo, se detiene y vuelve a empezar
.
Stop a sound Esta acción detiene el sonido indicado. Si hay varias instancias del sonido reproduciéndose, todas son detenidas.
If a sound is playing Si el sonido indicado está sonando la acción siguiente se ejecuta. Si no, la acción siguiente se ignora. Puedes seleccionar Not para que actúe al revés (es decir, si el sonido no está la acción se ejecuta). Por ejemplo, puedes comprobar si está sonando la música de fondo y si no está sonando, haces que empiece a sonar otra canción. Esta acción devuelve true cuando el sonido suena por los altavoces. Cuando usas la acción de hacer sonar un sonido tarda un poco hasta que el sonido llega a los altavoces y así que esta acción devolverá false durante ese pequeño espacio de tiempo. Cuando detienes un sonido, tampoco se para instantáneamente así que la acción tardará un poco en devolver false,
Go to previous room Ir al cuarto anterior. Puedes indicar el tipo de transición entre los cuartos. Experimenta para que veas cuál es el que te agrada. Si estás en el primer cuarto, se da un error.
Go to next room Ir al siguiente cuarto. Puedes indicar la transición. Si estás en el último cuarto da un error.
Restart the current room Se reinicia el cuarto actual. Puedes indicar el efecto de transición.
Go to a different room Con esta acción vas a un cuarto en particular. Puedes indicar el cuarto y el efecto de transición.
If previous room exists Esta acción verifica si existe el cuarto anterior. Si es cierto, se ejecuta la siguiente acción. Normalmente necesitas hacer esta comprobacion antes de moverte al cuarto anterior.
If next room exists Esta acción verifica si existe el siguiente cuarto. Si es cierto, se ejecuta la siguiente acción. Normalmente necesitas hacer esta comprobacion antes de moverte al siguiente cuarto.
Acciones principales, grupo 2 Aquí tenemos algunas acciones más, relacionadas con el tiempo, mostrar mensajes al usuario, y al juego en conjunto.
Set an alarm clock Con esta acción puedes configurar uno de los doce relojes de alarma para la instancia. Puedes indicar el número de pasos y la alarma. Después del número indicado de pasos, la instancia recibirá el correspondiente evento de alarma. También puedes incrementar o decrementar el valor marcando la casilla Relative. Si configures la alarma a un valor menor o igual que 0 la desactivas, por lo que no se genera el evento.
Sleep for a while Con esta acción puede congelar la escena por un cierto tiempo. Esto usualmente se usa al inicio de un nivel o cuando le das algún mensaje al jugador. Especificas el número de milisegundos a pausar. También indicas si la pantalla debiera ser dibujada primero para mostrar la situación más reciente.
Display a message Con esta acción puedes mostrar un mensaje en una ventana de diálogo. Simplemente tecleas el mensaje. Si usas el símbolo # en el texto del mensaje será interpretado como un carácter de nueva línea (usa \# para obtener el símbolo #). Si el mensaje empieza con una comilla o dobles comillas, se interpreta como una expresión. Ve el team correspondiente sobre las expresiones.
Show the game information Con esta acción puedes mostrar la ventana de información del juego.
Restart the game Con esta acción puedes reiniciar el juego desde el principio.
End the game Con esta acción termina el juego.
Save the game Con esta acción puedes guardar el estado actual del juego. Especificas el nombre del archivo a guardar (el archivo es creado en la carpeta de trabajo del juego). Después el juego puede ser cargado con la siguiente acción (observa que cosas como el sonido que está sonando, los contenidos de las estructuras de datos, partículas, etc…no se cargarán).
Load the game Carga el estado del juego desde un archivo. Aquí especificas el nombre del archivo. Asegúrate de que el juego guardado corresponde al mismo juego y que fue creado con la misma versión del Game Maker. De otra manera pudiera haber errores (para ser precisos, el juego se carga en el evento step actual. Por lo que aún se realizan algunas acciones después de esta aún son realizadas en el juego actual, ¡no en el cargado!).
Acciones de control Hay varias acciones con las que puedes controlar qué otras acciones se llevan a cabo. La mayoría de estas acciones hacen una pregunta, por ejemplo si es que una posición está vacía. Cuando la respuesta es yes (true) se ejecuta la siguiente acción, de otra forma se salta esa acción. Si quieres que se ejecuten o salten varias acciones basándote en el resultado puedes colocarlas dentro de un bloque. También puede haber una parte else, la cual se ejecuta cuando la respuesta es no. Así, una pregunta normalmente tiene la siguiente estructura:
Aquí se pregunta si una posición para la instancia actual está libre de colisión. De ser así, la instancia comienza a moverse en una dirección dada. Si no, la instancia es movida a una posición dada. Para todas las preguntas hay un campo marcado NOT. Si lo marcas, el resultado de la pregunta se invierte. Esto es, si el resultado era verdadero se vuelve falso, y si era falso, se vuelve verdadero. Esto te permite realizar ciertas acciones cuando una pregunta no es verdadera. Para muchas preguntas puedes indicar si deben aplicar a todas las instancias de un objeto en particular. En este caso el resultado es verdadero solo si es verdadero para todas las instancias del objeto. Por ejemplo, puedes checar si para todas las pelotas la posición ligeramente a la derecha está libre de colisión.
Las siguientes preguntas y acciones relacionadas están disponibles. (Nota que todas ellas tienen un icono con forma y color de fondo diferentes de manera que puedan ser distinguidos más fácilmente de otras acciones). If a position is collision free Esta pregunta devuelve verdadero si la instancia actual, colocada en la posición indicada no provoca una collision con algún objeto. Puedes especificar si la posición es absoluta o relativa. Puedes también indicar si solo los objetos sólidos o todos los objetos debieran ser tomados en cuenta. Esta acción es normalmente empleada para checar si la instancia se puede mover a una posición en particular.
If there is a collision at a position Esta es la inversa de la acción anterior. Devuelve verdadero si hay una colisión cuando la instancia actual es colocada en la posición indicada (de nuevo, ya sea sólo con objetos sólidos o con toda clase de objetos).
If there is an object at a position Esta pregunta devuelve verdadero si la instancia colocada en la posición indicada encuentra una instancia del objeto indicado.
If the number of instances is a value Especificas un objeto y un número. Si el número de instancias del objeto es igual al número la pregunta devuelve verdadero. De otra forma devuelve falso. Puedes también indicar que la revisión debiera ser si el número de instancias es menor o mayor que el valor. Esto se usa normalmente para checar si todas las instancias de un tipo en particular han desaparecido. Este es normalmente el momento de terminar el nivel o el juego.
With a change perform next action Especificas el número de lados del dado. Entonces si el dado cae en uno, el resultado es verdadero y se realiza la acción. Esto se puede emplear para agregar cierta aleatoriedad en tu juego. Por ejemplo, en cada paso puedes generar con cierta probabilidad una bomba o un cambio de dirección. Entre mayor sea el número de lados del dado, la probabilidad es menor. Puedes emplear números reales. Por ejemplo, si configuras el número de lados a 1.5 la siguiente acción se realizará dos de tres veces. El emplear un número menor que 1 no tiene sentido.
If the user answers yes to a question Especificas una pregunta. Se muestra una ventana de diálogo al usuario con dos botones: Yes y No. El resultado es verdadero si el jugador contesta Yes.
If an expression is true Puedes introducir una expresión. Si la expresión se evalúa como verdadera (esto es, un número mayor o igual a 0.5) se realizará la siguiente acción. Ve más abajo para más información sobre las expresiones.
If a mouse button is pressed Devuelve verdadero si el botón indicado del ratón es presionado. Un uso estándar está en el evento paso. Puedes checar si un botón del ratón está presionado, y si es así, por ejemplo moverte a esa posición (usa la acción jump to a point con los valores
mouse_x
y
mouse_y).
If instance is aligned with grid Devuelve verdadero si la posición de la instancia se encuentra sobre una cuadrícula. Especificas el espaciado horizontal y vertical de la cuadrícula. Esto es muy útil cuando ciertas acciones, como el dar una vuelta, no son permitidas cuando se está alineado a una posición en la cuadrícula.
Start of block Indica el inicio de un bloque de acciones.
End of block Indica el final de un bloque de acciones.
Else Detrás de esta acción sigue el else, que se ejecuta cuando el resultado de la pregunta es falso. Repeat next action Esta acción se emplea para repetir la siguiente acción (o bloque de acciones) cierto número de veces. Puedes simplemente indicar el número.
Exit the current event Cuando se encuentra esta acción, no se realiza ninguna otra en el evento. Normalmente se emplea después de una pregunta. Por ejemplo, cuando una posición está libre no se necesita hacer nada por lo que salimos del evento. En este ejemplo, las acciones siguientes son solo ejecutadas cuando hay una colisión.
Si deseas más control sobre lo que está ocurriendo en el juego puedes uar el lenguaje de programación de Game Maker, el GML, que se explica en la segunda parte del manual. Te da mucha más flexibilidad que usando las acciones, gracia a que puedes usar tus propias variables. Las acciones siguientes se ocupan de esto: Execute a piece of code Cuando agregas esta acción, se muestra una ventana en la que puedes introducir una pieza de código. Éste funciona en la misma forma que definir scripts. La única diferencia es que puedes indicar para qué instancias se debe ejecutar el código. Usa esta acción para pequeñas piezas de código. Para piezas más largas se te recomienda usar scripts.
Comment Usa esta acción para agregar una línea de comentarios a la lista de acciones. La línea se muestra en fuente cursiva. No hace nada cuando se ejecuta el evento. El agregar comentarios te ayuda a recordar lo que estás haciendo en tus eventos.
Set the value of a variable Hay muchas variables internas en el juego. Con esta acción puedes cambiar sus valores. También puedes crear tus propias variables y asignarles valores. Indicas el nombre de la variable y un nuevo valor. Cuando seleccionas la opción Relative, el valor se suma al valor actual de la variable. ¡Por favor nota que esto sólo puede usarse si la variable ya tiene un valor asignado!. Ve más adelante para más información sobre las variables.
If a variable has a value Con esta acción puedes checar cuál es el valor cierta variable. Si el valor de la variable es igual al número introducido, la pregunta
devuelve true. En cualquier otro caso devuelve false. Puedes indicar si se checará si la el valor es menor o mayor que el dado. Ve abajo para más información sobre las variables. De hecho, también puedes usar esta acción para comparar dos expresiones.
Draw the value of a variable Con esta acción puedes dibujar el valor de una variable en cierta posición de la pantalla. Esta acción sólo se puede usar en el evento Draw.
Acciones de score En la mayoría de los juegos el jugador tendrá cierto score. También muchos juegos le dan al jugador cierto número de vidas. Finalmente, a menudo el jugador cuenta con cierto nivel de energía. Las siguientes acciones permiten manejar de manera sencilla el score, las vidas y la energía del jugador.
Set the score Game Maker tiene un mecanismo interno de score. El score normalmente se muestra en el título de la ventana. Puedes usar esta acción para cambiar el score. Simplemente introduces un nuevo valor para éste. A menudo querrás agregar puntos al score. En este caso no olvides seleccionar la opción Relative.
If score has a value Con esta pregunta puedes checar si el score ha alcanzado un valor en particular. Puedes indicar el valor y si el score debe ser igual, menor o mayor a ese valor.
Draw the value of score Con esta acción puedes dibujar el valor del score en cierta posición de la pantalla. Proporcionas la posición y el título que se mostrará antes del score. El score se dibuja con la fuente actual. Esta acción sólo puede emplearse en el evento draw de algún objeto.
Display the highscore table Cada juego guarda los diez mejores scores. Esta acción muestra la lista de récords. Si el score actual está entre los mejores diez, el nuevo score se inserta y el jugador puede introducir su nombre. Puedes indicar la imagen de fondo a usar, si la ventana tendrá borde, el color para la nueva y las otras entradas, y la fuente a emplear.
Clear the highscore table Esta acción vacía la tabla de récords.
Set the number of lives El Game Maker también cuenta con un sistema interno de vidas. Con esta acción puedes cambiar el número de vidas que quedan. Normalmente lo pones a un valor como 3 al inicio del juego y lo aumentas o disminuyes dependiendo de lo que ocurra. No olvides
seleccionar la opción Relative si deseas agregar o restar al número de vidas. En el momento en que el número de vidas llegue a 0 (ó menos que 0) se genera un evento “no more lives”.
If lives is a value Con esta pregunta puedes checar si el número de vidas ha llegado a un cierto valor. Puedes indicar el valor y si el número de vidas debe ser igual, menor o mayor a ese valor.
Draw the number of lives Con esta acción puedes dibujar en pantalla en número de vidas. Das la posición y el título que se colocará antes del número de vidas. El número de vidas se dibuja con la fuente actual. Esta acción sólo puede ser usada en el evento draw de algún objeto.
Draw the lives as image En lugar de indicar el número de vidas con un número, es mejor usar pequeñas imágenes para indicar las vidas. Esta acción hace eso precisamente. Especificas la posición y la imagen, y en la posición indicada se dibuja el número de vidas como imágenes. Esta acción sólo puede emplearse en el evento draw de un objeto.
Set the health Game Maker tiene un mecanismo interno de energía. Puedes emplear esta acción para cambiar la energía. Un valor de 100 se considera como energía completa y 0 es sin energía. Simplemente das un nuevo valor para la energía. A menudo querrás restar algo a la energía. En este caso no olvides seleccionar la opción Relative. Cuando la energía sea igual o menor que 0 se genera un evento “out of health”.
If health is a value Con esta pregunta puedes checar si la energía ha alcanzado cierto valor. Indicas el valor y si la energía debe ser igual, menor o mayor que ese valor.
Draw the health bar Con esta acción puedes dibujar la energía en forma de una barra. Cuando la energía es 100 la barra es dibujada completa. Cuando es 0 la barra está vacía. Puedes indicar la posición y el tamaño de la barra de energía y el color para la barra y el fondo de la misma.
Set the window caption information Normalmente en el título de la ventana se muestra el nombre del cuarto y el score. Con esta acción puedes cambiar esto. Puedes indicar si se muestra o no el score, las vidas, la energía y los títulos para estas opciones.
Acciones de dibujo
Normalmente, a cada instancia se le dibuja su sprite en cada paso del juego. Puedes cambiar esto poniendo acciones en el evento draw de un objeto. Observa que estas acciones sólo se ejecutarán si están colocadas en el evento draw y la instancia es visible, en cualquier otro caso simplemente se ignoran.
Draw a sprite image Indicas el sprite, la posición (ya sea absoluta o relativa a la posición actual de la instancia) y la subimagen del sprite. (Las subimágenes están numeradas de 0 hacia arriba). Si quieres dibujar la subimagen actual, usa el número –1.
Draw a background image Indicas la imagen de fondo, la posición (absoluta o relativa) y si la imagen debe o no repetirse en todo el cuarto.
Draw a text Indicas el texto y la posición. Un símbolo # en el texto se interpreta como el inicio de una nueva línea. (Usa \# para mostrar el símbolo #). Por lo que puedes crear texto multilínea. Si el texto inicia con comilla simple o doble, es interpretado como una expresión. Por ejemplo, puedes usar
'X: ' + string(x) para mostrar el valor de la coordenada x de la instancia. (La variable x guarda la coordenada x actual. La función string() convierte este número en una cadena. + combina las dos cadenas).
Draw a text transformed Esta acción es similar a la acción anterior pero en este caso puedes escalar el texto vertical y horizontalmente y rotarlo un ángulo determinado. Esta acción sólo está disponible en la versión registrada.
Draw a rectangle Indicas las coordenadas de las dos esquinas opuestas del rectángulo, ya sean absolutas o relativas a la posición actual de la instancia.
Draw a horizontal gradient Esta acción también dibuja un rectángulo pero lo rellena con un degradado de izquierda a derecha. Tienes que especificar las coordenadas del rectángulo y los dos colores para el degradado. Esta acción sólo está disponible en la versión registrada.
Draw a vertical gradient Esta acción es igual que la anterior pero el degradado es de abajo a arriba. Esta acción sólo está disponible en la versión registrada.
Draw an ellipse Indicas las coordenadas de las dos esquinas opuestas del rectángulo alrededor de la elipse, ya sean absolutas o relativas a la posición actual de la instancia.
Draw a gradient ellipse Igual que la anterior pero puedes especificar un color para el centro y otro para el borde para rellenar la elipse con un degradado. Esta acción sólo está disponible en la versión registrada.
Draw a line Indicas las coordenadas de los dos extremos de la línea; ya sean absolutas o relativas a la posición actual de la instancial.
Draw an arrow Dibuja una flecha. Puedes especificar las coordenadas del principio y final de la fecha y el tamaño de la punta.
Set the colors Te permite seleccionar el color usado para rellenar los rectánguos y elipses, y el color empleado para las líneas alrededor de los rectángulos y elipses y para dibujar una línea.
Change fullscreen mode Con esta acción puedes cambiar el modo de la pantalla de ventana a pantalla completa y viceversa. Puedes indicar si se cambia entre modos o si cambiar a modo de ventana o a modo a pantalla completa.
Take a snapshot image of the game Puedes sacar una foto de la pantalla y guardarla como una imagen .bmp. Debes especificar el nombre del archivo donde se guardará la imagen. Esta acción sólo está disponible en la versión registrada.
Create an effect Con esta acción puedes crear varios efectos de una manera sencilla. Especificas el tipo de efecto (explosion, humo,…), su posición, tamaño y color y si debe dibujarse sobre los objetos o bajo ellos. Todo lo demás es automáico (para el efecto de lluvia la posición es irrelevante porque siempre cae desde la parte superior de la pantalla. Para conseguir lluvia continua debes llamar a esta acción desde el evento step). Esta acción sólo está disponible en la versión registrada.
Usando expresiones y variables En muchas acciones necesitas especificar valores para los parámetros. En lugar de escribir un número, puedes poner una fórmula (ejemplo: 32*12). Pero también puedes proporcionar expresiones mucho más complicadas. Por ejemplo, si quieres doblar la velocidad horizontal, puedes poner
2*hspeed. En esta expresión hspeed es una variable que se refiere a la velocidad horizontal actual de la instancia.
También hay otras variables que puedes usar, las más importantes son las siguientes: x coordenada x de la instancia
y coordenada y de la instancia hspeed velocidad horizontal (en píxeles por step) vspeed velocidad vertical (en píxeles por step) direction dirección actual en grados (de 0 a 360) speed velocidad actual en esta dirección visible si el objeto es visible (1) o no (0) image_index esta variable indica qué subimagen del sprite se está dibujando. Si pones la variable image_speed a 0 puedes mostrar una imagen fija, parando la animación del sprite. image_speed indica la velocidad con la que las subimágenes del sprite cambian durante la animación. Por defecto vale 1. Si pones un valor mayor a 1 algunas subimágenes de la animación se saltan y de la impresión de que la animación va más rápido. Si lo haces menor que 1 las subimágenes se repiten y da la impresión de que la animación va más lenta. score valor actual del score lives número actual de vidas health health actual (0-100) mouse_x posición x del ratón mouse_y posición y del ratón Puedes cambiar casi todos estos valores usando la acción set variable. También puedes definir tus propias variables simplemente dándoles un valor (no uses la opción relative al hacer esto, pues todavía no existe esa variable). También puedes usarlas luego en expresiones. Las variables que creas son variables locales de la instancia, es decir, cada objeto tiene la suya propia distinta a la de los demás. Para crear una única variable para todos, pon global seguido de un punto delante del nombre de la variable.
También puedes acceder a las variables de los demás objetos poniendo el nombre del objeto, un punto y el nombre de la variable a la que quieres acceder. Por ejemplo, para mover una pelota al lugar donde hay una moneda puedes dar a la posición los valores (moneda.x , usando
moneda.y). En caso de colisión, puedes acceder a las variables del otro objeto (el objeto contra el que estás chocando)
other.nombre_de_la_variable. En expresiones condicionales puedes usar comparaciones como < (menor que), >,
etc.
Por último, también puedes usar funciones. Por ejemplo, la función
random(10) devuelve un número real menor que 10. Así, puedes
hacer que la velocidad o la dirección tomen este valor. Existen muchas más funciones que se describen en la parte del manual dedicada al GML.
Creando rooms Ahora que has definido los objetos con su comportamiento en forma de eventos y acciones, es hora de crear los cuartos o niveles en los que se llevara a efecto el juego. Cualquier juego requerirá al menos un cuarto. En estos cuartos colocamos instancias de los objetos. Una vez que el juego inicia se muestra el primer cuarto y las instancias en él
toman vida por las acciones en sus eventos de creación.
Hay un gran número de posibilidades al crear cuartos. Además de establecer ciertas propiedades y agregar las instancias de los objetos puedes agregar fondos, definir vistas, y agregar tiles. La mayoría de estas opciones se discuten más adelante en el Capítulo 20. en este capítulo solamente discutiremos las opciones básicas, el agregar instancias de
objetos y la configuración de las imágenes de fondo.
Para crear un cuarto, selecciona Add Room en el menu Add. Se muestra la siguiente ventana:
En la parte superior de la ventana hay una barra de herramientas. Desde ella puedes indicar el tamaño de las celdas de la rejilla usada para alinear objetos, si deben mostrarse o no los fondos,...A veces es útil ocultar temporalmente algunos elementos del room. Observa que cuando estés añadiendo instancias de ojetos éstas siempre se mostrarán, independientemente de la configuración de las vistas. También hay botones para eliminar todas las instancias del room o para moverlas una cantidad determinada de píxeles. Usa valores negativos para moverlas hacia arriba o a hacia la izquierda. Esto es muy útil cuando decides agrandar el cuarto (o para situar instancias fuera del room).
Finalmente están los botones Undo para deshacer los cambios y OK para guardarlos (usa la cruz en la esquina superior derecha para cerrar la ventana sin guardar los cambios).
A la izquierda hay tres fichas (cinco en modo advanced). La ficha objects es donde puedes agregar instancias de los objetos al cuarto. En la ficha settings puedes indicar varias opciones para el cuarto. En la ficha backgrounds puedes configurar las imágenes de fondo para el cuarto.
Añadiendo instancias A la derecha en la ventana de diseño puedes ver el cuarto. Al principio está vacío, con un fondo gris.
Para agregar instancias al cuarto, primero selecciona la ficha objects si no está visible. A continuación selecciona el objeto que deseas agregar haciendo click en el botón con icono de un menu (o haciendo clic en el área de imagen a la izquierda). La imagen del objeto aparece a la izquierda. (observa que hay una cruz en la imagen. Esta indica cómo se
alinearan las instancias con la cuadrícula). Ahora haz click con el botón izquierdo del ratón en el área a la derecha. Aparece una instancia del objeto. Ésta se alineará a la cuadrícula indicada. Si mantienes presionada la tecla mientras colocas la instancia no se alineará a la cuadrícula. Si mantienes presionado el botón mientras mueves el ratón puedes mover la instancia sobre la room hasta una nueva posición. Si pulsas mientras pulsas el botón y mueves el ratón añadirás varias instancias a la vez. Con el botón derecho del ratón puedes eliminar las instancias. De esta manera es como defines el contenido del cuarto. Si mantienes presionado el botón mientras lo arrastras sobre el cuarto, eliminarás varias instancias.
Como te darás cuenta, si colocas una instancia sobre otra, la primera desaparece. Normalmente será lo que desees, pero no siempre. Esto puede evitarse al deshabilitar la opción Delete underlying a la izquierda.
Si quieres cambiar la posición de una instancia pulsa la tecla y pincha con el botón izquierdo del ratón. Sin solta ninguna de las dos teclas puedes arrastrar la instancia a una nueva posición (usa para posicionarlo con mayor precisión).
Si mantienes pulsado mientras pinchas con el botón derecho sobre una instancia aparece un menú. Desde este menú puedes borrar la instancia, especificar un posicionamiento preciso o mover la instancia al frente sobre todas las demás o al fondo bajo el resto.
Configuración del room Cada cuarto tiene ciertas opciones que puedes cambiar haciendo click en la ficha settings. Sólo trataremos las más importantes aquí.
Cada cuarto tiene un nombre, mejor dale uno con sentido. También hay un título. Este título se muestra en la ventana cuando se ejecuta el juego. Puedes establecer el ancho y alto del cuarto (en píxeles). También puedes configurar la velocidad del juego. Este es el número de pasos por segundo. Cuanto mayor sea la velocidad, más suave será el movimiento. Pero necesitarás una computadora más rápida para ejecutarlo.
Configurando el fondo Con la ficha backgrounds puedes establecer la imagen de fondo para el cuarto. De hecho, puedes indicar varios fondos. La ficha se ve como sigue:
En la parte superior versa el color de fondo. Puedes hacer clic sobre este para cambiarlo. El color de fondo sólo es útil si no usas una imagen de fondo que cubra todo el cuarto. De otra forma, mejor deshabilita la opción Draw background color ya que significaría una pérdida de tiempo.
Arriba verás una lista de 8 fondos. Puedes definir cada uno de ellos pero la mayoría de las veces sólo necesitaras uno ó dos. Para definir un fondo, primero selecciona uno en la lista. A continuación marca la opción Visible when room starts o de otra forma no lo verás. El nombre del fondo se pondrá en negritas cuando esté definido. Ahora indica una
imagen de fondo en el menu. Hay ciertas opciones que puedes cambiar. Primero de todo puedes indicar si la imagen de fondo se repetirá horizontal y/o verticalmente. Puedes también indicar la posición del fondo en el cuarto (esto también influirá el tiling). Otra opción es usar la opción Stretch para que el fondo ocupe toda la pantalla (puede distorsionar la imagen). Finalmente puedes hacer que el fondo se desplace dándole una velocidad horizontal o vertical (píxeles por step). No se recomienda dar velocidad al fondo si usas la opción Stretch.
Hay una opción más llamada Foreground image. Cuando la activas, el fondo se colocará en primer plano, y se dibujará al frente de todo en lugar de detrás de todo. Obviamente una imagen de este tipo debiera ser parcialmente transparente para que tenga alguna utilidad.
Distribuyendo tu juego Con la información de los capítulos anteriores puedes crear tus juegos. Una vez que hayas creado un buen juego probablemente quieras darlo a otras personas para que lo jueguen. Puedes distribuir libremente y en la forma que desees los juegos que crees con el Game Maker. Incluso puedes venderlos. Lee el acuerdo de licencia adjunto para más información al respecto.
Básicamente hay tres diferentes formas en las que puedes distribuir tus juegos. La manera más fácil es simplemente dar el archivo *.gm6 que contiene el juego. Sin embargo la otra persona debe tener el Game Maker. (No se te permite distribuir el Game Maker con tu juego peros ellos pueden bajarlo gratuitamente desde el sitio Web). Además, la otra persona puede hacer cambios al juego.
La segunda forma es crear un ejecutable del juego. Esto puede hacerse seleccionando la opción Create Executable en el menu File. Se te pedirá un nombre para el ejecutable que contendrá el juego. Indica un nombre, presiona OK y tendrás un juego ejecutable que puedes dar a quien tú quieras. Puedes configurar el icono para el juego ejecutable en la ventana Global Game Settings (Si tu juego usa algún otro archivo debieras copiarlos a la carpeta que contiene el ejecutable del juego). Ahora puedes distribuir este archivo a otras personas (tal vez quieras comprimirlo antes).
La tercera opción es crear un archivo de instalación. Hay varios programas freeware para la creación de instaladores disponibles en la red. Lo primero es crear una versión ejecutable del juego y luego emplear el instalador para crear una instalación. Cómo se haga esto depende del instalador que emplees.
Uso avanzado En esta sección se describen los aspectos más avanzados de Game Maker. En ella se explican los paths, fuentes, time lines, scripts y las técnicas para crear rooms con tiles y el uso de vistas. Esta sección se divide en los siguientes temas: Modo avanzado Más sobre los sprites Más sobre sonido y música Más sobre los fondos Más sobre los objetos Más acciones Más sobre las rooms Fuentes Paths Time lines Scripts
Modo avanzado Hasta ahora hemos considerado las opciones más simples de Game Maker. Pero hay muchas mas posibilidades. Para habilitarlas debes ejecutar Game Maker en Modo Avanzado (Advanced Mode).
Es fácil de cambiar. En el Menú File, click en el ítem Advanced Mode. (Para ver los cambios debes reiniciar Game Maker o al menos guardar tu juego y volver a cargarlo). Cuando comience Game Maker en Advanced Mode, el siguiente formulario se mostrara:
Contiene todo lo que estaba en Simple Mode, pero hay un número de recursos adicionales, botones e ítems de menú. También, como veremos en los siguientes capítulos los diferentes recursos tienen opciones adicionales. Aquí analizaremos los diferentes ítems del menú.
Menú File En el Menú File puedes encontrar los siguientes comandos.
•
Merge Game (Unir Juego). Con este comando puedes unir todos los recursos (sprites, sonidos, objetos, cuartos, etc.) de otro juego en tu actual proyecto. Esto es bastante útil se deseas hacer algo que quieras volver a usar (Ej.: Sistemas de menú). Fíjate que todos los recursos, instances y tiles tendrán nuevos nombres lo que puede causar problemas si los usas en scripts. Es tu responsabilidad hacer que sea seguro que los recursos en los dos diferentes archivos tengan distintos nombres, de otro modo, podrían aparecer problemas.
•
Preferences (Preferencias). Aquí puedes configurar varias opciones del programa. Estas opciones se aplicarán cada vez que uses Game Maker y se explican en el apartado siguiente.
Preferencias Aquí puedes poner un número de preferencias sobre Game Maker. Estas serán recordadas entre diferentes llamadas a Game Maker. Las siguientes preferencias se podrán elegir:
•
Show recently edited games in the file menú (Mostrar los juegos recientemente editados en el Menú File): Si está chequeada los ocho juegos mas recientemente editados serán mostrados debajo de recent files en el Menú File.
•
Load last opened file on startup (Cargar el último juego abierto al comienzo): Si está chequeada cuando comiences Game Maker el archivo abierto más recientemente será abierto automáticamente.
•
Maximal number of backups (Máximo numero de copias): Aquí indicas cuántas (1-9) diferentes copias de respaldo deben ser recordadas por el programa.
•
Show progress while loading and saving files. Cuando se carga o se guarda el juego se muestra un indicador de progreso.
•
At startup check for and remove old temporary files. Game Maker y los juegos creados con él, crean unos archivos temporales. Normalmente estos archivos se eliminan automáticamente pero a veces, debido a fallos en los juegos, no ocurre así. Activando esta opción Game Maker chequea si existen archivos de este tipo y los elimina al arrancar.
•
Run games in secure mode. (Ejecutar el juego en modo seguro): Si está chequeada, cualquier juego creado con Game Maker que funcione en tu maquina, no permitirá ejecutar programas externos, o cambiar o eliminar archivos en un lugar diferente del que se encuentre el juego (Esto es una garantía contra Troyanos). Chequeándola puede hacer que ciertos juegos que usen archivos externos no se ejecuten correctamente. Esta opción sólo funciona al ejecutar los juegos desdeGame Maker y no al jugarlos desde el ejecutable.
•
Show the origin and bounding box in the sprite image (Mostrar el origen y la bounding box en el sprite): Si está chequeada, en el formulario de propiedades del sprite, el origen y la bounding box del sprite será indicada.
•
In object properties, show hints for actions (En las propiedades del objeto, mostrar descripción para las acciones): Si esta chequeada, en el formulario de propiedades del objeto, cuando pases el puntero del mouse sobre alguna de las acciones, una descripción será mostrada.
•
When closing, remove instances outside the room. Si se activa, el programa te avisará si hay instancias o tiles fuera del room y te preguntará si quieres eliminarlas.
•
Remember room settings when closing the form. (Recordar la configuración del cuarto cuando se cierre el formulario): Si esta chequeada, un numero de opciones del cuarto; como whether to show the grid, whether to delete underlying objects, etc. serán recordadas cuando edites el cuarto más adelante.
•
Scripts and code and colors (Scripts y código en colores): Consulta el capítulo sobre scripts para más información.
•
Image editor (Editor de imágenes): Por defecto Game Maker tiene un editor interno de imágenes tú tienes un mejor programa editor de imágenes puedes indicarlo aquí para usar un programa diferente para edita imágenes.
•
External sound editors (Editores externos de sonido): Puedes indicar qué editor externo quieres usar para los diferentes tipos de sonido. (Fíjate que Game Maker no tiene un editor interno de sonido, por lo que si no indicas ninguno no podrás editar los sonidos).
Menú Edit En el Menú File puedes encontrar los siguientes comandos:
•
Insert group (Insertar grupo): Los recursos pueden ser agrupados juntos. Esto es bastante útil si tú haces un juego grande. Por ejemplo, puedes poner todos los sonidos relativos a un objeto juntos en un grupo, o puedes agrupar todos los objetos que usas en un nivel en particular. Este comando crea un nuevo grupo en el tipo de recurso seleccionado actualmente. Te preguntaras por el nombre. Los grupos pueden contener otros grupos dentro de ellos, etc. Como indica bajo puedes arrastrar recursos hacia los grupos.
•
Find Resource (Buscar recurso): Con este comando pones el nombre del recurso y abre el formulario de propiedades correspondiente.
•
Expand Resource Tree. Expande completamente el árbol de recursos, mostrándolos todos.
•
Collapse Resource Tree. Contrae completamente el árbol de recursos, ocultándolos todos.
•
Show Object Information. Con este comando puedes obtener un resumen de todos los objetos del juego.
Menú Add Con este menú puedes añadir recursos adicionales. Fíjate que para cada uno de ellos hay un botón en la barra de herramientas y un método abreviado del teclado.
Menú Scripts En este menú puedes encontrar los comandos siguientes:
•
Import Scripts. Se usa para importar scripts desde otros archivos.
•
Export Scripts. Sirve para guardar tus scripts en un archivo para poder distribuirlos. Cuando seleccionas un script sólo ése es guardado. Cuando seleccionas un grupo de scripts se guardan todos los scripts del grupo. Cuando seleccionas el recurso raíz (o un tipo diferente de recurso) se guardan todos los scripts. También puedes acceder a este menú clickando con el botón derecho del ratón sobre un script o un grupo de scripts.
•
Show Built-in Variables. Muestra una lista ordenada de todas las variables propias locales y globales.
•
Show Built-in Functions. Muestra una lista ordenada de todas las funciones de Game Maker.
•
Show Constants. Muestra una lista de todas las constantes propias de Game Maker y de las definidas en las opciones del juego.
•
Show Resource Names. Muestra una lista ordenada de todos los recursos. Puedes pinchar en los recursos para editarlos.
•
Search in Scripts. Puedes buscar una cadena de texto en todos los scripts a la vez. Puedes pinchar en los resultados para editar ese script.
•
Check Resource Names. Chequea todos los nombres de los recursos, mostrando los nombres incorrectos, duplicados o si coinciden con una variable, función o constante. Puedes pinchar en los resultados para editar ese recurso.
•
Check All Scripts. Chequea todos los scripts buscando errores. Puedes pinchar en los resultados para editar ese script.
Más sobre los sprites Existen varias posibilidades avanzadas para crear tus propios sprites. La información sobre las opciones avanzadas de los sprites se halla en los siguientes temas: Editando los sprites Strips Editando subimágenes individualmente Características avanzadas de los sprites
Editando los sprites Hasta ahora, cargábamos nuestros sprites desde archivos. Sin embargo, también es posible crearlos o editarlos con Game Maker. Para hacer esto, abre la ventana de propiedades de sprite, pulsando sobre uno de tus sprites. (O creando uno nuevo). Ahora presiona el botón etiquetado como Edit Sprite. Un Nuevo formulario aparecerá mostrando todas las subimágenes que forman el sprite.
El formulario de edición del sprite tiene el siguiente aspecto:
A la derecha veras las diferentes imágenes que forman el sprite. Observa que en Game Maker todas las subimágenes de un sprite, deben tener el mismo tamaño. A la izquierda, se reproduce una animación del sprite. (Si no ves la animación, active la opción Show Preview.) Bajo la previsualización, puedes cambiar la velocidad de animación y el color de fondo. De esta manera, puedes hacerte una idea de como se vera la animación en el juego. (Observa que esta velocidad es solo para la previsualización. La velocidad de la animación durante el juego, depende de la velocidad del nivel (“room”).
El editor de sprites contiene una gran variedad de funciones para crear o modificar el sprite. Puedes acceder a todas a través de los menús. (Para algunas, hay botones directamente en la barra de herramientas.) Algunos comandos trabajan sobre imagines individuales. Requieren que primero selecciones una sub-imagen con el ratón.
Menú File
El menú File contiene un cierto numero de funciones para cargar y grabar sprites.
•
New. Crea un Nuevo sprite vacío. Debes indicar el tamaño del sprite. (Recuerda que todas las imagines deben tener el mismo tamaño.)
•
Create from file. Crea el sprite desde un archivo. Pueden usarse gran variedad de tipos de archivo. Todos crean un sprite consistente en una imagen simple, a excepción de los GIFs animados, que son divididos en sus sub-imágenes. Por favor date cuenta de que el color transparente es el que tiene el píxel situado en la esquina inferior izquierda del sprite, no el color transparente del archivo GIF. Puedes elegir múltiples imagines para que se carguen todas. Deben tener el mismo tamaño.
•
Add from file. Añade una imagen (o imágenes) de un archivo al sprite con el que estemos trabajando. Si las imagines no tienen el mismo tamaño, puedes elegir donde ponerlas o estirarlas/encogerlas. Puedes elegir varias imagines para que se carguen todas. Deben tener el mismo tamaño.
•
Save as GIF. Guarda la imagen como un gif animado.
•
Save as strip. Guarda todas las imagines en formato bmp (mapa de bits), con todas las subimágenes colocadas una junto a otra.
•
Create from strip. Te permite crear un sprite desde un strip (tira de imágenes). Mira debajo para más información.
•
Add from strip. Utiliza esta opción para añadir imágenes de una tira (strip). Más info debajo.
•
Close saving changes. Cierra el formulario, guardando los cambios realizados en el sprite. Si no quieres guardar los cambios, pulsa sobre el botón de cierre de la ventana.
Menú Edit
El menú edición contiene varios comandos para trabajar con el sprite seleccionado. Puedes cortarlos al portapapeles (clipboard), pegar una imagen desde el portapapeles, borrar el sprite y cambiar el orden de las subimágenes dentro de la secuencia de la animación. Por último, existe un comando para editar una subimagen de forma individual, utilizando el programa de dibujo incorporado de GM (ver debajo).
Menú Transform
En el menú “transform” puedes realizar algunas transformaciones sobre las imágenes.
•
Mirror horizontal. Invierte horizontalmente la imagen.
•
Flip vertical. Invierte verticalmente la imagen.
•
Shift. Con esta opción puedes deslizar las imágenes a derecha o izquierda según especifiques
•
Rotate. Puedes rotar las imágenes 90 grados, 180, o cualquier otra cantidad de grados arbitrariamente. En el último caso, debes especificar la calidad. Experimenta para conseguir mejores resultados.
•
Resize Canvas. Aquí puedes cambiar el tamaño del lienzo. También puedes indicar donde se sitúan las imágenes antiguas dentro del nuevo lienzo.
•
Stretch. Te permite estirar o contraer las imágenes a un Nuevo tamaño. Puedes indicar la escala y la calidad.
•
Scale. Este comando cambia de tamaño las imágenes (pero no el tamaño del sprite que hay en su interior!). Puedes indicar la escala, la calidad y la posición de las imágenes actuales dentro de las escaladas.
Menú Images
En el menú “images” puedes realizar varias operaciones sobre las imágenes.
•
Cycle left. Mueve todo el ciclo una posición a la izquierda. Esto hace que la animación comience en un punto diferente.
•
Cycle right. Mueve todo el ciclo de la animación una posición hacia la derecha.
•
Black and white. Transforma el sprite en uno en blanco y negro (no afecta al color transparente!).
•
Colorize. Te permite cambiar el color (matiz) de las imágenes. Utiliza el deslizador para conseguir diferentes colores.
•
Colorize Partial. Te permite cambiar el color de parte de las imágenes. Puedes seleccionar el color antiguo y un rango (espectro) de colores similares, para después indicar en Nuevo color en que se convertirán los colores de este espectro. Esto puede utilizarse par alas instancias para cambiar solo el color de las camisetas de los jugadores, por ejemplo.
•
Shift Hue. Otra forma de cambiar el color de las imágenes. Pero en esta ocasión, los colores varían sobre la cantidad indicada, consiguiendo efectos más interesantes.
•
Intensity. Te permite cambiar la intensidad, introduciendo valores para la saturación y la luminosidad de las imágenes.
•
Invert. Invierte el color de las imágenes.
•
Fade. Aquí especificas un color una cantidad. Los colores en las imágenes realizaran un degradado hacia ese color.
•
Transparency. Te permite indicar un nivel de transparencia. Se consigue transformando un determinado número de sprites en píxeles transparentes.
•
Blur. Desenfocando las imágenes, los colores se mezclan un poco,
mas difusos. Cuanto mayor sea el valor, mas difusa se vera
la imagen.
•
Outline. Crea un contorno alrededor de la imagen. Se te pregunta el color y si las imágenes actuales deben ser borradas o no (dejando solo el contorno).
•
Boundary. Similar al contorno, pero no se dibuja fuera, sino sobre los píxeles de los márgenes.
•
Crop. Esto hace que las imágenes sean lo mas pequeñas posible. Esto es muy útil, porque, a mayores imágenes, más memoria de video se necesita. Deberías dejar solo un pequeño borde alrededor de los sprites para evitar problemas con las transparencias.
Experimenta con estos comandos para conseguir los sprites que pretendes.
Menú Animation
Bajo el menú de animación puedes crear nuevas animaciones fuera de la animación actual. Hay muchas opciones, deberías experimentar un poco para crear los efectos que quieres. Tampoco olvides que puedes guardar una animación y añadirla después a la actual. También puedes añadir algunas imágenes vacías y borrar las que no necesites. Explicaremos brevemente las diferentes posibilidades.
•
Set Length. Te permite cambiar la longitud de la animación. La animación se repite las veces necesarias para conseguir el número de frames que indiques. (Normalmente deseas que sea un múltiplo del número actual de frames.)
•
Stretch. Este comando también cambia la longitud de la animación. Pero en esta ocasión, los frames se duplican o se borran para conseguir el número adecuado. Así que si incrementas el numero de frames, la animación ira mas despacio, y viceversa.
• •
Reverse. Bien, como puedes suponer, invierte la animación. Se reproduce hacia atrás. Add Reverse. En esta ocasión la secuencia invertida es añadida, doblando el número de frames. Esto es muy útil cuando quieres que un objeto vaya de izquierda a derecha, cambie de color y vuelva, etc.
•
Translation sequence. Podrás crear una animación en la que la imagen se trasponga en cada paso. Debes indicar el número de pasos y la cantidad total de movimiento vertical u horizontal.
•
Rotation sequence. Crea una animación en la que la imagen rota. Puedes elegir si lo hará hacia la derecha o hacia la izquierda. Especifica el numero de frames y el ángulo total en grados (360 son un giro completo). Es posible que tengas que aumentar antes el tamaño del lienzo para estar seguro de que se ven todas las imágenes al completo.
•
Colorize. Crea una animación que convierte el color de la imagen en otro.
•
Fade to color. Crea una animación que efectúa un degradado de la imagen hacia un color determinado.
•
Disappear. Hace que la imagen vaya desapareciendo aumentando su transparencia.
•
Shrink. Encoge la imagen hasta hacerla desaparecer. Puedes indicar la direccion.
•
Grow. Hace crecer la imagen desde la nada.
•
Flatten. Aplana la imagen hasta que desaparece.
•
Raise. Hace levantarse la imagen desde la nada. Debes indicar la direccion
•
Overlay. Solapa la animación con otra animación o imagen de un archivo.
•
Morph. Transforma la animación en otra animación o imagen de un archive. Funciona major si ambas animaciones tienen el mismo tamaño.
Los dos últimos comandos en particular son muy potentes. Por ejemplo, para, hacer explotar un objeto, añade un numero de copias y después un numero de frames vacíos. Después solápalo con una animación de explosión. (Augúrate de que encaje el número de imágenes.) O haz un “morph” con la explosión. Puedes conseguir sprites estupendos.
Strips Como indicamos antes, los sprites normalmente se guardan como Gif animados o como tiras de imágenes (strips). Una tira es una imagen grande que guarda todas las imágenes cerca unas de otras. El único problema es que el tamaño original de las sub-imágenes no se guarda en el archive. Además muchos archivos de este tipo guardan varios sprites en un solo archive. En la siguiente muestra, veremos un strip con cuatro animaciones.
Para seleccionar sprites individuales, puedes elegir la opción Create from Strip o Add from Strip del menú File. Después de indicar el archivo de strip correcto, aparece el siguiente formulario:
A la derecha puedes ver (en parte) la tira de imágenes que elegiste. A la izquierda puedes indicar ciertos parámetros que especifican en que subimágenes estas interesado. Observa que uno o más rectángulos en la imagen indican que imágenes estas seleccionando. Estos son los parámetros que pueden ser especificados:
•
Number of images. El numero de imágenes que quieres coger de la tira (strip).
•
Images per row. Cuantas imágenes de las que hay, quieres por fila. Por ejemplo indicando una sola fila (row) seleccionaras una sola secuencia vertical de imágenes.
•
Image width. Anchura de las imágenes individuales.
•
Image height. Altura de las imágenes individuales.
•
Horizontal cell offset. Si no quieres seleccionar las imágenes de la parte superior izquierda, puedes indicar Aquí cuantas imágenes se ignoraran horizontalmente.
•
Vertical cell offset. Aquí seleccionas cuantas imágenes ignoras verticalmente.
•
Horizontal píxel offset. A veces existe un espacio adicional en la zona superior izquierda. Aquí indicas su tamaño (en píxeles).
•
Vertical píxel offset. Tamaño vertical del espacio adicional.
•
Horizontal separation. En algunas tiras existen líneas o espacios vacíos entre las imágenes. Aquí puedes indicar el espacio horizontal que se debe ignorar entre imagen e imagen (en píxeles).
•
Vertical separation. Espacio vertical a ignorar entre imágenes (en píxeles).
Cuando selecciones el número correcto de imágenes, presiona OK para crear el sprite. Por favor recuerda que solo se permiten utilizar imágenes creadas por terceros cuando has pedido su permiso o son freeware.
Editando subimágenes individualmente
También puedes editar las sub-imágenes individualmente. Para terminar selecciona una sub-imagen y elige la opción Edit Image del menú Image. Esto abrirá un pequeño programa de dibujo incorporado. Por favor comprueba que se trata de un programa diseñado para realizar pequeños cambios en imágenes ya existentes, no para dibujar otras nuevas. Para esto, utiliza mejor un programa de dibujo mas especifico y utiliza los archivos resultantes (o copia y pega) para utilizar la imagen enGame Maker. En las preferencias también puedes especificar un editor externo.
El formulario muestra la imagen en el centro y varios botones de herramientas de dibujo básicas a la izquierda. Aquí podrás aumentar o disminuir el zoom, dibujar píxeles, líneas, rectángulos, textos, etc. Date cuenta de que el color depende del botón del ratón que utilices (derecho o izquierdo). Para algunas herramientas de dibujo puedes definir algunas propiedades (como el ancho de la línea o la visibilidad del contorno). Existe un botón especial para cambiar todos los píxeles de un color por otro. Esto es particularmente útil para cambiar el color de fondo que se utiliza como transparencia. En la barra de herramientas, tenemos algunos botones especiales para mover todos los píxeles de la imagen en una dirección determinada. También puedes indicar si muestras la cuadricula cuando se amplia el zoom de la imagen (Solo funciona con un factor de zoom de 4 como mínimo).
Puedes seleccionar áreas normalmente presionando el botón de selección y dibujando un rectángulo. Después coloca el ratón dentro del área seleccionada para moverla donde quieras. Normalmente el área original se rellena con el color seleccionado para del botón izquierdo del ratón. Si mueves la selección con la tecla presionada, el área original permanecerá sin afectar. Con la tecla también puedes tener múltiples copias del área seleccionada. Si utilices el botón derecho del ratón para moverte en lugar del izquierdo, la selección se considera transparente.
La herramienta texto requiere algo de explicación. Para añadir un texto, presiona sobre el botón texto y pulsa sobre la imagen. Una ventana emergente donde añadir el texto aparecerá, utilice el símbolo # para añadir una línea. Una vez presiones OKel texto se colocara en la imagen, con una selección a su alrededor. Ahora puedes mover el texto presionando con el ratón sobre la selección y arrastrándola. Puedes cambiar el texto pulsando con el botón derecho en la selección. Utilizando el menúText también puedes cambiar el alineamiento y la fuente utilizada.
A la derecha del formulario puedes seleccionar los colores a utilizar (uno para el botón izquierdo del ratón y otro para el derecho). Existen cuatro formas de cambiar el color. Primero puedes pulsar con el botón del ratón (izquierdo o derecho) sobre uno de los 16 colores básicos. Observa que existe una muestra especial de color que contiene el color del píxel inferior izquierdo de la imagen que es el transparente. ^Puedes usar este color para hacer parte del sprite transparente. La segunda manera es pulsando sobre la imagen con el color cambiante. Podrás elegir muchos mas colores. Puedes mantener pulsado el ratón para ver el color que estas seleccionando. En tercer lugar, puedes pulsar con el botón izquierdo en las muestras que indican los colores derecho e izquierdo. Una ventana emergente de colores aparecerá y podrás seleccionar el color. Por último, puedes seleccionar la herramienta cuentagotas y pulsar con el botón izquierdo sobre la parte de la imagen que contenga el color que quieres copiar.
Hay dos características especiales más. Cuando pulsas la tecla puedes tomar un color para dibujar de la imagen actual. Cuado pulsas la tecla mientras dibujas líneas, solo podrás hacerlas horizontales, verticales o diagonales. Algo similar ocurre cuando presionas la tecla mientras dibujas elipses o rectángulos. Solo dibujaras círculos o cuadrados perfectos.
En los menús puedes encontrar las mismas transformaciones y comandos de cambio de imagen, que están disponibles en el editor de sprites. En esta ocasión solo son aplicables a la imagen actual. (Cuando el sprite tiene varias sub-imágenes, los comandos que cambian el tamaño, no están disponibles.) También puedes guardar la imagen como un archive bmp (mapa de bits). Existen dos comandos adicionales en el menú Image:
•
Clear. Limpia la imagen y la colorea con el color izquierdo (que se convierte en el color transparente).
•
Gradient fill. Con este comando puedes rellenar la imagen con un color que cambia de forma gradual (no muy útil para hacer sprites, pero es útil para fondos).
Observa que la mayoría de las rutinas de dibujo han desaparecido. Para tener más deberíamos utilizar un programa de dibujo más avanzado (o el sencillo programa de dibujo que viene con Windows). La forma más sencilla de hacerlo es utilizar el botón “copiar” para poner la imagen en el portapapeles. En tu programa de dibujo, solo tienes que pegarla. Molifícala y cópìala en el portapapeles. Ahora, en Game Maker puedes pegar la imagen modificada.
Características avanzadas de los sprites En el modo avanzado, dentro del formulario de propiedades del sprite, hay varias opciones avanzadas sobre las que trataremos a continuación.
Lo primero que vemos son opciones relacionadas con el chequeo de colisiones. Siempre que dos imágenes se encuentran, se genera un evento de colisión. Las colisiones se generan de la siguiente forma: Cada sprite tiene una “caja de contorno”. Esta “caja” contiene la parte no transparente de todas las sub-imágenes. Cuando las cajas de contorno se solapan, (se chequea comprobando cuando dos píxeles de las sub-imágenes de los dos sprites se solapan). Esta segunda operación es costosa y requiere memoria extra y un preprocesamiento previo. Así, que si no estas interesado en una colisión precisa para un determinado tipo de sprite, deberías deseleccionar la opción Precise colisión checking. En este caso solo se verificara la colisión entre las cajas de contorno y no de su interior. También puedes cambiar el tamaño de
la caja de contorno. Esto no se necesita casi nunca, pero en determinadas ocasiones, necesitaras hacer más pequeña la caja de contorno, para que las colisiones con algunas partes del sprite no se tengan en cuenta.
Los bordes de los sprites pueden verse un poco pixelados. Para evitarlo puedes seleccionar la opción Smooth edges. En este caso los píxeles de los bordes del sprite (los píxeles cercanos a los píxeles transparentes) son dibujados parcialmente transparentes. Esto puede hacer que se vean mucho mejor. (No utilices esta opción cuando los sprites sean parte de una imagen mayor, porque se verán líneas semi transparentes entre ellos.) ¡El efecto de esta selección solo se ve en el juego, no en el editor!
Durante el juego, los sprites se transforman en texturas. Las texturas se deben almacenar en la memoria (en la tarjeta de video) de video antes de utilizarse. Cuando seleccionamos la opción Preload texture esta acción se hace durante la carga del juego, no existiendo retardo durante el juego). Si tienes muchos sprites de gran tamaño que no se van a usar al principio deberías deseleccionar esta opción. Game Maker guardara las texturas en la memoria de video y las retomara cuando las necesite.
Por último, puedes indicar el origen del sprite. Esto es el punto del sprite que corresponde a su posición. Cuando defines la posición de una instancia, el origen del sprite se sitúa en esa posición. Por defecto se trata del punto situado en la esquina superior izquierda del sprite, pero a veces es más conveniente colocar el origen en el centro o en cualquier otro lugar importante del sprite. Incluso puedes elegir un punto fuera del sprite. También puedes definir el origen pulsando sobre la imagen. (Cuando el origen es mostrado en la imagen).
Más sobre sonido y música En el modo avanzado tienes un control mucho mayor sobre los sonidos y músicas del juego. Cuando añadas un sonido se mostrará la siguiente ventana:
Además de las opciones que ya habíamos visto (load, save y play) hay muchas otras que explicaremos ahora:
Primero puedes indicar el tipo de sonido entre los 4 posibles. Normal sounds se usan para efectos de sonido en archivos wav (aunque también pueden usare para archivos midi). Multiple normal sounds pueden sonar a la vez. Puedes incluso hacer sonar varias copias del mismo sonido a la vez. Background music es similar a los Normal sounds pero sólo puede sonar uno la vez. Así que cuando empieza a sonar un sonido de este tipo, los demás sonidos de este tipo dejarán de sonar. Por defecto se usan archivos midi para esto. 3D sound son los sonidos a los que les puedes aplicar efectos especiales mediante el uso de las funciones apropiadas. Sólo necesitarás estos para efectos de sonido avanzados
Los archivos de sonido suenan a través de DirectX, lo que nos da muchas posibilidades pero nos limita a archivos del tipo wav o midi. Si quieres utilizar archivos de otro tipo como mp3 tienes que seleccionar la opción para usar el media placer. Esto limita mucho los sonidos porque no se puede cambiar el sonido o aplicar efectos y sólo puede sonar un sonido a la vez. Los archivos midi suenan distinto, debido a que al usar el media placer utilizan el sintetizador de hardware, lo que hace que suenen distinto dependiendo del ordenador en el que suenen. Pero al ser usados como Normal sound o como Background music utilizan un sintetizador de software que suena igual en todos los ordenadores. No se aconseja usar mp3 en los juegos ya que necesitan ser descomprimidos y eso afecta a la velocidad del juego. Aunque sean de menor tamaño usan más memoria, suenan distinto en cada ordenador y no todos los ordenadores los soportan.
También puedes indicar efectos de sonido como chorus (coro) o echo (eco), pero sólo en la versión registrada). Puedes combinar los efectos y escucharlos. Usando GML puedes hasta cambiar los parámetros de estos efectos.
Puedes indicar el volumen de cada sonido y en qué altavoz debe sonar (izquierdo o derecho).
Puedes indicar si el sonido de be ser cargado con antelación (Preload) o no. Cuando un sonido suena primero debe ser cargado en la memoria de audio. Si usas la opción preload esto se hace al principio del juego, así que cuando necesites que el sonido suene ya estará listo. Si no usas esta opción, el sonido se carga en la memoria la primera vez que es usado, lo que ahorra memoria pero puede hacer que el sonido tarde un poco en sonar la primera vez que se usa.
Game Maker no tiene un editor interno de sonidos. Pero en Preferences puedes indicar los editores externos que quieras para editar tus sonidos. Si los indicas, puedes presionar en el botón Edit Sound para editar los sonidos que estés usando. (La ventana de Game Maker se ocultara mientras edites tus sonidos y se reestablecerá cuando cuando cierres el editor de sonidos).
Más sobre los fondos Además de importarlos desde archivos existentes, también tienes la posibilidad de crear tus propios fondos. Para este fín, presiona el botón Edit Background (Editar Fondo). Se abrirá un programa de dibujo que viene incluido en el que puedes crear o editar tus fondos. Es importante remarcar que éste no es un programa sofisticado de diseño. Para realizar tareas de diseño más avanzadas y disponer de herramientas de dibujo más sofisticadas utiliza algún programa especializado en ello. Hay una opción que es particularmente útil, en el menú Image (Imagen) encontrarás un comando llamado Gradient Fill (Relleno Degradado). Con esta opción se pueden crear muy buenos fondos.
En el modo avanzado, la ventana de propiedades de fondo, contiene algunas opciones avanzadas.
Los bordes de los fondos, sobre todo si son transparentes, pueden resultar un poco cuadrados. Para impedir esto puedes usar la opción Smooth edges. Los píxeles en el borde del fondo (es decir, los píxeles vecinos a los transparentes) son dibujados parcialmente transparentes, con lo que el resultado final es mucho mejor (no uses esta opción cuando tengas un fondo compuesto por varias imágenes, porque aparecerá una línea transparente entre ellas) ¡Este efecto sólo es visible en el juego, no en el editor!
Durante el juego, los fondos se transforman en texturas. Las texturas se cargan en la memoria gráfica (en la tarjeta gráfica) antes de ser usadas. Si activas la opción Preload texture esto ocurre inmediatamente cuando comienza el juego, evitando que haya retrasos durante el juego. Si tienes muchos fondos de gran tamaño que no se usan al principio del juego es mejor que no uses esta opción, porque consume mucha memoria. En este caso, Game Maker moverá las texturas dentro y fuera de la memoria gráfica según las necesite.
A veces quieres usar un background como un conjunto de tiles, es decir, una colección de pequeñas imágenes que se unen para formar una imagen mayor. Cuando crees una room puedes añadir estas imágenes en diferentes lugares del room. Esto es muy útil para crear niveles vistosos. Para usar un fondo como tile set, usa la opción Use as tile set. La ventana se mostrará de la forma siguiente:
Puedes configurar varias cosas para el tileset. En particular, puedes indicar la altura y anchura de cada tile (sólo puedes indicar un valor, así que asegúrate de que todas las tiles tienen el mismo tamaño). También puedes indicar el origen para la tile situada arriba y a la izquierda
del todo. Finalmente, se puede indicar la separación entre tiles (normalmente 0 ó 1). Para más información sobre las tiles, mira el capítulo sobre crear rooms.
Aviso: cuando pones bordes separadores entre los sprites y usas interpolación entre píxeles (consulta las global game settings) pueden aparecer rajas entre las tiles. Para evitarlo, asegúrate de que los píxeles alrededor de las tiles son del mismo color que los píxeles en el borde interior de las tiles.
Más sobre los objetos Cuando creas un objeto en modo avanzado, puedes cambiar otras opciones avanzadas.
Profundidad Primero que nada, puedes configurar el depth (profundidad) de las instancias de un objeto. Cuando las instancias son dibujadas, según el depth se dibujaran una encima de otras. Las instancias con mayor depth son dibujadas primero, y las instancias con menor depth se dibujaran últimas. Cuando 2 ó más instancias poseen el mismo depth, se dibujan según el orden en el que fueron creadas. Si quieres estar seguro que un objeto se encuentra por encima de los demás, introduce un valor negativo. Si quieres estar seguro que un objeto se encuentra por debajo de los demás, introduce un valor positivo muy alto. También puedes cambiar el depth de una instancia durante el juego usando la variable depth.
Objetos persistentes Puedes hacer persistente a un objeto. Los objetos persistentes continúan existiendo inclusive si pasan de una habitación a la otra. Estos sólo desaparecen cuando los destruyes expresamente. Así, solo es necesario poner una instancia del objeto en la primera habitación y seguirá apareciendo en las siguientes habitaciones. Esto es realmente muy útil cuando posees un personaje principal que debe moverse de habitación en habitación. El uso de objetos persistentes es una herramienta poderosa, pero también puede producir errores fácilmente.
Parents Todo objeto puede poseer un objeto padre. Cuando un objeto posee un objeto padre, este hereda las características del mismo. Dicho de otra manera, el objeto es una especie de variante del objeto padre. Por ejemplo, si tienes 4 pelotas distintas, llamadas ball1, ball2, ball3 y ball4, y todos se comportan de la misma manera pero tienen sprites distintos, puedes hacer que ball1 sea el objeto padre de el resto. Así solo será necesario que establezcas los eventos y acciones para ball1. Las demás pelotas heredaran las características de ball1 y actuaran de la misma manera. De manera que si aplicas acciones a las instancias del objeto padre, estas también se aplicaran a las instancias de los objetos hijos. Por ejemplo, si destruyes las instancias del objeto ball1 también se destruirán las instancias de los objetos ball2, ball3 y ball4. Esta opción nos permite ahorrar mucho tiempo y trabajo.
A menudo, los objetos deben comportarse casi idénticamente pero suelen encontrarse pequeñas diferencias. Por ejemplo, un monstruo se mueve de arriba hacia abajo y otro hacia la izquierda y la derecha. En lo demás ambos monstruos poseen el mismo comportamiento. En este caso casi todos los eventos deberían poseer las mismas acciones, pero uno o dos podrían llegar a ser diferentes. En este caso podemos hacer a un objeto el padre del otro. Pero también debemos definir algunos eventos para el objeto hijo. Estos eventos se sobrepondrán a los
eventos del padre. De forma tal que mientras un evento del objeto hijo contenga acciones, éstas se ejecutarán en lugar de las del mismo evento del objeto padre. Si además se requiere ejecutar el evento del padre, se puede 'llamar' al 'evento heredado' usando la acción apropiada. De hecho, es una buena práctica en tales casos crear un objeto base, por ejemplo un objeto ball0. Este objeto contiene todo el comportamiento por defecto pero nunca se utiliza en el juego. Todos los objetos 'reales' tienen a este objeto base como padre.
Los objetos padre pueden así mismo tener padres, y así sucesivamente. (Obviamente no está permitido crear círculos.) De ésta forma se puede crear una jerarquía de objetos. Esto es extremadamente útil para mantener tu juego estructurado y es ampliamente recomendado aprender a utilizar éste mecanismo. También hay otra utilidad de los objetos padre. Permite heredar el comportamiento en colisiones para otros objetos. Permíteme explicar esto con un ejemplo. Supongamos que tenemos cuatro objetos 'suelo' distintos. Cuando una pelota golpea el suelo ésta debe cambiar su dirección. Este cambio debe especificarse en el evento colisión de la pelota con el suelo. Debido a que hay 4 distintos suelos necesitamos escribir código en 4 eventos colisión distintos de la pelota. En cambio, cuando se tiene un objeto base y éste es padre de los 4 suelos reales, sólo se debe especificar el evento colisión con éste objeto base. Las demás colisiones ejecutarán el mismo evento. Esto, igualmente ahorra mucho trabajo.
Tal como se indica, dondequiera que se utiliza un objeto, se involucrarán a sus descendientes. Esto sucede cuando, en una acción, se indica que ésta debe aplicarse a instancias de un objeto determinado. Lo mismo sucede cuando se utiliza la sentencia with en código (ver abajo). Y funciona cuando se llaman a funciones como instance_position, instance_number, etc. Finalmente, sucede cuando se hace referencia a variables en otros objetos. En el ejemplo anterior, cuando se fija la variable ball1.speed a 10 este cambio es también aplicado a los objetos ball2, ball3 y ball4.
Máscaras Cuando dos instancias colisionan ocurre un evento de colisión. Para decidir cuando dos instancias se interceptan, se usan los sprites de las mismas. Esto es suficiente en la mayoría de los casos, pero a veces se quiere basar las colisiones en distintas formas. Por ejemplo, si haces un juego isométrico, los juegos tienen una altura (para darles una apariencia 3D). Pero para colisiones solo es necesario usar la parte de abajo del sprite. Esto puede lograrse creando un sprite por separado que es usado como máscara de colisión para el objeto.
Información El botón Show Information nos permite ver la información completa del objeto que también puede imprimirse si se quiere. Esto es útil cuando pierdes la vista de todas las acciones y eventos.
Más acciones En el modo avanzado hay un número de acciones adicionales disponibles que describiremos aquí. Estas acciones se describen con detalle en las siguientes secciones: Más acciones de movimiento Más acciones principales Más acciones de control Más acciones de dibujo Acciones de partículas Acciones extra
Más acciones de movimiento Algunas acciones de movimiento sólo están disponibles en el modo avanzado:
Set a path for the instance Con esta acción puedes especificar qué instancia debe seguir un path particular. Defines el path que debe seguir y la velocidad en píxeles por step. Cuando la velocidad es positiva la instancia empieza en el comienzo del path. Cuando es negativa comienza en el final. Luego especificas lo que sucederá cuando se alcanza el final del path. Puedes elegir parar el movimiento, volver a empezar desde el principio, volver a empezar desde la posición actual (que es lo mismo que volver al principio cuando el path se cierra), o el movimiento al revés. Finalmente puedes indicar que el path debe ser visto en absoluto, esto es, la posición será indicada en el path (esto es útil cuando tienes diseñado el path en un lugar en particular dentro del room) o relativa, en cual caso el punto de comienzo del path es colocado en la localización actual de la instancia (punto final cuando la velocidad es negativa). Consulta el capítulo de paths para más información.
End the path for the instance Usa esta acción para detener el path para la instancia.
Set the position on the path Con esta acción puedes cambiar la posición actual de la instancia en el path. Deberá ser un valor entre 0 y 1 (0=principio. 1= final)
Set the speed for the path Con esta acción puedes cambiar la velocidad de la instancia en el path. Una velocidad negativa mueve la instancia al revés a lo largo del path. Pon 0 para parar temporalmente el movimiento.
Perform a step towards a point Esta acción se debe poner en el evento step para que la instancia vaya hacia una posición en particular. Cuando la instancia llega a esa
posición no se moverá más. Tú especificas la posición a mover, la velocidad con la cual se moverá, es decir, el tamaño del paso, y si el movimiento debe parar cuando golpea una instancia sólida o cuando golpea cualquier instancia
Step towards a point avoiding objects Esta es una acción de movimiento muy útil. Debe ser colocada en el evento step. Como la anterior acción hace que una instancia vaya hacia una posición en particular. Pero en este caso este intenta de esquivar obstáculos. Cuando la instancia encuentra instancia sólida (o cualquier instancia) cambiará la dirección del movimiento para internar esquivar la instancia y moverse alrededor de ella. El acercamiento no está garantizado que funcione pero en los casos más simples moverá la instancia hacia la meta efectivamente. Para casos más complicados, hay funciones de planificación del movimiento. Especificas la posición a mover, la velocidad y si el movimiento debe esquivar instancias sólidas o cualquier instancia.
Más acciones principales Algunas acciones principales adicionales están disponibles en el modo avanzado. Las siguientes acciones se agregan:
Set a time line (Sólo disponible en el modo avanzado.) Con esta acción tu pones un time line particular para una instancia de un objeto e indicas el time line y la posición donde comienza dentro del time line (0 es el principio). Puedes usar esta acción para finalizar un time line escogiendo No Time Line como valor.
Set the time line position (Solo disponible en el modo avanzado). Con esta acción puedes cambiar la posición del time línea actual (absoluta o relativa). Esta puede ser usada para saltar ciertas partes del time line o para repetir ciertas partes. Por ejemplo, si quieres hacer una time line que se reproduzca siempre, en el último momento, agrega esta acción y pon la posición de nuevo a 0. Puedes usarlo para esperar a que algo suceda. Sólo agrega la acción de prueba y, si no es verdadera, pon la posición relativa de la time line a -1.
Show a video Con esta acción puedes mostrar un archivo de video/película. Especificas el nombre del archivo y si debe ser mostrado en pantalla completa o en la ventana. Estate seguro de que el archivo de video existe. Debes distribuirlo con tu juego o ponerlo en un datafile y exportarlo.
Replace a sprite from a file Esta acción puede ser usada para remplazar un sprite del contenido de un archivo. Indicas el sprite que quieres remplazar, el nombre del archivo (.bmp .jpg o .gif) y el número de sub-imágenes en el sprite cuando cargas de un archivo bmp o jpg. Para un archivo gif el número de sub-imágenes es automático basado en la cantidad de sub-imágenes del archivo gif. Otras opciones para el sprite, p. Ej., si es transparente o no, no se cambian. Puedes usar esta acción para evitar almacenar todos los sprites en el mismo programa. Por ejemplo, en el comienzo de un nivel puedes reemplazar sprites por los personajes que quieres usar. NO cambies un sprite que en el momento se esta utilizando por una instancia en el room. Esto puede dar efectos indeseados con colisiones. Esta acción sólo está disponible en la versión registrada.
Replace a sound from a file Con esta acción puedes remplazar un sonido por el contenido de un archivo (.wav .mid o .mp3). Especificas el sonido y el nombre del archivo. Esto evita tener que almacenar todos los sonidos en el juego. Por ejemplo, puedes usar diferentes piezas de una música de fondo y escoger el que quieres escuchar. NO cambies de sonido mientras se está jugando. Esta acción sólo está disponible en la versión registrada
Replace a background from a file Con esta acción puedes reemplazar un background por el contenido de un archivo (.bmp o .jpg). Especificas el nombre del archivo. Esto evita almacenar todos los background en el juego. No cambies un background que esté visible en ese momento.Esta acción sólo está disponible en la versión registrada
Más acciones de control Algunas acciones de control adicionales están en el modo avanzado. Las siguientes acciones se agregan:
Execute a script Con esta acción puedes ejecutar un script que agregaste a tu juego. Especificas el script y un máximo de 5 argumentos.
Call the inherited event Esta acción es útil cuando el objeto tiene un objeto padre. Esta acción llama al evento correspondiente en el objeto padre.
Más acciones de dibujo La siguiente acción de dibujo está disponible en el modo avanzado:
Set a font for drawing text Puedes poner la fuente que será usada para el texto. Esta fuente debe ser uno de los recursos de fuente que tienes definido. Si eliges No Font se usará la fuente predeterminada: Arial tamaño 12.
Acciones de partículas Un sistema de acciones que se encargan de las partículas está en la pestaña Extra. Estas acciones están disponibles sólo en la versión registrada de Game Maker.
Sistema de partículas significa crear efectos especiales. Las partículas son pequeños elementos (representados por un píxel o una forma pequeña). Tales se mueven según las reglas predefinidas y cambiando de color. Muchas partículas juntas pueden crear, por ejemplo, fuegos artificiales, llamas, lluvia, nieve, etc.
Game Maker contiene un sistema de partículas que se puede alcanzar con funciones. Un sistema más limitado de partículas se puede realizar con las acciones descritas abajo.
Un sistema de partículas puede tener partículas de diferentes tipos. Después de crear el sistema de partículas la primera cosa a hacer es especificar los tipos de partículas. Usando las acciones de abajo puedes especificar hasta 16 tipos de partículas. Cada tipo tiene una forma, un tamaño, un color inicial y otro final. El color cambia lentamente del color del comienzo al color del final. Las partículas tienen un tiempo de vida limitado. En el tipo defines el mínimo y el máximo tiempo de vida de las partículas. También tienen velocidad y dirección. Finalmente, gravedad y fricción puede usarse para trabajar con partículas.
Después de especificar el tipo de partículas debes crearlas y colocarlas en el room. Puedes hacer estallar un número de partículas de un tipo de partícula desde un lugar o puedes crear una corriente constante de aparición de las partículas. Partículas aparecen en emmiters (emisores). El sistema de partículas puede tener hasta 8 emisores trabajando al mismo tiempo. Después de crear los tipos de partículas tienes que crear los emisores y llamarlos para que estallen o fluyan.
Aquí hay un completo set de acciones. Experimenta con ellas para obtener el efecto que desees:
Create the particle system Esta acción crea el sistema de partículas. Debe ser llamada antes de que otras acciones sean usadas. Sólo debes llamarla una vez. Puedes especificar el depth (profundidad) en las partículas que se están dibujando. Si usas un depth positivo grande las partículas aparecerán detrás de las instancias. Si usas una profundidad negativa aparecerán delante de las instancias.
Destroy the particle system Esta acción destruye el sistema de partículas, liberando memoria. No te olvides de llamar a esta acción (p. Ej. Cuando vas a un room diferente) porque los sistemas de partículas usan mucha memoria.
Clear all particles in the system Esta acciones quita todas las partículas actualmente visibles. Esto no detiene los emisores así que nuevas partículas pueden ser creadas si tienes emisores que fluyen (lee más abajo)
Create a type of particle Con esta acción creas un tipo de partícula. Puedes definir hasta 16 tipos distintos. Para la partícula puedes especificar la forma o el sprite
que usará. Si especificas un sprite, este será usado. Si no seleccionas ningún sprite, la forma será usada. Hay un número de interesantes formas internas. Puedes indicar el tamaño máximo y el mínimo (cuando las partículas aparecen se utiliza un valor aleatorio entre estos). Finalmente especificas el aumento del tamaño en cada step. Para disminuir, usa un valor negativo. Nota que únicamente un tipo de partícula es creado, no una partícula. Para esto necesitas emisores (mira abajo)
Set the color for a particle type Una partícula puede tener un color (el color predeterminado es blanco). Con esta acción puedes definir el color que se usará para un tipo en particular. Debes indicar el tipo de partícula para la que se define el color. Luego especificas cómo se aplicará el color. Cualquier color es elegido entre dos colores dados, o el color comienza con el primer color y gradualmente sobre el tiempo de vida de la partícula, cambia al segundo color. Ambos colores pueden ser dados. Finalmente puedes indicar la transparencia alpha. Especificas la transparencia en el momento que la partícula es creada y cuando muere. La transparencia cambia lentamente entre esos valores. Es normalmente lindo que se disminuya el valor del alpha sobre el tiempo de vida de la partícula.
Set the life time for a particle type Una partícula vive un número limitado de steps. Después desaparece. Con esta acción pones el tiempo de vida para un tipo de partícula. Das dos valores límites y el tiempo de vida es elegido de forma aleatoria entre ellos.
Set the motion for a particle type Con esta acción puedes poner la velocidad y dirección del movimiento para un tipo de partícula. Otra vez das 2 valores límites y el valor será elegido de forma aleatoria entre aquellos valores. Por ejemplo, para hacer que la partícula se mueva en una dirección aleatoria, debes dar 0 y 360 para los límites de la dirección. Puedes también especificar la fricción. Esta cantidad es sustraída de la velocidad en cada step hasta que se convierta en 0. (Puedes hacer que la velocidad suba usando una fricción negativa).
Set the gravity of a particle type Con esta acción puedes poner la cantidad de gravedad y la dirección de ésta para un tipo de partícula. 270 es hacia abajo.
Create secondary particles Esto es un poco más complicado. Partículas pueden crear otras partículas durante su vida y cuando mueren. Con esta acción puedes especificar esto. Puedes definir el tipo y número de partículas que serán creadas en cada step durante su tiempo de vida y cuando una partícula muere. Se muy cuidadoso aquí. Puedes crear grandes números de partículas de esta manera, retrasando el sistema considerablemente. Para los números puedes usas también un valor negativo. Un valor negativo x significa que en cada step una partícula es creada con la proporción -1/x. Por ejemplo, si quieres generar una partícula secundaria cada 4 steps, usa el valor -4. Partículas secundarias son geniales para crear efectos como colas de partículas o partículas que explotan.
Create a particle emitter Esta acción crea un emmiter (emisor de partículas). Las partículas son generadas por los emitters. Puedes tener hasta 8 emisores. Elige el emisores y especifica su forma, su tamaño y posición (en forma de una caja de contorno)
Destroy an emitter Esta acción destruye el emisor indicado. Nota que las partículas existentes que se han creado con estos emisores no son eliminadas.
Burst a number of particles from an emitter Incluso si definiste un tipo de partículas y en un emisor todavía no hay partículas, tienes todavía que decirle al emisor que genere partículas. Con esta acción llamas a un emisor en particular para generar un número de partículas de un tipo determinado. Todas esas partículas se generan una sola vez. Para el número puedes usar también un valor negativo. Un valor negativo x significa que una partícula es creada con la proporción -1/x. Por ejemplo, si quieres general una partícula con la proporción del 25 por cierto, usa un valor de -4.
Stream particles from an emitter Con esta acción llamas a un emisor en particular para que haga fluir un número dado de partículas de un tipo dado. En cada step este número de partículas es generado, conduciendo a una corriente continua de partículas. El emisor continuará fluyendo partículas hasta que lo destruyas o que lo llames a fluir 0 partículas. Para el número puedes usar un valor negativo. Un valor negativo x significa que en cada step una partícula es creada con la probabilidad -1/x. Así por ejemplo, si quieres generar una partícula cada 4 steps, usa el valor de -4.
Acciones extra En la pestaña Extra hay también un número de acciones relacionadas con tocar CDs. Estas acciones sólo están disponibles en la versión registrada de Game Maker
Play a CD Con esta acción puedes tocar diferentes pistas de un CD colocado en el lector de CDs. Especificas la pista del comienzo y la pista del final.
Stop the CD Detiene la ejecución del CD.
Pause the CD Pausa la ejecución actual del CD.
Resume the CD Vuelve a tocar el CD pausado.
If a CD exists in the drive Si hay un CD en la lectora de CDs la acción siguiente será ejecutada.
If the CD is playing Si un CD está tocándose en la lectora de CDs la siguiente acción será ejecutada.
Finalmente, hay 2 acciones adicionales que pueden ser útiles en ciertos juegos.
Set the mouse cursor Puedes usar esta acción para remplazar el cursor del ratón por un sprite. Especificas el sprite y si el cursor debe ser todavía mostrado. El sprite puede ser animado. Nota que el sprite será sólo mostrado en el room, no en el área fuera de él.
Open a webpage in a browser Puedes indicar una dirección Web en esta acción. Esta Web será abierta en el navegador predeterminado del PC (esta acción puede actualmente también ser usada para abrir otros documentos). Esta acción no funciona en modo seguro.
Más sobre las rooms Los niveles en Game Maker tienen muchas opciones. Antes solo tratamos las más importantes. En este capítulo hablaremos sobre las opciones restantes. Cuando abres el formulario en modo avanzado se muestra de la siguiente manera:
Como verás, aparecen algunos botones nuevos en la barra de tareas. Estos son botones para ordenar las instancias vertical y horizontalmente. Esto es muy útil cuando las instancias se solapan. (Cuando estamos trabajando sobre “tiles” estos botones se comportan de la misma manera, sobre los tiles.) También hay botones para bloquear o desbloquear todas las instancias. Las instancias bloqueadas no pueden ni borrarse ni moverse. Esto te libra de borrados accidentales de instancias. Utilizando el menú emergente que aparece al pulsar con el botón derecho del rato y pulsando la tecla sobre una instancia, también puedes bloquear o desbloquear instancias individuales. Finalmente, puedes indicar si quieres una cuadrícula isométrica. Esto es muy útil cuando creas juegos en perspectiva isométrica. Lo primero, es que las líneas de la cuadrícula se dibujaran diagonalmente. Además el encaje de las instancias será diferente. (El encaje trabajara mejor cuando el origen de las instancias este situado en la esquina superior izquierda que es como se sitúa por defecto.) También tenemos dos nuevas etiquetas de las que hablaremos en los temas siguientes. Puedes encontrar más opciones avanzadas de las rooms en los temas: Configuración avanzada Añadiendo tiles Vistas
Configuración avanzada Existen aún dos aspectos en la etiqueta settings que aún no hemos discutido. Primero existe un recuadro etiquetado como Persistent. Normalmente, cuando abandonas un nivel (room) y vuelves después el nivel vuelve a su configuración inicial. Esto es adecuado cuando tienes un cierto numero de niveles en tu juego, pero no lo es tanto cuando haces juegos de otro estilo como RPGs o similares. En estos casos el nivel debería permanecer de la misma forma que cuando se abandono. Activando la opción Persistent conseguirás que esto suceda. El estado del nivel será recordado y cuando vuelvas después, estará justo como cuando lo dejaste. Solo cuando reinicias el juego, el nivel volverá a su configuración inicial. Actualmente existe una excepción a esto: Si marcas algunos objetos como persistentes, las instancias de estos objetos no permanecerán en el nivel, pero se moverán al siguiente. En Segundo lugar, tenemos el botón etiquetado como Creation code. Aquí puedes introducir un trozo de código GML que se ejecutará cuando se crea el nivel. Esto es útil cuando quieres inicializar variables para el nivel , crear determinadas instancias, etc. Esto es importante que suceda justo cuando te mueves hacia un nivel en particular. •
Primero, en el nivel actual (si lo hay) todas las instancias tienen un evento “fin de nivel”. En el siguiente nivel, todas las
instancias no persistentes son borradas. (No se genera un evento destrucción!!) •
Después, para el siguiente nivel, las instancias persistentes del nivel anterior son añadidas.
•
Todas las nuevas instancias son creadas y sus eventos de creación son ejecutados (si el nivel no es persistente o no ha sido visitado anteriormente).
•
Cuando estamos en el primer nivel, el evento “game-start” es generado para todas las instancias.
•
Ahora, es cuando se ejecuta el evento “creation code” del nivel.
•
Por último, todas las instancias generan el evento “room-start”.
Así, por ejemplo, el evento “room-start” puede utilizar variables inicializadas en el código de creación (“creation code”)para el nivel, y en dicho código puedes hacer referencia a las instancias (tanto las nuevas como las persistentes) en el nivel. Aún hay una opción que va más allá. En el menú emergente que aparece cuando pulsas con el botón derecho del ratón con la tecla pulsada, puedes indicar un código de creación para una instancia en particular. Este código es ejecutado cuando comienza el nivel, justo antes del evento de creación de la instancia sea ejecutado. Esto es muy útil para, por ejemplo, iniciar ciertos parámetros que son específicos de una instancia en cuestión.
Añadiendo tiles También puedes crear fondos “tileados” . La razón por la que se hace esto es la siguiente: En muchos juegos, querrás tener fondos bonitos. Por ejemplo en un juego de laberintos deberían verse bien las paredes y en un juego de plataformas , los árboles, plataformas, et, deberán tener un aspecto agradable. Puedes hacer esto en Game Maker definiendo muchos objetos diferentes y montando tu nivel con esos objetos. El problema esta en que esto requiere mucho trabajo, utiliza una gran cantidad de recursos y hace que el juego se ejecute más lentamente debido a que tiene que trabajar con muchos objetos diferentes al mismo tiempo. Por ejemplo, para crear bonitas paredes en un juego de laberintos, necesitas para empezar por lo menos 15 objetos “pared”.
La manera estándar, utilizada en muchos juegos, es que las paredes y los demás objetos estáticos sean dibujados sobre el fondo. Pero como probablemente te estés preguntando, ¿como hace el juego para saber que un objeto golpea una pared si esta solo dibujada sobre el fondo?. El truco es el siguiente: tú creas un único objeto “pared” en tu juego y colocas instancias de este objeto donde tiene que haber una pared. Este objeto debe tener el tamaño correcto, pero no tiene porque verse bonito. Y, aquí es donde viene el truco: lo hacemos invisible. De esta manera, cuando estés jugando el juego, no verás los objetos “pared”. Verás los bonitos fondos que coloques encima. Sin embargo los objetos “pared” continuarán allí y los objetos reaccionarán a las colisiones con ellos. Puedes utilizar esta técnica con todos aquellos objetos que no cambien su posición. (No puedes utilizarla cuando el objeto tenga que ser animado). Para juegos de plataformas, probablemente necesites un objeto suelo y un objeto pared, pero puedes hacer bonitos fondos para que parezca que caminas sobre hierba, ramas de árboles, etc. Para añadir “tiles” al nivel, necesitas primero añadir un recurso de fondo a tu juego que contenga los “tiles”. Si quieres que tus tiles sean parcialmente transparentes, asegúrate de que haces la imagen de fondo transparente. Cuando añadimos los recursos de fondo indicamos que este tiene que ser utilizado como un set de tiles. Después indicamos el tamaño de cada tile y cuando existe un espacio entre los tiles (como lo indicamos en el capítulo de recursos de fondos). Ahora, cuando definimos el nivel, pulsa sobre la etiqueta tiles. Aparecerá el siguiente formulario (aquí, ya hemos colocado varios tiles en el nivel).
En la esquina superior izquierda se muestra el set de tiles que estamos utilizando. Para seleccionar el set, pulsa sobre el botón menú debajo de el y selecciona la imagen de fondo correcta. Ahora puedes añadir tiles seleccionando el tile que quieres arriba a la izquierda y pinchando con el ratón en la parte del nivel donde quieras colocarlo. Funciona de la misma manera que añadir instancias. Los Tiles superpuestos por otros son borrados, a no ser que deselecciones la opción Delete underlying. Puedes utilizar el botón derecho para borrar tiles. Presiona la tecla para añadir varios tiles y presiona para moverlos. La tecla evitara que se encajen a la cuadrícula. También tienes aquí un menú emergente cuando pulsas la tecla
y pulsas sobre un tile con el botón derecho del ratón. Los botones de la barra de herramientas ahora borraran todos los tiles, los moverán, shift all tiles, ordenarán los tiles o los bloquearán o desbloquearán. (Actualmente están trabajando sobre la misma capa, ya lo verás más adelante.) En determinadas situaciones, querrás añadir una parte del fondo que no tenga exactamente el mismo tamaño o que consista en varios tiles. Esto puede hacerse de la siguiente manera. En la imagen de arriba a la izquierda presiona el botón izquierdo del ratón mientras mantienes pulsada la tecla . Ahora podrás arrastrar un área que podrás colocar después en el nivel como cualquier otro tile. Para seleccionar varios tiles mantén pulsada la tecla . Observa que esto solo funciona correctamente cuando no existe separación entre los tiles. Si quieres seleccionar un área con tiles de tamaño variado, presiona la tecla en lugar de la tecla Shift>. (Date cuenta de que puedes cambiar la tecla pulsada mientras estas arrastrando los tiles. A veces puede ser útil.) Los tiles pueden colocarse en capas a diferentes profundidades. Abajo del todo, ves la profundidad actual de la capa. La profundidad por defecto es 1000000 con lo que esta normalmente debajo de todas las demás capas. De esta forma las instancias se mostrarán sobre los tiles. Puedes utilizar el botón Add para añadir nuevas capas, cada una a diferente profundidad. Valores de profundidad negativos pueden utilizarse para colocar los tiles encima de las instancias como imágenes frontales. Si das diferentes profundidades a los objetos podrás hacer que se sitúen entre las diferentes capas de tiles. Si presionas el botón Delete borrarás una capa con todos sus tiles. (Siempre debe de haber al menos una capa) Si presionasChange puedes cambiar la profundidad de una capa de tiles. Si le das la misma profundidad que a otra capa, las capas se combinan. Utilizar tiles es un rasgo que debe ser utilizado tanto como sea posible. Es mucho más rápido que utilizar objetos y las imágenes de Tiles son almacenadas una sola vez. Así puedes utilizar grandes niveles creados a base de tiles con poco consume de memoria.
Vistas Finalmente, tenemos una etiqueta llamada views. Esta contiene un mecanismo para dibujar diferentes partes de tu nivel en distintas partes de la pantalla. Aquí tenemos varios usos de las vistas. Antes de cualquier otra cosa, en determinados juegos querrás mostrar solo una parte del nivel en cada momento. Por ejemplo, en la mayoría de los juegos de plataformas, la vista sigue al personaje principal. En juegos de dos jugadores, a menudo necesitaras dividir la pantalla en dos partes, una para cada jugador Un tercer uso es en los juegos en los que una parte de la pantalla utilice un scroll (la que sigue al personaje principal, por ejemplo) mientras que la otra continua estática (como podría ser la parte en la que se contiene el marcador). Esto se puede conseguir fácilmente con Game Maker. Cuando pulsas sobre la etiqueta views aparece la siguiente información:
A la derecha tenemos un opción “Enable the use of Views”. Debes seleccionarla si quieres utilizar las vistas. Debajo versa una lista de un total de ocho vistas que puedes definir. Debajo del listado tienes la información de las vistas. Lo primero es indicar cuando la vista debe ser visible al inicio del nivel. Asegúrate de que al menos una vista es visible. Las vistas visibles se muestran en negrita dentro del listado. Una vista esta definida por un área rectangular del nivel. Esta es el área que debe verse en la vista. Tú especificas la posición de la esquina superior izquierda y el ancho y alto del área. Después debes especificar que parte de la pantalla se destinará para mostrar la vista. Esta opción aparece nombrada como “Port on screen” (lo traduciremos como “lienzo” para la vista, dado que la traducción literal “puerto para la vista”, no resulta lo suficientemente descriptiva) . De Nuevo especificas la posición de la esquina superior izquierda y el tamaño. Si tienes una vista simple en la posición típica (0,0). Date cuenta de que el tamaño del lienzo para la vista puede ser diferente al tamaño de la vista. En ese caso, la vista se escalará para adecuarse al tamaño del lienzo. (En código también es posible rotar una vista.) Los lienzos pueden solaparse. En este caso son dibujados en el orden indicado uno encima de otro. Como se indica arriba, a menudo querrás que la vista siga a un objeto determinado. Este objeto puede ser indicado algo más abajo. Si hay múltiples instancias de ese objeto, solo el primero en crearse será seguido por la vista. (En GML puedes indicar a que instancia en particular debe seguir la vista.) Normalmente, el personaje será capaz de andar algo antes de que la vista comience a moverse con el.. Solo cuando el personaje se encuentra cerca del borde de la vista, esta comenzará a moverse. Puedes especificar también el tamaño del contorno que debe permanecer visible alrededor del objeto a seguir. Finalmente puedes restringir la velocidad con que se mueve la vista. Esto significa que el carácter puede caminar por la pantalla, pero esto le da más suavidad al movimiento del juego. Utiliza un valor de -1 si quieres que cambie esta velocidad automáticamente.
Fuentes Cuando quieres dibujar texto en tu juego, este se muestra con la fuente Arial y un tamaño de 12 puntos. Para poner textos más trabajados, probablemente quieras utilizar diferentes Fuentes. Para crear Fuentes diferentes, debes crear recursos de Fuente. En cada recurso de fuente especificas un tipo de fuente en particular con el que puede ser utilizado en el juego utilizando la acción “set a font”. Para añadir un recurso de fuente utilice el ítem Add Font en el menú Add o utilice el botón correspondiente en la barra de herramientas. Aparecerá la siguiente ventana emergente:
Como siempre deberás de ponerle un nombre a tu recurso de fuente. Después, puedes tomar el nombre de la fuente de la lista. También puedes indicar el tamaño y el estilo de la fuente. Date cuenta de que las Fuentes grandes necesitan mucha memoria. Te recomendamos encarecidamente que no utilices Fuentes de un tamaño mayor a 32. (Es posible escalar las Fuentes durante el juego). Un ejemplo de la fuente indicada aparece en la parte inferior de la ventana. Una fuente normalmente consta de 256 caracteres,enumerados de 0 a 255. Pero en general tu solo utilizaras una pequeña porción. Así que por defecto solo se guardan los caracteres del 32 al 127. Cuantos más caracteres guardes, más memoria necesitaras. Puedes cambiar el mapa de caracteres que se utilizará. Para ver el índice de cada carácter, puedes utilizar el mapa de caracteres que se encuentra en la ventana de inicio de WINDOWS bajo Accesorios/Herramientas del sistema. Algunos rangos estándar pueden ser indicados utilizando los botones: El rango”Normal” del 32 al 127, el rango completo “All” del 0 al 255,el rango numérico “Digits”conteniendo solo los diez dígitos, y el rango de letras “Letters”que contiene las letras mayúsculas y minúsculas. Otros rangos pueden ser utilizados indicando los índices del primer y ultimo carácter. Si se escribe un carácter que no esta incluido, este aparece como un espacio en blanco.
Normalmente tienes gran cantidad de Fuentes instaladas en tu ordenador, y hay webs donde puedes descargar cientos de Ellas. El problema es que cuando las utilices en tu juego puede que alguien que lo juegue no la tenga instaladas en su ordenador. Para evitar esto Game Maker guarda todas las Fuentes que quieras en los archivos de juego, Pero solo en los ejecutables. De tal forma que si das un juego ejecutable a alguien más, no necesitas darle los archivos de fuente. Pero si le das la versión editable, esa persona podrá instalárselas.
Paths En la mayoría de los juegos avanzados a menudo se suelen asignar ciertas trayectorias a las instancias. Aunque puedes conseguirlo utilizando alarmas o código, es bastante complicado. Los recursos de trayectoria (path) son un mecanismo mucho más simple. La idea es bastante sencilla: Defines una trayectoria, dibujándola. Una vez hecho esto puedes situar una acción en el evento Create del objeto para que este siga esa trayectoria en particular. En este capítulo explicaremos este procedimiento al detalle.
Definiendo paths Para añadir una trayectoria a tu juego, escoge Add Path en el menú Add. Aparecerá la siguiente ventana (en este ejemplo ya añadimos una pequeña trayectoria):
En la parte superior izquierda puedes especificar el nombre del path. Debajo encontrarás los puntos que definen el path. Cada punto tiene una posición y velocidad asignadas (indicado con sp). Dependiendo de cómo utilices la trayectoria, la posición puede ser absoluta o no. La instancia para la que después utilizaras la trayectoria la seguirá a ese punto especificado, o si es relativa, la instancia siempre empezará en la primera posición del path, y lo seguirá a partir de ahí. La velocidad es interpretada de la siguiente manera. Un valor de 100 significa la velocidad original de la instancia. Un valor menor reduce la velocidad, un valor más alto la incrementa (esto indica el porcentaje de la velocidad real). La velocidad debe ser interpretada de la siguiente manera: Un valor de 100 indica un 100% de la velocidad original definida para la trayectoria cuando se la asignamos a la instancia. Un valor menor, reduce esta velocidad, y un valor mayor la aumenta (siempre porcentualmente). La velocidad se interpolará entre los diferentes puntos, por lo que la velocidad cambiará de forma gradual.
Para añadir un punto presiona el botón Add. Se realizará una copia del punto seleccionado. Ahora puedes modificar la posición y la velocidad cambiando los valores en las ventanas de edición. Cuando seleccionas un punto en la lista, también puedes cambiar sus valores. Presiona Insert para insertar un nuevo punto antes del seleccionado, y Delete
para borrar el punto seleccionado. Finalmente, puedes usar Clear para borrar completamente el path.
A la derecha del formulario verás la trayectoria actual. El punto rojo indica el punto de control seleccionado. Los puntos azules, son todos los demás. El cuadrado verde indica la posición donde comienza la trayectoria. También puedes cambiar el path usando el ratón. Pulsa con el ratón sobre la imagen para agregar un punto. Pulsa sobre un punto existente y arrástralo para cambiar su posición. Cuando mantienes mientras pulsas el botón izquierdo del ratón, insertas un punto. Por ultimo, puedes usar el botón derecho para borrar puntos. (Date cuenta de que de esta manera no puedes cambiar la velocidad.)
Normalmente los puntos se alinean con una cuadricula. Puedes cambiar sus características en la parte superior de la barra de herramientas. también puedes indicar aquí si se muestra la cuadrícula o no. Si quieres posicionar un punto de forma precisa, presiona la tecla mientras lo añades o lo arrastras.
Puedes influir la forma de la trayectoria de dos formas. Primero puedes definir el tipo de unión entre los puntos. Puedes escoger líneas rectas o curvas. En segundo lugar, puedes indicar que pasa cuando se llega al último punto. Existen varias opciones. La más común es continuar moviéndose hacia el primer punto, cerrando el path (move to start). También puede dejar de moverse (stop moving), saltar al primer punto (jump to start), o invertir la trayectoria (reverse). La opción final (continue) reinicia el path desde la posición actual. De esta manera el path va a “avanzar”. Sólo se muestran las primeras cinco repeticiones, pero el path continúa más allá.
Sobre la barra de herramientas tenemos varios controles importantes. De izquierda a derecha estas son sus funciones: El primer botón indica que estas preparado y quieres cerrar el formulario, guardando los cambios (si quieres descartar los cambios, pulsa sobre la cruz para cerrar la ventana e indica que no quieres guardarlos). El siguiente es el botón de deshacer, para corregir el último cambio. Los siguientes botones te permiten borrar la trayectoria, invertir su sentido, deslizarla de un lado a otro, voltearla horizontal o verticalmente, rotarla y cambiar su tamaño. Los siguientes botones son para mover la vista (no la trayectoria en si, el área de la vista esta indicado en la barra de estado abajo del todo) y para centrarla.
Como ya hemos indicado antes, puedes definir después los valores de la cuadrícula y cuando se muestra o no. Por ultimo, existe un botón que indica si quieres ver un fondo en particular como fondo de la trayectoria. De esta forma es fácil colocar la trayectoria en un lugar
determinado del room, como por ejemplo en una pista de carreras, de forma que las instancias puedan seguir después la ruta correcta (esto solo se aprecia cuando utilizas trayectorias absolutas).
Asignando paths a los objetos Para asignar una trayectoria a una instancia de un objeto, puedes asignar la acción “path” en algunos eventos, por ejemplo en el evento “create”. En esta acción debes especificar la trayectoria que quieres de una lista desplegable. También hay otros dos valores que debes proporcionar.
Primero la velocidad a la que el path será recorrido (speed) en píxeles por paso. Cuando la velocidad es positiva, la instancia comienza al principio de la trayectoria. Si es negativa, comienza al final. Recuerda que cuando defines la trayectoria tu mismo especificas la velocidad real, relativa a la velocidad indicada aquí (de forma porcentual). también hay una acción para cambiar la velocidad con que la trayectoria es recorrida. Puedes utilizarla para, por ejemplo, hacer que una instancia acelere o frene a lo largo de la trayectoria. Observa que la velocidad normal de la instancia es ignorada cuando se realiza la trayectoria. Tampoco la gravedad o la fricción tienen efecto sobre ella.
Más adelante debes especificar que sucede cuando se alcanza el final de la trayectoria. Puedes elegir parar el movimiento y terminar la trayectoria, comenzar de nuevo desde el inicio (saltando de nuevo a la posición inicial donde se inicio la trayectoria) o volver a comenzar desde la última posición. Por ultimo, puedes optar por invertir la trayectoria.
Finalmente, puedes indicar si la trayectoria es absoluta o relativa. Una trayectoria absoluta es ejecutada en el lugar del nivel donde fue definida. La instancia se coloca en la posición inicial y comienza su movimiento desde allí (en la posición final si la velocidad es negativa). Esto es útil cuando, por ejemplo, tienes una pista de carreras sobre la que has definido la trayectoria. Cuando eliges una trayectoria relativa, las instancias comienzan a recorrer la trayectoria desde donde se encuentren. Esto es útil cuando una instancia debe hacer una trayectoria local, por ejemplo, las naves de “Space Invader” pueden hacer unos giros en particular desde su posición.
Cuando deseas colocar la instancia en un punto diferente a lo largo de la trayectoria, puedes utilizar la acción para definir la posición dentro de la trayectoria. Una posición dentro de la trayectoria siempre se encuentra entre 0 y 1. Un valor de 0 indica el inicio (que es lo más común). Un valor de 1 indica el final del path. Observa que en cada paso la variable
direction es
definida automáticamente en la
dirección correcta a lo largo de la trayectoria. Puedes utilizar esta variable para orientar correctamente el sprite.
Cuando usas scripts o piezas de código tienes más control sobre la forma en que el path es ejecutado. Existe una función para iniciar una trayectoria para una instancia. La variable anteriormente). La variable
variable
path_position indica
path_speed indica
la
velocidad
la
path_scale puede ser usada para escalar el path. Un valor
más grande, mientras que uno menor lo reducirá. La variable
la posición actual del path. (Entre 0 y 1 como se indicó
velocidad
con
que
se
recorre
la
trayectoria
del
path. La
de 1 indica la escala real. Un valor mayor indica que el path será
path_orientation indica
la orientación en que el path es recorrido
(derecha o izquierda). Esto permite que puedas realizar trayectorias en diferentes orientaciones (Ej. Moviéndose arriba y abajo en vez de izquierda y derecha.)
Finalmente, existen muchas funciones para conocer las propiedades de las trayectorias (coordenadas X e Y por ejemplo) y existen funciones para crear nuevas trayectorias.
También existen funciones que crean trayectorias libres de colisiones para que la instancia alcance una meta determinada. Lee las secciones posteriores sobre GML para más detalles.
Tal vez te preguntes que pasa cuando la instancia colisiona con otra instancia mientras este sigue una trayectoria. Básicamente sucede lo mismo que cuando la instancia se mueve con una velocidad determinada. Si la otra instancia es sólida la instancia se detendrá en la última posición antes del choque. (Asumiendo que existe un evento de colisión definido.) La variable
path_position se
detendrá aquí.
Cuando la instancia que se encuentra en su camino deja de interceptar la trayectoria, continuara recorriéndose la trayectoria. Para manipular las trayectorias tu mismo, la variable
path_positionprevious puede
ser útil. Esta variable guarda la última posición
de la trayectoria y puedes definir la posición de la trayectoria a este punto para parar el avance de la misma.
El evento path Como se describió antes, puedes indicar que sucede cuando la instancia llega al fin de la trayectoria. En este momento se ejecuta el evento End of path. Puedes encontrarlo dentro del evento Other. Aquí puedes añadir más acciones. Por ejemplo, podrías destruir la instancia, o asignarle un path diferente.
Time Lines En muchos juegos ciertas cosas deben pasar en ciertos lapsos de tiempo. Puedes intentar hacer esto usando el evento alarm pero cuando las cosas se vuelven muy complicadas esto podría no funcionar. Mediante el recurso “time line” lo puedes hacer. En una time line tú especificas qué acciones deben suceder en ciertos lapsos de tiempo. Puedes utilizar todas las acciones que están disponibles para los diferentes eventos. Cuando hayas creado una time line puedes asignarla a una instancia de un objeto. Esta instancia ejecutará las acciones en los lapsos de tiempo indicados. Permíteme explicarlo con un ejemplo. Supongamos que quieres crear un guardia. Este guardia debe moverse 20 pasos a la izquierda, después 10 arriba, 20 a la derecha, 10 hacia abajo y después detenerse. Para lograr esto creas una time line donde empiezas con un movimiento a la izquierda. En 20 pasos pones un movimiento hacia arriba. En el paso 30 un movimiento a la derecha, en el paso 50 un movimiento hacia abajo y en el 60 detienes el movimiento. Ahora puedes asignar esta línea de tiempo al guardia y el guardia hará exactamente lo que planeaste. También puedes usar una línea de tiempo para controlar tu juego de manera global. Crea un objeto invisible, crea una time line que en ciertos momentos cree enemigos, y asígnala al objeto. Si empiezas a trabajar con esto encontrarás que es un concepto muy poderoso.
Para crear una time line, selecciona Add time line del menú Add. Aparecerá la siguiente ventana:
Se parece un poco a la ventana de propiedades del objeto. A la izquierda puedes poner el nombre y además hay botones para añadir y modificar “moments” en la time line. Enseguida está la lista de los “moments” (momentos). Esta lista especifica los lapsos de tiempo en steps en que las acciones asignadas van a pasar. Y enseguida está la lista de acciones para el momento seleccionado y finalmente a la derecha está la lista total de acciones disponibles. Para añadir un momento presiona el botón Add, indicando un lapso de tiempo (esto es el número de pasos desde que la time line comienza). Ahora puedes arrastrar acciones a la lista de manera semejante como los eventos de los objetos. También hay botones para borrar el momento seleccionado, para borrar toda la time line, cambiar el momento y duplicarlo.
Finalmente existen dos botones especiales. Con el botón Merge puedes unir varios momentos en un rango deseado en uno solo. Con el botón Shift puedes cambiar todos los momentos cierta cantidad de tiempo avanzándolos o retrocediéndolos la cantidad deseada. Asegúrate de que no creaste momentos con un step negativo, porque nunca se ejecutarán.
Existen dos acciones relacionadas con las time lines:
Set
a
time
line
Con esta acción asignas una time line en particular a una instancia de un objeto. Aquí indicas la time line y la posición de inicio de la time line (0 es al principio). También puedes usar esta acción para finalizar una time line escogiendo No Time Line como valor
.
Set the time line position
Con esta acción puedes cambiar la posición de la time line actual (puede ser absoluta o relativa). Esto puede ser usado para saltar ciertas partes de la time line o para repetir ciertas partes. Por ejemplo, si quieres crear una time line que se repita una y otra vez, añade esta acción en el último momento para que la posición regrese a 0. También puedes usarlo para esperar a que pase algo. Sólo añade la acción de prueba (usa un if) y, si no es cierta, asignas la posición de la time line un valor relativa de -1.
Scripts Game Maker posee un lenguaje de programación interno. Una vez que te familiarices con Game Maker y quieras usarlo a sus máximos alcances, es prudente aprender a usar este lenguaje. Existen dos maneras para usar el lenguaje. Primero puedes crear scripts. Estos son piezas de código a los que les darás un nombre. Son mostrados en el árbol de recursos y pueden ser salvados a un archivo y cargarlos desde un archivo. Pueden ser usados para formar una librería que extienda las posibilidades de Game Maker. Alternativamente, puedes añadir una acción de código a algún evento y escribir una pieza de código ahí. Añadir el código funciona exactamente de la misma manera que añadir scripts excepto por dos cosas. Las piezas de código no tienen un nombre y no usan argumentos. Además ya tienen indicados a que objeto deben aplicar el código. Por lo demás escribes el código de la misma manera como en los scripts. En este capítulo nos vamos a concentrar a fondo en los scripts.
Como se señaló antes, un script es una pieza de código en el lenguaje de programación interno que realiza una tarea específica. Un script puede usar un número de argumentos. Para ejecutar un código desde algún evento, puedes usar la acción script. En esta opción especificas el script que desees ejecutar, junto con un máximo de cinco argumentos. (También puedes ejecutar scripts desde una pieza de código de la misma manera en que llamas una función. En este caso puedes usar 16 argumentos como máximo.) Cuando un script retorna un valor, puedes usarlo también como una función cuando provee valores en otras acciones.
Para añadir un script a tu juego, selecciona Add script de el menú Add. Aparecerá la siguiente ventana (en este ejemplo ya añadimos un pequeño script):
(Realmente, este es el editor de scripts interno. En las preferencias puedes indicar si deseas usar un editor externo.) Arriba a la derecha puedes indicar el nombre del script. Tienes un pequeño editor donde puedes escribir el script. El editor tiene varias propiedades útiles la mayoría mediante botones (presiona el botón derecho del ratón para algunos comandos adicionales):
•
Múltiple deshacer y rehacer ya sea por tecla presionada o en grupos (puede ser cambiado en las preferencias)
•
Sangría automática inteligente que se alinea con la línea previa (puede ser habilitado en las preferencias)
•
Tabulador inteligente que hasta el primer carácter (no espacio) en la línea previa (puede ser habilitado en las preferencias)
•
Usa para aumentar la sangría en las líneas seleccionadas y +I para reducirla en las líneas seleccionadas.
•
Cortar y pegar
•
Buscar y reemplazar
•
Usa + arriba, abajo, re-pag o av-pag para desplazarte sin cambiar la posición del cursor.
•
Usa F4 para abrir el script o el recurso cuyo nombre esté en la posición del cursor (no funciona en la acción de código; sólo en los scripts)
•
Guardar y Cargar el script como un archivo de texto.
También hay un botón con el cual puedes probar si el script está correcto. No todos los aspectos son probados, solo la sintaxis de tu script, junto con la existencia de alguna función usada.
Como habrás notado, partes del texto del script tienen diferentes colores. El editor reconoce la existencia de objetos, variables internas y funciones, etc. El color del código ayuda bastante a evitar errores. En particular, notas inmediatamente si escribiste mal algún nombre o si usaste una keyword (una palabra con una función definida como var, global, other, self, etc.) como variable. Sin embargo colorear el código es algo lento. En las preferencias del menú file puedes activarlo o desactivarlo. Además puedes cambiar el color para los diferentes componentes de los programas. (Si algo sale mal con el coloreado del código, presiona F12 dos veces, para desactivarlo y volver a activarlo.)
También puedes cambiar la fuente usada en los scripts y en las piezas de código. Los scripts son extremadamente útiles para extender las posibilidades del Game Maker. Aunque esto requiere que diseñes tus scripts con cuidado. Los scripts pueden ser guardados en librerías que pueden ser añadidos a tu juego. Para importar una librería, usa el item Import scripts de el menú file. Para guardar tu scripts como una librería usa Export scripts. Las librerías de scripts son simples archivos de texto (Aunque tienen la extensión .gml). Preferentemente no los edites directamente porque poseen una estructura especial. Algunas librerías con scripts útiles son incluidas. (Para evitar trabajo innecesario cuando cargas el juego, después de importar una librería, es mejor borrar las librerías que no utilices.)
Cuando se crean scripts es muy fácil cometer errores. Siempre prueba los scripts usando el botón apropiado. Cuando ocurre un error durante la ejecución del script este es reportado, junto con una indicación del tipo de error y el lugar. Ocasionalmente verás un error con el texto "Unexpected error occurred during the game" (Ocurrió un error inesperado al ejecutar el juego). Este mensaje de error indica que ha ocurrido un error en Windows o en el hardware del ordenador. Normalmente este error se debe a recursión infinita, falta de memoria o hardware, drivers o firmware insuficientes. Generalmente hablando, estos errores tienen que ver con el entorno externo a Game Maker. Si necesitas verificar las
cosas más cuidadosamente, puedes correr el juego en debug mode (F6). En este caso aparece una ventana en la cual puedes monitorear mucha de la información de tu juego:
En el menú Run puedes pausar el juego, correrlo paso a paso e incluso reiniciarlo. En el menú Watch puedes ver el valor de ciertas expresiones. Usa Add para escribir algunas expresiones cuyos valores se mostrarán en cada paso del juego. De esta manera puedes ver si el juego está haciendo las cosas de la manera adecuada. Puedes ver varias expresiones. Puedes salvarlas para usarlos después. (Ej. Para hacer correcciones al juego). En el menú Tools se encuentran comandos para ver más información. Puedes ver una lista de todas las instancias en el juego, puedes ver todas las variables globales y locales (usa el nombre del objeto o el id de la instancia.) Además puedes ver mensajes que envías desde tu código usando la funciónshow_debug_message(str). Finalmente puedes dar al juego comandos y cambiar la velocidad del juego. Si haces juegos complicados deberías aprender a usar las opciones del debug mode.
Terminando tu juego En esta sección veremos cómo convertir tu proyecto en un juego terminado. Aquí se describe cómo añadir archivos de ayuda al juego, configurar ciertas opciones y crear un ejecutable que pueda ser distribuido para que el juego funcione sin necesitarGame Maker. Esta sección se divide en los siguientes temas: Información del juego Opciones globales del juego Consideraciones sobre la velocidad
Información del juego Un buen juego provee al jugador con cierta información sobre como jugar el juego. Esta información es mostrada cuando el jugador presiona la tecla durante el juego. Para crear la información del juego, da doble clic en Game Information(información del juego) en el árbol de recursos a la izquierda de la pantalla. Se abre un pequeño editor de texto en donde puedes editar la información del juego. Puedes usar diferentes fuentes, diferentes colores, y estilos. También puedes poner un color de fondo.
En el menú File puedes fijar un numero de Options (opciones). Aquí puedes indicar el título de la ventana de la información del juego durante el juego. También puedes indicar la posición (usa -1 para centrar la ventana) y el tamaño de la ventana del game information. Puedes forzar a la ventana de la información para estar arriba y también indicar si el juego puede continuarse jugando mientras la información se muestra.
Una opción interesante es mimic the main window. Cuando habilitas esta opción la ventana de la ayuda se muestra exactamente en la misma posición y tamaño que la ventana del juego. Esto da como resultado que se vea como si el texto apareciera en la ventana del juego. Escogiendo el color de fondo apropiado provee un efecto visual agradable (podrías indicar en el fondo de la ayuda que el jugador debe presionar Escape para continuar jugando.)
Un buen consejo es hacer la información corta pero precisa. Por supuesto puedes agregar tu nombre porque tú creaste el juego. Todos los juegos de ejemplo proveen un archivo de información acerca del juego y de cómo fue creado.
Si quieres hacer una ayuda más imaginativa, usa por ejemplo Microsoft Word. Y entonces seleccionas la parte que desees y usa copiar y pegar para moverlo desde Microsoft Word hacia el editor del Game Information. Para juegos más avanzados probablemente no uses este mecanismo en todo, pero usa algunos rooms dedicados a mostrar la ayuda acerca del juego.
Opciones Globales del Juego Existen un número de opciones que puedes cambiar para tu juego. Estos cambian la forma de la ventana principal, fijan algunas opciones de gráficos, cambiar la imagen de cuando carga el juego, constantes e información sobre el creador del juego. También puedes indicar aquí cuales archivos serán incluidos en el juego convertido a .exe y como los errores deben ser manipulados.
Estas opciones pueden ser encontradas haciendo doble click en Game Options en el árbol de recursos a la izquierda de la pantalla. Estas están subdivididas en varias pestañas (Algunas funciones solo están disponibles en el modo avanzado).
La información detallada se encuentran en los temas siguientes: Opciones gráficas Resolución Otras opciones Opciones de carga Constantes Incluyendo archivos en los ejecutables Opciones de error Información sobre el juego
Opciones gráficas En esta pestaña puedes poner un número de opciones que están relacionadas con la apariencia gráfica del juego. Normalmente es útil comprobar los efectos de esas opciones porque pueden tener un efecto significativo en la forma en que el juego luce. Recuerda que diferentes usuarios tienen máquinas diferentes. Entonces asegúrate que las opciones funcionen en las máquinas de otra gente.
Start in fullscreen mode Cuando lo habilitas el juego se ejecuta a pantalla completa; de lo contrario corre en una ventana. Scaling Aquí puedes indicar lo que sucederá cuando la ventana sea más larga que el cuarto o el juego corra en modo de pantalla completa. Hay 3 opciones. Puedes indicar un escalado fijo. El cuarto es dibujado escalado la cantidad dada en el centro de la ventana de la pantalla. 100 indica que no hay escalado. La imagen en el modo ventana debe ser escalada. Típicamente usas el escalado cuando tus sprites y cuartos son muy pequeños. La segunda opción es escalar el cuarto tal que llena la ventana o la pantalla pero guarda la proporción de aspecto entre anchura y altura. La tercera opción es escalar tal que la ventana o la pantalla está completamente llena. Esto puede conducir a la deformación en una imagen (en particular en el modo ventana cuando el usuario puede volver a cambiar el tamaño de la ventana)
Interpolate colors between pixels Cuando lo seleccionas, los colores de píxeles en sprites, fondos y tiles que no están alineados con píxeles en la pantalla serán interpolados. Este es el caso cuando son escalados, rotados o colocados en posiciones con coordenadas no enteras (con decimales). La interpolación hace el movimiento más suave pero puede también crear un efecto borroso (también para tiles puede hacer que aparezcan grietas entre ellas si no diseñas el cuarto cuidadosamente) Color outside the room region Cuando el cuarto no llena totalmente la ventana o la pantalla hay algunas áreas que no se usan. Aquí puedes especificar el color de ese área. Allow the player to resize the game window Cuando lo seleccionas, en el modo ventana el usuario podrá cambiar el tamaño de la ventana arrastrando el ratón en las esquinas de la ventana. Let the game window always stay on top Cuando lo seleccionas, en modo ventana el juego estará siempre por encima de otras ventanas. Don't draw a border in windowed mode Si lo seleccionas, el modo ventana no tendrá bordes ni la barra de título. Don't show the buttons in the window caption Cuando lo seleccionas en el modo ventana la barra de título no mostrara los botones para minimizar, maximizar o cerrar. Display the cursor Aquí indicas si quieres que el puntero del ratón sea visible. Desactivarlo es más rápido y agradable. (Puedes hacer fácilmente tu propio cursor con Game Maker) Freeze the game when the form looses focus Cuando lo habilitas, si el jugador pone alguna otra ventana sobre el juego (por ejemplo otro programa) el juego se congela hasta que la ventana del juego es enfocada otra vez.
Resolución En esta pestaña puedes fijar la resolución de la pantalla a la cual el juego deberá correr. Por defecto, la resolución no cambia. Pero algunas veces quieres que tu juego corra en resoluciones más bajas o quieres fijar la frecuencia del monitor para hacer que la sincronización trabaje correctamente. Si quieres cambiar la resolución debes primero habilitar opción denominado Set the resolution of the screen.
Hay tres cosas que puedes cambiar. Primero está la profundidad del color. Esto indica el número de bits usados para representar el color de un píxel. La mayoría de las máquinas de ahora permiten 16-bit (alto color) o 32-bit (color completo) pero maquinas antiguas solo aceptan 8-bit y a veces 24-bit. Game Maker solo funciona correctamente in modo 16-bit y 32-bit dando una apariencia agradable a las imágenes pero toma mucha memoria y tiempo de procesamiento. Si quieres que tu juego corra en máquinas antiguas pon la profundidad del color a 16-bit. Si no utiliza 32-bit o directamente no la cambies.
Segundo, está la resolución de la pantalla, el número de píxeles (horizontal y vertical) en la pantalla. Cambiar la resolución es muy útil cuando, por ejemplo tienes rooms muy pequeñas. En este caso puede que ayude reducir la resolución de la pantalla. Realízalo, pero sin embargo esto afectará las otras aplicaciones funcionando. Esto puede en particular dar problemas con resoluciones bajas. Así, en general es mejor hacer esto sólo cuando el juego corra en pantalla completa. Game Makerautomáticamente cambiará la resolución en la que estaba la máquina antes de poner el juego, cuando este termine.
Finalmente puedes cambiar la frecuencia. Esto indica cuantas veces por segundo la imagen en la pantalla se refresca. Si tu room speed es mayor que la frecuencia no todos los steps se verán. Funciona bien si la frecuencia es un múltiplo de la velocidad del room (Si especificas una frecuencia que sea demasiada alta o no disponible la frecuencia no se cambia).
También hay una opción aquí llamada Use synchronization to avoid tearing. Esto requiere cierta explicación. La pantalla es re-dibujada un número de veces por segundo, dependiendo en la frecuencia de refresco. Si un room es dibujado en medio de un refresco de la pantalla, la parte superior aún mostrara la imagen antigua mientras la parte de abajo muestra una nueva imagen. Esto se llama tearing. Para evitar esto puedes chequear esta opción. En este caso la nueva imagen del room será solamente copiada a la pantalla cuando no esté ocurriendo un refresco, evitando así el tearing la mayoría de veces. La desventaja es que normalmente tendremos que esperar hasta el siguiente refresco. Esto significa que el número máximo de frames está limitado por la frecuencia del monitor y, cuando el proceso no es lo suficientemente rápido, el framerate (velocidad de refresco del juego) inmediatamente disminuye a la mitad. También puede ocurrir un conflicto entre la sincronización interna del juego y la sincronización del monitor. Si quieres hacer esto mejor pon la frecuencia del monitor a 60 y la room speed igual a 30 ó 60.
Otras opciones Aquí puedes fijar un número de opciones adicionales. Primero que todo puedes fijar un número de teclas predeterminadas:
Let end the game Cuando lo habilitas, al presionar la tecla Escape termina el juego. Los juegos más avanzados normalmente no quieren que esto pase porque talvez quieran hacer algunos procesos (como salvar) antes de terminar el juego. En este caso, deshabilita esta opción y provee tu propia acción para la tecla escape. (Dar un clic sobre la cruz de la ventana también genera un evento de la tecla escape.)
Let show the game information Cuando está habilitado, presionando la tecla F1 muestra la información del juego.
Let switch between screen modes Si lo habilitas, la tecla F4 cambiará entre pantalla completa y el modo ventana
Let and load and save the game
Cuando está habilitado, el jugador puede usar para guardar la situación actual del juego, y para cargar el último juego guardado (Nota que solamente los datos básicos de juegos se guardan. Una vez que utilices características avanzadas como partículas o estructuras de datos, esas opciones no se guardan y deberás crear un sistema de guardado y cargado tu mismo)
También puedes fijar la prioridad del proceso del juego. Esta prioridad indica cuanto tiempo de proceso se asigna al juego. En modo normal el sistema operativo trata de dar tiempo de proceso para cada proceso que lo necesite de una manera razonable. Cuando más alta puso la prioridad es cuando mas tiempo de proceso se le asigna al juego, haciendo que corra mas suave y rápidamente. Pero otros procesos consiguen menos tiempo (también Windows procesa así incluso que el ratón no se puede mover más. Úsalo con cuidado.
Opciones de carga Aquí puedes indicar lo que debe suceder cuando cargas el juego. Primero puedes especificar una imagen propia de cargado. Después puedes indicar si se mostrará una barra del proceso de cargado en la parte baja de la imagen. Tienes tres opciones aquí. Que no se muestre una barra de progreso, que se muestre la barra que está por defecto o puedes especificar dos imágenes: el background (fondo) de la barra de carga y el foreground (primer plano). Puedes indicar si la barra de cargado del frente deberá escalarse (predeterminado) o acortado mientras se vuelve mas largo. En el segundo caso, cerciórate que la imagen es suficientemente grande como para llenar la barra. (Nota que ambas imágenes pueden ser especificadas en ese caso, no solo una)
Es posible indicar que la imagen de cargado sea transparente. En este caso el ultimo píxel abajo a la izquierda de la imagen de fondo es usado como el color transparente. También la translucidez alpha puede ser indicada. Un valor de 0 significa translucidez completa. Un valor de 255 significa completamente opaco (Ambos solo funcionan bajo Windows 2000, XP o siguientes)
Segundo, puedes indicar el icono que será usado para los juegos ya transformados a .exe. Puedes usar solo iconos de 32x32. Si intentas seleccionar otro tipo de iconos obtendrás una advertencia.
Finalmente, puedes cambiar el id único del juego. Este id se va a usar para registrar los puntajes más altos y los juegos salvados. Si tú liberas una nueva versión de tu juego y no quieres usar los puntajes anteriores, debes cambiar este número.
Constantes Bajo esta pestaña puedes definir las constantes globales que puedes ser usadas en scripts y en piezas de código, o como valores para acciones. Cada constante tiene un nombre y un valor. Los nombres deben seguir las mismas reglas que las variables, es decir, deben empezar con una letra o un guión bajo y seguido de letras, dígitos o guiones bajos. Te recomiendo que hagas tus constantes fácilmente distinguibles. Una convención generalmente es utilizar solo mayúsculas y guiones bajos.
El valor de una constante deberá ser una expresión constante. Esto es, debe ser un número constante, una cadena de texto (con comillas alrededor) o una expresión. La expresión es evaluada antes de que cualquier cosa suceda en el juego. Por ejemplo no puedes referirte al room actual, instancias, o scripts. Pero puede contener constantes internas y los nombres de los recursos.
Puedes añadir una constante usando el botón Add y borrarlo usando Delete Puedes cambiar un nombre de una constante o el valor haciendo un clic en él. Hay también botones para borrar todas las constantes o clasificarlas por nombre.
Incluyendo archivos en los ejecutables Como se ha indicado antes puedes crear la versión .exe de tu juego. A veces tu juego utilizará archivos adicionales. Por ejemplo, puede que desees incluir archivos de video o archivos de texto que se usarán en el juego. En muchos casos querrás agregar DLLs o imágenes y sonidos que se agreguen durante el funcionamiento del juego. Puedes proveer estos junto al ejecutable pero a veces es mas fácil incluirlos dentro del juego. De esta manera, sólo necesitas distribuir 1 solo archivo.
Aquí puedes indicar los archivos que quieres incluir en el ejecutable. Arriba del formulario hay una lista de archivos a incluir. Usa Add para seleccionar los archivos y agregarlos a la lista (puedes seleccionar múltiples archivos simultáneamente). UsaDelete o Clear para quitar archivos de la lista. (Observa que en el archivo .gm6 no se encuentran los archivos, solo los nombres. Si envías a alguien el archivo .gm6 deberán enviar también los archivos incluidos)
Los archivos en la lista se empaquetan en el ejecutable que es creado. Cuando el juego corre ellos se desempaquetan y pueden accederse a ellos dentro del juego. Es importante darse cuenta de dónde sucede esto. Hay 2 posibilidades que puedes elegir. En la situación predeterminada los archivos son desempaquetados en la carpeta donde esta el .exe. Así el juego puede utilizar el nombre del archivo para acceder a ellos directamente (no se necesita decir la ruta). Esto funciona bien si el .exe se guarda en el disco duro pero fallará si se almacena en un dispositivo de sólo lectura como un CD.
La segunda posibilidad es indicar que el archivo debe ser desempaquetado dentro de un una carpeta temporal que es creada durante el funcionamiento del juego. Si seleccionas esta opción necesitarás proveer la ruta a la carpeta temporal cuando uses el nombre del archivo durante el juego. Esta ruta puede obtenerse usando la variable interna
temp_directory. No olvides añadir el signo “\” en este caso.
Por ejemplo, para ver un archivo de video debes hacer esto:
{ show_video(temp_directory+'\pelicula.avi',true,true); } Asegúrate de que la carpeta temporal sea eliminada cuando el juego termine. Así, no puedes almacenar juegos guardados o información especial en este caso. Elige esta opción cuando el juego tenga que correr desde un CD o cuando no deseas crear ni alterar ningún archivo durante el juego.
Si un archivo que se desempaqueta ya existe, el archivo no se sobreescribe. Puedes cambiar este comportamiento seleccionando Overwrite existing files (sobreescribir archivos existentes) También, cuando el juego termina los archivos no son eliminados (a menos que estén en la carpeta temporal que se eliminaa totalmente). Puedes cambiar esto seleccionando Remove at game end.
Aviso: Si estás testeando tu juego, el directorio de trabajo será aquél en el que se encuentra el archivo .gm6 del juego. Si los archivos que incluyes en el juego están guardados en este mismo directorio y seleccionas la opción Remove at game endpuede que se eliminen completamente! Así que es mejor que no guardes los archivos que vayas a incluir en el mismo directorio que el .gm6.
Opciones de error Aquí especificas algunas opciones relativas a la manera en que los errores son reportados:
Display error messages Si lo habilitas, los mensajes de error se muestran al jugador. En la versión final de tu juego deberías deshabilitar esta opción.
Write error messages to file
game_errors.log
Si lo seleccionas, todos los mensajes de errores son escritos en un archivo llamado
game_errors.log en la carpeta del juego.
Abort on all error messages Normalmente ciertos errores son fatales, mientras otros pueden ser ignorados. Cuando habilitas esta opción todos los errores son considerados fatales y el juego es terminado. En la versión final del juego deberías habilitar esta opción.
Treat uninitialized variables as 0 Un error común es utilizar una variable antes de que tenga un valor asignado. Algunas veces esto es difícil de evitar. Cuando habilitas esta opción, las variables sin inicializar no reportarán un error pero se les asignará el valor de 0. Aunque debes tener cuidado. Esto significará que ya no serás informado de errores de escritura.
Información sobre el juego Aquí indicas el nombre del autor del juego. La versión del juego, y alguna información acerca del juego. Además se mantiene la fecha de la última modificación. Esto es útil si estás trabajando con varias personas en un juego o haciendo una nueva versión. Esta información no es accesible mientras se ejecuta el juego.
Consideraciones sobre la velocidad Si estás haciendo juegos complicados probablemente quieras hacer que corran lo más rápido posible. Aparte de que Game Maker hace que el juego corra lo más rápido posible, mucho depende en cómo diseñes el juego. Además es muy fácil crear juegos que utilicen mucha memoria. En este capítulo te daré algunas sugerencias sobre cómo hacer tus juegos más rápidos y de tamaño pequeño.
Antes de nada, mira cuidadosamente los sprites y fondos que utilices. Sprites animados usan mucha memoria y dibujar muchos sprites toma mucho tiempo. Haz tus sprites lo mas pequeño posible. Saca cualquier área invisible alrededor de el (el comando crop en el editor de sprites lo hace automáticamente). Lo mismo aplica para los los fondos. Si tienes un fondo que cubre toda la pantalla, asegúrate de desactivar la opción de color de fondo.
Si utilizas el modo pantalla completa, asegúrate de que el tamaño del room (o ventana) no sea mayor que el tamaño de la pantalla. La mayoría de las tarjetas de video pueden eficientemente aumentar a escala las imágenes, pero reducir a escala es lento. Finalmente, si es posible, desactiva el cursor. Esto hace lentos los gráficos.
También ten cuidado con el uso de muchas views. Por cada view el room se vuelve a dibujar.
Aparte de los gráficos, otros aspectos influyen en la velocidad. Asegúrate de tener la menor cantidad de instancias como sea posible. En particular, destruye los objetos que ya no sean requeridos (Ej. cuando abandonan el cuarto). Evita mucho código en el evento step o en el evento draw de los objetos. Frecuentemente las cosas no necesitan ser verificadas en cada paso. La interpretación del código es razonablemente rápida, pero esto es interpretado. Además, algunas funciones y acciones toman mucho tiempo; en particular cuando tiene que verificar todos los objetos (como por ejemplo, la acción de rebote).
Piensa acerca de donde utilizar los eventos de colisión. Normalmente tienes dos opciones. Los objetos que no tienen eventos de colisión son tratados mucho más rápidos, entonces utilízalos en los objetos que tengan pocas instancias.
Ten cuidado con el uso de archivos de sonido muy grandes. Necesitan mucha memoria y además se comprimen muy mal. Deberías verificar tus sonidos y ver si puedes detenerlos.
Finalmente, si quieres hacer un juego que mucha gente pueda jugar, asegúrate de poder probarlo en máquinas viejas.
El Lenguaje Game Maker (GML) Game Maker posee un lenguaje propio de programación. Este lenguaje te da mucha más flexibilidad y control que las acciones normales. Este lenguaje se llama Lenguaje Game Maker (GML). En esta sección describiremos el GML y daremos un vistazo a las cerca de 1000 funciones y variables disponibles para controlar todos los aspectos de tu juego. Esta sección se divide en los siguientes temas: Estructura general del GML Haciendo cálculos Game Play Interacción con el usuario Gráficos del juego Música y sonido Ventanas, highscores y otros pop-ups Recursos Modificando los recursos Archivos, registro y ejecución de programas Estructuras de datos Creando partículas Juegos multijugador Usando DLLs Gráficos 3D
Estructura general del GML Como habrás leído antes, el Game Maker contiene un lenguaje de programación interno. Este lenguaje te da mucha más flexibilidad y control que las acciones estándar. Nos referiremos a este lenguaje como el GML (de Game Maker Language). Hay diferentes lugares en los que puedes escribir programas con este lenguaje. El primero, cuando defines scripts. Un script es un programa en GML. Segundo, cuando agregas una acción de código a un evento. En una acción de código debes escribir un programa en GML. Tercero, en el room creation code. Y finalmente, en cualquier momento que necesites especificar algún valor en una acción, puedes también emplear una expresión en GML. Una expresión, como veremos más adelante no es un programa completo, sino una pieza de código que devuelve un resultado.
En este capítulo describiremos la estructura básica de los programas en GML. Cuando desees usar programas en GML, se debe tener cuidado con ciertos aspectos. Primero que nada, para todos tus recursos (sprites, objetos, sonidos, etc.) debes emplear nombres que inicien con una letra y que sólo consistan de letras, números y el guión bajo "‘_". De otra forma no podrás referirte a ellas desde el programa. Mantente seguro que todos los recursos tengan nombres diferentes, también ten cuidado de no nombrar a tus recursos self, other, global o all porque estas son palabras que tienen un significado especial dentro del lenguaje. Tampoco debes usar ninguna de las palabras reservadas indicadas a continuación. La estructura básica del GML se trata con detalle en los siguientes capítulos: Un programa Variables Asignaciones Expresiones Variables extra Accediendo a variables en otras instancias Arrays Sentencia If Sentencia Repeat Sentencia While Sentencia Do Sentencia For Sentencia Switch Sentencia Break Sentencia Continue Sentencia Exit Funciones Scripts Construcciones With Comentarios Funciones y variables en GML
Un programa Un programa consiste de un sistema de instrucciones, llamados sentencias. Un programa debe comenzar con el símbolo ‘{‘ y terminar con el símbolo ‘}’ . Las sentencias deben separarse con el símbolo ';'. La estructura global de todo programa es:
{ ; ; ... } Hay un número de diferentes tipos de sentencias, de las cuales vamos a ver más abajo.
Variables Como en cualquier lenguaje de programación, el GML contiene variables. Las variables son las posiciones de memoria que guardan la información. Las variables pueden almacenar valores reales o cadenas de texto. Las variables no necesitan ser declaradas como en otros lenguajes. Hay un gran número de variables internas. Algunas son generales, como mouse_x y mouse_y, las cuales indican la posición actual del cursor, mientras otras son locales para la instancia del objeto para el cual se ejecuta el programa, como “x” e “y” que indican la posición actual de la instancia. Una variable tiene un nombre que debe iniciar con una letra, y puede contener sólo letras, números, y el símbolo ‘_’ (La longitud máxima es de 64 caracteres). Cuando haces uso de una nueva variable, ésta es local para la instancia actual y no es conocida en los programas de otras instancias (aún del mismo objeto), aunque existe la posibilidad de hacer referencia a variables de otras instancias; mira más abajo para mayor información.
Asignaciones Una asignación pasa el valor de una expresión a una variable. Una asignación tiene la siguiente forma:
= ;
Una expresión puede ser un simple valor pero también puede ser más complicada. Además de asignar un valor a una variable, también se le puede sumar usando +=, restar usando -=, multiplicarla usando *=, dividirla usando /=, o usando |=, &\ o ^=.
Expresiones Las expresiones pueden ser números reales (p. Ej. 3.4), números hexadecimales, comenzando con el signo ‘$’ (p. Ej. $00FFAA), cadenas entre comillas simples o dobles (p. Ej. ‘hola’ o “hola”) u otras más complicadas. Para las expresiones, existen los siguientes operadores binarios (en orden de prioridad):
•
&&, ||: funciones Booleanas (&& para la función and, || para la función)
•
<, <=, ==, !=, >, >=: comparaciones, el resultado es true (1) o false (0)
•
| & ^: operadores de bit (| = bitwise or, & = bitwise and, ^ = bitwise xor)
•
<< >>: operadores de bit (<< = shift left, > > = shift right)
•
+, -: adición, sustracción
•
*, /, div, mod: multiplicación, división, división entera y módulo.
Nota que el valor operador
x div y
es el valor de
x/y redondeado en la dirección de cero al número entero más cercano. El
mod devuelve el resto obtenido dividiendo sus operandos. En otras palabras, x mod y =
x – (x div y) * y.
También, los operadores de bit existen:
•
!: not, convierte un valor verdadero en falso y uno falso en verdadero
•
-: cambio de signo
•
~: cambio de signo de bit
Como valores se pueden emplear números, variables o funciones que devuelvan algún valor. Las sub-expresiones se pueden colocar entre paréntesis. Todos los operadores funcionan para valores reales. Las comparaciones también funcionan para las cadenas y el + concatena cadenas.
Ejemplo Aquí hay un ejemplo con algunas asignaciones
{ x = 23; color = $FFAA00; str = 'hola mundo'; y += 5; x *= y; x = y << 2; x = 23*((2+4) / sin(y)); str = 'hola' + " mundo"; b = (x < 5) && !(x==2 || x==4); }
Variables extra Puedes crear nuevas variables al asignándoles un valor (no es necesario declararlas antes). Si simplemente usas un nombre de variable, la variable será almacenada sólo para la instancia actual. Por lo que no esperes encontrarla cuando manejes otro objeto (u otra instancia del mismo objeto). También se puede cambiar y leer variables de otros objetos colocando el nombre del objeto con un punto antes del nombre de la variable.
{ if (global.hacer) { // hacer cualquier cosa global.hacer = false; } } A veces quieres variables que solo estén dentro del actual piece of code o de un script. De esta manera evitas perder memoria y estás seguro que no hay ningún conflicto con los nombres. Esto es también más rápido que usar variables globales. Para hacer esto debes declarar las variables en el comienzo del código, usando la palabra “var”. Esta declaración se ve así:
var ,,, ... Por ejemplo, puedes escribir:
{ var xx,yy; xx = x+10; yy = y+10; instance_create(xx,yy,pelota); }
Accediendo a variables en otras instancias Como se dijo antes, puedes alterar variables en la instancia actual usando sentencias como:
x = 3;
Pero en ciertos casos querrás acceder a variables en otra instancia. Por ejemplo, para detener el movimiento de todas las pelotas, o para mover al personaje principal a cierta posición, o, en el caso de una colisión, cambiar el sprite de la otra instancia involucrada. Esto puede lograrse antecediendo el nombre del objeto y un punto al nombre de la variable. Así por ejemplo, puedes escribir:
pelota.speed = 0;
Esto cambiará la velocidad de todas las instancias del objeto pelota. Hay ciertos “objetos” especiales.
•
self: La instancia actual para la que estamos ejecutando la acción
•
other: La otra instancia involucrada en un evento de colisión
•
all: Todas las instancias
•
noone: Ninguna instancia (tal vez te parezca raro pero puede ser útil como veremos más adelante)
•
global: : No es precisamente una instancia, sino un contenedor que almacena variables globales
Por ejemplo, puedes usar las siguientes sentencias:
other.sprite_index = sprite5; all.speed = 0; global.message = 'Un buen resultado'; global.x = pelota.x;
Ahora tal vez te estés preguntando lo que la última tarea realiza cuando hay más de una pelota. Bien, se toma la primera y su valor x es asignado al valor global.
Pero qué tal si deseas establecer la velocidad de una pelota en particular, en lugar de la de todas ellas. Esto es un poco más difícil. Cada instancia tiene un id único. Cuando colocas instancias en un cuarto en el diseñador, este id se muestra cuando colocas el ratón sobre la instancia. Estos números son mayores o iguales a 100000. Puedes emplear estos números como la parte a la izquierda del punto. Pero ten cuidado, el punto será interpretado como el punto decimal en el número. Para evitarlo, colócalo entre paréntesis. Así por ejemplo, asumiendo que el id de la pelota es 100032, puedes escribir:
(100032).speed = 0; Cuando creas una instancia en el programa, la llamada devuelve su id. Una pieza de programa válido es:
{ nnn = instance_create(100,100,pelota); nnn.speed = 8; }
Esto crea una pelota y establece su velocidad. Nota que hemos asignado el id de la instancia a una variable y usamos esta variable como indicación antes del punto. Esto es completamente válido. Déjame explicarlo un poco mejor. Un punto es de hecho, un operador. Toma un valor como el operador de la izquierda y una variable (dirección) como el operador de la derecha, y devuelve la dirección de esta variable en particular para el objeto o instancia indicados. Todos los nombres de objetos, y los objetos especiales nombrados antes representan valores y pueden ser tratados como con cualquier otro valor. Por ejemplo, el siguiente programa es válido:
{ obj[0] = pelota; obj[1] = bandera; obj[0].alarm[4] = 12; obj[1].id.x = 12; }
La última sentencia debiera interpretarse como sigue. Tomamos el id de la primera bandera. Para la instancia con ese id establecemos a 12 su coordenada x. Los nombres de objetos, objetos especiales y los id de las instancias pueden también emplearse en otros programas.
Arrays Puedes emplear arrays de una o dos dimensiones en el GML. Simplemente coloca el índice entre corchetes cuadrados para un array unidimensional, y los dos índices con una coma entre ellos para los arrays bidimensionales. En el momento en que emplees un índice el array es generado. Cada array inicia en el índice 0. Por lo que debes tener cuidado al usar índices muy grandes ya que se ocupará memoria para un array grande. Nunca emplees índices negativos. El sistema coloca un límite de 32000 para cada índice y 1000000 para el tamaño total. Por ejemplo, puedes escribir lo siguiente:
{ a[0] = 1; i = 1; while (i < 10) { a[i] = 2*a[i-1]; i += 1;} b[4,6] = 32; }
Sentencia If Una sentencia If tiene esta forma
if () o
if () else
La sentencia también puede ser un bloque. La expresión se evaluará. Si el valor (redondeado) es <=0 (false) se ejecuta la sentencia después del else, de otra forma (true) se ejecuta la otra sentencia. Es un buen hábito colocar siempre corchetes a las sentencias en la sentencia if. Por lo que mejor usa
if () { } else { } Ejemplo El siguiente programa mueve el objeto hacia el medio de la pantalla.
{ if (x<200) {x += 4} else {x -= 4}; }
Sentencia Repeat Una sentencia repeat tiene esta forma
repeat () La sentencia es repetida el numero de veces indicado por el valor redondeado de la expresión.
Ejemplo El siguiente programa crea 5 pelotas en posiciones aleatorias.
{ repeat (5) instance_create(random(400),random(400),pelota); }
Sentencia While Una sentencia While tiene esta forma
while ()
Mientras la expresión sea verdadera, la sentencia (que puede también ser un bloque) es ejecutada. Ten cuidado con tus ciclos while. Puedes fácilmente hacer que se repitan eternamente, en cuyo caso el juego se bloqueará y ya no responderá a los comandos del usuario.
Ejemplo El siguiente programa trata de colocar el objeto actual en una posición libre (esto es casi lo mismo que la acción para mover un objeto a una posición aleatoria).
{ while (!place_free(x,y)) { x = random(room_width); y = random(room_height); } }
Sentencia Do La sentencia Do tiene esta forma:
do until()
La sentencia (que puede también ser un bloque) es ejecutada hasta que la expresión sea verdadera. La sentencia se ejecuta por lo menos una vez. Ten cuidado con los ciclos do. Puedes fácilmente crear uno que se repita indefinidamente, en cuyo caso el juego se bloqueará y ya no responderá a los eventos generados por el usuario.
Ejemplo El siguiente programa intenta colocar el objeto actual en una posición libre (esto es lo mismo que mover un objeto en una posición aleatoria)
{ do { x = random(room_width); y = random(room_height); } until (place_free(x,y))
}
Sentencia For Una sentencia For tiene esta forma:
for ( ; ;)
Funciona de la manera siguiente. Primero se ejecuta la sentencia1. Entonces se evalúa la expresión. Si es verdadera, se ejecuta la sentencia3; entonces la sentencia2 y luego se evalúa nuevamente la expresión. Esto continúa hasta que la expresión sea falsa.
Puede sonar complicado. Debes interpretarlo de la manera siguiente. La primera sentencia inicializa el ciclo for. La expresión prueba si el ciclo debiera terminar. La sentencia2 es la sentencia de paso hacia la evaluación del siguiente ciclo.
El uso más común es para llevar un contador hasta cierto valor.
Ejemplo El siguiente programa inicializa un array llamada “lista” de longitud 10 con los valores 1-10.
{ for (i=0; i<=9; i+=1) lista[i] = i+1; }
Sentencia Switch En ciertas situaciones querrás llevar a cabo alguna acción dependiendo de un valor en particular. Puedes lograrlo empleando varias sentencias if pero es más sencillo si empleas la sentencia switch. Una sentencia switch tiene la siguiente forma:
switch () { case : ; ... ; break; case : ; ... ; break; ... default: ; ... }
Funciona así: primero se ejecuta la expresión. Después se compara con los resultados de las diferentes expresiones delante de las sentencias case. La ejecución continúa después de la sentencia case con el valor correcto, hasta que se encuentre una sentencia break. Si no se encuentra una sentencia case con el valor correcto, la ejecución continúa después de la sentencia default. (No es necesaria la sentencia default. Nota que se pueden colocar múltiples sentencias case para la misma sentencia. También, no es necesaria la sentencia break. Si no existe una sentencia break, la ejecución simplemente continúa con el código para la siguiente sentencia case.
Ejemplo El siguiente programa lleva a cabo una acción según la tecla que se presione.
switch (keyboard_key) { case vk_left: case vk_numpad4: x -= 4; break; case vk_right: case vk_numpad6: x += 4; break; }
Sentencia Break La sentencia Break tiene esta forma:
break Si se emplea en un ciclo for, while, repeat, en una sentencia switch o with, finaliza el ciclo o sentencia. Si es empleada fuera de una de estas sentencias finaliza el programa no el juego).
Sentencia Continue La sentencia Continue tiene esta forma
continue
Si se emplea dentro de un ciclo for, while, repeat o con una sentencia with, continua con el siguiente valor del ciclo for o de la sentencia with.
Sentencia Exit La sentencia Exit tiene esta forma:
exit
Simplemente termina la ejecución del programa/script actual. (¡No termina la ejecución del juego! Para ello necesitas la función game_end(); ver más abajo)
Funciones Una función tiene la siguiente estructura: nombre de la función, seguido por uno o varios argumentos entre paréntesis, separados por comas (también puede no incluir ningún argumento).
(,,...) Hay dos tipos de funciones. En primer lugar, tenemos una gran cantidad de funciones internas, para controlar todos los aspectos del juego. Después, cualquier scipt que definas en el juego puede ser usado como una función.
Nota que para una función sin argumentos aún se necesitan los paréntesis. Algunas funciones devuelven valores y pueden ser empleadas en expresiones. Otras simplemente ejecutan órdenes.
Nota que es imposible usar una función como el lado izquierda de una asignación. Por ejemplo, no puedes escribir
instante_nearest(x,y,obj).speed = 0.
escribir
(instance_nearest(x,y,obj)).speed = 0.
En lugar, debes
Scripts
Cuando creas un script, querrás tener acceso a los argumentos enviados a él (ya sea cuando uses una acción script, o cuando llames al script como una función desde un programa u otro, o inclusive desde el mismo script). Estos argumentos se almacenan en las variables argument0, argument1, …, argument15. Por lo que puede haber como máximo 16 argumentos. (Nota: cuando se llama un script desde una acción, sólo se pueden especificar los primeros 5 argumentos). Pueden usar también argument[0], etc.
Los scripts también pueden devolver un valor, por lo que pueden ser empleados en expresiones. Para ello debes emplear la sentencia return:
return ¡La ejecución del script termina en la sentencia return!
Ejemplo Aquí esta la definición de un script que calcula el cuadrado del argumento:
{ return (argument0*argument0); }
Para llamar un script desde una pieza de código, solo hazlo como cuando se hacen las llamadas a funciones. Esto es, escribe el nombre del script con sus argumentos entre paréntesis.
Construcciones With
Como se indicó antes, es posible leer y cambiar el valor de las variables en otras instancias. Pero en ciertos casos querrás hacer mucho más con esas otras instancias. Por ejemplo, imagina que deseas mover todas las pelotas 8 píxeles hacia abajo. Pudieras pensar que eso se logra con el siguiente código
pelota.y = pelota.y + 8; Pero no es correcto. El valor a la derecha de la asignación obtiene la coordenada y de la primera pelota y le suma 8. Entonces este nuevo valor se toma como la coordenada y para todas las pelotas. Por lo que el resultado es que todas las pelotas tienen la misma coordenada y. La sentencia
pelota.y += 8; tendrá exactamente el mismo efecto porque es simplemente una abreviatura de la primera declaración. Entonces, ¿cómo logramos esto? Para ello existe la declaración with. Su forma general es
with () indica una o más instancias. Para esto puedes emplear el id de la instancia, o el nombre de un objeto (para indicar todas las instancias de este objeto) o uno de los objetos especiales (all, self, other, noone). se ejecuta para cada una de las instancias indicadas, como si la instancia fuera la instancia (self) actual. Así, para mover todas las pelotas 8 píxeles hacia abajo, puedes escribir
with (pelota) y += 8;
Si deseas ejecutar múltiples declaraciones, colócalas entre corchetes. Por ejemplo, para mover todas las pelotas a una posición aleatoria, puedes usar
with (pelota) { x = random(room_width); y = random(room_height); }
Nota que, dentro de las sentencias, la instancia indicada se ha vuelto la instancia self. Entonces, la instancia self original ahora es la instancia other. Así, por ejemplo, para mover todas las pelotas a la posición de la instancia actual, puedes usar
with (pelota) { x = other.x; y = other.y; }
El uso de la declaración with es muy poderoso. A continuación te muestro unos cuantos ejemplos más. Para destruir todas las pelotas usas
with (pelota) instance_destroy(); Si una bomba explota y tu quieres destruir todas las instancias cercanas a ella puedes usar
with (all) { if (distance_to_object(other) < 50) instance_destroy(); }
Comentarios Puedes agregar comentarios a tus programas. Todo en una línea después de // no se ejecuta. Puedes hacer también una multi-línea de comentarios colocando el texto entre /* y */.
Funciones y variables en GML
El GML contiene un gran número de funciones y variables internas. Con ellas puedes controlar cualquier parte del juego. Para todas las acciones existe una función correspondiente por lo que de hecho no necesitas emplear ninguna acción si prefieres emplear código. Pero hay muchas más funciones y variables que controlan aspectos del juego que no se pueden acceder sólo empleando acciones. Por lo que si deseas crear juegos más avanzados se te recomienda leer los siguientes capítulos para tener un panorama general de todo lo que es posible lograr. Por favor nota que estas variables y funciones pueden también emplearse cuando se envían valores para las acciones. Por lo que aún si no planeas emplear código o escribir algún script, aún obtendrás beneficios de esta información.
En los capítulos siguientes se emplean las siguientes convenciones. Los nombres de variables marcados con un * son sólo de lectura, es decir, no se puede cambiar su valor. Los nombres de variables con [0...n] después de ellos son arrays. Se da el intervalo posible de sus índices.
Haciendo cálculos Game Maker contiene un gran número de funciones para realizar determinadas tareas. Aquí tienes una lista completa de estas funciones.
Esta sección está dividida en los temas: Constantes Funciones de valores reales Funciones de cadenas de texto Trabajando con el tiempo y la fecha
Constantes Game Maker incluye las siguientes constantes matemáticas:
true equivale a 1. false
equivale a 0.
pi equivale a 3.1415...
Funciones de valores reales Estas son las funciones disponibles para trabajar con números reales:
random(x) Devuelve un valor entre 0 y X. El valor devuelto es siempre menor que X. choose(val1,val2,val3,...) Devuelve uno de argumentos de forma aleatoria. La función acepta un máximo de 16 argumentos.
abs(x) Devuelve el valor absoluto de X. sign(x) Devuelve el signo de X (-1, 0 o 1). round(x) Devuelve el valor de X
redondeado al valor entero más cercano.
floor(x) Devuelve el valor de X redondeado hacia abajo. ceil(x) Devuelve el valor de X redondeado hacia arriba. frac(x) Devuelve la parte fraccional de X, sqrt(x) Devuelve la raíz cuadrada de X.
que es la parte situada tras el punto decimal.
El valor no debe ser negativo.
sqr(x) Devuelve el cuadrado de X. power(x,n) Devuelve X elevado a la potencia N. exp(x) Devuelve
E elevado a X.
ln(x) Devuelve el logaritmo neperiano (natural) de X. log2(x) Devuelve el logaritmo en base 2 de X. log10(x) Devuelve el logaritmo en base 10 de X. logn(n,x) Devuelve el logaritmo en base N de X.
sin(x) Devuelve el seno de X (X en radianes). cos(x) Devuelve el coseno de X (X en radianes). tan(x) Devuelve la tangente de X (X en radianes). arcsin(x) Devuelve el arcoseno de X. arccos(x) Devuelve el arcocoseno de X. arctan(x) Devuelve la arcotangente de X. arctan2(y,x)
Calcula la arcotangente de (Y/X), y devuelve un ángulo en el cuadrante correcto.
degtorad(x) Convierte grados a radianes. radtodeg(x) Convierte radianes a grados. min(val1,val2,val3,...) Devuelve el menor de los valores. La función soporta 16 argumentos. Deben ser todos números reales o cadenas de texto.
max(val1,val2,val3,...) Devuelve el mayor de los valores. La función soporta 16 argumentos. Deben ser todos números reales o cadenas de texto.
mean(val1,val2,val3,...) Devuelve el promedio de los valores. La función soporta 16 argumentos. Deben ser todos números reales.
median(val1,val2,val3,...) Devuelve el valor intermedio de los argumentos introducidos. (Cuando el número de argumentos es parejo, el menor de los dos valores intermedios, es el que devuelve la función. La función soporta 16 argumentos. Deben ser todos números reales.
point_distance(x1,y1,x2,y2) Devuelve la distancia existente entre el punto situado en (x1,y1) y el situado en (x2,y2). point_direction(x1,y1,x2,y2) Devuelve la dirección desde el punto (x1,y1) hacia el punto (x2,y2) en grados. lengthdir_x(len,dir) Devuelve la componente horizontal (x) del vector determinado por lengthdir_y(len,dir) Devuelve la componente vertical (y) del vector determinado por is_real(x) Averigua cuando X es un valor real.
la longitud y dirección indicadas.
la longitud y dirección indicadas.
(diferenciándolo de una cadena de texto).
is_string(x) Averigua cuando X es una cadena de texto.
(diferenciándolo de un número real).
Funciones de cadenas de texto Estas son las funciones disponibles para trabajar con cadenas de texto:
chr(val) Devuelve una cadena con el carácter al que hace referencia el código asci VAL. ord(str) Devuelve el código asci del primer carácter de la cadena de texto STR. real(str) Convierte una cadena de texto
en un número real. STR puede contener signos negativos, puntos decimales o una parte
exponencial.
string(val) Convierte el número real en una cadena de texto utilizando el formato estándar (sin decimales cuando se trata de un número entero y un máximo de dos dígitos decimales en cualquier otro caso).
string_format(val,tot,dec) Convierte VAL en una cadena de texto utilizando nuestro propio formato: TOT indica el máximo de dígitos y DEC el número de dígitos decimales.
string_length(str) Devuelve el número de caracteres de la cadena.
string_pos(substr,str) Devuelve la posición de SUBSTR en STR (0 No encontrado). string_copy(str,index,count) Devuelve una subcadena de STR, partiendo de la posición INDEX y de una longitud definida por COUNT.
string_char_at(str,index) Devuelve el carácter
situado en la posición INDEX de la cadena STR.
string_delete(str,index,count) Devuelve una copia de la cadena STR con una parte borrada, que empieza en INDEX y de una longitud definida por COUNT.
string_insert(substr,str,index) Devuelve una copia de la cadena STR con la subcadena SUBSTR añadida en la posición INDEX.
string_replace(str,substr,newstr) Devuelve una copia de STR con la primera ocurrencia de SUBSTR reemplazada por NEWSTR.
string_replace_all(str,substr,newstr) Devuelve una copia de STR con todas las ocurrencias encontradas de SUBSTR reemplazadas por la subcadena NEWSTR.
string_count(substr,str) Devuelve el número de ocurrencias de la subcadena SUBSTR existentes en STR. string_lower(str) Devuelve una copia en minúsculas de la cadena STR. string_upper(str) Devuelve una copia en mayúsculas de la cadena STR. string_repeat(str,count) Devuelve una cadena con un número de copias de la cadena STR definido por COUNT. string_letters(str) Devuelve una cadena de texto que solo contiene las letras de la cadena STR. string_digits(str) Devuelve una cadena que solo contiene los números de la cadena STR. string_lettersdigits(str) Devuelve una cadena que solo contiene los números y las letras de la cadena STR.
Trabajando con el tiempo y la fecha Game Maker dispone de varias funciones para trabajar con fechas y horas. La fecha y la hora se almacenan como un número real. La parte entera es el número de días que han pasado desde 12/30/1899 y parte decimal de este valor es la fracción de un día de 24 horas que ha transcurrido hasta el momento. Estas son las funciones disponibles:
date_current_datetime()Devuelve fecha y hora actual. date_current_date()Devuelve fecha actual ignorando la hora .date_current_time()Devuelve hora actual ignorando la fecha.
date_create_datetime(year,month,day,hour,minute,second) Crea un valor fecha-hora correspondiente a la fecha y hora indicados.
date_create_date(year,month,day) Crea un valor fecha-hora correspondiente a la fecha indicada. date_create_time(hour,minute,second) Crea un valor fecha-hora correspondiente a la hora indicada. date_valid_datetime(year,month,day,hour,minute,second) Muestra si la hora y fecha indicados son válidos. date_valid_date(year,month,day) Muestra si la fecha indicada es válida. date_valid_time(hour,minute,second) Muestra si la hora indicada es válida. date_inc_year(date,amount) Devuelve una nueva fecha N años después de la fecha indicada. N debe ser un número entero. date_inc_month(date,amount) Devuelve una nueva fecha N meses después de la fecha indicada. N debe ser un número entero.
date_inc_week(date,amount) Devuelve una nueva fecha N semanas después de la fecha indicada. N debe ser un número entero.
date_inc_day(date,amount) Devuelve una nueva fecha N días después de la fecha indicada. N debe ser un número entero. date_inc_hour(date,amount) Devuelve una nueva fecha
N horas después de la fecha indicada. N debe ser un número
entero.
date_inc_minute(date,amount) Devuelve una nueva fecha N minutos después de la fecha indicada. N debe ser un número entero.
date_inc_second(date,amount) Devuelve una nueva fecha N segundos después de la fecha indicada. N debe ser un número entero.
date_get_year(date) Devuelve el año actual. date_get_month(date) Devuelve el mes actual. date_get_week(date) Devuelve la semana actual. date_get_day(date) Devuelve el día actual. date_get_hour(date) Devuelve la hora actual. date_get_minute(date) Devuelve el minuto actual. date_get_second(date) Devuelve el segundo actual. date_get_weekday(date) Devuelve el día de la semana actual. date_get_day_of_year(date) Devuelve el día del año especificado. date_get_hour_of_year(date) Devuelve la hora del año especificado. date_get_minute_of_year(date) Devuelve el minuto del año especificado. date_get_second_of_year(date) Devuelve el segundo del año especificado. date_year_span(date1,date2) Devuelve el número de años que hay entre las dos fechas. Reporta los años incompletos como una fracción.
date_month_span(date1,date2) Devuelve el número de meses que hay entre las dos fechas. Reporta los meses incompletos como una fracción.
date_week_span(date1,date2) Devuelve el número de semanas que hay entre las dos fechas. Reporta las semanas incompletas como una fracción.
date_day_span(date1,date2) Devuelve el número de días que hay entre las dos fechas. Reporta los días incompletos como una fracción.
date_hour_span(date1,date2) Devuelve el número de horas que hay entre las dos fechas. Reporta las horas incompletas como una fracción.
date_minute_span(date1,date2) Devuelve el número de minutos que hay entre las dos fechas. Reporta los minutos incompletos como una fracción.
date_second_span(date1,date2) Devuelve el número de segundos que hay entre las dos fechas. Reporta los segundos incompletos como una fracción.
date_compare_datetime(date1,date2) Compara los dos valores fecha-hora. Devuelve -1, 0, ó 1 dependiendo en si la primera fecha es anterior, igual, o posterior que la segunda.
date_compare_date(date1,date2) Compara los dos valores fecha-hora tomando en cuenta sólo la parte de la fecha. Devuelve -1, 0, ó 1 dependiendo en si la primera es anterior, igual, o posterior que la segunda.
date_compare_time(date1,date2) Compara los dos valores fecha-hora tomando en cuenta sólo la parte de la hora. Devuelve -1, 0, ó 1 dependiendo en si la primera es anterior, igual, o posterior que la segunda.
date_date_of(date) Devuelve la parte de la fecha del valor fecha-hora indicado, estableciendo la hora a 0. date_time_of(date) Devuelve la hora del valor fecha-hora indicado, estableciendo la fecha a 0. date_datetime_string(date) Devuelve una cadena indicando la fecha y hora definidos, en el formato predeterminado para el sistema.
date_date_string(date) Devuelve una cadena indicando la fecha definida en el formato predeterminado para el sistema. date_time_string(date) Devuelve una cadena indicando la hora definida en el formato predeterminado para el sistema. date_days_in_month(date) Devuelve el número de días que hay en el mes indicado. date_days_in_year(date) Devuelve el número de días que hay en el año indicado. date_leap_year(date) Define si el año indicado es un año bisiesto. date_is_today(date) Define si la fecha indicada es la actual.
Game play Hay una gran cantidad de variables y funciones que puedes emplear para definir el game play (jugabilidad). Estas en particular influyen en el movimiento y creación de instancias, el timing, y el manejo de los eventos.
La información sobre el game play se puede encontrar en las siguientes secciones: Moviéndose Paths Planificación del movimiento Detección de colisiones Instancias Desactivando instancias Timing Rooms Score Generando eventos Otras variables y funciones
Moviéndose Obviamente, un aspecto importante de los juegos es el movimiento de las instancias de los objetos. Cada instancia tiene dos variables internas
x e y que indican la posición de la instancia. (Para ser precisos, indican el lugar donde se encuentra el punto de origen del sprite).
La posición (0,0) es la esquina superior izquierda del cuarto. Puedes cambiar la posición de la instancia al cambiar los valores de sus variables
x e y. Es lo que debes hacer si deseas movimientos más complicados. Este código normalmente se coloca en el evento step del
objeto.
Si el objeto se mueve con velocidad y dirección constantes, hay una manera más fácil de lograrlo. Cada instancia tiene una velocidad horizontal (hspeed) y vertical (vspeed). Ambas se indican en píxeles por paso (step). Una velocidad horizontal positiva indica movimiento a la derecha, una velocidad horizontal negativa indica movimiento a la izquierda. La velocidad vertical positiva es movimiento hacia abajo y la negativa indica movimiento hacia arriba. Por lo que sólo debes establecer estos valores una vez (por ejemplo en el evento de creación) para dar al objeto un movimiento constante.
Hay otra manera muy diferente de especificar el movimiento, usando dirección (en grados 0-359), y velocidad (no debe ser negativa). Puedes configurar y leer estas variables para especificar un movimiento arbitrario. (Internamente se convierte a valores de
hspeed y vspeed). También tenemos la fricción y la gravedad, y la dirección de la gravedad.
Finalmente, tenemos la función
motion_add(dir,speed) para agregar movimiento al actual.
Para concluir, cada instancia tiene las siguientes variables y funciones referentes a su posición y movimiento:
x
Su posición x.
y
Su posición y.
xprevious Su posición x anterior. yprevious xstart
Su posición y previa.
Su posición x inicial en el cuarto.
ystart Su posición y inicial en el cuarto. hspeed
Componente horizontal de la velocidad.
vspeed Componente vertical de la velocidad. direction Su dirección actual (0-360, contra las manecillas del reloj, 0 = a la derecha). speed Su velocidad actual (píxeles por step). friction Fricción actual (píxeles por step). gravity Cantidad actual de gravedad (píxeles por paso). gravity_direction Dirección de la gravedad (270 es hacia abajo). motion_set(dir,speed) Establece el movimiento a la velocidad speed y la dirección dir. motion_add(dir,speed) Agrega el movimiento al movimiento actual (como una suma vectorial). Existe un gran número de funciones para ayudarte a definir el movimiento:
place_free(x,y) Devuelve si la instancia colocada en la posición (x, y) está libre de colisión. Normalmente se emplea para revisar antes de mover la instancia a la nueva posición.
place_empty(x,y) Devuelve si la instancia colocada en la posición (x, y) no se encuentra con nadie. Esta función también toma en cuenta las instancias no sólidas.
place_meeting(x,y,obj) Devuelve si la instancia colocada en la posición (x,y) se encuentra con un el objeto obj. obj puede ser un objeto en cuyo caso la función devuelve verdadero si se encuentra con una instancia de ese objeto. También puede ser el instancia, o la palabra especial
id de una
other.
place_snapped(hsnap,vsnap) Devuelve si la instancia está alineada con los valores de snap hsnap y vsnap. move_random(hsnap,vsnap) Mueve la instancia a una posición libre, y la alinea con los valores hsnap y vsnap,
al igual que
la acción correspondiente.
move_snap(hsnap,vsnap) Alinea la instancia, como la acción correspondiente. move_wrap(hor,vert,margin) Teleporta la instancia cuando sale del room al lado opuesto. hor indica si debe teleportarse horizontalmente y
vert indica si debe teleprotarse verticalmente. margin indica cuánto debe salir el origen de la instancia del room
para teleportarse (es decir, un margen alrededor del room). Esta función se usa normalmente el evento Outside.
move_towards_point(x,y,sp) Mueve la instancia con velocidad sp hacia el punto (x,y). move_bounce_solid(adv) Rebotar contra objetos sólidos, como la acción correspondiente. adv indica si se emplea rebote avanzado, que toma en cuenta las paredes inclinadas.
move_bounce_all(adv) Rebotar contra todas las instancias, en lugar de sólo con las sólidas. move_contact_solid(dir,maxdist) Mover la instancia en la dirección dir hasta que haya contacto con un objeto sólido. Si no hay collision en la posición actual, la instancia es colocada justo antes de donde ocurre una colisión. Si ya hay una colisión en la posición actual, la instancia no se mueve. Puedes especificar la distancia máxima a mover la instancia maxdist (emplea un número negativo para indicar distancia arbitraria).
move_contact_all(dir,maxdist) Igual que la función anterior pero esta vez se detiene hasta que haya contacto con cualquier objeto, no solo sólidos.
move_outside_solid(dir,maxdist) Mueve la instancia en la dirección dir hasta que no esté al alcance de un objeto sólido. Si no hay collision en la posición actual, no se mueve la instancia. Puedes especificar la distancia máxima a mover (usa un valor negativo para indicar una distancia arbitraria).
move_outside_all(dir,maxdist) Igual que la anterior pero se mueve hasta estar fuera de alcance de cualquier objeto, no solo objetos sólidos.
distance_to_point(x,y) Devuelve la distancia de la caja límite de la instancia actual hacia el punto (x,y). distance_to_object(obj) Devuelve la distancia de la instancia actual a la instancia más cercana del objeto obj. position_empty(x,y) Indica si no hay nada en la posición (x,y). position_meeting(x,y,obj) Indica si en la posición (x,y) hay una instancia obj. obj puede ser un objeto, una id de una instancia, o las palabras clave
self, other o all.
Paths En Game Maker puedes definir caminos o trayectorias (paths) y ordenar a las instancias que los sigan. Aunque puedes usar las acciones para esto, existen funciones que te dan más flexibilidad:
path_start(path,speed,endaction,absolute) Comienza un path para la instancia actual. path path que deseas iniciar.
speed es la velocidad
instancia se moverá al revés sobre el path).
es el nombre del
con la que la instancia debe moverse por el path (una velocidad negativa indica que la
endaction indica que debería ocurrir cuando la instancia llegue al final del camino. Puedes
usar los siguientes valores para esto: 0 : parase 1: continuar desde la posición inicial del path (s el path no está cerrado saltamos a la posición inicial) 2: continuar desde la posición inicial 3: recorrer el path al revés (cambia el signo de la velocidad) El argumento
absolute debe ser true o false. Cuando es true se usan las coordenadas absolutas del path. Cuando es false el path es
relativo a la posición actual de la instancia. Para ser más precisos, si la velocidad es positiva el punto inicial del path se colocará en la posición actual de la instancia y se seguirá desde ahí. Cuando la velocidad es negativa, el punto final del path se colocará en la posición de la instancia y el path se seguirá al revés desde ahí.
path_end() Termina el path para la instancia actual. path_index* Índice del path que la instancia sigue. No se puede cambiar directamente, debes utilizar la
función
path_start(path,speed,endaction,absolute).
path_position Posición en el path actual. 0 es el principio del path y 1 es el final. Los valores deben estar entre 0 y 1. path_positionprevious Posición previa en el path. Esto se puede usar en eventos de colisión para colocar la instancia en la posición anterior antes de una colisión.
path_speed Velocidad (en píxels por paso) con la que la instancia sigue el path. Con una velocidad negativa el path se recorre en sentido inverso.
path_orientation Orientación (antihoraria) en la que se realiza el path. 0 es la orientación normal del path. path_scale Escala del path. Auméntala para hacer el path más grande. 1 es el valor normal del path. path_endaction La acción que se debe ejecutar al finalizar el path. Puedes indicar los valores explicados más arriba.
Planificación del movimiento La planificación del movimiento te ayuda a mover una instancia de un punto a otro esquivando otras instancias que pudiera encontrarse por el camino (por ejempo, paredes). Resulta imposible dar funciones generales que funcionen en cualquier situación. Así mismo, las operaciones necesarias para calcular un camino libre de colisiones consumen bastantes recursos, así que debes usar estas funciones con criterio. Ten todo esto en cuenta cuando uses las siguientes funciones.
Game Maker dispone de diferentes formas de planificar el movimiento. La más simple consiste en hacer que una instancia de un paso hacia la posición final, intentando ir en línea recta pero tomando otra dirección si esto último resulta imposible. Estas funciones deben usarse en el evento step de la instancia y se corresponden a las acciones ya comentadas:
mp_linear_step(x,y,stepsize,checkall) Esta función hace que la instancia de un paso hacia la posición (x,y). La longitud del paso se indica con el parámetro
stepsize. Si la instancia ya ha llegado a esa posición no se moverá. Si checkall es
true la instancia se parará cuando choque con una instancia de cualquier objeto. Si es false, sólo se parará al chocar con un objeto sólido. Esta función no propone un camino alternativo, simplemente se parará si encuentra un obstáculo. La función devuelve si se ha alcanzado el destino.
mp_linear_step_object(x,y,stepsize,obj) Igual que la anterior, pero esta vez sólo se tienen en cuenta las instancias del objeto
obj. obj puede ser un objeto o una id de una instancia particular.
mp_potential_step(x,y,stepsize,checkall) Igual que las anteriores, pero en este caso la instancia intentará esquivar los obstáculos que encuentre. Cuando la instancia se choque con un obstáculo cambiará su dirección para tratar de esquivar el objeto, moviéndose alrededor de él. Puede que no siempre se consiga llegar a la meta, pero la función siempre intentará acercar lo más posible a la instancia. Devuelve true si se llega a la meta.
mp_potential_step_object(x,y,stepsize,obj) ) Igual que la anterior, pero esta vez sólo se tienen en cuenta las instancias del objeto
obj. obj puede ser un objeto o una id de una instancia particular.
mp_potential_settings(maxrot,rotstep,ahead,onspot) La función anterior hace su trabajo usando un número de parámetros que pueden ser cambiados con esta función. El método funciona como sigue: primero la instancia intenta moverse en línea recta hacia la meta. Para ello, mira un número de pasos adelante para ver si hay algún obstáculo. Este número de pasos corresponde al
valor
ahead (por defecto 3). Reduciendo este valor la instancia comenzará a cambiar su dirección más tarde si encuentra un obstáculo.
Aumentándolo cambiará antes de dirección. Si detectamos una colisión, la función mira a la derecha y a la izquierda para encontrar un camino libre. Esto se realiza en pasos de tamaño
rotstep(por defecto 10). Reduciéndolo conseguimos que la instancia tenga más
posibilidades para moverse pero la función será más lenta. El parámetro
maxrot
(por defecto 30) indica cuánto puede cambiar como
máximo la dirección en un paso. Así que aunque pueda moverse en línea recta hacia la meta no lo hará si debe girar más de lo indicado por este parámetro. Aumentándolo conseguimos que la instancia pueda girar más en cada paso, haciendo que sea más fácil encontrar un camino aunque éste será menos uniforme. Disminuyendo su valor el camino será más suave pero la instancia realizará giros más largos, haciendo que a veces no pueda llegar exactamente a la meta. Cuando la instancia no se puede mover en ninguna dirección el comportamiento dependerá del valor de por
onspot. Si onspot es true la instancia rotará en su posición la cantidad indicada
maxrot. Si es false se parará (esto es útil para coches, por ejemplo, pero reduce las posibilidades de encontrar un camino hacia la
meta).
Observa que el acercamiento potencial sólo usa información local. Así que sólo encontrará un camino si la información es suficiente para determinar la dirección correcta. Por ejemplo, normalmente no podrá encontrar el camino para escapar de un laberinto.
El segundo tipo de funciones calcula un camino libre colisiones. Una vez que el camino se ha calculado puedes asignárselo a la instancia para que se mueva hacia la meta como si fuera un path normal que tú hubieras creado. El cálculo del camino tarda un poco pero una vez hecho la ejecución del path es muy rápida. Por supuesto, esto es válido si la situación no cambia (por ejemplo, si los obstáculos se mueven). Entonces necesitarás volver a calcular el path. De nuevo, estas funciones pueden fallar en algunas circunstancias. Estas funciones sólo están disponibles en la versión registrada de Game Maker.
Las dos primeras funciones usan el acercamiento por movimiento lineal y potencial que se usan en las funciones anteriores.
mp_linear_path(path,xg,yg,stepsize,checkall) Calcula un path en línea recta para la instancia desde su posición hasta (xg,yg) usando el paso especificado en
stepsize. Usa pasos como en la funciónmp_linear_step(). El path indicado debe
existir con anterioridad a la llamada de la función y será sobreescrito por el nuevo path (consulta el capítulo sobre cómo crear y destruir paths). La función devuelve si se ha encontrado un path. Si no consigue encontrar un camino, la función devolverá un path hasta la posición donde la instancia quedó bloqueada.
mp_linear_path_object(path,xg,yg,stepsize,obj) Igual que la anterior, pero esta vez sólo se tienen en cuenta las instancias del objeto
obj. obj puede ser un objeto o una id de una instancia particular.
mp_potential_path(path,xg,yg,stepsize,factor,checkall) Esta función calcula un camino para instancia desde su posición actual y orientación hasta (xg,yg) usando el paso especificado en obstáculos. Utiliza pasos potenciales como la función con
stepsize e intentando evitar colisionar con los
mp_potential_step() y los parámetros se pueden configurar
mp_potential_settings(). El path indicado debe existir con anterioridad a la llamada de la función y será sobreescrito por
el nuevo path (consulta el capítulo sobre cómo crear y destruir paths). La función devolverá si se ha encontrado un camino. Para evitar que la función continúe calculando para siempre debes especificar unfactor mayor que 1. La función se detendrá y devolverá un mensaje de error si no puede encontrar un camino que sea más corto que la distancia del origen a la meta multiplicada por
factor. Un factor de
4 es normalmente suficiente pero si crees que la instancia tendrá un camino largo puedes aumentarlo. Si la función falla se crea el camino
en dirección a la meta pero la instancia no llegará la meta.
mp_potential_path_object(path,xg,yg,stepsize,factor,obj) Igual que la anterior, pero esta vez sólo se tienen en cuenta las instancias del objeto
obj. obj puede ser un objeto o una id de una instancia particular.
Las demás funciones usan un mecanismo mucho más complejo basado en rejillas (un algoritmo A*). Tiene más sexito a la hora de encontrar caminos y hacerlos más cortos, pero requiere más trabajo por tu parte. Además, también puede fallar en algunas ocasiones. El funcionamiento es como sigue: primero situamos una rejilla sobre la parte del cuarto afectada. Puedes usar si quieres usar una rejilla fina (más lento) o más espaciada. Después, determinamos las celdas de la rejilla ocupadas por objetos relevantes (usando colisión precisa o la caja de contorno) y marcamos estas celdas como prohibidas. Así que una celda estará prohibida si parte de un obstáculo la está ocupando. Finalmente especificamos la posición inicial y final, que deben estar en celdas libres de la rejilla y la función calcula el camino más corto entre ellas. El camino irá de centro a centro de las celdas libres. Así que las celdas deben ser lo suficientemente grandes como para que la instancia entre totalmente dentro de ellas. Ahora puedes asignar el path a una instancia y hacer que lo siga.
Este sistema es muy potente (se usa en muchos juegos profesionales) pero requiere que lo planifiques con cuidado. Debes determinar la zona del cuarto sobre la que situar la rejilla y el tamaño de las celdas con la mayor precisión posible. También debes decidir qué objetos deben tomarse en cuenta y si es necesaria la colisión precisa o no. Todos estos parámetros afectan de manera muy notable a la eficiencia del método.
En particular, el tamaño de las celdas es crucial. Recuerda que las celdas deben lo suficientemente grandes como para que la instancia que se mueve entre totalmente dentro de ellas (ten cuidado con la posición del origen de la instancia y recuerda que puedes mover el path para hacer que el centro del objeto coincida con el centro de la celda). Por otro lado, cuanto menores sean las celdas más caminos diferentes podrás encontrar. Si haces las celdas demasiado grandes puede que unos pocos objetos ocupen todas las celdas cerrando todos los caminos posibles.
Las funciones para el método de rejilla son:
mp_grid_create(left,top,hcells,vcells,cellwidth,cellheight) Esta función crea la rejilla. Devuelve un índice que debe ser usado en las demás funciones. Puedes crear y mantener varias rejillas al mismo tiempo.left y posición de la esquina superior izquierda de la rejilla y respectivamente. Finalmente,
top indican la
hcells y vcells indican el número de celdas horizontales y verticales
cellwidth y cellheight indican la anchura y altura de las celdas.
mp_grid_destroy(id) Destruye la rejilla indicada y libera la memoria usada. No olvides llamar a esta función cuando no necesites usar más la rejilla.
mp_grid_clear_all(id) Marca todas las celdas como libres. mp_grid_clear_cell(id,h,v) Marca la celda indicada como libre (la primera celda es la 0,0). mp_grid_clear_rectangle(id,left,top,right,bottom) Marca como libres todas las celdas que intersectan el rectángulo definido en coordenadas absolutas del cuarto.
mp_grid_add_cell(id,h,v) Marca ls celdas indicadas como prohibidas. mp_grid_add_rectangle(id,left,top,right,bottom) Marca todas las celdas que intersectan el rectángulo como prohibidas.
mp_grid_add_instances(id,obj,prec) Marca todas las celdas que intersectan una instancia del objeto indicado como prohibidas. También puedes especificar una id de una instancia concreta, o la palabra clave instancias.
all para indicar todas las
prec indica si hay que usar colisión precisa (sólo funcionará si en el sprite de la instancia está activada la misma opción).
mp_grid_path(id,path,xstart,ystart,xgoal,ygoal,allowdiag) Calcula el path a través de la rejilla. El path indicado debe existir con anterioridad a la llamada de la función y será sobreescrito por el nuevo path (consulta el capítulo sobre cómo crear y destruir paths). meta.
xstart e ystart indican el comienzo del path y xgoal e ygoal las coordenadas de la
allowdiag indica si se permiten movimientos diagonales entre celdas o sólo horizontales y verticales. La función devuelve si
consiguió calcular un path (observa que el path es independiente de la instancia actual).
mp_grid_draw(id) Esta función dibuja la rejilla marcando las celdas libres y prohibidas (muy útil para buscar errores).
Detección de colisiones Al planificar movimientos o decidir ciertas acciones es importante comprobar si ocurren colisiones con otras instancias en otras posiciones. Las funciones siguientes se utilizan para esto. Todas ellas tienen 3 argumentos en común: el argumento palabra clave
objpuede ser un objeto, la
all, o la id de una instancia. El argumento prec indica si se debe usar colisión precisa o la caja de contorno de la instancia
(la colisión precisa sólo funciona si el sprite de la instancia tiene activada la misma opción). El argumento
notme indica si no se debe tener
en cuenta a la instancia que llama a la función. Todas estas funciones devuelven la id de una de las instancias con las que se detecta colisión. Si no hay colisión devuelven un valor negativo.
collision_point(x,y,obj,prec,notme) Comprueba si hay una colisión en el punto (x,y) con instancias del objeto obj. collision_rectangle(x1,y1,x2,y2,obj,prec,notme) Comprueba si hay una colisión con las esquinas indicadas e instancias del objeto
obj. Por ejemplo, puedes usar esta función para ver si un área está libre de obstáculos.
collision_circle(xc,yc,radius,obj,prec,notme) Comprueba si hay una colisión con centro (xc,yc) y radio r e instancias del objeto
entre la elipse (sólida) con las
obj.
collision_line(x1,y1,x2,y2,obj,prec,notme) Comprueba si hay una colisión (x2,y2) e instancias del objeto
entre la circunferencia (sólido)
obj. Puedes usar esta función para ver si un objeto está cerca de una posición.
collision_ellipse(x1,y1,x2,y2,obj,prec,notme) Comprueba si hay una colisión esquinas indicadas e instancias del objeto
entre el rectángulo (sólido)
entre la línea que va de (x1,y1) a
obj. Esta función es muy poderosa. Puedes usarla para comprobar si una instancia puede ver a otra
chequeando si entre ellas hay una pared.
Instancias Las unidades básicas del juego son las instancias. Durante el juego, puedes cambiar varios aspectos de estas instancias. También puedes crear o destruir instancias. Además de las variables de movimiento y las de dibujo cada instancia posee las siguientes variables:
object_index* Índice del objeto del cual ésta es una instancia. No se puede cambiar. id* La id única de la instancia (>= 100000) (Al definir cuartos la id de la instancia bajo el puntero del ratón es indicada). No se puede cambiar.
mask_index Índice de l sprite usado como máscara para las colisiones. Si indicas -1 la máscara será igual al sprite de la instancia. solid Indica si la instancia es sólida o no. persistent Indica si la instancia es persistente y reaparecerá al moverse a otro cuarto. A veces puedes querer volver a ponerlo a 0 (por ejemplo, al volver al primer cuarto).
Al trabajar con instancias hay un problema: no es fácil identificar una instancia concreta. No tienen un nombre. Cuando sólo hay una instancia de un objeto puedes acceder a ella usando el nombre del objeto pero normalmente necesitas conocer la id de la instancia. Este identificador único se puede usar en construcciones with y para identificar la instancia. Afortunadamente, las siguientes variables te ayudan a localizar la id de una instancia:
instance_count* Número de instancias que existen en el cuarto. instance_id[0..n-1]* La id de la instancia número n. Observa que la asignación de las instancias al
instance_id[] cambia en cada step, así que debes actualizar este valor. Por ejemplo:
imagina que cada unidad en tu juego tiene un poder y quieres encontrar la más poderosa de todas. Puedes hacerlo con el siguiente código:
{ maxid = -1; maxpower = 0; for (i=0; i maxpower) {maxid = iii; maxpower = iii.power;} } } } Después del bucle maxid contendrá la id de la instancia más podersa (No destruyas instancias durante un bucle como éste porque se eliminarán inmediatamente y te saltarás instancias existentes).
instance_find(obj,n) Devuelve la id de la instancia n+1 de tipo obj. obj puede ser un objeto o la palabra clave all. Si no existe se devuelve el objeto especial
noone. Recuerda que el orden de las instancias cambia en cada step así que no puedes usar valores
de steps anteriores.
instance_exists(obj) Devuelve si existe alguna instancia del objeto obj. obj puede ser un objeto, la id de una instancia palabra clave
o la
all.
instance_number(obj) Devuelve el número de instancias de tipo obj. obj puede ser un objeto o la palabra clave all. instance_position(x,y,obj) Devuelve la id de la instancia de tipo obj en la posición (x,y). Cuando hay varias instancias en esa posición se devuelve la id de la prtimera. especial
obj puede ser un objeto o la palabra clave all. Si no existe se devuelve el objeto
noone
instance_nearest(x,y,obj) Devuelve la id de la instancia de tipo obj que esté más cercana en ese momento a (x,y).
obj puede ser un objeto o la palabra clave all.
instance_furthest(x,y,obj) Devuelve la id de la instancia de tipo obj que esté más lejana en ese momento a (x,y).
obj puede ser un objeto o la palabra clave all.
instance_place(x,y,obj) Devuelve la id de la instancia de tipo obj encontrada cuando la instancia actual se coloca en la posición (x,y).
obj puede ser un objeto o la palabra clave all. Si no existe se devuelve el objeto especialnoone.
Las siguientes funciones se usan para crear y destruir instancias:
instance_create(x,y,obj) Crea una instancia de obj en la posición (x,y). La función devuelve la id de la nueva instancia creada.
instance_copy(performevent) Crea una copia de la instancia actual. El argumento indica si se debe ejecutar el evento create en la nueva instancia. La función devuelve la id de la nueva copia.
instance_destroy() Destruye la instancia actual. instance_change(obj,perf) Cambia la instancia a una del tipo obj. perf indica si se deben ejecutar los eventos de destrucción y creación.
position_destroy(x,y) Destruye toda las instancias cuyo sprite pasa por el punto (x,y). position_change(x,y,obj,perf) Cambia todas las instancias en la posición indicada a otras del tipo obj. perf indica si se deben ejecutar los eventos de destrucción y creación.
Desactivando instancias Cuando creas un cuarto muy grande, por ejemplo en juegos de plataformas, con una vista (view) muy pequeña, muchas instancias se quedan fuera de la vista. Aunque no sean visibles, estas instancias siguen ejecutando sus eventos. También, al efectuar chequeos de colisión son tomadas en cuenta. Esto puede hacer que el juego se ralentice. Para remediar esto, Game Maker contiene unas funciones para desactivar o activar instancias. Pero antes de usarlas debes entender cómo funcionan.
Cuando desactivas instancias es como si las eliminaras del juego. No son visibles, no ejecutan sus eventos,…así que para todas las funciones y acciones estas instancias ya no existen y no son tomadas en cuenta. Así consigues que el juego sea más rápido. Pero ten cuidado, ya que
esto puede generar errores en tu juego. Por ejemplo, al eliminar todas las instancias de un objeto, las instancias que estén desactivadas no serán eliminadas! Así, una llave que recoja el jugador no podrá abrir una puerta que esté desactivada, por ejemplo.
El error más crucial que puedes hacer es el de desactivar la instancia que se encarga de activar las demás instancias. Para evitar esto algunas funciones permiten especificar si la instancia que desactiva a las demás debe ser desactivada o no.
Las rutinas disponibles son las siguientes:
instance_deactivate_all(notme) Desactiva todas las instancias del cuarto. Si notme es true la instancia actual no es desactivada (normalmente es lo que se desea).
instance_deactivate_object(obj) Desactiva todas las instancias en el cuarto del objeto especificado. También puedes indicar
all para desactivar todas las instancias o la id de una instancia concreta para desactivarla.
instance_deactivate_region(left,top,width,height,inside,notme) Desactiva todas las instancias en la región indicada (es decir, todas aquellas cuya caja de contorno está parcial o completamente dentro de la región indicada). Si
inside es igual a false las instancias completamente fuera de la región son desactivadas. Si notme es true la instancia actual no es
desactivada (normalmente es lo que se desea).
instance_activate_all() Activa todas las instancias del cuarto. instance_activate_object(obj) Activa todas las instancias en el cuarto del objeto especificado. También puedes indicar
all para activar todas las instancias o la id de una instancia concreta para activarla.
instance_activate_region(left,top,width,height,inside) Activa las instancias dentro de la región especificada. Si
inside es false las instancias fuera de la región son activadas.
Por ejemplo, para desactivar todas las instancias fuera de la vista y activar las que estén dentro podemos poner este código en el evento step del personaje del jugador:
{ instance_activate_all(); instance_deactivate_region(view_xview[0],view_yview[0], view_wview[0],view_hview[0],false,true); } Normalmente es mejor usar una región ligeramente mayor que la vista.
Timing
Los buenos juegos requirieron de cuidado especial de los tiempos en que las cosas se llevaban a cabo (timing). Afortunadamente el Game Maker se ocupa de la mayor parte del timing por ti. Se asegura de que las cosas ocurran con un ritmo constante. Este ritmo es definido al definir los cuartos. Pero puedes cambiarlo usando la variable global room_speed. Así por ejemplo, puedes incrementar lentamente la velocidad del juego, haciéndolo más difícil, agregando una muy pequeña cantidad (como 0.001) a room_speed en cada step. Si tu máquina es lenta la velocidad del juego pudiera no alcanzarse. Esto puede comprobarse usando la variable fps que monitorea constantemente el número actual de cuadros por segundo. Finalmente, para un timing avanzado puedes usar la variable current_time que te da el número de milisegundos desde que la computadora fue iniciada. Aquí está la colección completa de variables disponibles (sólo la primera puede ser cambiada):
room_speed Velocidad del juego en el cuarto actual (en steps por segundo). fps* Número de cuadros que son dibujados por segundo. current_time* Número de milisegundos que han pasado desde que el sistema fue iniciado. current_year* El año actual. current_month* El mes actual. current_day* El día actual. current_weekday* El día actual de la semana (1=domingo, …, 7=sábado). current_hour* La hora actual. current_minute* El minuto actual. current_second* El segundo actual.
Algunas veces querrás detener el juego por un corto periodo. Para esto, usa la función sleep:
sleep(numb) Pausa el juego durante numb milisegundos.
Como debes saber, cada instancia tiene 12 diferentes alarmas que puedes configurar. Para cambiar los valores (u obtener los valores) de las diferentes alarmas usa la siguiente variable:
alarm[0..11] Valor de la alarma indicada. (Nota: ¡las alarmas solo se actualizan cuando el evento de alarma para el objeto contiene acciones!)
Hemos visto que para los problemas de un timing complejo puedes usar el recurso de las líneas de tiempo (time lines). Cada instancia puede tener un recurso time line asociado con ella. Las siguientes variables están relacionadas con esto:
timeline_index Índice de la time line asociada con la instancia. Puedes establecerlo a una time line en particular para usarla. Ponlo en –1 para dejar de usar la time line para la instancia.
timeline_position Posición actual dentro de la time line. Puedes cambiarla para saltar o repetir ciertas partes. timeline_speed Normalmente, en cada step la posición en la time line se incrementa en 1. Puedes cambiar esta cantidad configurando esta variable a un valor diferente. Puedes usar números reales, por ejemplo 0.5. Si el valor es mayor que uno, varios momentos pueden ocurrir dentro del mismo tiempo del step. Se realizarán en el orden correcto, por lo que no se saltará ninguna acción.
Rooms
Los juegos funcionan en cuartos. Cada cuarto tiene un índice que se indica por el nombre del cuarto. El cuarto actual es almacenado en la variable room. No puedes asumir que los cuartos están numerados en un orden consecutivo. Por lo que nunca sumes o restes un número de la variable room. En lugar de ello usa las funciones y variables indicadas abajo. Por lo que una típica pieza de código que usarás sería:
{ if (room != room_last) { room_goto_next(); } else { game_end(); } } Las siguientes variables y funciones se relacionan con los cuartos (rooms).
room Índice del cuarto actual; puede cambiarse para ir a un cuarto diferente, pero mejor usa las rutinas listadas abajo. room_first* Índice del primer cuarto en el juego. room_last* Índice del ultimo cuarto en el juego. room_goto(numb) Ir al cuarto con indice numb. room_goto_previous()Ir al cuarto anterior. room_goto_next()Ir al siguiente cuarto. room_restart() Reiniciar el cuarto actual. room_previous(numb)Devuelve el índice del cuarto anterior a numb (-1 = ninguno) pero no va a él. room_next(numb) Devuelve el índice del cuarto posterior a numb (-1 =ninguno). game_end() Finaliza el juego. game_restart() Reinicia el juego.
Los cuartos tienen varias propiedades adicionales:
room_width* Ancho del cuarto en píxeles. room_height* Alto del cuarto en píxeles. room_caption Título de la ventana del cuarto. room_persistent Indica si el cuarto es persistente. Muchos juegos ofrecen al jugador la posibilidad de guardar el juego y cargar un juego guardado. En el Game Maker esto ocurre automáticamente cuando el jugador presiona para guardar y para cargar. También puedes guardar y cargar juegos desde una pieza de código (nota que la carga sólo se lleva a cabo al final del step actual).
game_save(string) Guarda el juego al archivo con nombre string. game_load(string) Carga el juego del archivo con nombre string. Ten en cuenta que sólo los datos básicos del juego son guardados. Por ejemplo, si guardas cuando una canción está sonando, al cargar el juego la canción no sonará desde ese momento. Los recursos editados tampoco son guardados, ni las partículas, los contenidos de las estructuras de datos ni la configuración multijugador.
Score Otro aspecto importante de muchos juegos es el score (marcador), la energía, y el número de vidas. El Game Maker mantiene el
score en la variable global score y el número de vidas en la variable global lives. Puedes cambiar el score simplemente
cambiado el valor de esta variable. Lo mismo se aplica para la energía y las vidas. Si la variable
lives es mayor que 0 y se vuelve menor
o igual a 0 se ejecuta el evento no-more-lives para todas las instancias. Si no quieres mostrar el score y las vidas en el título, pon la variable
show_score, etc., a falso. También puedes cambiar el título del marcador, de las vidas o de la energía. Para juegos más
complicados mejor muestra el score tú mismo.
score El marcador actual. lives El número de vidas. health La energía actual (0-100). show_score Indica si se muestra el marcador en el título de la ventana. show_lives Indica si se muestra el número de vidas en el título de la ventana. show_health Indica si se muestra la energía en el título de la ventana. caption_score El título empleado para el marcador. caption_lives El título empleado para el número de vidas.
caption_health El título para la energía.
Generando eventos Como sabes, el Game Maker está completamente manejado por eventos. Todas las acciones ocurren como resultado de eventos. Hay una gran cantidad de eventos diferentes. Los eventos de creación y destrucción ocurren cuando una instancia es creada o destruida. En cada step, el sistema maneja primero los eventos de alarma. Después los eventos de teclado y ratón, y luego el siguiente evento step. Después de esto las instancias son colocadas en su nueva posición después de lo cual se maneja el evento de colisión. Finalmente el evento draw se usa para dibujar las instancias (nota que cuando empleas múltiples vistas el evento draw es llamado varias veces en cada step). También puedes aplicar un evento a la instancia actual desde una pieza de código. Se tienen las siguientes funciones:
event_perform(type,numb) Realiza el evento numb del tipo type para la instancia actual. Se pueden emplear los siguientes tipos de eventos:
ev_create ev_destroy ev_step ev_alarm ev_keyboard ev_mouse ev_collision ev_other ev_draw ev_keypress ev_keyrelease Cuando hay varios eventos del tipo dado, numb puede usarse para especificar el evento preciso. Para el evento de alarma
numb puede
tener un valor de 0 a 11. Para el evento de teclado puedes usar el código de tecla para la tecla. Para los eventos de ratón puedes usar las siguientes constantes:
ev_left_button ev_right_button ev_middle_button ev_no_button ev_left_press ev_right_press ev_middle_press ev_left_release ev_right_release ev_middle_release ev_mouse_enter
ev_mouse_leave ev_mouse_wheel_up ev_mouse_wheel_down ev_global_left_button ev_global_right_button ev_global_middle_button ev_global_left_press ev_global_right_press ev_global_middle_press ev_global_left_release ev_global_right_release ev_global_middle_release ev_joystick1_left ev_joystick1_right ev_joystick1_up ev_joystick1_down ev_joystick1_button1 ev_joystick1_button2 ev_joystick1_button3 ev_joystick1_button4 ev_joystick1_button5 ev_joystick1_button6 ev_joystick1_button7 ev_joystick1_button8 ev_joystick2_left ev_joystick2_right ev_joystick2_up ev_joystick2_down ev_joystick2_button1 ev_joystick2_button2 ev_joystick2_button3 ev_joystick2_button4 ev_joystick2_button5 ev_joystick2_button6 ev_joystick2_button7 ev_joystick2_button8 Para el evento de collision proporcionas el índice del otro objeto. Finalmente, para el evento other puedes usar las siguientes constantes:
ev_outside ev_boundary ev_game_start ev_game_end ev_room_start ev_room_end ev_no_more_lives ev_no_more_health ev_animation_end ev_end_of_path ev_user0 ev_user1 ev_user2 ev_user3 ev_user4 ev_user5 ev_user6 ev_user7 ev_user8 ev_user9 ev_user10 ev_user11 ev_user12 ev_user13 ev_user14 ev_user15
Para el evento step puedes dar el índice usando las siguientes constantes:
ev_step_normal ev_step_begin ev_step_end event_perform_object(obj,type,numb) Esta función funciona igual que la anterior pero esta vez puedes especificar eventos en otro objeto. Nota que las acciones en estos eventos se aplican a la instancia actual, no a las instancias del objeto dado.
event_user(numb)
En los eventos other también puedes definir 16 eventos definidos por el usuario. Estos son ejecutados solo si
llamas esta función. Numb debe tener valores de 0 a 11.
event_inherited()
Ejecuta el evento heredado. Esto sólo funciona si la instancia tiene un objeto padre.
Puedes obtener información sobre el evento actualmente ejecutado usando las siguientes variables de sólo lectura:
event_type* El tipo del evento que se está ejecutando. event_number* El número del evento que se está ejecutando. event_object* El índice del objeto para el cual se está ejecutando el evento actual. event_action* El índice de la acción que está siendo ejecutada (0 es la primera en el evento, etc.)
Otras variables y funciones Aquí puedes ver algunas variables y funciones que se refieren a los errores.
error_occurred Indica si ha ocurrido un error error_last Cadena de texto que indica el último mensaje de error show_debug_message(str) Muestra la cadena str en modo debug Las siguientes funciones te permiten saber si ciertas variables existen, darles un valor o leerlo. En todas ellas el nombre de la variable se pasa como una cadena de texto:
variable_global_exists(name) Devuelve si la variable global con el nombre especificado existe. variable_local_exists(name) Devuelve si la variable local con el nombre especificado existe para la instancia actual. variable_global_get(name) Devuelve el valor de la variable global indicada. variable_global_array_get(name,ind) Devuelve el valor de índice ind del array global con el nombre indicado. variable_global_array2_get(name,ind1,ind2) Devuelve el valor de índice ind1, ind2 del array bidimensional global con el nombre indicado.
variable_local_get(name) Devuelve el valor de la variable local indicada para la instancia actual. variable_local_array_get(name,ind) Devuelve el valor de índice ind del array locall con el nombre indicado. variable_local_array2_get(name,ind1,ind2) Devuelve el valor de índice ind1, ind2 del array bidimensional global con el nombre indicado.
variable_global_set(name,value) Otorga el valor indicado a la variable global especificada. variable_global_array_set(name,ind,value) Otorga el valor indicado al elemento ind del array global especificado. variable_global_array2_set(name,ind1,ind2,value) Otorga el valor indicado al elemento ind 1, ind2 del array bidimensional global especificado.
variable_local_set(name,value) Otorga el valor indicado a la variable local especificada. variable_local_array_set(name,ind,value) Otorga el valor indicado al elemento ind del array local especificado. variable_local_array2_set(name,ind1,ind2,value) Otorga el valor indicado al elemento ind 1, ind2 del array bidimensional local especificado.
Por ejemplo, puedes escribir:
{ if variable_global_exists('ammunition') global.ammunition += 1 else global.ammunition = 0 } También puees usar estas funciones para pasar variables a los scripts usando referencias, utilizando el nombre de las variables como cadenas de texto.
Puedes cambiar la prioridad del programa usando la función :
set_program_priority(priority) Cambia la prioridad del programa. Debes indicar un valor comprendido entre -3 y +3. Usando -3 el programa se ejecutará sólo si no hay otro proceso que requiera tiempo de computación. -2 y -1 son valores por debajo de lo normal, así que otros procesos tendrán prioridad sobre el juego. 0 es el valor normal. +1 y +2 son valores de alta prioridad, que pueden hacer que el juego se ejecute más suavemente y a mayor velocidad. Otros procesos tendrán menos tiempo de computación. +3 indica ejecución en tiempo real: todo el tiempo de computación se pone en disposición del juego. Esto puede crear problemas con otras aplicaciones que se estén ejecutando en el ordenador. Además, los eventos de teclado o pinchar en el botón para cerrar la ventana pueden dejar de ser atendidos por Windows. Así que sólo debes usar este valor si realmente necesitas todo el procesamiento posible. Se cuidadoso y no olvides guardar tu juego antes de ejecutarlo.
Interacción con el usuario No hay juego sin interacción con el usuario. La manera estándar de interactuar con el usuario en el Game Maker es colocando acciones en los eventos del ratón o del teclado. Pero en ocasiones se necesita más control. Desde una pieza de código puedes chequear la posición del ratón o si alguno de sus botones es presionado. Normalmente esto se chequea en el evento step de algún objeto controlador y llevas a cabo las acciones adecuadas. La información sobre este tema se encuentra en las secciones: El teclado El ratón El joystick
El teclado Para interacción con el teclado (keyboard) las siguientes funciones y variables existen:
keyboard_lastkey Código de la última tecla presionada. Mira más las constantes para los códigos de tecla. Puedes cambiarlo, p. ej, ponerlo a 0 si tu lo manipulaste.
keyboard_key Código de tecla de la tecla presionada actualmente (mira mas abajo; 0 si no se presiona ninguna) keyboard_lastchar Último carácter presionado (como string) keyboard_string Cadena de caracteres de los últimos 1024 caracteres tipeados. Esta cadena solo contendrá caracteres imprimibles en la pantalla. También responde a la tecla de retroceso borrando el último carácter.
En ocasiones es útil mapear una tecla a otra. Por ejemplo pudieras permitir al jugador emplear tanto las teclas del cursor como las del teclado numérico. En lugar de duplicar las acciones puedes mapear el teclado numérico a las teclas del cursor. También pudieras implementar un mecanismo en el que el jugador pueda seleccionar las teclas a usar. Para este fin, contamos con las siguientes funciones:
keyboard_set_map(key1,key2) Mapea la tecla con el código de tecla key 1 a key2. keyboard_get_map(key) Devuelve el mapeado actual para una tecla keyboard_unset_map() Restablece todas sus teclas a su mapa original.
Para chequear si una tecla o botón del ratón en particular han sido presionados puedes emplear las siguientes funciones. Esto es útil particularmente cuando se presionan varias teclas simultáneamente.
keyboard_check(key) Indica si la tecla con el código de tecla particular está presionado. keyboard_check_pressed(key) Indica si la tecla con el código de tecla particular fue presionado desde el último step. keyboard_check_released(key) Indica si la tecla con el código de tecla particular dejó de presionarse desde el último step. keyboard_check_direct(key) Indica si la tecla con el código de tecla es presionada chequeando el hardware directamente. El resultado es independiente de la aplicación enfocada. Esta función permite algunos chequeos más. En este caso puedes emplear los códigos vk_lshift, vk_lcontrol, vk_lalt, vk_rshift, vk_rcontrol y vk_ralt para checar si se presiona la tecla shift, control o alt, ya sea izquierda o derecha
Las siguientes rutinas puedes ser usadas para manipular el estado del teclado:
keyboard_get_numlock()Indica si BloqNum está activada. keyboard_set_numlock(on) Activa (on=true) o desactiva (on=false) BloqNum.
keyboard_key_press(key) Simula presionar la tecla con el código de tecla keyboard_key_release(key) Simulates a release of the key with the indicated keycode. Las siguientes constantes para los códigos de tecla son:
vk_nokey Código de tecla que representa que no hay teclas presionadas vk_anykey Código de tecla que representa que cualquier tecla ha sido presionada. vk_left Código para tecla de la flecha izquierda vk_right Código para tecla de la flecha derecha vk_up Código para tecla de la flecha arriba vk_down Código para tecla de la flecha abajo vk_enter Tecla Enter o Intro vk_escape Tecla Escape vk_space Tecla Espacio vk_shift Tecla Shift vk_control Tecla Control vk_alt Tecla Alt vk_backspace Tecla Backspace o Retroceso vk_tab Tecla Tab vk_home Tecla Inicio vk_end Tecla Fin vk_delete Tecla Suprimir vk_insert Tecla Insertar vk_pageup Tecla Re Pag vk_pagedown Tecla Av Pag vk_pause Tecla Pausa/Inter vk_printscreen Tecla Impr Pant/Pet Sis vk_f1 ... vk_f12 Códigos de tecla para las las teclas funcionales F1 hasta F12 vk_numpad0 ... vk_numpad9 Teclas numéricas en el teclado numérico vk_multiply Tecla de multiplicación en el teclado numérico vk_divide Tecla de división en el teclado numérico vk_add Tecla de suma en el teclado numérico vk_subtract Tecla de substracción en el teclado numérico vk_decimal Tecla de punto decimal en el teclado numérico Para las letras usa por ejemplo
ord('A'). (Letras Mayúsculas). Para los dígitos usa por ejemplo ord('5') para obtener la tecla <5>
(no en el teclado numérico). Las siguientes constantes solo sirven para
vk_lshift Tecla Shift de la Izquierda vk_lcontrol Tecla Control de la Izquierda vk_lalt Tecla Alt de la Izquierda vk_rshift Tecla Shift de la Derecha
keyboard_check_direct:
vk_rcontrol Tecla Control de la Derecha vk_ralt Tecla Alt de la Derecha
Por ejemplo, asumiendo que tienes un objeto que el usuario puede controlar con las teclas del cursor puedes colocar el siguiente código en el evento step del objeto:
{ if (keyboard_check(vk_left))
x -= 4;
if (keyboard_check(vk_right)) x += 4; if (keyboard_check(vk_up))
y -= 4;
if (keyboard_check(vk_down))
y += 4;
} Claro, esto es mucho más fácil si simplemente lo ponemos en los eventos del teclado.
Hay algunas funciones adicionales relacionadas con la interacción con el teclado
keyboard_clear(key) ‘Limpia’ el estado de la tecla mencionada en “key”. Esto significa que no generará eventos de teclado hasta que se vuelva a presionar.
io_clear()
‘Limpia’ todos los estados del teclado y del ratón.
io_handle()
Maneja la entrada y salida por parte del usuario, actualizando los estados del teclado y del ratón.
keyboard_wait()
Espera hasta que el usuario presione una tecla del teclado.
El ratón Para más interacción, las siguientes variables y funciones existes:
mouse_x* Coordenada X del ratón. No puede cambiarse. mouse_y* Coordenada Y del ratón. No puede cambiarse. mouse_button Botón del ratón presionado actualmente. Como valores puedes emplear mb_none (ningún botón),
mb_any (cualquier botón), mb_left (botón izquierdo), mb_middle (botón central) o mb_right (botón derecho).
mouse_lastbutton último botón presionado del ratón. Para chequear si un botón particular del ratón se presionó puedes usar estas funciones. Esto es muy útil cuando muchas teclas se presionan simultáneamente.
mouse_check_button(numb) Indica si se presiona el botón del ratón numb (como valores de numb emplea mb_none, mb_left, mb_middle, o mb_right).
mouse_check_button_pressed(numb) Indica si el botón del ratón fue presionado desde el ultimo step. mouse_check_button_released(numb) Indica si el botón del ratón se soltó desde el último step. Hay funciones adicionales relacionadas con la interacción con el ratón:
mouse_clear(button) “limpia” el estado del botón del Mouse. Esto significa que no se generarán mas eventos del ratón hasta que se vuelva a presionar otra vez.
io_clear()
‘Limpia’ todos los estados del teclado y del ratón.
io_handle()
Maneja la entrada y salida por parte del usuario, actualizando los estados del teclado y del ratón.
mouse_wait()Espera hasta que el usuario presione un botón en el ratón.
El joystick Tenemos algunos eventos asociados con los joysticks (mandos de control, controles, palancas de mando, palancas de juego, etc.) Pero para tener control total sobre los joysticks hay un grupo de funciones para tratarlos. El Game Maker soporta hasta dos joystick. Por lo que todas estas funciones reciben el id del joystick como argumento.
joystick_exists(id)
Indica si el joystick id (1 o 2) existe
.
joystick_name(id)
Devuelve el nombre del joystick.
joystick_axes(id)
Devuelve el número de ejes del joystick.
joystick_buttons(id)
Devuelve el número de botones del joystick.
joystick_has_pov(id)
Indica si el joystick tiene capacidades point-of-view.
joystick_direction(id)
Devuelve el código (vk_numpad1 a vk_numpad9) correspondiente a la dirección del joystick id (1 o
2).
joystick_check_button(id,numb)
Indica si el botón del joystick id es presionado (numb está en el intervalo 1-32).
joystick_xpos(id)
Devuelve la posición (-1 a 1) del eje-x del joystick id.
joystick_ypos(id)
Devuelve la posición y del joystick id.
joystick_zpos(id)
Devuelve la posición z del joystick id (si es que cuenta con eje z).
joystick_rpos(id)
Devuelve la posición del timón del joystick id (del cuarto eje).
joystick_upos(id)
Devuelve la posición u del joystick id (del quinto eje).
joystick_vpos(id)
Devuelve la posición v del joystick id (del sexto eje).
joystick_pov(id)
Devuelve la posición del point-of-view del joystick id. Este es un ángulo entre 0 y 360 grados. 0 es adelante, 90
a la derecha, 180 atrás y 270 a la izquierda. Cuando no se especifica la dirección del point-of-view devuelve –1.
Gráficos del juego Una parte importante de un juego son los gráficos. Game Maker normalmente toma el control de casi todo y en juegos sencillos no hay necesidad de preocuparse. Pero a veces necesitas tomar mayor control sobre ellos. Para algunos aspectos hay acciones, pero mediante código puedes controlar muchos más aspectos. Este capítulo muestra todas las variables y funciones disponibles para esto y da más información sobre lo que está sucediendo realmente.
La información sobre la parte gráfica se encuentra en las secciones siguientes: Imágenes y sprites Fondos Dibujando sprites y fondos Dibujando formas Fuentes y texto Funciones avanzadas de dibujo Dibujando superficies Tiles El display La ventana Vistas Transiciones Redibujando la pantalla
Imágenes y Sprites Cada objeto tiene un sprite asociado. Puede ser una imagen simple o compuesta por varias subimágenes. Para cada instancia del objeto, el programa dibuja la imagen correspondiente en la pantalla, con su origen (definido en las propiedades de sprite) en la posición (x,y) de la instancia. Cuando hay varias subimágenes, ésta se reproduce a través de las subimágenes para crear un efecto de animación. Hay varias variables que afectan en el modo en que se dibuja la imagen. Estas pueden sert utilizadas para cambiar los efectos. Cada instancia posee las siguientes variables:
visible : Si visible es cierto (1) la imagen se dibuja,
en caso contrario no se dibuja. Las instancias invisibles aun son activas y crean
eventos de colisión; Simplemente no puedes verlas. Definir la visibilidad como falso es útil para por ejemplo objetos controladores (hazlos también no sólidos para evitar eventos de colisión con ellos) o palancas ocultas.
sprite_index Este es el índice del sprite actual para la instancia. Puedes cambiarlo para asignar un sprite diferente a la instancia. Como valor puedes usar los nombres de los diferentes sprites que definas . Cambiando el sprite no cambias el índice de la subimagen actual.
sprite_width* Indica el ancho del sprite. Este valor no puede ser cambiado, pero puedes utilizarlo.
sprite_height* Indica el alto del sprite. Este valor no puede ser cambiado, pero puedes utilizarlo. sprite_xoffset* Indica el offset horizontal del sprite, como esta definido en las propiedades del sprite. Este valor no puede ser cambiado, pero puedes utilizarlo.
sprite_yoffset* Indica el offset horizontal del sprite, como esta definido en las propiedades del sprite. Este valor no puede ser cambiado, pero puedes utilizarlo.
image_number* El numero de subimágenes del sprite actual de la instancia (no puede ser cambiado). image_index Cuando la imagen tiene varias subimágenes, el programa las recorre cíclicamente. Esta variable indica la subimagen dibujada actualmente (están numeradas desde 0). Puedes cambiar la imagen actual cambiando esta variable. EL programa continuará reproduciendo el ciclo de subimágenes, pero comenzando desde el nuevo índice. (El valor puede ser fraccional. En este caso, se redondea siempre hacia abajo para obtener el índice de la subimagen dibujada.
image_speed La velocidad con que se reproduce el ciclo de subimágenes. Un valor de 1 indica que en cada paso se muestra la siguiente subimagen . Valores menores, reducirán la velocidad de visualización de la animación, dibujando la misma subimagen varias veces. Valores mayores harán que se salten subimágenes para aumentar la velocidad de la animación. A veces quieres que una subimagen en particular sea visible y no quieres que el programa muestre todas las demás subimágenes. Puedes conseguir esto definiendo la velocidad igual a 0 y eligiendo la subimagen correcta. Por ejemplo, asumamos que tenemos un objeto que puede rotar y has creado un sprite que tiene varias subimágenes para las diferentes orientaciones (en sentido contrario a las agujas del reloj) Puedes introducir el siguiente código en el evento step:
{ image_index = direction * image_number/360; image_speed = 0; } depth Normalmente las imágenes son dibujadas en el orden en que se crean las instancias. Puedes cambiar este orden cambiando la profundidad de la imagen. El valor por defecto es 0, hasta que le introduzcas un valor diferente en las propiedades del objeto. Cuanto mayor es el valor más al fondo se dibujará la instancia. (También puedes utilizar valores negativos.) Las instancias con mayor profundidad permanecerán debajo de las instancias con menor profundidad. Definiendo la profundidad garantizamos que las instancias son dibujadas en el orden que queremos. (Ej. El avión sobre la nube). Las instancias de fondo tendrán una alta profundidad (valor positivo) y las imágenes frontales tendrán una profundidad baja (valores negativos).
image_xscale Un valor de escala para hacer
mayores o menores las imágenes. Un valor de 1 indica el tamaño normal. Debes separar
la escala horizontal xscale y la vertical yscale. Cambiando la escala también cambian el ancho y el alto de la imagen e influye en los eventos de collisión, como podrías esperar. Cambiar la escala puede ser utilizado para dar un efecto 3-D. Puedes utilizar un valor de -1 para invertir horizontalmente la imagen.
image_yscale Escala vertical yscale. 1 no modifica el tamaño. Puedes utilizar un valor de -1 para invertir verticalmente la imagen. image_angle El ángulo con que se rota la imagen. Se especifica en grados en sentido contrario a las agujas del reloj. indica que no hay rotación. Esta variable solo puede modificarse en la versión registrada!
Un valor de 0
image_alpha El valor de transparencia (alpha) que se aplica al dibujar la imagen. Un valor de 1 es la opacidad normal; un valor de 0 es totalmente transparente.
image_blend
Teñido de color que se aplica al dibujar la imagen. Un valor de color blanco (c_white) es el que se utiliza por defecto.
Cuando especificas un color diferente, la imagen se tiñe de dicho color. Esto puede ser utilizado para colorear el personaje en tiempo de ejecución. Esta variable solo puede modificarse en la versión registrada!
bbox_left* Lado izquierdo de la caja de contorno utilizada por la imagen de la instancia (Se toma en cuenta el escalado). bbox_right* Lado derecho de la caja de contorno utilizada por la imagen de la instancia bbox_top* parte superior de la caja de contorno utilizada por la imagen de la instancia. bbox_bottom*
parte inferior de la caja de contorno utilizada por la imagen de la instancia.
Fondos Cada room (cuarto) puede tener hasta 8 fondos. Así mismo, también puede tener un color de fondo. Todos los aspecto de estos fondos se pueden cambiar con código usando las siguientes variables (observa que algunas son vectores con un rango de 0 a 7; este número indica el fondo al que se aplicarán los cambios):
background_color Color de fondo para el cuarto. background_showcolor Indica si se debe limpiar la pantalla con el color de fondo. background_visible[0..7] Indica si el fondo indicado es visible o no. Por ejemplo, para indicar que el fondo número 3 no debe mostrarse, deberíamos hacerlo así: background_visible[3]=false;
background_foreground[0..7] Indica si el fondo está en primer plano (se dibujará encima de todo lo demás, tapando todo lo que quede por debajo).
background_index[0..7] Imagen de fondo asignada al fondo indicado. background_x[0..7] Posición x del fondo. background_y[0...7] Posición y del fondo. background_width[0...7]* Anchura de la imagen del fondo. background_height[0...7]* Altura de la imagen del fondo. background_htiled[0..7] Indica si el fondo debe repetirse horizontalmente para llenar toda la pantalla. background_vtiled[0..7] Indica si el fondo debe repetirse verticalmente para llenar toda la pantalla. background_xscale[0..7] Factor de escalado horizontal del fondo: un número entre 0 y 1 hará la imagen más pequeña y un número mayor que 1 la hará más grande. (Debe ser un valor positivo)
background_yscale[0..7] Factor de escalado vertical del fondo: un número entre 0 y 1 hará la imagen más pequeña y un número mayor que 1 la hará más grande. (Debe ser un valor positivo)
background_hspeed[0..7] Velocidad horizontal de scrolling del fondo, en píxeles por step. El scrolling es el movimiento del fondo, por lo tanto esto se refiere al movimiento horizontal del fondo.
background_vspeed[0..7] Velocidad vertical de scrolling del fondo, en píxeles por step. El scrolling es el movimiento del fondo, por lo tanto esto se refiere al movimiento vertical del fondo.
background_blend[0..7] Color de teñido usado al dibujar el fondo. El valor por defecto es c_white. Esta variable sólo se puede usar en la versión registrada!
background_alpha[0..7] Factor de transparencia usado al dibujar el fondo. 1 es el valor normal (imagen totalmente opaca) y 0 es totalmente transparente (utiliza valores intermedios para dibujar fondos parcialmente transparentes).
Dibujando sprites y fondos Normalmente los objetos tienen un sprite asociado que se dibuja en la pantalla. Pero también puedes usar el evento draw. para dibujar otras cosas. Esta sección y las dos siguientes te darán información sobre este aspecto. Primero de todo, hay un grupo de funciones que sirven para dibujar sprites y fondos de distintas maneras. Estas funciones te dan un gran control sobre la apariencia gráfica del juego y te permiten hacer cosas como dibujar sólo un trozo de un fondo, rotar un sprite...
draw_sprite(sprite,subimg,x,y) Dibuja la subimagen subimg (-1 = subimagen actual) del sprite con índice
sprite
con su origen en la posición (x,y) sin teñirlo de ningún color y sin usar transparencia.
draw_sprite_stretched(sprite,subimg,x,y,w,h) Dibuja la subimagen subimg índice
sprite
de forma que llene la región con esquina superior-izquierda en (x,y), anchura
del sprite con
w y altura h.
draw_sprite_tiled(sprite,subimg,x,y) Dibuja el sprite repitiéndolo horizontal y verticalmente de forma que llene toda la pantalla. (x,y) es la posición donde se dibuja una de las copias del sprite.
draw_sprite_part(sprite,subimg,left,top,width,height,x,y) Dibuja la parte del sprite indicada con su esquina superior izquierda en (x,y). La parte del sprite que queremos dibujar se indica con superior-izquierda) y
left
y
top(coordenadas de la esquina
width y height (anchura y altura del trozo que queremos dibujar).
draw_background(back,x,y) Dibuja el fondo en la posición (x,y), sin teñirlo de ningún color y sin transparencia. draw_background_stretched(back,x,y,w,h) Dibuja el fondo escalado de forma que ocupe la región indicada. draw_background_tiled(back,x,y) Dibuja el fondo repitiéndolo en horizontal y vertical de forma que llene toda la pantalla.
draw_background_part(back,left,top,width,height,x,y) Dibuja el trozo indicado del fondo con su esquina superior-izquierda en la posición (x,y).
Las funciones siguientes son versiones extendidas de las funciones anteriores. Estas funciones sólo están disponibles en la versión registrada de Game Maker.
draw_sprite_ext(sprite,subimg,x,y,xscale,yscale,rot,color,alpha) Dibuja el sprite escalado con factores
xscale (horizontal) e yscale
(vertical) y rotado
rot grados en sentido antihorario. color indica el color con el que
queremos teñir el sprite (usa el color blanco c_white si no quieres teñir el sprite de ningún color) y
alpha indica el factor de
transparencia. Un valor igual a 0 hace la imagen totalmente transparente y un valor igual a 1 la hace totalmente opaca. Con valores intermedios conseguirás que la imagen sea parcialmente transparente. Con esta función se pueden crear efectos muy espectaculares como
explosiones semi-transparentes.
draw_sprite_stretched_ext(sprite,subimg,x,y,w,h,color,alpha) Dibuja el sprite escalado de forma que ocupe la región indicada: esquina superior izquierda en (x,y), anchura
w y altura h. color indica el color de teñido y alpha el factor de
transparencia.
draw_sprite_tiled_ext(sprite,subimg,x,y,xscale,yscale,color,alpha) Dibuja el sprite repetido de forma que cubra toda la pantalla con factores de escala, color de teñido y factor de transparencia.
draw_sprite_part_ext(sprite,subimg,left,top,width,height,x,y,xscale,yscale,color,al pha) Dibuja la parte indicada del sprite con factores de escala, color de teñido y factor de transparencia. draw_sprite_general(sprite,subimg,left,top,width,height,x,y,xscale,yscale,rot,c1,c2 ,c3,c4,alpha) La función más general para dibujar sprites. Dibuja la parte indicada de la subimagen subimg(-1 = subimagen actual) del sprite con índice sprite situando su esquina superior-izquierda en la posición (x,y) y con factores de escala, ángulo de rotación, un color de teñido para cada una de las 4 esquinas del sprite (en el orden arriba-izquierda, arriba-derecha, abajo-derecha y abajo-izquierda) y un factor de transparencia. Observa que el sprite se rotará sobre su esquina superior-izquierda y no sobre su origen.
draw_background_ext(back,x,y,xscale,yscale,rot,color,alpha) teñido del color especificado (usa c_white si no quieres teñirlo) y con factor de transparencia
Dibuja el fondo escalado, rotado,
alpha (0-1).
draw_background_stretched_ext(back,x,y,w,h,color,alpha) Dibuja el fondo escalado de forma que ocupe la región indicada con color de teñido y factor de transparencia.
draw_background_tiled_ext(back,x,y,xscale,yscale,color,alpha) Dibuja el fondo repetido de forma que ocupe todo el cuarto con factores de escala, color de teñido y factor de transparencia.
draw_background_part_ext(back,left,top,width,height,x,y,xscale,yscale,color,alpha) Dibuja la parte indicada del fondo situando su esquina superior-izquierda en la posición (x,y) con factores de escala, color de teñido y factor de transparencia.
draw_background_general(back,left,top,width,height,x,y,xscale,yscale,rot,c1,c2,c3,c 4,alpha) La función más general para dibujar fondos. Dibuja la parte indicada del fondo situando su esquina superior-izquierda en la posición (x,y) con factores de escala, ángulo de rotación, un color de teñido para cada una de las cuatro esquinas (en el orden arribaizquierda, arriba-derecha, abajo-derecha y abajo-izquierda) y un factor de transparencia. Observa que el sprite se rotará sobre su esquina superior-izquierda del trozo indicado del fondo.
Dibujando formas Game Maker dispone de una amplia colección de funciones para dibujar diferentes formas. También hay otras funciones para dibujar texto (consulta el capítulo siguiente). Estas funciones de dibujo sólo se pueden usar en el evento draw ya que no tienen sentido si se colocan en otro evento. Debes tener en cuenta que las colisiones entre las instancias se determinan según sus sprites y sus máscaras de colisión y no según lo que cada instancia dibuja en la pantalla. Las funciones siguientes sirven para dibujar las formas básicas:
draw_clear(col) Pinta todo el cuarto del color especificado. draw_clear_alpha(col,alpha) Pinta todo el cuarto del color especificado y con el factor de transparencia indicado (muy útil
para superficies).
draw_point(x,y) Dibuja un punto en (x,y) en el color de dibujo actual. draw_line(x1,y1,x2,y2) Dibuja una línea desde (x1,y1) hasta (x2,y2). draw_rectangle(x1,y1,x2,y2,outline) Dibuja un rectángulo. outline indica si sólo debe dibujarse el borde (true) o si el rectángulo debe estar relleno (false).
draw_roundrect(x1,y1,x2,y2,outline) Dibuja un rectángulo redondeado. outline indica si sólo debe dibujarse el borde (true) o si el rectángulo debe estar relleno (false).
draw_triangle(x1,y1,x2,y2,x3,y3,outline) Dibuja un triángulo. outline indica si sólo debe dibujarse el borde (true) o si debe estar relleno (false).
draw_circle(x,y,r,outline) Dibuja un círculo con su centro en (x,y) y radio r. outline indica si sólo debe dibujarse el borde (true) o si debe estar relleno (false).
draw_ellipse(x1,y1,x2,y2,outline) Dibuja una elipse. outline indica si sólo debe dibujarse el borde (true) o si debe estar rellena (false).
draw_arrow(x1,y1,x2,y2,size) Dibuja una flecha desde (x1,y1) hasta (x2,y2). size indica el tamaño de la flecha en píxeles.
draw_button(x1,y1,x2,y2,up) Dibuja un botón. up indica si está pulsado (0) o no (1). draw_path(path,x,y,absolute) Con esta función puedes dibujar el path indicado en el cuarto con su comienzo en la posición (x,y). Si
absolute es true el path se dibuja en la posición en la que fue definido y los valores de x e y son ignorados.
draw_healthbar(x1,y1,x2,y2,amount,backcol,mincol,maxcol,direction,showback,showbord er) Con esta función puedes dibujar una barra de vida (o una barra que indique cualquier otra cosa como poder, magia,…). Los parámetros x1, y1, x2 e y2 indican el área total de la barra. entre 0 y 100).
amount indica el porcentaje de la barra que debe estar relleno (debe estar
backcol es el color de fondo de la barra. mincol y maxcol indican el color cuando el porcentaje de llenado
(parámetro amount) es 0 y 100 respectivamente. Para un porcentaje intermedio el color se interpola entre estos dos. Así puedes crear fácilmente una barra que vaya de verde a rojo, por ejemplo.
direction es la dirección en la que la barra se dibuja: 0 significa que la
barra está fijada a la izquierda, 1 a la derecha, 2 arriba y 3 abajo. Finalmente, y
showback indica si debe mostrarse una caja de fondo
showborder si la caja de fondo y la barra deben tener un borde negro.
Muchas de las funciones anteriores utilizan los colores y transparencia generales de dibujo que pueden ser cambiados con estas funciones:
draw_set_color(col) Indica el color que debe usarse para dibujar primitivas. draw_set_alpha(alpha) Indica el factor de transparencia que debe usarse para dibujar primitivas. Debe estar comprendido el rango 0-1. 0 significa totalmente transparente y 1 totalmente opaco.
draw_get_color() Devuelve el color general de dibujo utilizado para dibujar primitivas. draw_get_alpha()Devuelve el factor de transparencia general de dibujo utilizado para dibujar primitivas. Hay un gran rango de colores predefinidos:
en
c_aqua c_black c_blue c_dkgray c_fuchsia c_gray c_green c_lime c_ltgray c_maroon c_navy c_olive c_purple c_red c_silver c_teal c_white c_yellow Sin embargo, también puedes usar las funciones siguientes para crear tus propios colores:
make_color_rgb(red,green,blue) Devuelve un color con los componentes indicados de rojo, verde y azul. Los valores indicados deben estar entre 0 y 255 (ambos inclusive).
make_color_hsv(hue,saturation,value) Devuelve un color con los componentes indicados de brillo, saturación y valor. Los valores indicados deben estar entre 0 y 255 (ambos inclusive).
color_get_red(col) Devuelve el componente de rojo del color. color_get_green(col) Devuelve el componente de verde del color. color_get_blue(col) Devuelve el componente de azul del color. color_get_hue(col) Devuelve el componente de brillo del color. color_get_saturation(col) Devuelve el componente de saturación del color. color_get_value(col) Devuelve el componente de valor del color. merge_color(col1,col2,amount) Devuelve un color resultante de mezclar los dos colores indicados. La mezcla se determina por el parámetro
amount: un valor igual a 0 corresponde a col1, un valor de 1 corresponde a col2 y un valor intermedio hace que se
mezclen los dos colores.
También puedes utilizar las siguientes funciones misceláneas:
draw_getpixel(x,y) Devuelve el color del píxel en la posición (x,y) del cuarto. Esta función no es muy rápida, así que úsala con cuidado.
screen_save(fname) Salva una imagen bmp de la pantalla en el archive especificado. Útil para crear screenshots. screen_save_part(fname,x,y,w,h) Salva la parte de la pantalla indicada a un archive bmp.
Fuentes y texto A veces necesitas dibujar texto. Para ello, primero debes indicar la fuente que quieres usar. Las fuentes se pueden definir creando un recurso de fuente (directamente en Game Maker o usando las funciones de modificación de recursos). Para dibujar texto disponemos de varias funciones distintas. En todas ellas debes indicar el texto a ser dibujado y la posición del mismo. Además, existen dos funciones para definir la alineación del texto en horizontal y vertical respecto a esa posición.
Para dibujar texto disponemos de las funciones siguientes:
draw_set_font(font) Indica la fuente que debe usarse para dibujar texto. Puedes indicar el valor -1 para usar la fuente por defecto (Arial 12).
draw_set_halign(halign) Indica la alineación horizontal del texto. Debes indicar uno de los siguientes valores: fa_left
izquierda
fa_center fa_right
centrada derecha
draw_set_valign(valign) Indica la alineación vertical del texto. Debes indicar uno de los siguientes valores: fa_top
arriba
fa_middle
centrada
fa_bottom
abajo
draw_text(x,y,string) Dibuja el texto indicado en la posición (x,y) usando el color y el factor de transparencia de dibujo generales. Los símbolo #, chr(13) o chr(10) (tecla ENTER o de salto de línea) son interpretados como caracteres de salto de línea. De esta forma puedes dibujar textos de varias líneas (Usa \# para dibujar el símbolo #).
draw_text_ext(x,y,string,sep,w) Similar a la función anterior pero ahora puedes especificar 2 cosas más. Primero de todo,
sep indica la distancia de separación entre las líneas del texto si es que tiene varias líneas. Usa -1 para obtener la distancia por
defecto. Por último,
w indica la anchura del texto en píxeles. Las líneas más largas que esta distancia se dividen en nuevas líneas cuando
encuentren un espacio en el texto o el símbolo -. Utiliza el valor -1 si no quieres que el texto se divida automáticamente en varias líneas.
string_width(string) Anchura que el texto indicado ocuparía si se dibujara con la fuente actual usando la función
draw_text(). Puedes usar esta función para posicionar los gráficos con precisión.
string_height(string) Altura que el texto indicado ocuparía si se dibujara con la fuente actual usando la función
draw_text(). Puedes usar esta función para posicionar los gráficos con precisión.
string_width_ext(string,sep,w) Anchura que el texto indicado ocuparía si se dibujara con la fuente actual usando la función
draw_text_ext(). Puedes usar esta función para posicionar los gráficos con precisión.
string_height_ext(string,sep,w) Altura que el texto indicado ocuparía si se dibujara con la fuente actual usando la función
draw_text_ext(). Puedes usar esta función para posicionar los gráficos con precisión.
Las siguientes funciones te permiten dibujar texto escalado o rotado e incluso aplicarle gradientes de color. Estas funciones sólo están disponibles en la versión registrada de Game Maker!
draw_text_transformed(x,y,string,xscale,yscale,angle) Dibuja el texto indicado en la posición (x,y) con factores de escala y rotado
angle grados en sentido antihorario.
draw_text_ext_transformed(x,y,string,sep,w,xscale,yscale,angle) Combina las funciones
draw_text_ext() y draw_text_transformed(). De esta forma es posible dibujar textos multilíneas rotados o
escalados.
draw_text_color(x,y,string,c1,c2,c3,c4,alpha) Dibuja el texto indicado aplicando a cada esquina el color indicado en el orden arriba-izquierda, arriba-derecha, abajo-derecha, abajo-izquierda y con factor de transparenciaalpha (0-1).
draw_text_ext_color(x,y,string,sep,w,c1,c2,c3,c4,alpha) Similar a draw_text_ext() pero con vértices coloreados.
draw_text_transformed_color(x,y,string,xscale,yscale,angle,c1,c2,c3,c4,alpha) Similar a
draw_text_transformed()pero con vértices coloreados.
draw_text_ext_transformed_color(x,y,string,sep,w,xscale,yscale,angle,c1,c2,c3,c4,al pha) Similar a draw_text_ext_transformed()pero con vértices coloreados.
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:
•
bm_zero: El factor de mezcla es (0, 0, 0, 0).
•
bm_one: El factor de mezcla es (1, 1, 1, 1).
•
bm_src_color: El factor de mezcla es (Rf, Gf, Bf, Af).
•
bm_inv_src_color: El factor de mezcla es (1–Rf, 1–Gf, 1–Bf, 1–Af).
•
bm_src_alpha: El factor de mezcla es (Af, Af, Af, Af).
•
bm_inv_src_alpha: El factor de mezcla es (1–Af, 1–Af, 1–Af, 1–Af).
•
bm_dest_alpha: El factor de mezcla es (Ad, Ad, Ad, Ad).
•
bm_inv_dest_alpha: El factor de mezcla es (1–Ad, 1–Ad, 1–Ad, 1–Ad).
•
bm_dest_color: El factor de mezcla es (Rd, Gd, Bd, Ad).
•
bm_inv_dest_color: El factor de mezcla es (1–Rd, 1–Gd, 1–Bd, 1–Ad).
•
bm_src_alpha_sat: El factor de mezcla es (f, f, f, 1); f = min(Af, 1–Ad).
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.
Dibujando superficies Esta funcionalidad sólo está disponible en la versión registrada de Game Maker
En algunas situaciones puede que no quieras dibujar directamente en la pantalla sino en un lienzo que más tarde puedas usar para dibujar otras cosas. Por ejemplo, puedes querer que el usuario dibuje en la pantalla. En vez de dejar que el usuario dibuje directamente en la pantalla (lo que no funcionaría, ya que la pantalla se refresca en cada step) puedes hacer que dibuje en un lienzo a parte y copiar este lienzo a la pantalla en cada paso. También podrías querer usar una textura que cambie con el tiempo, crear un efecto de transiciones entre cuartos, efectos de iluminación…
Las superficies hacen posibles cosas como éstas. Las superficies son muy sencillas de usar: primero creas una superficie indicando su tamaño. Luego indicas que vas a dibujar sobre la superficie. Desde este momento, todas las funciones de dibujo se aplicarán a la superficie. Cuando termines de dibujar, indicas que ya no vas a dibujar más en la superficie. Ya tienes lista la superficie, ahora puedes dibujarla directamente en la pantalla, usarla como textura…Consulta el final del capítulo para conocer algunos detalles con los que debes tener cuidado al trabajar con superficies.
Las siguientes funciones sirven para tratar superficies:
surface_create(w,h) Crea una superficie con la anchura y altura indicadas. La función devuelve la id de la superficie que debe ser usada en las demás funciones. Observa que la superficie no se “limpia” (es decir, que no se pinta toda ella de un mismo color). Para esto, debes indicar que vas a dibujar en la superficie y llamar a la función apropiada, por ejemplo draw_clear(color).
surface_free(id) Libera la memoria utilizada por la superficie. surface_exists(id) Devuelve si la superficie con la id especificada existe.
Estas funciones nos dan información sobre la superficie:
surface_get_width(id) Devuelve la anchura de la superficie. surface_get_height(id) Devuelve la altura de la superficie. surface_get_texture(id) Devuelve la textura correspondiente a la superficie. Esto se puede usar para dibujar objetos texturizados con la imagen de la superficie.
Estas dos funciones manejan el mecanismo de dibujo:
surface_set_target(id) Indica que la superficie con la id correspondiente es el objetivo de dibujo. Esto significa que todas las funciones de dibujo que se llamen actuarán sobre la superficie. Simplemente resetea la proyección para que cubra sólo a la superficie.
surface_reset_target() Vuelve a fijar la pantalla como objetivo de dibujo. Es decir, las funciones de dibujo que se llamen a partir de ahora funcionarán normalmente ¡No olvides llamar a esta función cuando termines de dibujar sobre la superficie!
Las funciones siguientes nos permiten manejar las superficies:
surface_getpixel(id,x,y) Devuelve el color del píxel en la posición (x,y) de la superficie. Esta función no es muy rápida así que úsala con moderación.
surface_save(id,fname) Guarda una imagen bmp de la superficie, creando para ello el archivo con el nombre indicado. Se puede usar para crear screenshots, por ejemplo.
surface_save_part(id,fname,x,y,w,h) Igual que la función anterior, pero esta vez sólo se copiará la parte de la superficie que indiques.
Para dibujar superficies hay muchas posibilidades:
draw_surface(id,x,y) Dibuja la superficie en la posición (x,y). draw_surface_stretched(id,x,y,w,h) Dibuja la superficie en la posición (x,y) y escalada de forma que tenga la anchura y altura indicadas.
draw_surface_tiled(id,x,y) Dibuja la superficie en la posición (x,y) y la repite una y otra vez para que ocupe todo el cuarto. draw_surface_part(id,left,top,width,height,x,y) Dibuja la parte indicada de la superficie en la posición (x,y).
draw_surface_ext(id,x,y,xscale,yscale,rot,color,alpha) Dibuja la superficie en la posición (x,y), con factores de escala, rotación, transparencia y tiñiéndola con el color indicado (utiliza c_white si no quieres teñir la superficie).
draw_surface_stretched_ext(id,x,y,w,h,color,alpha) Dibuja la superficie en la posición (x,y) escalada para que ocupe la región indicada con factor de transparencia y tiñiéndola del color especificado.
draw_surface_tiled_ext(id,x,y,xscale,yscale,color,alpha) Dibuja la superficie repitiéndola para que
ocupe todo el cuarto pero con factores de escala, transparencia y tiñiéndola del color indicado.
draw_surface_part_ext(id,left,top,width,height,x,y,xscale,yscale,color,alpha) Dibuja la parte indicada de la superficie en la posición (x,y) pero con factores de escala, transparencia y color.
draw_surface_general(id,left,top,width,height,x,y,xscale,yscale,rot,c1,c2,c3,c4,alp ha) La función más general de dibujo. Dibuja la parte indicada de la superficie con su origen en la posición (x,y), con factores de escala, transparencia y rotada
rot grados en sentido antihorario. Además debes indicar 4 colores para cada una de las esquinas de la superficie
en este orden: esquina superior izquierda, esquina superior derecha, esquina inferior derecha y esquina inferior izquierda.
Por último, existen dos funciones para copiar superficies:
surface_copy(destination,x,y,source) Copia la superfcie en la posición (x,y) en la superficie indicada por
destination.
surface_copy_part(destination,x,y,source,xs,ys,ws,hs) Copia la parte indicada de la superfcie en la posición (x,y) en la superficie indicada por
destination.
Observa que no hay funciones para copiar parte de la pantalla a una superficie. Esto es imposible debido a la diferencia de formato entre la pantalla y las superficies. Si necesitaras usar esto puedes indicar la superficie como objetivo de dibujo y dibujar todo el room. Luego usando las funciones para copiar superficies puedes copiar partes de ella a la pantalla.
También puedes crear sprites y fondos de superficies. Esto se explica con más detalle en la sección de modificación de recursos.
Al usar superficies debes tener algunas cosas en cuenta:
•
Nunca debes cambiar el objetivo de dibujo mientras dibujas estás dibujando sobre la pantalla. Es decir, nunca uses las funciones surface_set_target() ni surface_reset_target() en el evento draw. Esto causará graves problemas en la proyección.
•
Las superficies no funcionan correctamente en modo 3D. Puedes usarlas mientras no estés en modo 3D (llamando a la función d3d_end() antes de usarlas) pero una vez que empieces a usar el modo 3D de nuevo las superficies se destruirán automáticamente.
•
Por motivos de velocidad, las superficies se mantienen en la memoria de video constantemente. Como resultado de esto, podrías perder las superficies al cambiar la resolución de la pantalla o cuando salte el salvapantallas.
•
Las superficies no se guardarán al guardar un juego.
Tiles Como ya debes saber, puedes añadir tiles a los cuartos. Una tile es una parte de un fondo. En realidad, una tile es simplemente una imagen visible: no reaccionan ante eventos y no generan colisiones. Como resultado de esto, las tiles funcionan mucho más rápido que los objetos.
Así pues, todo lo que no sufra colisiones o no reaccione ante eventos funcionará mucho mejor si lo haces con tiles. Incluso a veces es mejor utilizar un tile para mostrar los gráficos y poner por debajo un objeto invisible que se encargue de las colisiones. Para definir un tile necesitas un fondo. Sobre este fondo indicas la esquina superior (top) izquierda (left), la anchura (width) y la altura (height) de un rectángulo. La parte del fondo que queda dentro de este rectángulo pasa a ser una tile.
Puedes añadir tiles al diseñar el room, pero también puedes hacerlo mientras el juego se ejecuta. Puedes cambiar su posición, escalarlas o hacerlas transparentes. Una tile tiene las propiedades siguientes:
•
background. El fondo del que se crea la tile.
•
left, top, width, height. La parte del fondo usada en la tile (izquierda, arriba, anchura y altura).
•
x,y. Posición de la esquina superior izquierda del tile en el room.
•
depth. Profundidad del tile. Puedes escoger la profundidad que quieras, haciendo que las tiles aparezcan entre varias instancias distintas.
•
visible. Indica si es visible.
•
xscale, yscale. Factores de escalado horixontal y vertical (el tamaño normal es 1).
•
blend. Color de teñido usado al dibujar el tile.
•
alpha. Factor de transparencia utilizado al dibujar el tile.
Para cambiar las propiedades de una tile debes conocer su id. Cuando creas tiles desde el editor de rooms la id se muestra en la barra inferior de información. Pero también existen funciones para conocer la id de una tile en una posición particular.
Las funciones siguientes sirven para manejar tiles:
tile_add(background,left,top,width,height,x,y,depth) Añade una nueva tile al cuarto con las propiedades indicadas. Esta función devuelve la id de la nueva tile que se puede usar más tarde en el resto de funciones.
tile_delete(id) Elimina el tile con la id especificada. tile_exists(id) Devuelve si existe una tile con la id especificada.
Las funciones siguientes nos dan información sobre las tiles:
tile_get_x(id) Devuelve la posición x de la tile con la id especificada. tile_get_y(id) Devuelve la posición y de la tile con la id especificada. tile_get_left(id) Devuelve el valor de la propiedad left
(izquierda) de la tile con la id especificada.
tile_get_top(id) Devuelve el valor de la propiedad top (arriba) de la tile con la id especificada. tile_get_width(id) Devuelve la anchura de la tile con la id especificada. tile_get_height(id) Devuelve la altura de la tile con la id especificada. tile_get_depth(id) Devuelve la profundidad de la tile con la id especificada.
tile_get_visible(id) Devuelve si la tile con la id especificada es visible o no. tile_get_xscale(id) Devuelve el factor horizontal de escalado de la tile con la id especificada. tile_get_yscale(id) Devuelve el factor vertical de escalado de la tile con la id especificada. tile_get_background(id) Devuelve el fondo de la tile con la id especificada. tile_get_blend(id) Devuelve el color de teñido de la tile con la id especificada. tile_get_alpha(id) Devuelve el factor de transparencia de la tile con la id especificada.
Las funciones siguientes sirven para manipular las propiedades de las tiles:
tile_set_position(id,x,y) Coloca la tile con la id especificada en la posición x,y. tile_set_region(id,left,top,width,height) Cambia la región del tile con la id especificada sobre su fondo. tile_set_background(id,background) Cambia el fondo de la tile con la id especificada. tile_set_visible(id,visible) Cambia la visibilidad de la tile con la id especificada. tile_set_depth(id,depth) Cambia la profundidad de la tile con la id especificada. tile_set_scale(id,xscale,yscale) Cambia los factores de escala de la tile con la id especificada. tile_set_blend(id,color) Cambia el color de teñido de la tile con la id especificada. Sólo disponible en la versión registrada!
tile_set_alpha(id,alpha) Cambia la transparencia de la tile con la id especificada. Las funciones siguientes manejan capas de tiles, es decir, grupos de tiles que tienen la misma profundidad:
tile_layer_hide(depth) Oculta todas las tiles con la profundidad indicada. tile_layer_show(depth) Muestra todas las tiles con la profundidad indicada. tile_layer_delete(depth) Elimina todas las tiles con la profundidad indicada.. tile_layer_shift(depth,x,y) Mueve todas las tiles con la profundidad indicada siguiendo el vector (x,y). Esta función se puede usar para capas de tiles móviles.
tile_layer_find(depth,x,y) Devuelve la id de la tile con la profundidad indicada que se encuentra en la posición (x,y). Si no se encuentra ninguna tile la función devuelve -1. Cuando se encuentran varias tiles en esa posición con la misma profundidad se devuelve la primera.
tile_layer_delete_at(depth,x,y) Elimina la tile con la profundidad indicada que se encuentra en la posición (x,y). Si se encentran varias tiles en esa posición y con la profundidad indicada se eliminan todas.
tile_layer_depth(depth,newdepth) Cambia la profundidad de todas las tiles con la profundidad indicada a la nueva profundidad. Es decir, con esta función puedes mover capas enteras de tiles a otra profundidad.
El display
El display es todo el área del monitor. Tiene varias características como el tamaño (típicamente 1024x768 ó 1280x1024), la profundidad de color (que es el número de bits que se utilizan para representar 1 píxel) y suele ser de 16 bits (color de alta densidad) ó 32 bits (color verdadero) y la frecuencia de refresco, que es el número de veces por segundo que se refresca el display, es decir, cuántas veces por segundo se vuelven a dibujar los píxeles en la pantalla (típicamente entre 60 y 120). Estos parámetros se pueden cambiar desde las propiedades de la pantalla en Windows. Pero para algunos juegos, sobre todo los que se ejecuten en pantalla completa, es importante poder controlar estos aspectos. Todos ellos se pueden inicializar desde la pestaña Game Settings. Para cambiar estos parámetros durante el juego Game Maker dispone de un grupo de funciones que veremos a continuación. Debes tener en cuenta que al cambiar estos parámetros el sistema necesitará un poco de tiempo para volver a ajustarlo todo. Las funciones para cambiar el modo sólo están disponibles en la versión registrada de Game Maker.
display_get_width() Devuelve la anchura del display en píxeles. display_get_height()Devuelve la altura del display en píxeles. display_get_colordepth()Devuelve la profundidad de color en bits. display_get_frequency()Devuelve la frecuencia de refresco del monitor. display_set_size(w,h) Cambia la altura y anchura del display a los nuevos valores indicados. La función devuelve true si los cambios se aplicaron con éxito y false en caso contrario (Debes tener en cuenta que sólo algunas combinaciones están permitidas, por ejemplo 800x600, 1024x768 ó 1280x1024).
display_set_colordepth(coldepth) Cambia la profundidad de color a la especificada. En general sólo se permite usar profundidad de color de 16 ó 32 bits. La función devuelve true si los cambios se aplicaron con éxito y false en caso contrario.
display_set_frequency(frequency) Cambia la frecuencia de refresco del monitor a la especificada. Sólo unas pocas frecuencias están permitidas. Por ejemplo, puedes ajustar este valor a 60 y usar un room_speed del mismo valor para lograr animaciones fluidas de 60 frames por segundo. La función devuelve true si los cambios se aplicaron con éxito y false en caso contrario.
display_set_all(w,h,frequency,coldepth)
Cambia todos los valores a la vez. Para valores que no quieras cambiar
utiliza -1. La función devuelve true si los cambios se aplicaron con éxito y false en caso contrario.
display_test_all(w,h,frequency,coldepth)
Comprueba si los valores especificados están permitidos. La función no
aplica los valores al display, sólo chequea si son válidos. Para los valores que no quieras cambiar usa el valor -1. La función devuelve true si los cambios se pueden aplicar y false en caso contrario.
display_reset() Resetea las características del display a los originales, es decir, a los que estaban presentes cuando se inició el programa.
A veces es útil poder conocer la posición del puntero en el display o poder cambiarla. Para ello se usan las funciones siguientes:
display_mouse_get_x() Devuelve la coordenada x del puntero en el display. display_mouse_get_y()Devuelve la coordenada x del puntero en el display. display_mouse_set(x,y) Cambia la posición del puntero a los valores indicados.
La ventana
El juego se ejecuta en una ventana. Esta ventana tiene varias propiedades como si tiene borde, si ocupa toda la pantalla...Normalmente estos valores se fijan desde la opción Game Settings. Pero también puedes cambiarlos durante el juego. Para ello puedes usar las funciones siguientes:
window_set_visible(visible) Hace que la ventana se vuelva visible o invisible. Normalmente la ventana es visible durante todo el juego. Cuando la ventana sea invisible el programa no ejecutará ni recibirá los eventos del teclado.
window_get_visible() Devuelve si la ventana es visible. window_set_fullscreen(full) Hace que la ventana ocupe toda la pantalla (modo pantalla completa) o no. window_get_fullscreen() Devuelve si la ventana ocupa toda la pantalla. window_set_showborder(show) Indica si el borde alrededor de la ventana debe mostrarse (si la ventana está a pantalla completa el borde no se muestra).
window_get_showborder() Devuelve si el borde de la ventana es visible cuando ésta no está a pantalla completa. window_set_showicons(show) Indica si deben mostrarse los iconos de la ventana (minimizar, maximizar y cerrar). Si la ventana está a pantalla completa no se muestran.
window_get_showicons() Devuelve si los iconos de la ventana son visibles. window_set_stayontop(stay) Indica si la ventana de be mostrarse siempre por encima de otras ventanas que puedan existir. window_get_stayontop() Devuelve si la ventana se mantiene siempre por encima de las demás. window_set_sizeable(sizeable) Indica si el jugador puede cambiar el tamaño de la ventana. El jugador sólo podrá hacer esto si el borde de la ventana es visible y la ventana no está a pantalla completa.
window_get_sizeable() Devuelve si el jugador puede cambiar el tamaño de la ventana. window_set_caption(caption) Indica el título de la ventana. Normalmente esto se especifica al definir el room y se cambia usando la variable room_caption. Por ello, esta función no es útil a no ser que dibujes tú mismo el room en lugar de dejar que Game Maker lo haga automáticamente. El título de la ventana sólo es visible cuando ésta tiene borde visible y no está a pantalla completa.
window_get_caption() Devuelve el título de la ventana. window_set_cursor(curs) Indica el puntero que se usará en la ventana. Puedes indicar una de las siguientes constantes: cr_default cr_none cr_arrow cr_cross cr_beam cr_size_nesw cr_size_ns cr_size_nwse cr_size_we cr_uparrow cr_hourglass cr_drag cr_nodrop cr_hsplit cr_vsplit cr_multidrag cr_sqlwait
cr_no cr_appstart cr_help cr_handpoint cr_size_all Por ejemplo, para hacer que no se vea el cursor o puntero usa window_set_cursor(cr_none).
window_get_cursor() Devuelve el cursor utilizado en la ventana. window_set_color(color) Indica el color de la parte de la ventana que no se usa para mostrar el room. window_get_color() Devuelve el color de la ventana. window_set_region_scale(scale,adaptwindow) Si la ventana es mayor que el cuarto actual el cuarto se muestra centrado en la ventana. Con esta función es posible indicar si queremos que el cuarto sea escalado para que ocupe toda la ventana o una parte concreta. Si usamos el valor 1 el cuarto no será escalado. Si usamos el valor 0 el cuarto se escalará para ocupar toda la ventana. Si usas un valor negativo el cuarto será escalado al máximo valor dentro de la ventana que le permita seguir conservando su relación de aspecto entre altura y anchura. El segundo parámetro, adaptwindow, indica si el tamaño de la ventana debe adaptarse al cuarto si éste, una vez escalado, no entra por completo dentro de la misma. Esto sólo suele ser útil cuando el primer parámetro (el que indica el escalado del cuarto) es positivo.
window_get_region_scale() Devuelve el factor de escala de la región de dibujo. La ventana tiene una posición en la pantalla y un tamaño. Cuando hablamos de posición y tamaño siempre nos referimos a la ventana sin los bordes. Puedes cambiar estos valores aunque raramente querrás utilizarlo desde el juego. Normalmente, se determinan automáticamente o el jugador escoge los que le interesan. Las funciones siguientes te permiten cambiar estos aspectos de las ventanas. Observa que estas funciones sólo funcionarán si la ventana no está a pantalla completa. Si la ventana está a pantalla completa los cambios no se aplicarán hasta que la ventana vuelva al modo normal.
window_set_position(x,y) Indica la posición de la ventana. window_set_size(w,h) Indica el nuevo tamaño de la ventana. Observa que si el tamaño indicado es menor que la región de dibujo se mantendrá lo suficientemente grande como para que la región entre por completo dentro de él.
window_set_rectangle(x,y,w,h) Indica la nueva posición y medidas de la ventana (es como usar las dos funciones anteriores a la vez).
window_center() Centra la ventana en la pantalla. window_default() Da a la ventana los valores por defecto de tamaño y posición (centrada). window_get_x() Devuelve la coordenada x de la ventana. window_get_y()Devuelve la coordenada y de la ventana. window_get_width()Devuelve la anchura de la ventana. window_get_height()Devuelve la altura de la ventana. Puede que nunca necesites utilizar las funciones de posicionamiento de l ventana ya que Game Maker lo realizará automáticamente.
En algunas ocasiones puede que quieras conocer la posición del ratón respecto a la ventana (normalmente se usa la posición del ratón respecto a un cuarto o a una vista). Las siguientes funciones sirven para esto:
window_mouse_get_x() Devuelve la coordenada x del puntero en la ventana. window_mouse_get_y()Devuelve la coordenada y del puntero en la ventana. window_mouse_set(x,y) Indica la nueva posición del puntero en la ventana.
Vistas Como ya deberías saber puedes definir hasta 8 vistas diferentes al diseñar un cuarto. Una vista se define por su área en el cuarto y por su puerto o viewport en la pantalla (la región de dibujo dentro de la ventana). Usando vistas puedes mostrar diferentes partes del cuarto en diferentes lugares de la pantalla. Además, puedes asegurar que un objeto concreto siempre permanezca visible en una vista.
Puedes controlar las vistas con código. Puedes hacerlas visibles o invisibles, cambiar su posición o tamaño dentro de la región de dibujo o en el cuarto (lo cual es muy útil cuando no indicas ningún objeto que deba ser seguido por la vista). Puedes cambiar el tamaño de los bordes horizontal y vertical alrededor del objeto a ser seguido. Si el objeto que quieres que sea seguido cambia a otro tipo de objeto durante el juego (por ejemplo, si acumula mucha experiencia y evoluciona en un personaje más poderoso) puede que las vistas siguientes no lo sigan correctamente. Para solucionar esto, puedes indicar este código en el evento de creación de todos los objetos del personaje (en este ejemplo se supone que la vista principal es la vista 0):
{ view_object[0] = object_index; } Las siguientes variables actúan sobre las propiedades de las vistas. Todas, excepto las dos primeras, son vectores con 8 elementos: el primer elemento (0) indica la primera vista y el último elemento (7) la última.
view_enabled Indica si las vistas están activadas en el cuarto actual. view_current* La vista que actualmente se está dibujando (0...7). Usa esta variable sólo en el evento draw. Por ejemplo, puedes chequear el valor de esta variable para dibujar algo sólo en unas vistas y no en otras. El valor de esta variable no se puede cambiar.
view_visible[0..7] Devuelve si la vista indicada es visible en la pantalla view_xview[0..7] Posición X de la vista en el cuarto. view_yview[0..7] Posición Y de la vista en el cuarto. view_wview[0..7] Anchura de la vista en el cuarto. view_hview[0..7] Altura de la vista en el cuarto. view_xport[0..7] Posición X del puerto en la región de dibujo. view_yport[0..7] Posición Y del puerto en la región de dibujo. view_wport[0..7] Anchura del puerto en la región de dibujo.
view_hport[0..7] Altura del puerto en la región de dibujo. view_angle[0..7] Ángulo de rotación usado para la vista en el cuarto (grados en sentido antihorario). view_hborder[0..7] Tamaño en píxeles del borde horizontal alrededor del objeto a seguir por la vista. view_vborder[0..7] Tamaño en píxeles del borde vertical alrededor del objeto a seguir por la vista. view_hspeed[0..7] Velocidad horizontal máxima de la vista. view_vspeed[0..7] Velocidad vertical máxima de la vista. view_object[0..7] Objeto cuya instancia debe permanecer visible en la vista. Si hay varias instancias de este objeto se usará la primera. Puedes asignar una id de una instancia a esta variable para indicar una instancia concreta que quieras seguir.
Observa que el tamaño de la imagen en la pantalla se calcula a partir de las vistas visible al comienzo del cuarto. Si cambias las vistas durante el juego puede que ya no entren correctamente en la pantalla. Para solucionar esto, puedes adaptar tú mismo el tamaño de la pantalla con las siguientes funciones:
window_set_region_size(w,h,adaptwindow) Indica la anchura y altura de la región de dibujo en la ventana. adaptwindow indica si el tamaño de la ventana debe adaptarse si la región de dibujo no cabe dentro de ella. La ventanasiempre se adaptará si usas escalado fijo (Consulta la función window_set_region_scale() en el capítulo La ventana).
window_get_region_width() Devuelve la anchura actual de la región de dibujo. window_get_region_height()Devuelve la altura actual de la región de dibujo. A veces necesitarás conocer la posición del ratón. Normalmente puedes hacer esto con las variables mouse_x y mouse_y. Cuando hay muchas vistas, estas variables dan la posición del ratón respecto a la vista en la que el ratón se encuentra. Pero puede ser que en alguna ocasión necesites conocer la posición del ratón respecto a una vista concreta, incluso cuando el ratón se encuentre fuera de esa vista. Para hacer esto, puedes usar las siguientes funciones:
window_view_mouse_get_x(id) Devuelve la coordenada x del ratón respecto a la vista indicada. window_view_mouse_get_y(id) Devuelve la coordenada y del ratón respecto a la vista indicada. window_view_mouse_set(id,x,y) Indica la posición del ratón respecto a la vista indicada. window_views_mouse_get_x()Devuelve la coordenada x del ratón respecto a la vista en la que se encuentra (es lo mismo que mouse_x).
window_views_mouse_get_y()Devuelve la coordenada y del ratón respecto a la vista en la que se encuentra (es lo mismo que mouse_y).
window_views_mouse_set(x,y) Indica la posición del ratón respecto a la primera vista que es visible.
Transiciones Al moverse de una room a otra puedes seleccionar una transición. También puedes seleccionar la transición que se utilizará en el frame siguiente sin tener que cambiar de cuarto. Para esto usamos la variable transition_kind. Asignándole un valor entre 1 y 13 se usará la
transición correspondiente. Si usamos un valor igual a 0 significa que no se aplicará ninguna transición. La transición sólo se aplicará la próxima vez que se dibuje un frame.
transition_kind Indica la transición al próximo frame: 0 = sin transición 1 = Crear desde la izquierda 2 = Crear desde la derecha 3 = Crear desde arriba 4 = Crear desde abajo 5 = Crear desde el centro 6 = Cambiar desde la izquierda 7 = Cambiar desde la derecha 8 = Cambiar desde arriba 9 = Cambiar desde abajo 10 = Mezclar desde la izquierda 11 = Mezclar desde la derecha 12 = Mezclar desde arriba 13 = Mezclar desde abajo
Observa que es muy sencillo crear tus propias transiciones. Por ejemplo, para crear un efecto de oscurecimiento puedes dibujar un rectángulo negro que tape toda la pantalla y hacer que su factor de transparencia vaya aumentando poco a poco. O puedes cambiar la posición y el tamaño de una vista para mover el cuarto fuera de la zona visible. Utilizando superficies y partículas puedes crear transiciones realmente asombrosas!
Redibujando la pantalla Normalmente al final de cada paso del juego (step) el cuarto se dibuja en la pantalla. Pero en algunas ocasiones puede que quieras dibujar el cuarto en otro momento. Esto ocurre cuando tu programa toma el control, por ejemplo: antes de que el programa se congele durante un largo período es recomendable dibujar el cuarto. O cuando el juego muestra un mensaje y espera a que el jugador presione un tecla para continuar es necesario dibujar el cuarto en medio de esta operación. Existen dos funciones para hacer esto:
screen_redraw() Redibuja la pantalla ejecutando todos los eventos de dibujo. screen_refresh() Refresca la pantalla usando la imagen del cuarto actual sin ejecutar los eventos de dibujo. Para entender la segunda función es necesario ver cómo trabaja internamente el mecanismo de dibujo. Internamente existe una imagen donde se dibuja todo. Esta imagen no es visible en la pantalla. Sólo al final de un paso del juego, cuando se ha dibujado todo, la imagen de la pantalla se reemplaza por esta imagen interna (esta técnica se conoce como “double buffering”). La primera función scrren_redraw() dibuja la imagen interna y luego refresca la imagen de la pantalla. La segunda funciónscreen_refresh() sólo refresca la imagen de la pantalla, pero no actualiza la imagen interna.
Ahora deberías entender por qué no puedes usar las acciones o funciones de dibujo en otros eventos a parte de los eventos de dibujo. Si lo haces así, dibujarías elementos en la imagen interna pero no en la pantalla. Cuando se ejecuta el evento draw, primero se dibuja el fondo del cuarto, tapando y borrando todo lo que habías dibujado en la imagen interna. Pero cuando usas screen_refresh() después de dibujar algo, la imagen se volverá visible en la pantalla. Por ejemplo, podemos crear un trozo de código que dibuje un texto en la pantalla, llame a la función de refresco y espere a que el jugador pulse una tecla:
{ draw_text(screen_width/2,100,'Pulsa cualquier tecla para continuar'); screen_refresh(); keyboard_wait(); } Observa que al dibujar en un evento distinto del evento draw sólo puedes dibujar en la imagen interna, ¡nunca en una vista! Así que las coordenadas que usas serán las mismas que si no hubiera vistas. Ten cuidado al usar esta técnica: asegúrate de que has entendido bien como funciona y ten en cuenta que el refresco de la pantalla tarda un poco de tiempo.
Cuando estás dibujando el propio cuarto puede ser útil no dejar que se dibuje automáticamente. Por ejemplo, puedes querer que el cuarto sólo se dibuje cada 5 pasos. Para ello puedes usar la función siguiente:
set_automatic_draw(value) Indica si el cuarto se debe dibujar automáticamente (true por defecto) o no (false). Finalmente, hay una función que te permite sincronizar el dibujo con la frecuencia de refresco del monitor:
set_synchronization(value) Indica si se debe sincronizar el dibujo con la frecuencia de refresco del monitor. También puedes obligar a que el programa espere hasta la próxima sincronización vertical:
screen_wait_vsync() Espera hasta la siguiente sincronización vertical del monitor.
Música y sonido Actualmente, el sonido juega un papel crucial en los videojuegos de computadora. Estos deben ser agregados al juego en forma de recursos de sonido, pero asegúrate de que los nombres que uses sean nombres de variable válidos. Como ya habrás leído, puedes indicar cuatro diferentes tipos de sonido: normal, música de fondo, 3D, y sonidos que deben ser reproducidos a través de un reproductor multimedia.
Los sonidos normales son usados para efectos de sonido y por lo general, son archivos WAV. Puedes reproducir muchos del tipo NORMAL a la vez (incluso puedes reproducir múltiples instancias del mismo sonido a la vez) y se caracterizan por podérseles aplicar cualquier tipo de efectos en ellas.
El sonido de fondo comúnmente consiste en archivos MIDI pero algunas veces también pueden usarse WAV y a estos también se les puede aplicar efectos de sonido. La única diferencia que tienen con los sonidos NORMALES, es que los de fondo solo pueden reproducirse uno a la vez. Si reproduces un sonido, el que previamente se había estado reproduciendo es parado.
El uso y características del sonido 3D son descritos más adelante, en el subcapítulo “Sonidos 3D”. Son sonidos mono (WAV o MIDI). Finalmente, si quieres usar otro tipo de sonido, en partículas mp3, estos no pueden ser reproducidos por DirectX. En su lugar, el reproductor multimedia normal debe ser usado para esto, lo cual lo hace mucho más limitado, ya que solo puedes reproducir un sonido a la vez, no se le pueden aplicar efectos (ni siquiera cambio de volumen) y el tiempo (p.e. los sonidos rebobinados son de calidad pobre). También puede haber retardos en reproducirlos. Se recomienda altamente no usar este tipo de media, ya que hay algunas computadoras que probablemente no estén capacitadas para reproducirlos).
Puedes encontrar información sobre las funciones de audio en las secciones siguientes: Funciones básicas de sonido Efectos de sonido Sonido 3D Música desde el CD
Funciones básicas de sonido Existen cinco funciones básicas relacionadas con sonido: 2 para reproducir un sonido, una para ver si un sonido se está reproduciendo, y dos más para parar el sonido. La mayoría necesita el índice del sonido como argumento. El nombre del sonido representa su índice, pero también puedes almacenar el índice en una variable, y usarla como argumento.
sound_play(index) Reproduce el sonido indicado una vez. Si el sonido es música de fondo, la actual es parada. sound_loop(index) Reproduce el sonido indicado, rebobinándolo continuamente. Si el sonido es música de fondo, la actual es parada.
sound_stop(index) Para el sonido indicado. Si hay varios sonidos con este índice reproduciéndose simultáneamente, todos son parados.
sound_stop_all() Para todos los sonidos. sound_isplaying(index) Devuelve si (una copia de) el sonido indicado se esta reproduciendo. Nótese que esta función devuelve true cuando el sonido realmente esta reproduciéndose a través de los altavoces (línea de salida). Después de llamar la función de reproducir un sonido, no llega a los altavoces inmediatamente, lo que quiere decir que mientras esto no suceda, esta función devolverá false. Parecido es si cuando el sonido es parado y lo escuchas por un tiempo más (p.e. por el eco), la función devolverá true.
Es posible usar efectos de sonido. en lo particular puedes cambiar el volumen y pan (si el sonido viene del altavoz izquierdo o derecho). En estos casos el volumen solamente puede ser reducido. Estas funciones no trabajan con archivos que se reproducen a través del reproductor multimedia.
sound_volume(index,value) Cambia el volumen del sonido indicado (0 = bajo, 1 = alto,) sound_global_volume(value) Cambia el volumen global de todos los sonidos (0=bajo, 1=alto) sound_fade(index,value,time) Cambia el volumen del sonido indicado a el nuevo value (0=bajo, 1=alto) durante el tiempo indicado (en milisegundos). Esto puede ser usado para ascender o descender el sonido (p.e. para entradas).
sound_pan(index,value) Cambia el pan del sonido indicado (-1=izquierda, 0,centro, 1=derecha). sound_background_tempo(factor) Cambia el tempo de la música de fondo (si es un archivo midi). factor indica el factor a multiplicar por el tempo. Un valor de 1 corresponde al tempo normal. Valores mayores corresponden a un tempo más rápido, menores a un tempo más lento. Debe oscilar entre 0.01 y 100.
A demás de los archivos MIDI y WAV (y mp3) existe un cuarto tipo de archivo que puede ser reproducido: archivos direct music. Tienen la extensión .sgt. Dichos archivos frecuentemente se refieren a otros archivos describiendo p.e. banda o género. Para encontrar estos archivos, el sistema de sonido debe saber donde se localizan. Con este propósito, puedes usar las siguientes funciones para estableces el directorio de búsqueda de archivos. NOTA: Debes agregar los archivos tu mismo. Game Maker no incluye automáticamente dichos archivos adicionales.
sound_set_search_directory(dir) Establece el directorio en donde se deben buscar archivos direct music. El string DIR no debe incluir la diagonal al final.
Efectos de sonido Esta funcionalidad esta disponible únicamente en la versión registrada de Game Maker.
Los efectos de sonido pueden ser usados para cambiar la manera en que los sonidos normales y música de fondo, suena. Ten en cuenta que los efectos de sonidos solo aplican en archivos WAV y MIDI, no a los mp3. Esta sección describe las funciones que existen para usar y
cambiar efectos de sonido. Ten también en cuenta que para poder usar estas funciones necesitas una buena comprensión de cómo el sonido y los sintetizadores trabajan. No se han agregado explicaciones de los diferentes parámetros que se dan. Busca en la web o en libros para más información.
Para aplicar un efecto de sonido a un sonido en particular, puedes indicarlo cuando definas el sonido como recurso o puedes usar la siguiente función:
sound_effect_set(snd,effect) Establece una (combinación de) efecto(s) de sonido para el sonido indicado. EFFECT puede ser cualquiera de estos valores:
se_none se_chorus se_echo se_flanger se_gargle se_reverb se_compressor se_equalizer Puedes establecer una combinación de efectos, sumando los valores. Entonces, por ejemplo, puedes usar:
sound_effect_set(snd,se_echo+se_reverb); para obtener una combinación de los efectos echo y reverb.
Todos los efectos tienen distintas configuraciones, una vez que el efecto ha sido aplicado en un sonido. El orden en esto es crucial. Primero aplicas el efecto al sonido y después estableces sus parámetros. Una vez que reapliques los efectos al sonido, la configuración se borra y necesitas establecerla de nuevo. Nótese que todos los parámetros deben oscilar en un rango en particular, según se indique a continuación. Las siguientes funciones existen para cambiar la configuración de los efectos de sonido: *Al final de cada parámetro, entre paréntesis está el rango que se necesita usar p.e. (0 a 100,pred.50) pred.=predeterminado
sound_effect_chorus(snd,wetdry,depth,feedback,frequency,wave,delay,phase) Establece los parámetros para el efecto de chorus al sonido indicado. Los siguientes parámetros son requeridos: WETDRY Radio de la señal wet (procesada) a la señal dry (no procesada).(0 a 100,pred.50) DEPTH Porcentaje con el cual el tiempo de espera es modulado por el oscilador de baja frecuencia, en cientos por punto de porcentaje. (0 a 100,pred.25) FEEDBACK Porcentaje de señal de salida para respaldar la entrada del sonido. (-99 a 100,pred.0) FREQUENCY Frecuencia del LFO (0 a 10,pred.0) WAVE Forma de la onda del LFO (0- triangular, 1-onda,pred.1) DELAY Tiempo (número) en milisegundos que la entrada debe esperar antes de ser reproducida de nuevo (0 a 20,pred.0) PHASE Fase diferencial entre LFOs izquierdos o derechos.(0 a 4,pred.2)
sound_effect_echo(snd,wetdry,feedback,leftdelay,rightdelay,pandelay) Establece los parámetros para el efecto de echo al sonido indicado. Los siguientes parámetros son requeridos: WETDRY Radio de la señal wet (procesada) a la señal dry (no procesada).(0 a 100,pred.50) FEEDBACK .Porcentaje de señal de salida para respaldar la entrada del sonido. (-99 a 100,pred.0) LEFTDELAY. Retraso para el canal izquierdo, en milisegundos. (1 a 2000,pred.333) RIGHTDELAY. Retraso para el canal derecho, en milisegundos. (1 a 2000,pred.333) PANDELAY. Indica si el LEFTDELAY y RIGHTDELAY deben intercambiarse con cada echo que sucede.(0 y 1,pred.0)
sound_effect_flanger(snd,wetdry,depth,feedback,frequency,wave,delay,phase) Establece los parámetros para el efecto de flanger al sonido indicado. Los siguientes parámetros son requeridos: WETDRY Radio de la señal wet (procesada) a la señal dry (no procesada).(0 a 100,pred.50) DEPTH Porcentaje con el cual el tiempo de espera es modulado por el oscilador de baja frecuencia, en cientos por punto de porcentaje. (0 a 100,pred.25) FEEDBACK Porcentaje de señal de salida para respaldar la entrada del sonido. (-99 a 100,pred.0) FREQUENCY Frecuencia del LFO (0 a 10,pred.0) WAVE Forma de la onda del LFO (0- triangular, 1-onda,pred.1) DELAY Tiempo (número) en milisegundos que la entrada debe esperar antes de ser reproducida de nuevo (0 a 20,pred.0) PHASE Fase diferencial entre LFOs izquierdos o derechos.(0 a 4,pred.2)
sound_effect_gargle(snd,rate,wave) Establece los parámetros para el efecto de gargle al sonido indicado. Los siguientes parámetros son requeridos:
RATE Variable de modulación,en Hertz. (1 a 1000, pred.1) WAVE Forma de la onda del LFO (0- triangular, 1-onda,pred.1)
sound_effect_reverb(snd,gain,mix,time,ratio) Establece los parámetros para el efecto de reverb al sonido indicado. Los siguientes parámetros son requeridos:
GAIN Señal ganada por la entrada, en decibels (dB) (-96 a 0,pred.0) MIX Mezcla de la repetición, en dB. (-96 a 0,pred.0) TIME Tiempo de la repetición, en milisegundos (0.001 a 3000,pred.1000) RATIO
Radio de frecuencia (0.001 a 0.999,pred.0.001)
sound_effect_compressor(snd,gain,attack,release,threshold,ratio,delay) Establece los parámetros para el efecto de compressor al sonido indicado. Los siguientes parámetros son requeridos:
GAIN Señal de salida ganada después de la compresión (-60 a 60, pred.0) ATTACK Tiempo antes de que la compresión termine (0.01 a 500,0.01) RELEASE Velocidad a la que la entrada es parada después de que la entrada llegue debajo del umbral.(50 a 3000,pred.50)
RATIO
Radio de frecuencia (0.001 a 0.999,pred.0.001)
DELAY Tiempo (número) en milisegundos que la entrada debe esperar antes de ser reproducida de nuevo (0 a 20,pred.0)
sound_effect_equalizer(snd,center,bandwidth,gain) Establece los parámetros para el efecto de equalizer al sonido indicado. Los siguientes parámetros son requeridos:
center Fecuencia central, en Hertz (80 a 16000) bandwidth Banda ancha, en semitonos (1 a 36) gain Ganancia. (-15 a 15)
Sonido 3D Esta funcionalidad esta disponible únicamente en la versión registrada de Game Maker.
Sonido 3D se refiera al sonido que tiene una posición (y velocidad) con respecto al oyente. A pesar de que es más prominente usarlo en juegos 3D, también puede ser efectivamente aplicado en juegos 2D. La idea es que el sonido tenga una posición en el espacio. En todas las funciones, se asume que el oyente está en una posición (0,0,0). El sistema calcula como el receptor estaría oyendo el sonido, y lo adapta acorde a esto. Este efecto es especialmente bueno cuando tienes un buen equipo de sonido. De cualquier manera, esto también funciona en altavoces pequeños.
Además de una posición, el sonido también puede tener una velocidad. Esto lleva al muy conocido efecto Doppler, que están correctamente modelado. Finalmente el sonido puede tener una orientación y, una vez más, el sonido es adaptado por consiguiente. Game Maker cuenta con la modalidad de sonido 3D, a través de las funciones que se indican abajo, pero solo funcionan con recursos de sonido que fueron indicados como 3D. (La desventaja es que los sonidos 3D son mono, no estéreo).
sound_3d_set_sound_position(snd,x,y,z)
Establece la posición al sonido indicado con respecto a la posición del
oyente en el espacio. Valores en el eje x incrementan de izquierda a derecha, en el eje y de arriba hacia abajo, y en el eje z de cerca a lejos. Estos valores son medidos en metros. El volumen con el que el sonido se debe oír depende en esta medida, de la misma manera a como ocurre en el mundo real.
sound_3d_set_sound_velocity(snd,x,y,z)
Establece la velocidad al sonido indicado con el vector indicado en el
espacio. Por favor note que estableciendo la velocidad no significa que la posición cambie. La velocidad es usada sólo para calcular efectos doppler. Entonces, si quieres mover un sonido debes cambiar tu mismo la posición del sonido.
sound_3d_set_sound_distance(snd,mindist,maxdist)
Establece la distancia mínima a la cual el sonido está en
su máxima amplitud, y la distancia máxima a la cual el sonido ya no se debe oir. Entonces, cuando la distancia oscila entre 0 y la máxima distancia, el sonido esta en su máxima amplitud. Cuando se oscile entre la distancia mínima y la máxima, la amplitud decrece lentamente hasta que la distancia máxima es alcanzada, o el sonido ya no es audible. Por predeterminado (default), la distancia mínima es 1 metro y la máxima 1 billón de metros.
sound_3d_set_sound_cone(snd,x,y,z,anglein,angleout,voloutside
Normalmente el sonido tiene la misma amplitud, a una distancia dada, en todas las direcciones. Puedes establecer un cono de sonido para cambiar esto y dirigir el sonido. x,y,z especifican la dirección del cono. ANGLEIN especifica el ángulo interior. Si el oyente esta dentro de este ángulo, puede escuchar el sonido en su volumen normal. ANGLEOUT especifica el ángulo exterior. Cuando el oyente esta afuera de este ángulo, el volumen es indicado con VOLOUTSIDE. Para ser precisos, VOLOUTSIDE es un número negativo que indica el número de cientos de decibeles que deben ser sustraídos del volumen interior. Entre el ángulo interior y exterior, el volumen decrece gradualmente.
Música desde el CD Esta funcionalidad esta disponible únicamente en la versión registrada de Game Maker.
Existen también funciones para tratar con la reproducción de música desde un CD:
cd_init()Debe llamarse antes de usar las otras funciones, así como cuando se cambia un CD (o simplemente de tiempo a tiempo). cd_present()Devuelve si hay un cd en el dispositivo CD predeterminado. cd_number()Devuelve el numero de pistas en el CD. cd_playing()Devuelve si el CD se está reproduciendo. cd_paused().Devuelve si el CD esta pausado o parado. cd_track()Devuelve el número de la pista que se está reproduciendo (1=la primera) cd_length().Devuelve la longitud total del CD en milisegundos. cd_track_length(n). Devuelve la longitud de una pista n del CD en milisegundos cd_position().Devuelve la posición actual en el CD en milisegundos. cd_track_position().Devuelve la posición actual de la pista reproducida, en milisegundos. cd_play(first,last). Le indica al CD desde que pista a que pista debe reproducir. Si deseas que reproduzca todo el CD, indica 1 y 1000 como argumentos.
cd_stop()Deja de reproducir. cd_pause().Pausa la reproducción. cd_resume().Continua la reproducción. cd_set_position(pos). Establece la posición en el CD, en milisegundos. cd_set_track_position(pos). Establece la posición de la pista actual en milisegundos. cd_open_door()Abre la caja del Reproductor de CDs. cd_close_door()Cierra la caja del Reproductor de CDs. Hay una función general para acceder la funcionalidad multimedia de Windows:
MCI_command(str) Esta función envía el comando al sistema multimedia de Windows usando el Media Control Interface (MCI, Interfaz de Control de Medios). Devuelve la cadena de texto de resultado. Puedes usar esta función para controlar cualquier tipo de
hardware multimedia. Para más información sobre este comando, consulta la ayuda de Windows. Por ejemplo,
MCI_command('play
cdaudio from 1') pone a sonar el cd (después de inicializalo correctamente). Esta función es sólo para uso avanzado.
Ventanas, highscores, y otros pop-ups
En esta sección vamos a aprender algunas funciones que pueden ser usadas para mostrar ventanas con videos, imágenes, etc...para mostrar mensajes y preguntas al jugador, y mostrar la tabla de mayores puntajes. Esta sección está dividida en los temas: Ventanas Preguntas y mensajes pop-up Tablas de récords
Ventanas Muchos juegos tienen ventanas, las cuales pueden mostrar un video, una imagen o algún texto. Frecuentemente son usadas al principio del juego (como intro), al principio de un nivel, o al final del juego (p.e. los créditos). En Game Maker, dichas ventanas con texto, imágenes o video pueden mostrarse en cualquier momento del juego, y mientras esto sucede, el juego es temporalmente pausado. Estas son las funciones:
show_text(fname,full,backcol,delay) Muestra una ventana con texto. fname es el nombre del archive de texto (.txt o .rtf). Debes poner este archivo en el directorio del juego tu mismo. También, cuando crees una versión independiente del juego (standalone), no debes olvidar incluir este archive ahí. full indica si se debe mostrar en pantalla completa. BACKCOL es el color de fondo, y DELAY es el retardo en segundos antes de volver al juego (aunque el jugador siempre tendrá la posibilidad de volver al juego manualmente, haciendo clic con el Mouse)
show_image(fname,full,delay) Muestra una ventana con una imagen. fname es el nombre del archivo de imagen (únicamente .bmp, .jpg y .wmf), pero debes poner los archivos en el directorio del juego tu mismo. FULL indica si deseas mostrarlo en pantalla completa. DELAY es el retardo en segundos antes de volver al juego.
show_video(fname,full,loop) Muestra una ventana de video. FNAME es el nombre del archivo de video (.avi,.mpg), pero debes poner este archivo en el directorio del juego tu mismo. FULL indica si deseas mostrarlo en pantalla completa. DELAY es el retardo en segundos antes de volver al juego.
show_info() Muestra la información del juego. load_info(fname) Carga la información del juego con el nombre de archive FNAME, el cual debería ser un archivo RTF. Esto hace posible mostrar diferentes archivos de ayuda, en diferentes momentos.
Preguntas y mensajes “pop-up” Existen otras funciones para mostrar mensajes, preguntas, un menú con opciones, o un cuadro de diálogo en el cual el jugador puede insertar un número, un string, indicar un color o un nombre de archivo:
show_message(str) Muestra un cuadro de dialogo con un string STR como mensaje. show_message_ext(str,but1,but2,but3) Muestra un cuadro de diálogo con el string STR como mensaje, más un máximo de 3 botones. But1,but2 y but3 contienen el texto de cada botón. Un string vacío significa que el botón no se mostrará. En los textos puedes usar el símbolo “&” para indicar que el siguiente carácter debe ser usado como acceso directo a ese botón (p.e. “&Acepto”, si se presiona “A” se simula la presión del botón). Esta función devuelve el número del botón presionado (0 si el usuario presiona la tecla ESC).
show_question(str) Muestra una pregunta; devuelve true cuando el usuario elige “yes” y de otra manera, false. get_integer(str,def) Pregunta un número al jugador por medio de un cuadro de diálogo. STR es el mensaje, DEF es el número predeterminado que se mostrará.
get_string(str,def) Pregunta un string al jugador en un cuadro de diálogo. STR es el mensaje, DEF es el valor predeterminado. message_background(back) Establece la imagen de fondo par a los cuadros de diálogo para cualquiera de las funciones arriba. BACK debe ser uno de los archivos definidos en el juego. Si BACK es parcialmente transparente, también lo será el cuadro de diálogo (solo para Windows 2000 o superior).
message_alpha(alpha) Establece la traslucidez de los cuadros de diálogo para cualquiera de las funciones anteriores. ALPHA debe oscilar entre 0 (completamente traslúcido) y 1 (completamente opaco) (solo para WIN2000 o superior).
message_button(spr) Establece el sprite usado para los botones en los cuadros de diálogo. SPR debe ser un sprite consistiendo de 3 imágenes, la primera indica el botón cuando no esta presionado y el mouse está alejado, el Segundo indica el botón cuando el mouse está sobre el pero no presionado, y el tercero cuando del botón es presionado.
message_text_font(name,size,color,style) Establece la fuente para el texto de los cuadros de diálogo (esta debe ser una fuente normal de Windows, no una de las fuentes de recurso que usas en tu juego!) STYLE indica el estilo de la fuente (0=normal, 1=negrita, 2=cursiva, 3=negrita y cursiva).
message_button_font(name,size,color,style) Establece la fuente para los botones en los cuadros de diálogo. STYLE indica el estilo de fuente. (0=normal, 1=negrita, 2=cursiva, 3=negrita y cursiva).
message_input_font(name,size,color,style) Establece la fuente
para el campo de entrada en los cuadros de
diálogo. STYLE indica el estilo de fuente. (0=normal, 1=negrita, 2=cursiva, 3=negrita y cursiva).
message_mouse_color(col) Establece el color de la fuente para los botones en los cuadros de diálogo cuando el mouse está sobre ellos.
message_input_color(col) Establece el color para el fondo del campo de entrada en los cuadros de diálogo. message_caption(show,str) Establece el título del cuadro de diálogo. SHOW indica si
se debería mostrar el borde (1) o no (0)
y STR indica el título cuando el borde si es mostrado.
message_position(x,y) Establece la posición para los cuadros de diálogo en la pantalla. message_size(w,h) Arregla el tamaño de los cuadros de diálogo en la pantalla. Si eliges 0 para el ancho(w), el ancho de la imagen es usado. Si eliges 0 para el alto (h), el alto se calcula basándose en el número de líneas del mensaje.
show_menu(str,def) Muestra un menú pop-up. STR indica el texto del menú. Este consiste en diferentes opciones del menú con una barra vertical entre ellas. Por ejemplo, str = ‘menu0|menu1|menu2’. Cuando la primera opción es seleccionada, se devuelve un 0, para la segunda un 1, etc. Cuando ninguna opción es seleccionada, el valor predeterminado def es devuelto.
show_menu_pos(x,y,str,def) Muestra un menú popup, como en la función anterior, pero en la posición x, y en la pantalla.
get_color(defcol) Le pide al jugador un color. DEFCOL es el color predeterminado. Si el jugador presiona CANCEL el valor -1 es devuelto.
get_open_filename(filter,fname) Le pide al jugador un archive para abrir, con el filtro (FILTER) dado. El filtro tiene la forma ‘nombre1|máscara1|nombre2|máscara2’ . Una máscara contiene diferentes opciones con un ';'(punto y coma) entre ellas. '*' (asterisco) significa cualquier string. Por ejemplo: ‘Mapa de bits|*bmp;*.wmf’.Si el jugador presiona Cancel, un string vacío es devuelto.
get_save_filename(filter,fname) Pide un archivo para guardarlo, con el filtro dado. Si el jugador presiona Cancel, un string vacío es devuelto.
get_directory(dname) Pide un directorio. DNAME es el nombre predeterminado. Si el usuario presiona Cancel, un string vacío es devuelto.
get_directory_alt(capt,root) Una forma alternativa de preguntar por un directorio. CAPT es el titulo a mostrar. ROOT es la raíz del diagrama del directorio a mostrar. Usa un string vacío para mostrar el diagrama completo. Si el usuario presiona Cancel, un string vacío es devuelto.
show_error(str,abort) Muestra un mensaje de error estándar (y/o escribe el error al archivo de registros). ABORT indica si el juego debería cerrarse (true-abortar, false-ignorar).
Tablas de récords Una ventana “pop-up” especial es la lista de MEJORES PUNTAJES que se mantiene para cada juego. Las siguientes funciones existen para esto:
highscore_show(numb) Muestra la tabla de highscores. NUMB es un nuevo puntaje. Si el puntaje es suficientemente bueno para ser agregado a la lista, el jugador puede introducir un nombre. Usa -1 para únicamente mostrar la lista actual.
highscore_set_background(back) Establece la imagen de fondo. BACK debe ser el índice de uno de los recursos de fondo. highscore_set_border(show) Establece si la forma de highscore debe mostrar un borde o no. highscore_set_font(name,size,style) Establece la fuente usada para el texto en la tabla. (Esta es una fuente normal de Windows, no una de los recursos de fuente). Debes especificar un nombre y un estilo (0=normal, 1=negrita, 2=cursiva, 3=negrita y cursiva).
highscore_set_colors(back,new,other)Establece los colores usados para el fondo, el de una nueva entrada en la tabla, y el de las demás entradas. entradas.
highscore_set_strings(caption,nobody,escape) Cambia los diferentes strings predeterminados usados al mostrar la tabla de highscores. CAPTION es el título de la forma. NOBODY es el string usado cuando no hay nadie en un lugar en particular. ESCAPE es el string en el inferior indicando que se debe presionar la tecla ESC. Puedes usar esto en particular cuando tu juego usa un idioma diferente.
highscore_show_ext(numb,back,border,col1,col2,name,size) Muestra la tabla de hightscores con diferentes opciones (también puede lograrse usando las funciones anteriores). NUMB es el nuevo puntaje. Si el puntaje es suficientemente bueno para ser agregado a la lista, el jugador puede introducir un nombre. Usa -1 para mostrar simplemente la lista actual. BACK es la imagen de fondo a usar, BORDER indica si se debe mostrar o no el borde. COL1 es el color para la nueva entrada, COL2 para las demás entradas. NAME es el nombre de la fuente a usar, y SIZE es el tamaño de la fuente.
highscore_clear() Limpia la tabla de puntajes. highscore_add(str,numb) Agrega al jugador con el nombre STR y puntaje NUMB a la lista. highscore_add_current() Agrega el puntaje actual a la lista de hightsocres. También se le pide al jugador que proporcione un nombre.
highscore_value(place) Devuelve el puntaje de la persona en el lugar PLACE(1-10). Esto puede ser usado para dibujar tu propia lista de puntajes.
highscore_name(place) Devuelve el nombre de la persona con el lugar PLACE(1-10). draw_highscore(x1,y1,x2,y2) Dibuja la tabla de puntajes en la room, con la caja dada (x1,y1,x2,y2), usando la fuente actual.
Recursos
En Game Maker puedes especificar varios tipos de recursos, como sprites, sonidos, fondos, objetos, etc. En este capítulo encontrarás un número de opciones que actúan sobre estos recursos, para modificarlos u obtener información de ellos en tiempo real. Los recursos se dividen en los siguientes tipos: Sprites Sonidos Fondos Fuentes Paths Scripts Time lines Objetos Rooms
Sprites Las funciones siguientes te dan información sobre un sprite:
sprite_exists(ind) Devuelve si el sprite con el índice (ind) especificado existe. sprite_get_name(ind) Devuelve el nombre del sprite con el ind especificado. sprite_get_number(ind) Devuelve el número de subimágenes del sprite con el índice dado. sprite_get_width(ind) Devuelve el ancho del sprite con el índice especificado. sprite_get_height(ind) Devuelve la altura del sprite con el índice dado. sprite_get_transparent(ind) Devuelve si el sprite con el índice especificado utiliza transparencia. sprite_get_smooth(ind) Devuelve si el sprite tiene los bordes suavizados. sprite_get_preload(ind) Devuelve si el sprite debe ser cargado al principio del juego. sprite_get_xoffset(ind) Devuelve el x-offset (punto de origen en x) del sprite con el índice especificado. sprite_get_yoffset(ind) Devuelve el y-offset (punto de origen en y) del sprite con el índice especificado. sprite_get_bbox_left(ind) Devuelve el valor del límite izquierdo del sprite (bounding box) con el índice especificado. sprite_get_bbox_right(ind) Devuelve el valor del límite derecho del sprite (bounding box) con el índice especificado. sprite_get_bbox_top(ind) Devuelve el valor del límite superior del sprite (bounding box) con el índice especificado. sprite_get_bbox_bottom(ind) Devuelve el valor del límite inferior del sprite (bounding box) con el índice especificado. sprite_get_bbox_mode(ind) Devuelve el modo usado para la caja de controno del sprite (0=automatic, 1=full image, 2=manual).
sprite_get_precise(ind) Devuelve si el sprite con el índice dado utiliza la colisión precisa (precise collision checking).
Sonidos
Las funciones siguientes te dan información sobre los sonidos:
sound_exists(ind) Devuelve si un sonido con el índice dado existe. sound_get_name(ind) Devuelve el nombre del sonido con el índice dado. sound_get_kind(ind) Devuelve el tipo de sonido del sonido especificado (0=normal, 1=background, 2=3d, 3=mmplayer). sound_get_preload(ind) Devuelve si el sonido especificado debe cargarse al principio del juego. Los sonidos usan muchos recursos y algunos sistemas sólo pueden guardar y hacer sonar un número limitado de ellos. Si haces un juego muy grande, deberías llevar un control sobre los sonidos que se cargan en la memoria de audio en cada momento. Podrías desactivar la opción Preload para asegurarte de que los sonidos no se carga hasta que van a ser usados (aunque este método puede originar cierto retraso la primera vez que se escuche el sonido). Además, los sonidos no se eliminan de la memoria cuando ya no van a ser utilizados. Para controlar esto puedes usar las siguientes funciones:
sound_discard(index) Elimina el sonido indicado de la memoria de audio. sound_restore(index) Carga el sonido indicado en la memoria de audio para que se pueda utilizar cuando se necesite inmediatamente.
Fondos Las siguientes funciones te darán información acerca de un fondo :
background_exists(ind) Devuelve si el background (fondo) con el índice dado existe. background_get_name(ind) Devuelve el nombre del fondo con el índice indicado. background_get_width(ind) Devuelve el ancho del fondo con el índice indicado. background_get_height(ind) Devuelve la altura del fondo con el índice especificado. background_get_transparent(ind) Devuelve si el fondo con el índice indicado es transparente. background_get_smooth(ind) Devuelve si el fondo tiene los bordes suavizados. background_get_preload(ind) Devuelve si el fondo debe ser cargado al principio del juego.
Fuentes Las funciones siguientes te dan información sobre las fuentes:
font_exists(ind) Devuelve si la fuente con el índice especificado existe. font_get_name(ind) Devuelve el nombre de la fuente con el índice especificado. font_get_fontname(ind) Devuelve el nombre de fuente (arial, verdana,...) de la fuente con el índice especificado. font_get_bold(ind) Devuelve si la fuente con el índice especificado está en negrita. font_get_italic(ind) Devuelve si la fuente con el índice especificado es cursiva.
font_get_first(ind) Devuelve el primer carácter de la fuente con el índice especificado. font_get_last(ind) Devuelve el último carácter de la fuente con el índice especificado.
Paths Las funciones siguientes te proporcionarán información sobre un path:
path_exists(ind) Devuelve si el path con el índice dado existe. path_get_name(ind) Devuelve el nombre del path con el índice dado. path_get_length(ind) Devuelve la longitud del path con el índice indicado. path_get_kind(ind) Devuelve el tipo de conexiones del path con el índice especificado (0=recto, 1=curvo). path_get_closed(ind) Devuelve si el path es cerrado o no. path_get_precision(ind) Devuelve la precisión utilizado para paths redondeadas. path_get_number(ind) Devuelve el número de puntos del path. path_get_point_x(ind,n) Devuelve la coordenada x del punto n del path. El primer punto es el 0. path_get_point_y(ind,n) Devuelve la coordenada y del punto n del path. El primer punto es el 0. path_get_point_speed(ind,n) Devuelve la velocidad del punto n del path. El primer punto es el 0. path_get_x(ind,pos) Devuelve la coordenada x en la posición pos del path (pos debe estar comprendida entre 0 y 1). path_get_y(ind,pos) Devuelve la coordenada y en la posición pos del path (pos debe estar comprendida entre 0 y 1). path_get_speed(ind,pos) Devuelve la velocidad en la posición pos del path (pos debe estar comprendida entre 0 y 1).
Scripts Las siguientes opciones te darán información acerca de un script:
script_exists(ind) Devuelve si un script con el índice indicado existe. script_get_name(ind) Devuelve el nombre del script con el índice indicado. script_get_text(ind) Devuelve la cadena de texto del script con el índice dado.
Time lines Las funciones siguientes te dan información sobre las time lines:
timeline_exists(ind) Devuelve si la time line con el índice especificado existe. timeline_get_name(ind) Devuelve el nombre de la time line con el índice especificado.
Objetos
Las siguientes funciones proporcionarán información acerca de un objeto:
object_exists(ind) Devuelve si el objeto con el índice dado existe. object_get_name(ind) Devuelve el nombre del objeto con el índice dado. object_get_sprite(ind) Devuelve el índice del sprite por defecto del objeto con el índice especificado. object_get_solid(ind) Devuelve si el objeto con el índice dado es sólido por defecto. object_get_visible(ind) Devuelve si el objeto con el índice dado es visible por defecto. object_get_depth(ind) Devuelve la profundidad del objeto con el índice dado. object_get_persistent(ind) Devuelve si el objeto con el índice señalado es persistente. object_get_mask(ind) Devuelve el índice de la máscara del objeto con el índice dado (-1 si no tiene máscara especial). object_get_parent(ind) Devuelve el índice del objeto pariente del objeto ind (-1 si no tiene pariente). object_is_ancestor(ind1,ind2) Devuelve si el objeto ind2 es un parent del objeto ind1.
Rooms Las siguientes funciones darán información acerca de una habitación:
room_exists(ind) Devuelve si el cuarto con el índice señalado existe. room_get_name(ind) Devuelve el nombre de la habitación con el índice dado.
Observa que como las habitaciones cambian durante el juego hay otras rutinas para obtener información de la habitación actual.
Modificando los recursos Estas funciones sólo están disponibles en la versión registrada de Game Maker. Es posible crear nuevos recursos durante el juego. También se pueden cambiar recursos existentes. Las posibilidades se muestran en este capítulo. Pero se debe tener cuidado: la modificación de recursos fácilmente puede llevar a ¡¡¡errores en los juegos!!! Al modificar recursos, se deben seguir las siguientes reglas: •
No cambies recursos que están siendo utilizados. ¡Esto provocará errores! Por ejemplo, no cambies un sprite que está siendo utilizado por alguna instancia.
•
Cuando guardas/salvas el juego mientras se está ejecutando, los recursos agregados y modificados NO son guardados con el juego. Por lo que, si más tarde se carga el juego, los recursos modificados podrían no estar disponibles. En general, cuando se manipulan recursos ya no se puede hacer uso del sistema interno de salvado y carga de juegos.
•
Cuando reinicias un juego mientras está en ejecución, los recursos modificados no son reestablecidos a su forma original. En general, cuando se manipulan recursos ya no se puede hacer uso de la acción o de la función para reiniciar el juego.
•
La manipulación de recursos puede ser muy lenta. Por ejemplo, el cambiar sprites o fondos es relativamente lento. Por lo que no es cambiarlos durante la ejecución del juego.
•
La creación de recursos durante la ejecución del juego (en particular los sprites y fondos) fácilmente consume gran cantidad de memoria. Se debe ser extremadamente cuidadoso con esto. Por ejemplo, si se tiene un un sprite 128x128 con 32 cuadros de animación y decides crear 36 copias rotadas estarás usando 36x32x128x128x4 = ¡36 MB de memoria!
•
Se deben eliminar los recursos que ya no son utilizados. De otra forma pronto se ocuparía toda la memoria del sistema.
En general, no se deben modificar recursos durante el juego. Es mejor crear y cambiar los recursos al inicio del juego o quizá al inicio de una habitación.
Las funciones para modificar recursos se dividen en las siguientes secciones: Sprites Sonidos Fondos Fuentes Paths Scripts Time lines Objetos Rooms
Sprites Las siguientes funciones permiten modificar las propiedades de los sprites:
sprite_set_offset(ind,xoff,yoff) sprite_set_bbox_mode(ind,mode)
Establece el offset del sprite.
Establece a mode el tipo de caja de colisión del sprite (0 = automática, 1 = imagen
completa, 2 = manual).
sprite_set_bbox(ind,left,top,right,bottom)
Configura la caja de colisión del sprite con índice ind. Funciona solo
cuando es manual el modo de caja de colisión.
sprite_set_precise(ind,mode)
Establece si el sprite con índice ind usa chequeo de colisión precisa (true o false).
Las siguientes funciones pueden utilizarse para crear nuevos sprites y para eliminarlos.
sprite_duplicate(ind)
Crea una copia del sprite con índice ind. Devuelve el índice del nuevo sprite. Devuelve -1 si se presenta
algún error.
sprite_assign(ind,spr)
Asigna el sprite spr al al sprite con índice ind. Es decir, crea una copia del sprite. De esta manera
fácilmente puedes asignar un sprite existente a p. ej. un nuevo sprite.
sprite_merge(ind1,ind2)
Fusiona las imagines del sprite ind2 en el sprite ind1, agregándolas al final de este ultimo. Si los
tamaños no corresponden los sprites son encogidos. ¡No se elimina el sprite ind2!
sprite_add(fname,imgnumb,precise,transparent,smooth,preload,xorig,yorig)
Agrega a los
recursos sprites la imagen del archivo fname. Solo se pueden agregar imágenes bmp, jpg y gif. Cuando se trata de un bmp o jpg la imagen puede ser una tira que contenga las subimágenes del sprite una junto a la otra. Se usa
imgnumb
para indicar el número de subimágenes
(1 para una sola). Este argumento no es empleado con imágenes gif (animadas); se emplea el número de imágenes del archivo gif.
precise
transparente. texturas.
indica si se usará chequeo de colisión precisa.
smooth
indica si se alisarán los bordes.
xorig y yorig
transparent
preload
indica si la imagen es parcialmente
indica si se precargará la imagen en la memoria de
indican la posición de origen en el sprite. La función devuelve el índice del nuevo sprite. Si ocurre algún error
devuelve -1.
sprite_replace(ind,fname,imgnumb,precise,transparent,smooth,preload,xorig,yorig)
Lo
mismo que la anterior pero en este caso se reemplaza al sprite con índice ind. El valor devuelvo por la función indica si tuvo éxito la operación.
sprite_create_from_screen(x,y,w,h,precise,transparent,smooth,preload,xorig,yorig)
Cr
ea un nuevo sprite copiando de un área indicada de la pantalla. Esto permite crear cualquier sprite que se desee. Se dibuja la imagen en pantalla empleando las funciones de dibujado y luego se crea un sprite con ella. (Si no se hace dentro del evento drawing aún se puede hacer de manera que no sea visible si no se refresca la pantalla). Los demás parámetros son similares a los indicados en las anteriores funciones. La función devuelve el índice del sprite. Pero se poner algo de cuidado aquí. Aunque se habla de la pantalla, de hecho, lo que importa es el área en donde se dibuja. No importa el hecho de que haya una ventana en pantalla y que la imagen pudiera estar escalada en esta ventana.
sprite_add_from_screen(ind,x,y,w,h)
Agrega un área de la pantalla como la siguiente subimagen del sprite con índice
ind. x, y, w y h indican las dimensiones del área en pantalla (coordenadas x, y, ancho y alto).
sprite_delete(ind)
Elimina el sprite, liberando la memoria utilizada.
Se cuenta con la siguiente rutina para cambiar la apariencia de un sprite.
sprite_set_alpha_from_sprite(ind,spr)
Cambia los valores alfa (transparencia) del sprite con índice ind usando los
valores de luminosidad (hue) del sprite spr. Esta acción no se puede deshacer.
Sonidos Las siguientes rutinas pueden ser utilizadas para crear nuevos sonidos y para eliminarlos.
sound_add(fname,kind,preload)
Agrega un recurso de sonido al juego. Fname es el nombre del archive de sonido. kind
indica el tipo de sonido (0=normal, 1=de fondo, 2=3D, 3=mmplayer), preload indica si el sonido debiera ser almacenado inmediatamente en la memoria de audio (true o false). La función devuelve el índice del nuevo sonido, que puede utilizarse para reproducirlo. (O devolverá -1 si ocurriera algún error, p. ej. que el archivo no existiera).
sound_replace(index,fname,kind,loadonuse)
Lo mismo que la anterior pero esta vez no se crea un nuevo sonido
sino que se sustituye el que tenga índice index, liberando el anterior sonido. El valor devuelto por esta función indica si tuvo éxito la operación.
sound_delete(index)
Elimina el sonido index, liberando toda la memoria asociada con él. Ya no es posible recuperarlo.
Fondos Las siguientes rutinas pueden ser empleadas para crear nuevas imágenes de fondo y para eliminarlas.
background_duplicate(ind)
Crea un duplicado del fondo con el índice ind. Devuelve el índice del nuevo fondo. Cuando se
presenta algún error se devuelve -1.
background_assign(ind,back)
Asigna el fondo back al fondo ind. Esto es, crea una copia del fondo.
background_add(fname,transparent,smooth,preload) juego de recursos background. Solo se pueden manejar imágenes bmp y jpg. transparente.
smooth
indica si se alisarán los bordes.
preload
Agrega la imagen almacenada en el archivo fname al
transparent
indica si la imagen es parcialmente
indica si se precargará la imagen en la memoria de texturas. La
función devuelve el índice del nuevo fondo, el cual se puede usar para dibujarlo o para asignarlo a la variable background_index[0] para hacerlo visible en la habitación actual. Devuelve -1 cuando ocurre algún error.
background_replace(ind,fname,transparent,smooth,preload)
Lo mismo que la anterior pero en este caso
el fondo con índice ind es reemplazado. La función devuelve un valor indicando si tuvo éxito la operación. Cuando el fondo reemplazado es visible en la habitación será reemplazado.
background_create_color(w,h,col,preload)
Crea un nuevo fondo del tamaño dado (w=ancho, h=alto) con el color
col. Devuelve el índice del nuevo fondo, -1 si ocurre algún error.
background_create_gradient(w,h,col1,col2,kind,preload)
Crea un fondo del tamaño indicado (w=ancho,
h=alto) coloreado con un gradiente. col1 y col2 indican los dos colores. kind es un número entre 0 y 5 que indica el tipo de gradiente: 0=horizontal, 1=vertical, 2=rectángulo, 3=elipse, 4=doble horizontal, 5=doble vertical. Esta función devuelve el índice del nuevo fondo, ó -1 si ocurre algún error.
background_create_from_screen(x,y,w,h,transparent,smooth,preload)
Crea un fondo copiando un
área indicada de la pantalla (x, y=coordenadas esquina superior izquierda, w=ancho, h=alto). Esta función permite crear cualquier fondo que se desee. Se dibuja la imagen en pantalla usando las funciones de dibujo y a continuación se crea un nuevo fondo de ella. (Si no se hace esto en el evento drawing incluso se puede lograr que no sea visible en pantalla si no se refresca). Los otros parámetros son similares a los de las anteriores funciones. La función devuelve el índice del nuevo fondo. Se requiere algo de cuidado aquí. Aunque se habla de la pantalla, lo que importa es la región en la que se dibuja. No importa el hecho de que haya una ventana en pantalla y que la imagen en ella pudiera estar escalada.
background_delete(ind)
Elimina el fondo, liberando la memoria utilizada.
La siguiente rutina permite cambiar la apariencia de un fondo.
background_set_alpha_from_background(ind,back)
Cambia los valores alfa (transparencia) del fondo con
índice ind usando los valores hue del fondo back. Esta acción no puede deshacerse.
Fuentes Es posible crear, reemplazar y eliminar fuentes durante el juego usando las siguientes funciones. (No se debe reemplazar una fuente que está configurada como la actual o en su caso se debe reestablecer la fuente después del cambio).
font_add(name,size,bold,italic,first,last)
Agrega una nueva fuente y devuelve su índice. Se indica el tamaño
(size), si es negrita (bold), cursiva (italic) y el primer y ultimo caracteres que deben ser creados (first y last).
font_add_sprite(spr,first,prop,sep)
Agrega una nueva fuente y devuelve su índice. La fuente es creada de un sprite.
El sprite debe contener una subimagen para cada carácter. first indica el índice del primer carácter en el sprite. Por ejemplo, se puede usar ord('0') si el sprite solo contiene los dígitos. prop indica si la fuente es proporcional. En una fuente proporcional, para cada carácter el ancho de la caja de colisión es utilizado como el ancho del mismo. Finalmente, sep indica la distancia que debe separar a los caracteres horizontalmente. Un valor típico debiera estar entre 2 y 8 dependiendo del tamaño de la fuente.
font_replace(ind,name,size,bold,italic,first,last)
Reemplaza la fuente ind con una nueva fuente,
indicando el nombre (name), tamaño (size) si es negrita (bold) o cursive (italic) y el primer y último carácter que deben crearse.
font_replace_sprite(ind,spr,first,prop,sep)
Reemplaza la fuente ind con una nueva fuente basada en el sprite
spr.
font_delete(ind)
Elimina la fuente con índice ind, liberando la memoria utilizada.
Paths Es posible crear trayectorias y agregar puntos a las mismas. Sin embargo, nunca debe modificarse una trayectoria que está siendo usada por alguna instancia. Se pueden provocar resultados inesperados. Se tienen las siguientes funciones:
path_set_kind(ind,val)
Establece el tipo de conexiones de la trayectoria ind (0=recta, 1=suave) (0=straight, 1=smooth).
path_set_closed(ind,closed)
Establece si la trayectoria ind debe ser cerrada (true) o abierta (false).
path_set_precision(ind,prec)
Establece la precisión con la que se calcula la suavidad de la trayectoria (prec debe estar
entre 1 y 8).
path_add()
Agrega una nueva trayectoria vacía. Devuelve el índice de la trayectoria.
path_delete(ind)
Elimina la trayectoria con índice ind.
path_duplicate(ind)
Crea un duplicado de la trayectoria ind. Devuelve el índice de la nueva trayectoria.
path_assign(ind,path)
Asigna la trayectoria path a la trayectoria ind. Por tanto, crea una copia de la trayectoria. De esta
manera se puede fácilmente configurar una trayectoria existente a p. Ej. otra trayectoria nueva.
path_add_point(ind,x,y,speed)
Agrega un punto a la trayectoria con índice ind, en la posición (x,y) y con factor de
velocidad speed. Se debe recordar que un factor de 100 corresponde a la velocidad actual. Valores inferiores indican una reducción de la velocidad y valores superiores un incremento de la misma.
path_insert_point(ind,n,x,y,speed)
Inserta un punto en la trayectoria con índice ind antes del punto n, en la posición
(x,y) y con factor de velocidad speed.
path_change_point(ind,n,x,y,speed)
Cambia el punto n de la trayectoria ind a la posición (x,y) y con factor de
velocidad speed.
path_delete_point(ind,n) path_clear_points(ind) path_reverse(ind) path_mirror(ind) path_flip(ind)
Elimina el punto n de la trayectoria con índice ind.
Limpia todos los puntos de la trayectoria ind, volviéndola una trayectoria vacía.
Invierte la trayectoria ind.
Voltea horizontalmente la trayectoria ind (con respecto a su centro).
Voltea verticalmente la trayectoria ind (con respecto a su centro).
path_rotate(ind,angle)
Rota angle grados la trayectoria ind en contra de las manecillas del reloj (alrededor de su centro).
path_scale(ind,xscale,yscale)
Escala la trayectoria ind con los factores indicados (con respecto a su centro).
path_shift(ind,xshift,yshift)
Mueve la trayectoria con los valores indicados.
Scripts No se pueden modificar los scripts durante la ejecución del juego. Los scripts son una parte de la lógica del juego. La modificación de los mismos llevaría a una autoreescritura de código que muy fácilmente llevaría a errores. Hay otras formas de hacer algo parecido. Si realmente se necesita ejecutar una pieza de código no conocida en tiempo de diseño (p. ej. Desde un archivo) se pueden hacer uso de las siguientes funciones:
execute_string(str)
Ejecuta el fragmento de código en la cadena str.
execute_file(fname)
Ejecuta el código dentro del archive fname.
En ocasiones se quiere almacenar en una variable el índice de un script para luego ejecutarlo. Para ello se puede utilizar la siguiente función
script_execute(scr,arg0,arg1,...)
Time lines
Ejecuta el script con índice scr con los argumentos indicados.
Las siguientes rutinas permiten la creación y modificación de las time lines. ¡No se deben alterar las líneas de tiempo que estén en uso!
timeline_add()
Agrega una nueva línea de tiempo. Devuelve el índice de la misma.
timeline_delete(ind)
Elimina la línea de tiempo con índice ind. Debe asegurarse que ninguna instancia emplee dicha línea de
tiempo en ninguna habitación.
timeline_moment_add(ind,step,codestr)
Agrega una acción de código a la línea de tiempo en el instante step. codestr
contiene el código para las acciones. Si el step no existe se crea. Por lo que pueden agregarse múltiples acciones de código para el mismo instante.
timeline_moment_clear(ind,step)
Se puede utilizar esta función para borrar todas las acciones de una línea de tiempo
(ind) en un instante (step) en particular.
Objetos También los objetos pueden ser manipulados y creados en tiempo de ejecución. NUNCA se debe cambiar o eliminar un objeto del cual existan instancias. Esto puede provocar efectos inesperados ya que ciertas propiedades son almacenadas en la instancia y, por tanto, al cambiarlas en el objeto no se tendrá el efecto deseado.
object_set_sprite(ind,spr)
Establece el sprite para el objeto con índice ind. El valor -1 remueve del objeto el sprite actual.
object_set_solid(ind,solid)
Establece si al crear instancias del objeto ind deberán considerarse sólidas (true o false).
object_set_visible(ind,vis)
Establece si las instancias creadas del objeto ind deben ser visibles por defecto (true o
false).
object_set_depth(ind,depth)
Establece la profundidad (depth) por defecto de las instancias creadas del objeto ind.
object_set_persistent(ind,pers)
Establece si las instancias creadas del objeto deben ser persistentes por defecto (true
o false).
object_set_mask(ind,spr)
Establece el sprite para la máscara del objeto con índice ind. Para que la máscara sea el sprite del
objeto se puede usar -1.
object_set_parent(ind,obj)
Establece el padre (obj) para el objeto ind. Si se usa -1 se indica que el objeto ind no tiene
padre. El cambiar el objeto padre cambia el comportamiento de las instancias del objeto.
Las siguientes rutinas son útiles para crear objetos mientras el juego se ejecuta. Como con todas las rutinas de modificación de recursos, se debe ser muy cuidadoso para que no se creen nuevos objetos todo el tiempo.
object_add()
Agrega un nuevo objeto. Devuelve el índice del mismo. Después se puede utilizar este índice en las rutinas anteriores
para configurar ciertas propiedades del objeto y luego se puede utilizar el índice para crear instancias del objeto.
object_delete(ind)
Elimina el objeto con índice ind. Se debe asegurar de que no existan instancias de este objeto en ninguna de
las habitaciones.
object_event_add(ind,evtype,evnumb,codestr)
Para asignarle un comportamiento a un objeto se deben definir
eventos para dicho objeto. Solo se pueden agregar acciones de código. Se debe indicar el objeto (ind), el tipo de evento (evtype), el número de evento (evnumb, se pueden usar las constantes indicadas antes para la función event_perform()). Por ultimo se proporciona la cadena
de código que debe ejecutarse (codestr). Se pueden agregar múltiples acciones a cada evento.
object_event_clear(ind,evtype,evnumb)
Se puede emplear esta función para borrar todas las acciones para un
evento en particular.
La creación de objetos es en particular muy útil cuando se están diseñando scripts o bibliotecas de acciones. Por ejemplo, un script de inicialización puede crear un objeto para mostrar un texto y otro script puede agregar un objeto con un texto en particular. De esta forma se tiene un mecanismo simple para desplegar mensajes sin la necesidad de crear objetos usando la interfaz estándar.
Rooms La manipulación de habitaciones en tiempo de ejecución es algo muy riesgoso. Se debe tomar en cuenta que las habitaciones cambian todo el tiempo debido a lo que ocurre dentro del juego. Esto normalmente solo ocurre para la habitación en turno y hay muchas rutinas descritas en anteriores secciones para manipular las instancias, los fondos y los tiles en la habitación actual. Pero los cambios en la habitación active se mantendrán si dicha habitación es persistente. Entonces, nunca se debieran manipular elementos de la habitación en turno o de cualquier otra habitación que sea persistente y que ya haya sido visitada antes. Tales cambios en general no serán percibidos pero en ocasiones podrían ocasionar errores inesperados. Debido al hecho de que las habitaciones están enlazadas de manera complicada no hay ninguna rutina que permita eliminar una habitación.
Las siguientes funciones están disponibles
room_set_width(ind,w)
Establece el ancho (w) para la habitación con índice ind.
room_set_height(ind,h)
Establece la altura (h) para la habitación con índice ind.
room_set_caption(ind,str)
Establece el título (caption) para la habitación con índice ind.
room_set_persistent(ind,val) room_set_code(ind,str)
Establece si la habitación con índice ind será persistente o no (val).
Configura el código de inicialización (str) para la habitación con índice ind.
room_set_background_color(ind,col,show)
Configura las propiedades de color para la habitación con índice ind si no
cuenta con una imagen de fondo. col indica el color y show indica si el color debe mostrarse o no.
room_set_background(ind,bind,vis,fore,back,x,y,htiled,vtiled,hspeed,vspeed,alpha)
Es
tablece el fondo con índice bind (0-7) como fondo para la habitación con índice ind. vis indica si el fondo será visible y fore si se trata de un fondo de primer plano. back es el índice de la imagen de fondo. x, y indican la posición de la imagen y htiled y vtiled indican si la imagen debe dividirse en tiles. hspeed y vspeed indican la velocidad con la que el fondo se mueve y alpha indica un valor de transparencia alfa (1 = sólido y más rápido).
room_set_view(ind,vind,vis,xview,yview,wview,hview,xport,yport,wport,hport,hborder, vborder,hspeed,vspeed,obj)
Establece la vista con índice vind (0-7) para la habitación con índice ind. vis indica si la vista es
visible. xview, yview, wview y hview indican la posición de la vista en la habitación. xport, yport, wport y hport indican la posición en pantalla. Cuando la vista debe seguir a un objeto hborder y vborder indican el borde mínimo visible que debe mantenerse alrededor del objeto. hspeed y vspeed indican la máxima velocidad con la que la vista puede moverse. obj es el índice del objeto o el índice de la instancia.
room_set_view_enabled(ind,val) room_add()
Establece si las vistas deben habilitarse para la habitación con índice ind.
Agrega una nueva habitación. Devuelve el índice de la misma. Se debe notar que la habitación no formará parte del orden
de habitaciones. Por lo que la nueva habitación no cuenta con habitaciones previa ni siguiente. Si se desea moverse a una habitación agregada se debe indicar el índice de la misma.
room_duplicate(ind)
Agrega una copia de la habitación con índice ind. Devuelve el índice de la nueva habitación.
room_assign(ind,room)
Asigna la habitación room al índice ind. Por tanto, esta función crea una copia de la habitación.
room_instance_add(ind,x,y,obj)
Agrega a la habitación ind una nueva instancia del objeto obj, colocándola en la posición
x, y. Devuelve el índice de la instancia.
room_instance_clear(ind)
Elimina todas las instancias dentro de la habitación ind.
room_tile_add(ind,back,left,top,width,height,x,y,depth) Agrega un nuevo tile a la habitación en la posición indicada. Devuelve el índice del tile. back es el fondo del cual se toma el tile. Left, top, width y height indican la parte del fondo que forma al tile. x, y es la posición del tile en la habitación y depth es la profundidad del tile.
room_tile_add_ext(ind,back,left,top,width,height,x,y,depth,xscale, yscale,alpha)
Lo
mismo que la anterior rutina pero también se puede especificar un factor de escalado en las direcciones x e y, y una transparencia alpha para el tile.
room_tile_clear(ind)
Elimina todos los tiles de la habitación indicada.
Archivos, registro, y ejecución de programas
En juegos más avanzados probablemente querrás leer datos de un archivo que has incluido con el juego. Por ejemplo, pudieras crear un archivo que indique en qué momento deben ocurrir ciertas cosas. Probablemente también quieras guardar información para la siguiente vez que se ejecute el juego (por ejemplo, el cuarto actual). En algunas situaciones puede ser que necesites ejecutar programas externos, o crear nuevos archivos con datos del juego.
Puedes encontrar toda la información sobre estos temas en las secciones siguientes: Archivos Registro Archivos INI Ejecución de programas
Archivos
Es útil utilizar archivos externos en juegos. Por ejemplo, podrías hacer un archivo que describe qué ciertas cosas deben suceder en qué momento. También puedes querer salvar la información para la próxima vez que se ejecute el juego. Las funciones siguientes sirven para leer y escribir datos en archivos de texto:
file_text_open_read(fname) Abre el archivo fname para lectura. La función devuelve la id del archivo que debes utilizar en el resto de funciones. Puedes abrir hasta un máximo de 32 archivos simultáneamente. No olvides cerrar los archivos una vez que no los necesites.
file_text_open_write(fname) Abre el archivo fname para escritura, creándolo si no existe. La función devuelve la id del archivo que debes usar en las demás funciones.
file_text_open_append(fname) Abre el archivo fname para agregar datos al final, creándolo si no existe. La función devuelve la id del archivo que debes usar en las demás funciones.
file_text_close(fileid) Cierra el archivo indicado por fileid (¡No olvides llamarla!). file_text_write_string(fileid,str) Escribe la cadena str al archivo indicado por fileid. file_text_write_real(fileid,x) Escribe el valor real x en el archivo indicado por fileid. file_text_writeln(fileid) Escribe un carácter de nueva línea en el archivo. file_text_read_string(fileid) Lee una cadena del archivo y devuelve esta cadena. Una cadena termina al final de la línea.
file_text_read_real(fileid)
Lee un valor real del archivo y devuelve este valor.
file_text_readln(fileid) Salta el resto de la línea en el archivo e inicia al principio de la siguiente línea. file_text_eof(fileid) Indica si hemos llegado al final del archivo.
Para manipular archivos del sistema puedes utilizar las siguientes funciones:
file_exists(fname) Indica si el archivo con el nombre fname existe (true) o no (false).
file_delete(fname) Borra el archivo con el nombre fname. file_rename(oldname,newname) Renombra el archivo con el nombre oldname a newname. file_copy(fname,newname) Copia el archivo fname al nombre newname directory_exists(dname) Indica si la carpeta dname existe. directory_create(dname) Crea una carpeta con el nombre dname (incluyendo la ruta a esa carpeta) si no existe. file_find_first(mask,attr) Devuelve el nombre del primer archivo que satisfaga las condiciones de la máscara mask y los atributos attr. Si no existe tal archivo, devuelve una cadena vacía. La máscara puede contener una ruta y comodines (*), por ejemplo ‘C:\temp\*.doc’. Los atributos indican archivos adicionales que quieras ver. (Por lo que los archivos normales son siempre devueltos cuando satisfacen la máscara). Puedes agregar las siguientes constantes para ver el tipo de archivos que desees:
fa_readonly archivos de sólo lectura fa_hidden archivos ocultos fa_sysfile archivos de sistema fa_volumeid archivos volume-id fa_directory carpetas fa_archive archivos archivados file_find_next() Devuelve el nombre del siguiente archivo que satisface la máscara y los atributos indicados previamente. Si no existe tal archivo, devuelve una cadena vacía.
file_find_close() Debe ser llamada después de manipular los archivos para liberar la memoria. file_attributes(fname,attr) Indica si el archivo fname tiene todos los atributos dados por attr. Usa una combinación de las constantes indicadas anteriormente.
Las siguientes funciones sirven para cambiar los nombres de archivos. Observa que estas funciones no afectan a los archivos en sí, si no al nombre:
filename_name(fname) Devuelve el nombre del archivo fname, con la extensión pero sin la ruta. filename_path(fname) Devuelve la ruta al archivo indicado, incluyendo la última barra de separación. filename_dir(fname) Devuelve el directorio del archivo, que normalmente suele ser igual que la ruta pero sin la última barra de separación.
filename_drive(fname) Devuelve la información de la unidad del archivo. filename_ext(fname) Devuelve la extensión del archivo, incluyendo el punto. filename_change_ext(fname,newext) Devuelve el nombre del archivo con la extensión sustituida por newext. Si indicas una cadena de texto vacía para newext puedes eliminar la extensión del archivo.
En algunas situaciones puede que quieras leer datos de archivos binarios. Para ello dispones de las siguientes rutinas de bajo nivel:
file_bin_open(fname,mod) Abre el archivo con el nombre especificado. El parámetro mod indica qué se puede hacer con el archivo: 0=leer, 1=escribir y 2= leer y escribir. La función devuelve la id del archivo que debe utilizarse en las demás funciones. Puedes abrir hasta un máximo de 32 archivos simultáneamente, pero no olvides cerrarlos cuando hayas terminado con ellos.
file_bin_rewrite(fileid) Limpia el archivo indicado por fileid, es decir, borra todo su contenido y se sitúa al principio del archivo para empezar a escribir.
file_bin_close(fileid) Cierra el archivo especificado. No olvides llamarla! file_bin_size(fileid) Devuelve el tamaño en bytes del archivo indicado. file_bin_position(fileid) Devuelve la posición actual en el archivo en bytes (0 es el principio del archivo). file_bin_seek(fileid,pos) Mueve la posición en el archivo a la posición indicada por pos. Para añadir contenido al final de un archivo, usa el valor file_bin_size(fileid) para el parámetro pos.
file_bin_write_byte(fileid,byte) Escribe un byte de datos al archivo especificado. file_bin_read_byte(fileid) Lee un byte de datos del archivo.
Si el jugador ha seleccionado modo seguro en sus preferencias, para ciertas rutinas, no se permite especificar la ruta y sólo puedes acceder a los archivos en la carpeta de la aplicación p. Ej. para escribir en ellos.
Las siguientes tres variables de sólo lectura pueden ser útiles:
game_id* Identificador único para el juego. Puedes usarlo si necesitas un nombre único de archivo. working_directory* Carpeta de trabajo del juego. (No incluye la diagonal invertida final). temp_directory* Carpeta temporal creada para el juego. Puedes almacenar archivos temporales aquí. Serán eliminados cuando el juego finalice.
En ciertas situaciones podrías dar al jugador la posibilidad de introducir argumentos mediante la línea de comandos al juego que están ejecutando (para por ejemplo activar trucos o modos especiales). Para obtener estos argumentos puedes usar las siguientes dos rutinas:
parameter_count() Devuelve el número de parámetros de la línea de comandos (nota que el nombre del programa es uno de ellos).
parameter_string(n) Devuelve los parámetros n de la línea de comandos. El primer parámetro tiene índice 0 y es el nombre del programa.
Por último, puedes leer el valor de las variables de entorno con la siguiente función:
environment_get_variable(name) Devuelve el valor (una cadena de texto) de la variable de entorno con el nombre especificado.
Registro Si deseas almacenar una pequeña cantidad de información entre cada ejecución del juego hay un mecanismo más simple que el emplear un archivo. Puedes usar el registro. El registro es una gran base de datos de Windows para mantener todo tipo de configuraciones para los programas. Una entrada tiene un nombre, y un valor. Puedes usar tanto cadenas como valores reales. Tenemos las siguientes funciones:
registry_write_string(name,str) Crea una entrada en el registro con el nombre name y como valor la cadena str. registry_write_real(name,x) Crea una entrada en el registro con el nombre name y el valor real x.
registry_read_string(name) Devuelve la cadena almacenada con el nombre name. (El nombre debe existir, de otra forma se devuelve una cadena vacía).
registry_read_real(name) Devuelve el valor real almacenado en la entrada name. (El nombre debe existir, de otra forma se devuelve el número 0).
registry_exists(name) Indica si la entrada name existe.
En realidad, los valores en el registro están agrupados en claves. Las rutinas anteriores trabajan con valores dentro de la clave que está creada especialmente para tu juego. Tu programa puede usar esto para obtener cierta información sobre el sistema en el que se está ejecutando el juego. También puedes leer valores en otras claves. Puedes escribir valores en ellas pero ten mucho cuidado. PUEDES FÁCILMENTE DESTRUIR TU SISTEMA de esta forma. (La escritura no se permite en modo seguro). Nota que las claves también están colocadas en grupos. Las siguientes rutinas trabajan por defecto con el grupo HKEY_CURRENT_USER. Pero si quieres puedes cambiar este grupo raíz de trabajo. Por ejemplo, para obtener el directorio temporal actual, usa:
path = registry_read_string_ext('\Environment','TEMP');
Las siguientes funciones existen para moverte por el registro con libertad:
registry_write_string_ext(key,name,str) Crea una entrada en el registro dentro de la clave key con el nombre name y como valor la cadena str.
registry_write_real_ext(key,name,x) Crea una entrada en el registro dentro de la clave key con el nombre name y el valor real x.
registry_read_string_ext(key,name) Devuelve la cadena con el nombre name dentro de la clave key (el nombre debe existir, de otra forma se devuelve una cadena vacía).
registry_read_real_ext(key,name) Devuelve el valor real con el nombre name en la clave key (el nombre debe existir, de otra forma se devuelve el número 0).
registry_exists_ext(key,name) Indica si el nombre name existe dentro de la clave key. registry_set_root(root) Configura la raíz para las otras rutinas. Usa los siguientes valores: 0 = HKEY_CURRENT_USER 1 = HKEY_LOCAL_MACHINE 2 = HKEY_CLASSES_ROOT 3 = HKEY_USERS
Archivos INI
Para pasar ciertos parámetros a un programa es corriente utilizar los archivos INI. Los archivos INI contienen secciones y cada sección contiene un número de parejas nombre-valor. Por ejemplo:
[Form] Arriba=100 Izquierda=100 Titulo=El mejor juego de la historia [Game] MaxScore=12324 Este archivo contiene dos secciones: la primera llamada Form y la segunda llamada Game. Primera sección contiene 3 parejas de valores. Las dos primeras tienen un valor real mientras que la tercera es una cadena de texto. Los archivos INI son muy fáciles de crear y editar. En Game Maker puedes utilizar las siguientes funciones para esto:
ini_open(name) Abre el archivo de INI con el nombre dado ¡El archivo INI se debe almacenar en la misma carpeta que el juego! ini_close()Cierra el archivo INI actualmente abierto. ini_read_string(section,key,default) Lee el valor (una cadena de texto) de la llave indicada con key de la sección indicada como section. Cuando no existe la llave o la sección se devuelve el valor especificado por default.
ini_read_real(section,key,default) Lee el valor real de la llave indicada con key de la sección indicada como section. Cuando no existe la llave o la sección se devuelve el valor especificado por default.
ini_write_string(section,key,value) Escribe el valor value (una cadena de texto) en la llave indicada con key en la sección indicada con section.
ini_write_real(section,key,value) Escribe el valor real value en la llave indicada con key en la sección indicada con section.
ini_key_exists(section,key) Devuelve si la llave indicada existe en la sección indicada. ini_section_exists(section) Devuelve si existe la sección indicada. ini_key_delete(section,key) Elimina la llave indicada de la sección indicada. ini_section_delete(section) Elimina la sección indicada.
Ejecución de programas Game Maker también tiene la posibilidad de iniciar programas externos. Hay dos funciones disponibles para esto: execute_program y execute_shell. La función execute_program inicia un programa, posiblemente con algunos argumentos. Puede esperar hasta que el programa termine (pausando el juego) o continuar con el juego. La función execute_shell abre un archivo. Puede ser cualquier archivo para cuyo tipo esté definida una asociación, p. Ej. un archivo html, un archivo de Word, etc. O puede ser un programa. No puede esperar a que se termine la ejecución por lo que el juego continúa.
execute_program(prog,arg,wait) Ejecuta el programa prog con los argumentos arg. wait indica si se debe esperar a que termine la aplicación.
execute_shell(prog,arg) Ejecuta el programa (o archivo) en el entorno.
Ambas funciones no funcionarán si el jugador activa el modo seguro en sus preferencias. Puedes comprobar esto usando la variable de solo lectura:
secure_mode* Indica si el juego está ejecutándose en modo seguro.
Estructuras de datos Esta función sólo está disponible en la versión registrada de Game Maker.
En los juegos normalmente necesitas guardar información. Por ejemplo, necesitas guardar listas de ítems que lleva un personaje o nombres de lugares que necesita visitar. Puedes usar arrays para esto. Pero si necesitas hacer operaciones más complicadas, como ordenar los datos o buscar un ítem determinado, necesitas escribir grandes trozos de código en GML, que pueden ser lentos al ejecutarse.
Para remediar esto, Game Maker dispone de un número de funciones de estructuras de datos. Hasta el momento hay 6 tipos de estructuras de datos diferentes: stacks (pilas), queues (colas), lists (listas), maps (mapas), priority queues (colas de prioridad) y grids (rejillas). Cada uno de estos tipos está preparado para un uso particular.
Todas las estructuras de datos funcionan generalmente de la misma manera. Creas una estructura de datos con una función que devuelve la id de esa estructura y luego usas esa id para hacer diferentes operaciones. Cuando has terminado, puedes destruir la estructura para ahorrar espacio. Puedes usar tantas estructuras a la vez como desees y éstas pueden guardar valores reales o cadenas de texto.
Observa que las estructuras de datos no se guardan cuando guardas el juego usando las funciones o acciones apropiadas. Para guardarlas, deberás crear tu propio sistema.
Al comparar valores, por ejemplo al ordenar una lista, Game Maker debe decidir cuándo dos valores son iguales. Al usar cadenas de texto y valores enteros esto es evidente, pero para valores reales, debido a errores de redondeo, números iguales pueden convertirse en diferentes. Por ejemplo, (5/3)*3 no será igual a 5. Para evitar esto, puedes especificar la precisión que deseas usar. Cuando la diferencia entre dos números es menor que esta precisión, los dos números se consideran iguales. Por defecto se utiliza una precisión de 0.0000001.Puedes cambiar este valor con las funciones siguientes:
ds_set_precision(prec) Especifica la precisión usada en comparaciones. Esta precisión se utiliza en las estructuras de datos pero no en el resto de comparaciones en GML!
Las estructuras de datos disponibles son las siguientes:
Pilas Colas Listas Mapas Colas de prioridad Rejillas
Pilas Una pila es una estructura LIFO (último en entrar, primero en salir). Puedes empujar (push) valores en la pila o quitarlos tirando de ellos (pop). El último valor que se empujó en la lista es el primero al que se accede al tirar de la lista. Es como si vas poniendo un libro encima de otro: cuando quieras coger un libro, el último que pusiste estará encima de todos los demás y será el que cojas. Las pilas se utilizan para gestionar interrupciones o cuando se usan funciones recursivas:
ds_stack_create() Crea una nueva pila. La función devuelve un número entero con la id de la pila para usarla en las diferentes funciones. Puedes crear varias pilas.
ds_stack_destroy(id)
Destruye la pila, liberando la memoria usada. No olvides usar esta función cuando ya no necesites la
pila.
ds_stack_clear(id) Limpia la pila, borrando todos los valores que contiene pero no la destruye. ds_stack_size(id) Devuelve el número de valores en la pila. ds_stack_empty(id) Devuelve true si la pila está vacía. Es lo mismo que chequear si el número de valores en la pila es cero. ds_stack_push(id,val) Empuja el valor dentro de la pila. ds_stack_pop(id) Devuelve el valor al final de la pila (esto es, el último valor introducido) y lo elimina de la pila. ds_stack_top(id) Devuelve el valor al principio de la pila (el primero que se introdujo) pero no lo elimina.
Colas Una cola es parecido a una pila, pero funciona como una estructura FIFO (primero en entrar, primero en salir). El primer valor que se mete en la cola es el primero en salir, como una cola en una tienda. El primer cliente en llegar será el primero en ser atendido y los demás tendrán que esperar su turno en orden. Para trabajar con colas existen las funciones siguientes (observa que las 5 primeras son equivalentes a las funciones de las pilas: todas las estructuras de datos poseen estas 5 funciones)
ds_queue_create()Crea una nueva cola. La función devuelve un número entero con la id de la cola para usarla en las diferentes funciones. Puedes crear varias colas.
ds_queue_destroy(id) Destruye la cola, liberando la memoria usada. No olvides usar esta función cuando ya no necesites la cola.
ds_queue_clear(id)Limpia la cola, borrando todos los valores que contiene pero no la destruye. ds_queue_size(id) Devuelve el número de valores en la cola. ds_queue_empty(id) Devuelve true si la cola está vacía. Es lo mismo que chequear si el número de valores en la cola es cero. ds_queue_enqueue(id,val)
Introduce el valor en la cola.
ds_queue_dequeue(id) Devuelve el último valor de la cola (el primero en introducirse) y lo elimina de la cola. ds_queue_head(id) Devuelve el valor al principio de la cola, esto es, el primero que se introdujo, pero no lo elimina de la cola. ds_queue_tail(id) Devuelve el último valor de la cola pero no lo elimina.
Listas Una lista guarda una colección de valore en un orden determinado. Puedes añadir valores a la lista a la posición que desees. Por eso, puedes acceder acceder a los valores usando un índice de su posición en la lista. También puedes ordenar los elementos de forma ascendente o descendente. Las listas se pueden usar para muchas cosas, por ejemplo, para guardar valores que cambian. Las listas se han programado usando arrays, pero al estar definidas en código compilado son mucho más rápidas que los arrays.
ds_list_create()Crea una nueva lista. La función devuelve un número entero con la id de la lista para usarla en las diferentes funciones. Puedes crear varias listas.
ds_list_destroy(id) Destruye la lista, liberando la memoria usada. No olvides usar esta función cuando ya no necesites la lista. ds_list_clear(id)
Limpia la lista, borrando todos los valores que contiene pero no la destruye.
ds_list_size(id) Devuelve el número de valores en la lista. ds_list_empty(id) Devuelve true si la lista está vacía. Es lo mismo que chequear si el número de valores en la lista es cero. ds_list_add(id,val) Inserta el valor al final de la lista. ds_list_insert(id,pos,val) Inserta el valor en la posición pos. La primera posición es 0 y la última es igual al tamaño de la lista menos 1.
ds_list_replace(id,pos,val) Reemplaza el valor en la posición pos por val. ds_list_delete(id,pos) Elimina el valor en la posición pos.
ds_list_find_index(id,val) Devuelve la posición en la lista del valor val. Si no encuentra el valor en la lista devuelve -1. ds_list_find_value(id,pos) Devuelve el valor en al posición pos. ds_list_sort(id,ascend) Ordena los valores de la lista. Si ascend es true o 1 los ordena de forma ascendente, en caso contrario los ordena de manera descendente.
Mapas En algunas ocasiones necesitas guardar pares de valores consistentes de una llave (key) y un valor. Por ejemplo, un personaje puede llevar varios ítems diferentes y puede tener un número diferente de cada uno. En este caso, el ítem será la llave y la cantidad será el valor. Los mapas manejan estas parejas de valores, ordenándolos por la llave. Puedes añadir valores al mapa y buscar uno concreto usando las llaves. Como las llaves también están ordenadas, puedes encontrar los valores correspondientes a la llave siguiente o anterior. A veces es útil usar un mapa para guardar llaves sin ningún valor asignado. En este caso puedes asignarles a todas las llaves el valor 0.
ds_map_create()Crea un nuevo mapa. La función devuelve un número entero con la id del mapa para usarla en las diferentes funciones. Puedes crear varios mapas.
ds_map_destroy(id) Destruye el mapa, liberando la memoria usada. No olvides usar esta función cuando ya no necesites el mapa. ds_map_clear(id)Limpia el mapa, borrando todos las parejas llave-valor que contiene pero no lo destruye. ds_map_size(id) Devuelve el número de parejas llave-valor en el mapa. ds_map_empty(id) Devuelve true si el mapa está vacía. Es lo mismo que chequear si el número de valores en el mapa es cero. ds_map_add(id,key,val) Añade la pareja llave (key)-valor (val) al mapa. ds_map_replace(id,key,val) Reemplaza el valor correspondiente a la llave con un nuevo valor. ds_map_delete(id,key) Elimina la pareja llave-valor especificada del mapa. Si hay varias parejas con la misma llave sólo 1 es eliminada.
ds_map_exists(id,key) Devuelve true si la llave existe en el mapa. ds_map_find_value(id,key) Devuelve el valor correspondiente a la llave. ds_map_find_previous(id,key) Devuelve la mayor llave que sea menor que la indicada. ds_map_find_next(id,key) Devuelve la menor llave que sea mayor que la indicada.
ds_map_find_first(id) Devuelve la menor llave del mapa. ds_map_find_last(id) Devuelve la mayor llave del mapa.
Colas de prioridad En una cola de prioridad a cada valor se le asigna una prioridad. Así puedes buscar los valores con mayor o menor prioridad y controlar ciertas cosas según su prioridad.
ds_ priority _create()Crea una nueva cola. La función devuelve un número entero con la id de la cola para usarla en las diferentes funciones. Puedes crear varias colas.
ds_ priority _destroy(id) Destruye la cola, liberando la memoria usada. No olvides usar esta función cuando ya no necesites la cola.
ds_ priority _clear(id)Limpia la cola, borrando todos los valores que contiene pero no la destruye. ds_ priority _size(id) Devuelve el número de valores en la cola. ds_ priority _empty(id) Devuelve true si la cola está vacía. Es lo mismo que chequear si el número de valores en la cola es cero.
ds_priority_add(id,val,prio) Añade el valor con la prioridad especificada a la cola. ds_priority_change_priority(id,val,prio) Cambia la prioridad del valor especificado al nuevo valor. ds_priority_find_priority(id,val) Devuelve la prioridad del valor especificado. ds_priority_delete_value(id,val) Elimina el valor (con su prioridad) de la cola de prioridad. ds_priority_delete_min(id)Devuelve el valor con la menor prioridad y lo elimina de la cola. ds_priority_find_min(id) Devuelve el valor con la menor prioridad pero no lo elimina de la cola. ds_priority_delete_max(id) Devuelve el valor con la mayor prioridad y lo elimina de la cola. ds_priority_find_max(id) Devuelve el valor con la mayor prioridad pero no lo elimina de la cola.
Rejillas Una rejilla es simplemente un vector (o arreglo) bidimensional. Una rejilla tiene un entero con su altura y anchura. Esta estructura te permite acceder a los valores indicando el valor de la celda deseada (el primer valor en las direcciones x e y es 0). Pero también puedes dar valores por regiones, añadirlos y encontrar los valores máximo, mínimo o medio de una región. Esta estructura es útil para representar por ejemplo un campo de juego. Aunque todo lo que hace esta estructura se puede conseguir usando vectores, las operaciones por regiones son mucho más rápidas.
ds_grid_create(w,h) Crea una rejilla con la anchura especificada en w y la altura especificada en h. La función devuelve la id de la rejilla que debe usarse en las demás funciones.
ds_grid_destroy(id) Destruye la rejilla, liberando la memoria usada. No olvides usar esta función cuando ya no necesites la rejilla.
ds_grid_resize(id,w,h) Aumenta el tamaño de la rejilla a la nueva anchura y altura especificadas. Las celdas ya existentes
mantienen su valor.
ds_grid_width(id) Devuelve la anchura de la rejilla. ds_grid_height(id) Devuelve la altura de la rejilla. ds_grid_clear(id,val) Hace que todos las celdas de la rejilla tomen el valor val (puede ser un número o una cadena de texto). ds_grid_set(id,x,y,val)Asigna a la celda x,y el valor val. ds_grid_add(id,x,y,val) Suma el valor a la celda especificada. Para cadenas de texto, la cadena se concatena a la que ya existe en la celda.
ds_grid_multiply(id,x,y,val) Multiplica la celda por el valor. Sólo se puede usar con números. ds_grid_set_region(id,x1,y1,x2,y2,val) Todas las celdas de la región especificada toman el valor especificado. ds_grid_add_region(id,x1,y1,x2,y2,val)Suma el valor a la región especificada. Para cadenas de texto, concatena la cadena de texto a la existente en cada celda.
ds_grid_multiply_region(id,x1,y1,x2,y2,val) Multiplica el valor por todas las celdas de la región (sólo para valores numéricos).
ds_grid_set_disk(id,xm,ym,r,val) Da el valor especificado a toda las celdas dentro del círculo de centro xm,ym y radio r.
ds_grid_add_disk(id,xm,ym,r,val) Suma el valor a la región especificada por el círculo. Para cadenas de texto, concatena la cadena de texto a la existente en cada celda.
ds_grid_multiply_disk(id,xm,ym,r,val) Multiplica el valor por todas las celdas de la región (sólo para valores numéricos).
ds_grid_get(id,x,y) Devuelve el valor de la celda indicada. ds_grid_get_sum(id,x1,y1,x2,y2) Devuelve la suma de los valores de las celdas de la región especificada. Sólo funciona con valores numéricos.
ds_grid_get_max(id,x1,y1,x2,y2) Devuelve el máximo valor de las celdas de la región especificada. Sólo funciona con valores numéricos.
ds_grid_get_min(id,x1,y1,x2,y2) Devuelve el mínimo valor de las celdas de la región especificada. Sólo funciona con valores numéricos.
ds_grid_get_mean(id,x1,y1,x2,y2) Devuelve el valor medio de las celdas de la región especificada. Sólo funciona con valores numéricos.
ds_grid_get_disk_sum(id,xm,ym,r) Devuelve la suma de los valores de las celdas de la región circular especificada. Sólo funciona con valores numéricos..
ds_grid_get_disk_min(id,xm,ym,r) Devuelve el mínimo valor de las celdas de la región circular especificada. Sólo funciona con valores numéricos.
ds_grid_get_disk_max(id,xm,ym,r) Devuelve el máximo valor de las celdas de la región circular especificada. Sólo funciona con valores numéricos.
ds_grid_get_disk_mean(id,xm,ym,r) Devuelve el valor medio de las celdas de la región circular especificada. Sólo funciona con valores numéricos.
ds_grid_value_exists(id,x1,y1,x2,y2,val) Devuelve true si el valor especificado existe en la región.
ds_grid_value_x(id,x1,y1,x2,y2,val) Devuelve la coordenada x de la celda de la región en la que aparece el valor especificado.
ds_grid_value_y(id,x1,y1,x2,y2,val) Devuelve la coordenada y de la celda de la región en la que aparece el valor especificado.
ds_grid_value_disk_exists(id,xm,ym,r,val) Devuelve true si el valor especificado existe en la región circular. ds_grid_value_disk_x(id,xm,ym,r,val) Devuelve la coordenada x de la celda de la región circular en la que aparece el valor especificado.
ds_grid_value_disk_y(id,xm,ym,r,val) Devuelve la coordenada y de la celda de la región circular en la que aparece el valor especificado.
Creando partículas Esta función solo está disponible en la versión registrada de Game Maker.
Los sistemas de partículas se emplean para crear efectos especiales. Las partículas son pequeños elementos (ya sean representados por un pequeño sprite, un píxel o una pequeña forma). Tales partículas se mueven de acuerdo a reglas predefinidas y pueden cambiar su color mientras se mueven. Muchas partículas juntas pueden crear p. Ej. Fuegos artificiales, flamas, lluvia, nieve, campos estelares, polvo, etc.
Game Maker contiene un extenso sistema de partículas que puede ser empleado para crear grandes efectos. Aunque no es sencillo de utilizar por lo que mejor lee cuidadosamente esta sección antes de probarlo. Los sistemas de partículas tienen muchos parámetros y no siempre es fácil entender cómo crear los efectos que se desean. Si lo encuentras demasiado difícil, Game Maker también dispone de un sistema de efectos para crear explosiones, humo, lluvia e incluso fuegos artificiales.
Primero que nada hay tipos de partículas. Un tipo de partícula define una clase de partículas en específico. Tales tipos pueden tener muchos parámetros que describen la forma, el tamaño, color y movimiento de las partículas.
Después tenemos los sistemas de partículas. Puede haber diferentes sistemas de partículas en un juego. Un sistema de partículas puede tener partículas de diferentes tipos. Un sistema de partículas cuenta con emisores que crean las partículas, ya sea continuamente o en estallidos. También puede contar con atractores que atraen las partículas. Finalmente, puede también tener destructores que destruirán las partículas. Una vez que se ha creado una partícula en un sistema, ésta será automáticamente dibujada y actualizada por el sistema.
La información sobre partículas se divide en las secciones siguientes:
Efectos simples
Tipos de partículas
Sistemas de partículas
Emisores
Atractores
Destructores
Deflectores
Cambiadores
Ejemplo de fuegos artificiales
Efectos simples
La forma más sencilla de crear partículas es usando el mecanismo de efectos. Los efectos se crean usando partículas, pero tú no tienes que preocuparte de eso. Simplemente eliges el tipo de efecto, la posición donde debe crearse, su color y su tamaño y del resto se encarga Game Maker.
Los efectos disponibles son:
•
ef_explosion
•
ef_ring
•
ef_ellipse
•
ef_firework
•
ef_smoke
•
ef_smokeup
•
ef_star
•
ef_spark
•
ef_flare
•
ef_cloud
•
ef_rain
•
ef_snow
Algunos sólo necesitarás crearlos una vez (como la explosión) mientras que otros deberás crearlos en cada step (como el humo o la lluvia). Observa que los efectos de nieve y lluvia siempre se crean en la parte superior de la pantalla así que la posición que especifiques para ellos será irrelevante.
Aunque esto pueda sonar limitado, se pueden conseguir efectos muy espectaculares. Por ejemplo, creando una pequeña nube de humo rojo debajo de una nave espacial en cada step se consigue una cola de fuego. Las dos funciones siguientes sirven para crear efectos:
effect_create_below(kind,x,y,size,color)
Crea un efecto del tipo indicado en kind en la posición especificada. size
es el tamaño del efecto según la convención siguiente: 0 = pequeño, 1 = mediano, 2 = grande. color indica el color del efecto. El efecto se crea por debajo de la instancia con una profundidad (depth) igual a 100000.
effect_create_above(kind,x,y,size,color) la instancia, con una profundidad igual a-100000.
Para eliminar todos los efectos usa la función:
effect_clear()
Detiene y elimina todos los efectos.
Tipos de partículas
Igual que la función anterior, pero esta vez el efecto se crea encima de
Un tipo de particular define la forma, color y movimiento de una clase de partículas. Sólo necesitas definir un tipo de partícula una vez durante el juego, una vez hecho esto puede ser usado por cualquier sistema de partículas. Los tipos de partículas tienen un gran número de características que pueden ser cambiadas para alterar su apariencia o comportamiento. Con la elección adecuada puedes crear cualquier tipo de efecto.
Las funciones para crear y destruir tipos de partículas son:
part_type_create()
Crea un Nuevo tipo de particular. Devuelve el índice del tipo. Este índice debe usarse en todas las llamadas
a las funciones siguientes para configurar las propiedades del tipo de partícula, por lo que es aconsejable que lo guardes en una variable global.
part_type_destroy(ind)
Destruye el tipo de particular ind. Llama a esta función cuando ya no se necesite el tipo de partícula
para ahorrar espacio.
part_type_exists(ind) part_type_clear(ind)
Devuelve si el tipo indicado de particular existe.
Devuelve el tipo de particular ind a sus valores por defecto.
La forma de una partícula Las partículas tienen una forma. Esta forma se indica mediante un sprite. Puedes usar cualquier sprite que quieras para tus partículas pero debes saber que además hay 15 tipos de sprites ya definidos. Estos sprites son todos de tamaño 64x64 y poseen valores de transparencia que los hacen fundirse de manera excelente con el fondo. Estos sprites se indican con las constantes:
•
pt_shape_pixel (pixel)
•
pt_shape_disk (disco)
•
pt_shape_square (cuadrado)
•
pt_shape_line (línea)
•
pt_shape_star (estrella)
•
pt_shape_circle (círculo)
•
pt_shape_ring (anillo)
•
pt_shape_sphere (esfera)
•
pt_shape_flare (brillo)
•
pt_shape_spark (chispa)
•
pt_shape_explosion (explosión)
•
pt_shape_cloud (nube)
•
pt_shape_smoke (humo)
•
pt_shape_snow (nieve)
Para indicar la forma debes usar la función:
part_type_shape(ind,shape)
Aplica la forma tipo shape a la partícula ind.
También puedes usar tu propio sprite con la función:
part_type_sprite(ind,sprite,animate,stretch,random)
Asigna el sprite para el tipo de particular ind. Con la
opción animate puedes indicar si el sprite debe ser animado. Con stretch indicas si la animación debe repetirse durante el tiempo de vida de la partícula. Y con random indicas si se escoge una subimagen aleatoria como la imagen inicial.
Una vez que hayas seeccionado el sprite para el tipo de partícula puedes elegir el tamaño de éste. Un tamaño de 1 significa el tamaño normal del sprite. Un tipo de partícula se puede definir para que todas las partículas tengan el mismo tamaño o para que tengan tamaños distintos. También puedes especificar un rango de tamaños, si el tamaño debe variar durante la vida de la partícula y si puede alternarse al crecer o disminuir, creando un efecto de tintineo.
part_type_size(ind,size_min,size_max,size_incr,size_wiggle)
Establece los parámetros de tamaño
para el tipo de partícula. Debes indicar el tamaño inicial, el tamaño final, la cantidad que debe crecer en cada step (usa un valor negativo para que disminuya) y el tintineo (El valor por defecto es 1 y el tamaño no cambia).
Las partículas también tienen una orientación que se indica en grados en sentido antihorario. Al igual que el tamaño, la orientación puede crecer, disminuir y puede ser la misma para todas las partículas o diferente para cada una.
part_type_orientation(ind,ang_min,ang_max,ang_incr,ang_wiggle,ang_relative) Aplica la orientación al tipo de partícula. Debes indicar la orientación inicial, final, el incremento o decremento en cada step, si la orientación tintinea y si los valores son relativos al movimiento actual (1) o absolutos (0). Por ejemplo, si ponemos todos los valores a 0 menos ang_relative, que lo ponemos a 1, la orientación de la partícula seguirá el camino que ésta describa.
Color y blending Las partículas tendrán un color. Hay diferentes maneras de especificar un color para una partícula. La más simple es especificar solamente un color. Pero también puedes especificar dos ó tres colores que se interpolarán a lo largo de la vida de la partícula. Por ejemplo, una
partícula puede crearse siendo blanca y poco a poco irse convirtiendo en negra. Otra posibilidad es indicar que el color de cada partícula debe ser diferente y elegido de un rango de colores especificado.
El color por defecto es blanco. Cuando usas un sprite con sus propios colores esto es lo que normalmente quieres y no necesitas especificar ninguna propiedad de color.
part_type_color1(ind,color1) partícula.
Indica un sólo color para la
part_type_color2(ind,color1,color2)
part_type_color3(ind,color1,color2,color3) part_type_color_mix(ind,color1,color2)
Especifica dos colores entre los que se interpolará. Ahora los colores representan el color incial, medio y final.
El color será seleccionado de una mezcla aleatoria de estos dos colores y
permanecerá inalterado durante la vida de la partícula.
part_type_color_rgb(ind,rmin,rmax,gmin,gmax,bmin,bmax)
Se puede usar para especificar que cada
partícula tendrá un color fijo pero escogido de un rango de colores que especificas en modo rgb.
part_type_color_hsv(ind,hmin,hmax,smin,smax,vmin,vmax)
Igual que la anterior, pero esta vez el rango se
especifica en modo hsv.
Además del color, también puedes especificar un valor de transparencia. Así puedes conseguir que las partículas desaparezcan poco a poco.
part_type_alpha1(ind,alpha1)
Aplica un único valor de transparencia (entre 0 y 1) al tipo de partícula.
part_type_alpha2(ind,alpha1,alpha2)
Igual que la anterior, pero esta vez la transparencia en cada momento se
interpola entre las dos especificadas.
part_type_alpha3(ind,alpha1,alpha2,alpha3)
Igual que a anterior, pero esta vez la transparencia en cada
momento se interpola entre las tres especificadas.
Normalmente las partículas se mezclan con el fondo igual que los sprites. Pero también es posible usar additive blending, controlando así la forma en que se mezclan. Esto resulta un efecto muy bueno para explosiones.
part_type_blend(ind,additive)
Indica si se debe utilizar additive blending (1) or normal blending (0) para el tipo de
partícula.
Vida y muerte Las partículas viven durante un tiempo limitado, después, desaparecen. La vida de las partículas se mide en steps. Puedes indicar su vida, o un rango para cada tipo de partículas. Además, las partículas pueden crear otras partículas en cada step o cuando mueren. Vigila que el número de partículas total no sea demasiado elevado.
part_type_life(ind,life_min,life_max)
Establece los límites del tiempo de vida para el tipo de partícula (Ambos son
100 por defecto).
part_type_step(ind,step_number,step_type)
Establece el número y tipo de partículas que deben ser generadas en
cada step para el tipo indicado de particula. Si usas un número negativo para step_number, por ejemplo -5, se generará una partícula cada 5 steps.
part_type_death(ind,death_number,death_type)
Establece el número y tipo de partículas que deben ser
generadas cuando una particular del tipo indicado llega al final de su ciclo de vida. Puedes usar valores negativos al igual que en la función anterior. La partícula sólo creará otras partículas al llegar al final de su vida y no cuando sea destruida por un destructor (lee más adelante).
Movimiento de las partículas Las partículas se pueden mover durante su vida. Pueden tener velocidad inicial y dirección y cambiar durante su vida. También pueden verse afectadas por la gravedad.
part_type_speed(ind,speed_min,speed_max,speed_incr,speed_wiggle)
Establece las propiedades de
velocidad para el tipo de partícula. (Todos los valores son 0 por defecto). Especificas un valor mínimo y máximo para la partícula y cuando ésta sea creada se escogerá un valor aleatorio entre ellos. Puedes especificar un valor negativo en speed_incr para hacer que la partícula se frene (aunque nunca llegará a tener velocidad negativa).
part_type_direction(ind,dir_min,dir_max,dir_incr,dir_wiggle)
Establece las propiedades de
dirección para el tipo de partícula, en grados antihorarios (0-360). (Todos los valores son 0 por defecto).
part_type_gravity(ind,grav_amount,grav_dir)
Establece las propiedades de gravedad para el tipo de partícula.
(Por defecto no hay valor de gravedad).
Sistemas de partículas Las partículas tienen vida en sistemas de partículas. Por lo que para tener partículas en tu juego necesitas crear uno o más sistemas de partículas. Puede haber muchos tipos diferentes de sistemas de partículas. Por ejemplo, si tu juego tiene varias pelotas y cada pelota debiera tener una cola de partículas, lo más probable es que cada pelota tenga su sistema de partículas. La manera más fácil para manejar los sistemas de partículas es crear uno y luego crear partículas en él, usando los tipos partículas que especificaste antes. Pero, como veremos a continuación, los sistemas de partículas pueden contener emisores que automáticamente producen partículas, atractores que las atraen y destructores que las eliminan.
Una vez que las partículas se añaden a un sistema son dibujadas y actualizadas en cada step automáticamente. Para definir si las partículas se deben dibujar delante o detrás de las demás instancias, los sistemas de partículas poseen una profundidad.
Los sistemas de partículas no se eliminarán aunque reinicies el juego, para eliminarlos debes usar la función adecuada. Así que asegúrate de hacerlo cuando ya no los necesites.
Las siguientes funciones permiten manejar los sistemas de partículas:
part_system_create()
Crea un nuevo sistema de partículas. Devuelve el índice del sistema creado. Este índice debe emplearse
en las llamadas a las funciones siguientes para configurar las propiedades del sistema de partículas.
part_system_destroy(ind)
Destruye el sistema de partículas ind. Llama a esta función si ya no harás uso del sistema para
ahorrar espacio.
part_system_exists(ind) part_system_clear(ind)
Devuelve si el sistema de partículas ind existe.
Devuelve el sistema ind a sus valores por defecto, removiendo todas las partículas, emisores y
atractores en él.
part_system_draw_order(ind,oldtonew)
Establece el orden en el que el sistema dibuja las partículas. Cuando oldtonew
es true las partículas más viejas son dibujadas primero y las nuevas se dibujan sobre ellas (valor por defecto). De otra forma las partículas más recientes son dibujadas primero. Esto puede resultar en varios efectos diferentes.
part_system_depth(ind,depth)
Especifica la profundidad del sistema de partículas.
part_system_position(ind,x,y)
Especifica la posición en la que se dibuja el sistema de partículas. Si quieres dibujar el
sistema relativo a un objeto puedes usar sus coordenadas.
Como ya hemos visto, los sistemas de partículas se dibujan y actualizan automáticamente. Pero a veces puedes no querer que esto sea así. Las siguientes funciones te permiten controlar estos aspectos:
part_system_automatic_update(ind,automatic)
Indica si el sistema debe actualizare automáticamente (1) o no
(0).
part_system_automatic_draw(ind,automatic) part_system_update(ind)
Indica si el sistema debe dibujarse automáticamente (1) o no (0).
Esta función actualiza el sistema y permite a los emisores crear partículas. Puedes llamar a esta
función cuando no uses actualización automática, o para acelerar un poco el sistema al inicio.
part_system_drawit(ind)
Esta función dibuja el sistema de partículas si has desactivado la opción automática. Debes llamar a
esta función desde el evento draw de algún objeto.
Las siguientes funciones se encargan de las partículas de un sistema de partículas:
part_particles_create(ind,x,y,parttype,number)
Esta función crea number partículas del tipo ind en la posición
(x,y) dentro del sistema.
part_particles_create_color(ind,x,y,parttype,color,number)
Esta función crea number partículas del
tipo ind en la posición (x,y) dentro del sistema con el color indicado. Esto es útil cuando el tipo de partícula sólo usa un color o no define ninguno.
part_particles_clear(ind) part_particles_count(ind)
Emisores
Esta función elimina todas las partículas del sistema.
Esta función devuelve el número de partículas en el sistema.
Los emisores crean partículas. Pueden crear un flujo continuo de partículas o pueden lanzar un cierto número de partículas usando la función adecuada. Un sistema de partículas puede tener un número arbitrario de emisores. Un emisor tiene las siguientes propiedades:
•
xmin, xmax, ymin, ymax
•
shape
•
indican la extensión de la región en la cual se generan las partículas.
indica la forma de la región. Puede tener uno de los siguientes valores:
o
ps_shape_rectangle
o
ps_shape_ellipse
o
ps_shape_diamond
o
ps_shape_line
distribution o
indica la distribución usada para general las partículas. Puede tener uno de los siguientes valores:
ps_distr_linear
indica una distribución lineal, esto es que en toda la región se tiene la misma oportunidad de
que aparezca una partícula
o
ps_distr_gaussian
indica una distribución Gaussiana en la cual se generan más partículas en el centro que en
las orillas de la región
•
particle type
•
number
indica el tipo de partículas que serán generadas
indica el número de partículas generadas en cada step. Si es menor que 0, en cada step se generará una particular con
una probabilidad de –1/number. Por ejemplo con un valor de –5 se generará una particular en promedio una vez cada 5 steps.
Las siguientes funciones permiten establecer los emisores y permitirles crear partículas. Nota que cada una de ellas necesita el id del sistema de partículas al que pertenecen como primer argumento.
part_emitter_create(ps)
Crea un nuevo emisor en el sistema de partículas ps. Devuelve el índice del emisor. Este índice debe
usarse en todas las llamadas a las funciones siguientes para configurar las propiedades del emisor.
part_emitter_destroy(ps,ind)
Destruye el emisor ind en el sistema de partículas ps. Llama a esta función si no necesitas
más del emisor para ahorrar espacio.
part_emitter_destroy_all(ps) part_emitter_exists(ps,ind) part_emitter_clear(ps,ind)
Destruye todos los emisores del sistema de partículas ps.
Devuelve true si el emisor ind existe en el sistema ps.
Devuelve el emisor ind a sus valores por defecto.
part_emitter_region(ps,ind,xmin,xmax,ymin,ymax,shape,distribution)
Establece la región y
distribución del emisor.
part_emitter_burst(ps,ind,parttype,number)
Emite number partículas del tipo partype en forma de estallido (una
sola vez) desde el emisor ind.
part_emitter_stream(ps,ind,parttype,number)
Desde este momento se crearán number partículas de tipo partype
desde el emisor ind en cada step. Si indicas un número menor a 0 en cada step una particular sera generada con una probabilidad de – 1/number. Por ejemplo con un valor de –5 se creará en promedio una particular cada 5 steps.
Atractores
Además de los emisores, un sistema de partículas también puede contener atractores. Un atractor atrae a las partículas (o las aleja). Un sistema de partículas puede tener múltiples atractores. Aunque se te recomienda solo usar unos pocos porque alentarán el procesamiento de las partículas. Un atractor tiene las siguientes propiedades:
•
x,y
•
force
indican la posición del atractor. indican la fuerza de atracción del atractor. El cómo actúe la fuerza sobre las partículas depende de los siguientes
parámetros.
•
dist
indica la máxima distancia a la cual el atractor tiene efecto. Solo las partículas con una distancia al atractor menor que dist
serán atraídas.
•
kind
indica el tipo de atractor. Se tienen los siguientes valores
o
ps_force_constant
o
ps_force_linear
indica que la fuerza es constante independientemente de la distancia.
indica una fuerza que aumenta linealmente. A la distancia máxima la fuerza es 0 mientras
que en la posición del atractor la fuerza tiene el valor force indicado.
o •
ps_force_quadratic
additive
indica que la fuerza aumenta de manera cuadrática.
indica si la fuerza se suma a la velocidad y dirección en cada step (true) o si solo se aplica a la posición de la
particular (false). Cuando es true la particular acelerará hacia el atractor mientras que cuando sea false se moverá hacia él con velocidad constante.
Las siguientes funciones definen atractores. Nota que todas necesitan como primer argumento el índice del sistema de partículas al cual pertenecen.
part_attractor_create(ps)
Crea un nuevo atractor en el sistema de partículas ps. Devuelve el índice del atractor. Este índice
debe emplearse en la llamada a las funciones siguientes para configurar las propiedades del atractor.
part_attractor_destroy(ps,ind)
Destruye el atractor ind dentro del sistema de partículas ps. Llama a esta función si ya
no necesitas el atractor para ahorrar espacio.
part_attractor_destroy_all(ps) part_attractor_exists(ps,ind) part_attractor_clear(ps,ind)
Destruye todos los atractores que hayan sido creados en el sistema de partículas ps.
Devuelve true si el atractor ind existe dentro del sistema de partículas ps.
Devuelve los valores del atractor a sus valores por defecto.
part_attractor_position(ps,ind,x,y)
Establece a (x,y) la posición del atractor ind.
part_attractor_force(ps,ind,force,dist,kind,aditive)
Establece las propiedades de fuerza del atractor
ind.
Destructores Los destructores destruyen las partículas cuando aparecen dentro de su región. Un sistema de partículas puede tener un número arbitrario de destructores. Un destructor cuenta con las siguientes propiedades:
•
xmin, xmax, ymin, ymax
•
shape
indican la extensión de la región en la cual se destruyen las partículas.
indica la forma de la región. Puede tener uno de los valores siguientes:
o
ps_shape_rectangle
o
ps_shape_ellipse
o
ps_shape_diamond
Las funciones siguientes configuran las propiedades de los destructores. Nota que cada una de ellas necesita como primer argumento el índice del sistema de partículas al que pertenece el destructor.
part_destroyer_create(ps)
Crea un nuevo destructor en el sistema de partículas ps. Devuelve el índice del destructor. Este
índice debe usarse en las llamadas a las funciones siguientes para configurar las propiedades del destructor.
part_destroyer_destroy(ps,ind)
Destruye el destructor ind dentro del sistema de partículas ps. Llama a esta función
cuando ya no hagas uso del destructor para ahorrar espacio.
part_destroyer_destroy_all(ps) part_destroyer_exists(ps,ind) part_destroyer_clear(ps,ind)
Destruye todos los destructores que hayan sido creados en el sistema de partículas ps.
Devuelve true si el destructor ind existe dentro del sistema de partículas ps.
Devuelve el destructor a sus valores por defecto.
part_destroyer_region(ps,ind,xmin,xmax,ymin,ymax,shape)
Establece la región del destructor.
Deflectores Los deflectores desvían a las partículas cuando aparecen dentro de su región. Un sistema de partículas puede tener un número arbitrario de deflectores. Un deflector tiene las siguientes propiedades:
•
xmin, xmax, ymin, ymax indican la extensión de la región en la cual las partículas son desviadas.
•
kind
•
indica el tipo de deflector. Puede tener uno de los siguientes valores:
o
ps_deflect_horizontal
o
ps_deflect_vertical
friction
refleja las partículas horizontalmente; normalmente usado para paredes verticales
refleja las partículas verticalmente; normalmente usado para paredes horizontales
la cantidad de fricción como resultado de un impacto con el deflector. Entre mayor sea este valor más se alentará la
particular al impactarse con el deflector.
Se tienen las siguientes funciones para configurar las propiedades del deflector. Nota que todas necesitan como primer argumento el índice del sistema de partículas al cual pertenece el deflector.
part_deflector_create(ps)
Crea un nuevo deflector en el sistema de partículas ps. Devuelve el índice del deflector. Este
índice debe emplearse en las llamadas a las funciones siguientes para configurar las propiedades del deflector.
part_deflector_destroy(ps,ind)
Destruye el deflector ind del sistema de partículas ps. Llama a esta función cuando ya no
necesites el deflector para ahorrar espacio.
part_deflector_destroy_all(ps) part_deflector_exists(ps,ind) part_deflector_clear(ps,ind)
Destruye todos los deflectores que hayan sido creados en el sistema de partículas ps.
Devuelve true si el deflector ind existe dentro del sistema de partículas ps.
Devuelve el deflector a sus valores por defecto.
part_deflector_region(ps,ind,xmin,xmax,ymin,ymax) Establece la región para el deflector.
part_deflector_kind(ps,ind,kind)
Establece el tipo de deflector.
part_deflector_friction(ps,ind,friction)
Establece la fricción del deflector.
Cambiadores Los cambiadores cambian ciertas partículas cuando aparecen dentro de su región. Un sistema de partículas puede tener un número arbitrario de cambiadores. Un cambiador tiene las siguientes propiedades:
•
xmin, xmax, ymin, ymax
•
shape
indican la extensión de la región en la cual las partículas son cambiadas.
indica la forma de la región. Puede tener uno de los valores siguientes:
o
ps_shape_rectangle
o
ps_shape_ellipse
o
ps_shape_diamond
•
parttype1
indica el tipo de partícula a ser cambiado.
•
parttype2
indica el tipo de partícula al que se cambiará.
•
kind o
indica el tipo del cambiador. Puede tener uno de los siguientes valores:
ps_change_motion
sólo cambia los parámetros de movimiento de la partícula, no el color o forma ni las
propiedades de tiempo de vida
o
ps_change_shape
o
ps_change_all
sólo cambia los parámetros de forma de la partícula como el tamaño, el color y forma
cambia todos los parámetros, básicamente significa que la partícula es destruida y se crea una
nueva del nuevo tipo.
Las siguientes funciones permiten establecer las propiedades del cambiador. Nota que cada una de ellas necesita como primer argumento el índice del sistema de partículas al que pertenece el cambiador.
part_changer_create(ps)
Crea un nuevo cambiador en el sistema de partículas ps. Devuelve el índice del cambiador. Este
índice debe usarse en las llamadas a las funciones siguientes para configurar las propiedades del cambiador.
part_changer_destroy(ps,ind)
Destruye el cambiador ind en el sistema de partículas ps. Llama a esta función si ya no
necesitas el cambiador para ahorrar espacio.
part_changer_destroy_all(ps) part_changer_exists(ps,ind) part_changer_clear(ps,ind)
Destruye todos los cambiadores que hayan sido creados en el sistema de partículas ps.
Devuelve true si el cambiador ind existe en el sistema de partículas ps.
Devuelve las propiedades del cambiador a sus valores por defecto.
part_changer_region(ps,ind,xmin,xmax,ymin,ymax,shape) part_changer_types(ps,ind,parttype1,parttype2)
Establece el tipo de partícula que debe ser cambiado y el tipo
al que debe ser cambiado.
part_changer_kind(ps,ind,kind)
Establece el tipo de cambiador.
jemplo de fuegos artificiales
Establece la región para el cambiador.
Aquí tienes un ejemplo de un sistema de partículas que crea unos fuegos artificiales. Hace uso de dos tipos de partículas: uno que forma el cohete y otro que forma los fuegos artificiales en si. El cohete genera las partículas de los fuegos artificiales cuando se destruye. También tenemos un emisor en el sistema de partículas que emite regularmente partículas del cohete desde la parte baja de la pantalla. Para hacer que esto funcione necesitas un objeto. En su evento de creación colocamos el siguiente código que crea los tipos de partículas, un sistema de partículas y el emisor:
{ // Crear el sistema de partículas ps = part_system_create(); // the firework particles pt1 = part_type_create(); part_type_shape(pt1,pt_shape_flare); part_type_size(pt1,0.1,0.2,0,0); part_type_speed(pt1,0.5,4,0,0); part_type_direction(pt1,0,360,0,0); part_type_color1(pt1,c_red); part_type_alpha2(pt1,1,0.4); part_type_life(pt1,20,30); part_type_gravity(pt1,0.2,270); // El cohete pt2 = part_type_create(); part_type_shape(pt2,pt_shape_sphere); part_type_size(pt2,0.2,0.2,0,0); part_type_speed(pt2,10,14,0,0); part_type_direction(pt2,80,100,0,0); part_type_color2(pt2,c_white,c_gray); part_type_life(pt2,30,60); part_type_gravity(pt2,0.2,270); part_type_death(pt2,150,pt1);
/* Crear el fuego artificial al morir*/
// Crear el emisor em = part_emitter_create(ps); part_emitter_region(ps,em,100,540,480,490,ps_shape_rectangle,ps_distr_linear); part_emitter_stream(ps,em,pt2,-4); }
// Crear 1 cada 4 steps
Listo! Asegúrate de que el sistema de partículas (y tal vez los tipos de partículas) se destruyen al cambiar de room o el efecto durará para siempre.
Juegos multijugador Esta funcionalidad sólo está disponible en la versión registrada de Game Maker. Jugar contra la computadora es divertido. Pero jugar contra oponentes humanos puede serlo mucho más. Es relativamente fácil crear este tipo de juegos porque no tienes que implementar IA compleja para un oponente manejado por la computadora. Por supuesto que puedes sentar a dos jugadores tras el mismo monitor y emplear diferentes teclas o algún otro dispositivo de entrada, pero es mucho más interesante cuando cada jugador está detrás de su propia computadora. O aún mejor, un jugador se encuentra del otro lado del océano. El Game Maker tiene soporte multijugador. Por favor toma en cuenta que el crear juegos multijugador efectivos que se sincronicen bien y no tengan latencia es una tarea difícil. Este capítulo da una breve descripción de las posibilidades. En el sitio web hay un tutorial con más información.
La ayuda sobre este tema se encuentra en las siguientes secciones:
Configurando la conexión Creando y uniéndose a sesiones Jugadores Datos compartidos Mensajes
Configurando la conexión Para que dos computadoras se comuniquen necesitarán cierto protocolo de conexión. Como la mayoría de los juegos, el Game Maker ofrece cuatro diferentes tipos de conexión: IPX, TCP/IP, Módem y Serial. La conexión IPX (para ser más precisos, se trata de un protocolo) funciona casi completamente transparente. Puede emplearse para jugar juegos con otras personas en la misma red local. Se necesita que esté instalada en tu computadora para que pueda emplearse. (Si no funciona, consulta la documentación de Windows. O ve a la opción Red dentro del Panel de Control y agrega el protocolo IPX). TCP/IP es el protocolo de internet. Puede usarse para jugar con otros jugadores en cualquier lugar mediante internet, suponiendo que conozcas su dirección IP. Una conexión modem se realiza a través del modem. Tienes que introducir cierta información del modem (una cadena de inicialización y un número telefónico) para usarla. Finalmente, al usar la línea serial (una conexión directa entre las computadoras) necesitas introducir varias opciones de puertos. Hay cuatro funciones dentro del GML que pueden emplearse para inicializar estas conexiones:
mplay_init_ipx()inicializa una conexión IPX. mplay_init_tcpip(addr)inicializa una conexión TCP/IP. addr es una cadena que indica la dirección web o IP, p. Ej. 'www.gameplay.com' o '123.123.123.12', posiblemente seguida por un número de puerto (p. Ej. ':12'). Sólo se necesita la dirección para unirse a una sesión (ve a continuación). En una red local no se necesitan direcciones.
mplay_init_modem(initstr,phonenr)inicializa una conexión vía módem. initstr es la cadena de inicialización para el módem (puede estar vacía). phonenr es una cadena que contiene el número telefónico a marcar (p. Ej. '0201234567'). Sólo se necesita el número telefónico al unirse a una sesión (ve a continuación).
mplay_init_serial(portno,baudrate,stopbits,parity,flow) inicializa una conexión en serie. portno es el número de puerto (1-4). baudrate es la velocidad a emplear en baudios (100-256K). stopbits indica el número de bits de parada (0 = 1 bit, 1 = 1.5 bit, 2 = 2 bits). parity indica la paridad (0=ninguna, 1=impar, 2=par, 3=mark). Y flow indica el tipo de control de flujo (0=ninguna, 1=xon/xoff, 2=rts, 3=dtr, 4=rts and dtr). La función devuelve si la conexión se efectuó con éxito. Una llamada típica a esta función es mplay_init_serial(1,57600,0,0,4). Si especificas 0 al primer argumento se abre un diálogo para que el usuario pueda cambiar la configuración manualmente. Tu juego debe llamar una de estas funciones una sola vez. Todas las funciones indican si han tenido éxito (si se logra la conexión). No tiene éxito si el protocolo en particular no está instalado o soportado por tu máquina. Para checar si hay una conexión exitosa disponible puedes emplear la siguiente función
mplay_connect_status()devuelve el estado de la conexión actual. 0=no hay conexión, 1=conexión IPX, 2=conexión TCP/IP, 3=conexión vía módem, y 4=conexión serial.
Para finalizar la conexión llama a la función
mplay_end() finaliza la conexión actual.
Cuando empleas una conexión TCP/IP tal vez quieras decirle a la persona con la que deseas jugar cuál es la dirección ip de tu computadora. La siguiente función te será de ayuda:
mplay_ipaddress()devuelve la dirección IP de tu máquina (p. Ej. '123.123.123.12') como cadena. Puedes p. Ej. mostrarla en pantalla. Nota que esta rutina es lenta por lo que mejor no la llames a menudo.
Creando y uniéndose a sesiones Cuando te conectas a una red, puede haber múltiples juegos ejecutándose en la misma red. Esos juegos reciben el nombre de sesiones. Estas diferentes sesiones pueden corresponder a juegos diferentes o al mismo. Un juego debe identificarse en la red. Afortunadamente, Game Maker hace esto por ti. Lo único que debes saber es que cuando cambias el id del juego en la ventana de opciones esta identificación cambia. De esta forma puedes evitar que personas con versiones anteriores de tu juego jueguen contra personas que cuentan con versiones más recientes.
Si quieres iniciar un nuevo juego multijugador necesitas crear una nueva sesión. Para esto puedes emplear la siguiente rutina:
mplay_session_create(sesname,playnumb,playername) Crea una nueva nueva sesión en la conexión actual. sesname es una cadena que indica el nombre de la sesión. playnumb indica el número máximo de jugadores permitidos para este juego (usa 0 para un número arbitrario de jugadores). playname es tu nombre como jugador. Indica si ha tenido éxito.
Una instancia del juego debe crear la sesión. La(s) otra(s) instancia(s) del juego deben unirse a esta sesión. Esto es un poco más complicado. Primero debes ver las sesiones disponibles y luego elegir a la que te unirás. Hay tres rutinas importantes para esto:
mplay_session_find()
Busca todas las sesiones que aún aceptan jugadores y devuelve el número de sesiones encontradas.
mplay_session_name(numb) Devuelve el nombre de la sesión número numb (0 es la primer sesión). Esta rutina puede ser llamada sólo después de haber llamado a la anterior.
mplay_session_join(numb,playername)
Con esta rutina te unes a la sesión número numb (0 es la primer
sesión). playername es tu nombre como jugador. Indica si ha tenido éxito.
Hay una rutina más que puede cambiar el modo de la sesión. Debe llamarse antes de crear una sesión:
mplay_session_mode(move) Indica si se mueve la sesión de host a otra computadora cuando el host actual cierre. move debe ser true o false (valor por defecto).
Para checar el estado de la sesión actual puedes usar la siguiente función
mplay_session_status() Devuelve el estado de la sesión actual. 0 = no hay sesión, 1 = sesión creada, 2 = se unió a la sesión.
Un jugador puede detener una sesión empleando la siguiente rutina:
mplay_session_end() Finaliza la sesión para este jugador.
Jugadores Cada instancia del juego que se una a una sesión es un jugador. Como se indicó antes, los jugadores tienen nombres. Hay tres rutinas referentes a los jugadores:
mplay_player_find()
Busca todos los jugadores en la sesión actual y devuelve el número de jugadores encontrados.
mplay_player_name(numb)
Devuelve el nombre del jugador número numb (0 es el primer jugador, el cual siempre eres tú).
Esta rutina puede sólo ser llamada después de haber llamado a la anterior.
mplay_player_id(numb)
Devuelve el id único del jugador número numb (0 es el primer jugador, el cual siempre eres tú). Esta
rutina puede llamarse sólo después de haber llamado la primera. Este id es usado al enviar y recibir mensajes de otros jugadores.
Datos compartidos La comunicación mediante datos compartidos es probablemente la mejor forma de sincronizar el juego. Todo el proceso de comunicación no es visible para ti. Hay un juego de 10000 valores que son comunes a todas las entidades del juego. Cada entidad puede establecer y leer valores. Game Maker se asegura de que cada entidad vea los mismos valores. Un valor puede ser un número real o una cadena. Sólo hay dos rutinas:
mplay_data_write(ind,val) mplay_data_read(ind)
Escribe el valor val (cadena o real) en la ubicación ind (ind entre 0 y 10000).
Devuelve el valor en la ubicación ind (ind entre 0 y 10000). Inicialmente todos los valores son 0.
Para sincronizar la información en las diferentes máquinas puedes ya sea usar un modo garantizado (guaranteed mode) que asegura que el cambio llegue a la otra máquina (pero el cual es lento) o un modo no garantizado (non-guaranteed mode). Para cambiar esto usa la siguiente rutina:
mplay_data_mode(guar) Indica si se usa o no transmisión garantizada para los datos compartidos. guar debe ser true (valor por defecto) o false.
Mensajes El segundo mecanismo de comunicación que el Game Maker soporta es el envío y la recepción de mensajes. Un jugador puede enviar mensajes a un jugador o a todos los jugadores. Los jugadores pueden ver si han llegado mensajes y llevar a cabo las acciones adecuadas. Los mensajes pueden enviarse en modo garantizado en el que estás seguro de que llegarán (pero puede ser lento) o en modo no garantizado, el cual es más rápido.
Existen las siguientes rutinas de mensajes:
mplay_message_send(player,id,val) Envía un mensaje al jugador player (ya sea un identificador o un nombre; usa 0 para enviar el mensaje a todos los jugadores). id es un entero que funciona como identificador del mensaje y val es el valor (ya sea un número real o una cadena). El mensaje es enviado en modo no garantizado. Si val contiene un mensaje de texto la longitud máxima del mensaje es de 30000 caracteres.
mplay_message_send_guaranteed(player,id,val) Envía un mensaje al jugador player (ya sea un identificador o un nombre; usa 0 para enviar el mensaje a todos los jugadores). id es un entero que funciona como identificador del mensaje y val es el valor (ya sea un número real o una cadena). Este es un envío garantizado. Si val contiene un mensaje de texto la longitud máxima del mensaje es de 30000 caracteres.
mplay_message_receive(player) Recibe el siguiente mensaje de la cola de mensajes que llegó del jugador player (identificador o nombre). Usa 0 para indicar mensajes de cualquier jugador. La rutina indica si de hecho hubo un nuevo mensaje. Si es así, puedes emplear las siguientes rutinas para obtener su contenido:
mplay_message_id() Devuelve el identificador del último mensaje recibido. mplay_message_value() Devuelve el valor del último mensaje recibido. mplay_message_player() Devuelve el jugador que envió el último mensaje recibido. mplay_message_name() Devuelve el nombre del jugador que envió el último mensaje recibido. mplay_message_count(player) Devuelve el número de mensajes restantes en la cola de espera del jugador player (usa 0 para contar todos los mensajes).
mplay_message_clear(player) Elimina todos los mensajes en la cola de espera del jugador player (usa 0 para eliminar todos los mensajes). Debemos hacer algunas observaciones. Primero, si quieres enviar un mensaje sólo a un usuario en particular, necesitarás conocer el id del jugador. Como se indicó antes puedes obtener este id con la función mplay_player_id(). Este identificador del jugador también es empleado al recibir mensajes de un jugador en particular. Alternativamente, puedes dar el nombre del jugador como cadena. Si varios jugadores tienen el mismo nombre, el mensaje sólo llegará al primero.
En segundo lugar, podrías preguntarte porqué cada mensaje tiene un entero identificador. La razón es que esto ayuda a tu aplicación a enviar diferentes tipos de mensajes. El receptor puede checar el tipo de mensaje usando el id y llevar a cabo las acciones apropiadas. (Como no está garantizado que los mensajes lleguen, el enviar el id y el valor en mensajes diferentes causaría serios problemas).
Usando DLLs
Esta función solo está disponible en la versión registrada de Game Maker.
En aquellos casos en los que la funcionalidad del GML no cubra tus objetivos, se pueden ampliar las posibilidades usando plug-ins (agregados o complementos). Un plug-in consiste en un archivo DLL (Dynamic Link Library – Biblioteca de enlazado dinámico). En este archivo DLL se pueden definir funciones. Tales funciones pueden ser programadas en cualquier lenguaje que soporte la creación de DLLs (p. Ej. Delphi, C, C++, etc.). Aunque se necesita contar con ciertas habilidades de programación para poder hacerlo. Las funciones plug-in deben tener un formato específico. Pueden tener entre 0 y 11 argumentos, cada uno de los cuales puede ser un número real (double en C) o una cadena terminada en un carácter nulo. (Para más de 4 argumentos, sólo se soporta argumentos reales). Estas funciones deben devolver ya sea un valor real o una cadena terminada en carácter nulo.
En Delphi se puede crear una DLL seleccionando New en el menú File y luego eligiendo DLL. A continuación tienes un ejemplo de una DLL escrita en Delphi que puede ser empleada con Game Maker. (Esto es código de Delphi ¡no GML!)
library MyDLL;
uses SysUtils, Classes; function MyMin(x,y:double):double;
cdecl;
begin if x
Para hacer uso de esta DLL en Game Maker primero necesitas especificar las funciones externas que deseas emplear y qué tipo de argumentos requieren. Para ello tenemos la siguiente función en el GML:
external_define(dll,name,calltype,restype,argnumb,arg1type,arg2type, …) Define
una función
externa. dll es el nombre del archivo dll. name es el nombre de las funciones. calltype es la convención de llamada empleada. Usa dll_cdecl o dll_stdcall. restype es el tipo del resultado. Usa ty_real o ty_string. argnumb es el número de argumentos (0-11). Después, para cada argumento debes especificar su tipo. Para ello usa nuevamente ty_real o ty_string. Cuando hay más de 4 argumentos todos ellos deben ser de tipo ty_real.
Esta función devuelve el id de la función externa que debe emplearse para llamarla. En el ejemplo de arriba, al inicio del juego usarías el siguiente código GML:
{ global.mmm = external_define('MYOWN.DLL','MyMin',dll_cdecl, ty_real,2,ty_real,ty_real); global.ddd = external_define('MYOWN.DLL','DoubleString',dll_cdecl, ty_string,1,ty_string); } Ahora en el momento que necesites llamar a las funciones, usas la siguiente función:
external_call(id,arg1,arg2,…)
Llama a la función externa con el id y los argumentos dados. Necesitas proporcionar el
número correcto de argumentos del tipo correcto (real o string). La función devuelve el resultado de la función externa.
Así, por ejemplo, escribirías:
{ aaa = external_call(global.mmm,x,y); sss = external_call(global.ddd,'Hello'); } Si ya no utilizarás la DLL, lo mejor sería liberarla.
external_free(dll)
Libera la DLL con el nombre indicado. Esto es particularmente necesario si el juego debiera remover la DLL.
Mientras la DLL no haya sido liberada, no puede ser removida. Lo mejor es realizar esto p. Ej. en el evento game end.
Ahora te preguntarás cómo hacer una función en una DLL que haga algo en el juego. Por ejemplo, podrías querer una DLL que agregue instancias de objetos a tu juego. La forma más fácil es dejar que la función DLL devuelva una cadena que contenga una pieza de código GML. Esta cadena que contiene una pieza de GML puede ser ejecutada usando la siguiente función del GML
execute_string(str)
Ejecuta la pieza de código en la cadena str.
Alternativamente puedes dejar que la DLL cree un archivo con un script que puede ser ejecutado (esta función también puede ser empleada para luego modificar el comportamiento del juego).
execute_file(fname)
Ejecuta el código en el archivo fname.
Ahora puedes llamar una función externa y ejecutar la cadena resultante, por ejemplo:
{ ccc = external_call(global.ddd,x,y);
execute_string(ccc); } En algunos casos especiales pudieras necesitar el handle de ventana (identificador de Windows) de la ventana principal del juego. Este puede obtenerse con la siguiente función y luego ser pasado a la DLL:
window_handle()
Devuelve el handle de la ventana principal.
Nota: las DLLs no pueden ser empleadas en modo seguro. El empleo de DLLs externas es una función extremadamente poderosa. Pero por favor haz uso de ellas sólo si sabes lo que estás haciendo.
Gráficos 3D
Esta función sólo está disponible en la versión registrada de Game Maker.
Game Maker es un programa destinado para crear juegos en 2 dimensiones e isométricos. Sin embargo existen algunas funciones para crear gráficos tridimensionales. Pero antes que inicies con esto hay un par de cosas que debes entender.
•
La funcionalidad 3D en Game Maker está limitada a la parte gráfica. No hay más soporte para otras funciones 3D. Una vez que comiences a usar gráficos 3D posiblemente tendrás problemas con otros aspectos de Game Maker, como las vistas, orden de profundidad, etc. La funcionalidad es limitada y tiene baja prioridad de ser extendida. Así que no esperes soporte para objetos de modelos 3D, etc.
•
Cuando usas la funcionalidad 3D, son varias cosas las que ya no pueden ser usadas. o
Ya no podrás usar backgrounds ni foregrounds en tus rooms (La razón es que son usados como mosaicos para llenar la imagen pero con proyecciones de perspectiva esto ya no funciona correctamente).
Ya no podrás usar la posición del ratón. El ratón no será transformado a las coordenadas 3D. Aún puedes obtener la
o
posición del ratón en la pantalla (en la vista) pero tendrás que hacer cálculos con esto por ti mismo (o no usar el ratón del todo). o
Ya no podrás usar tiles. Lo más posible es que los tiles ya no encajen correctamente.
o
La comprobación de colisiones todavía usa las posiciones 2-d de las instancias en el cuarto. Así que no hay detección de colisiones en 3D. En ocasiones aún podrás usar esto (si utilizas el cuarto como una representación de un mundo plano (peje. para carreras o juegos FPS) pero en otras circunstancias tendrás que hacer las cosas por ti mismo.
•
Todas las funciones 3D son a través de código. Debes estar algo familiarizado con el lenguaje GML. Además debes entender bastante acerca de como funciona Game Maker de lo contrario te meterás en dificultades.
•
Necesitas tener conocimiento básico acerca de gráficos 3D. En particular usaré términos como proyecciones de perspectiva, hidden surface removal, iluminación, y niebla, sin mucha explicación.
•
No hay modelado 3D en Game Maker. Además que no planeo añadir soporte para cargar modelos 3D.
•
Es preciso que trabajes con cuidado para mantener una velocidad razonable. Además, esto no está realmente optimizado en velocidad.
Si todo esto no te desanimó, continúa leyendo.
Esta sección se divide en los siguientes temas: Rumbo al modo 3D Dibujo fácil Dibujando polígonos en 3D Dibujando formas básicas Viendo el mundo Transformaciones Niebla Iluminación Creando modelos Palabras finales
Rumbo al modo 3D Si deseas usar el modo 3D antes necesitas poner Game Maker en modo 3D. Después puedes regresar al modo 2D si lo deseas. Las siguientes dos funciones existen para ello.
d3d_start ( ) d3d_end ( )
Inicia el modo 3D.
Detiene el modo 3D.
Nota que todas las funciones relacionadas con 3D inician con d3d_.
Iniciar el modo 3D dará resultado a los siguientes cambios. Primero que nada hidden surface removal es cambiado a encendido (usando un z-buffer de 16 bits). Esto significa que por cada píxel en la pantalla sólo el dibujado con el valor z menor (= al valor depth, profundidad) es mostrado. Si las instancias tienen la misma profundidad es confuso lo que pasará y puedes obtener efectos feos. ¡Asegúrate que las instancias que pueden sobreponerse no tengan la misma profundidad!
En segundo lugar, la proyección ortográfica es remplazada por una perspectiva. Esto significa lo siguiente. Normalmente el tamaño de las instancias en la pantalla es independiente de su profundidad. Con una proyección en perspectiva las instancias que poseen mayor profundidad parecerán más pequeñas. Cuando la profundidad es 0 al viejo tamaño (a menos que cambies la proyección; velo mas adelante). El punto de vista para la cámara es puesta a una distancia sobre el cuarto. (Esta distancia es igual al ancho del cuarto; la cual da una proyección por defecto razonable.) Sólo las instancias que estén frente la cámara son dibujadas. Así que no uses instancias con una profundidad menor a 0 (o al menos no menor que –w donde w (width) es el ancho del cuarto o la vista).
En tercer lugar, la coordenada-y vertical es invertida. Mientras que la posición (0,0) está en la esquina superior-izquierda de la vista, en el modo 3D la posición (0,0) está en la posición inferior-izquierda, lo cual es normal para las vistas 3-dimensionales.
En realidad puedes cambiar hidden surface removal (eliminar las superficies ocultas) y la proyección de perspectiva encendido o apagado usando las siguientes funciones.
d3d_set_hidden (habilita)
Habilita eliminar superficie oculta (true) o la deshabilita (false).
d3d_set_perspective(habilita)
Habilita el uso de una proyección en perspectiva (true) o la deshabilita
(false).
Dibujo fácil Una vez que haz cambiado al modo 3D puedes usar Game Maker como sueles hacerlo (excepto por las remarcas hechas al principio). Sólo los objetos aparecerán en diferentes tamaños basados en profundidad. Incluso puedes usar vistas. Una función adicional puede ser usada. Si dibujas cierto número de cosas en una pieza de código quizá quieras cambiar el valor de profundidad entre las primitivas que dibujes. Para esto usa:
d3d_set_depth(profundidad)
Establece la profundidad usada para dibujar.
Nota que al momento en que una nueva instancia es dibujada la profundidad es devuelta al valor original de esa instancia.
Dibujando polígonos en 3D El problema de dibujar de la vieja manera es que un sprite o polígono siempre se encuentra en un plano-xy, esto es, todas las esquinas tienen la misma profundidad. Para 3D verdadero debes ser capaz de tener vértices a diferentes profundidades. A partir de
este momento hablaremos de la coordenada-z en vez de la profundidad (depth). Así que debemos especificar coordenadas como (x,y,z). Para esto existe una versión especial de funciones de dibujado avanzado:
d3d_primitive_begin(tipo)
Inicia una primitiva 3D de un tipo indicado:
pr_pointlist,
pr_linelist,pr_linestrip,pr_trianglelist,pr_trianglestrip o pr_trianglefan. d3d_vertex(x,y,z)
Añade el vértice (x,y,z) a la primitiva, usando color y valor alfa especificados con
anterioridad.
d3d_vertex_color(x,y,z,col,alpha)
Añade el vértice (x,y,z) a la primitiva, con su propio color y valor
alpha. Esto te permite crear primitivas con un suave cambio de color y valores alfa.
d3d_primitive_end( )
Finaliza la descripción de la primitiva. Esta función realmente la dibuja.
Por ejemplo, para dibujar un tetraedro (pirámide de tres lados) situada en el plano z=0 con su punta en z = 200, puedes usar el siguiente código:
{ d3d_primitive_begin(pr_trianglelist); d3d_vertex(100,100,0); d3d_vertex(100,200,0); d3d_vertex(150,150,200); d3d_vertex(100,200,0); d3d_vertex(200,200,0); d3d_vertex(150,150,200); d3d_vertex(200,200,0); d3d_vertex(100,100,0); d3d_vertex(150,150,200); d3d_vertex(100,100,0); d3d_vertex(100,200,0); d3d_vertex(200,200,0); d3d_primitive_end(); }
Ahora que si quieres usar esto, lo más posible es que sólo verás un triangulo en la pantalla porque la punta del tetraedro estaré en frente del punto de vista. Aparte, usando sólo un color, sería difícil de ver las diferentes caras. Adelante veremos maneras de cambiar el punto de vista. Asignando colores lo cual puede hacerse como antes añadiendo la función draw_set_color(col) entre las vértices.
También puedes usar polígonos texturizados en 3D. Funciona de la misma manera como está descrito en las funciones de dibujado avanzado en la documentación. Pero en esta ocasión necesitas variantes 3D de las funciones básicas. De una cosa te debes dar
cuenta. En una textura la posición (0,0) es la esquina superior-izquierda. Pero en ocasiones, cuando se usan proyecciones (como se indica adelante), la esquina inferior-izquierda es (0,0). En ese caso necesitas girar la textura verticalmente.
d3d_primitive_begin_texture(tipo,texid)
Inicia una primitiva 3D del tipo indicado con la textura
indicada.
d3d_vertex_texture(x,y,z,xtex,ytex)
Añade el vértice (x,y,z) a la primitiva con posición
(xtext,ytext) en la textura, mezclando con el color y valor alpha especificados anteriormente.
d3d_vertex_texture_color(x,y,z,xtex,ytex,col,alpha)
Añade el vértice (x,y,z) a la
primitiva con posición (xtex,ytex) en la textura, mezclando con su propio color y valor alpha.
d3d_primitive_end()
Finaliza la descripción de la primitiva. Esta función en realidad la dibuja.
Así que, por ejemplo puedes usar el siguiente código para dibujar una imagen de fondo que desaparece a la distancia
{ var ttt; ttt = background_get_texture(back); d3d_primitive_begin_texture(pr_trianglefan,ttt); d3d_vertex_texture(0,480,0,0,0); d3d_vertex_texture(640,480,0,1,0); d3d_vertex_texture(640,480,1000,1,1); d3d_vertex_texture(0,480,1000,0,1); d3d_primitive_end(); }
Un triángulo tiene una cara frontal y una trasera. La cara frontal está definida para ser el lado donde los vértices son definidos en orden contrario al reloj. Normalmente ambos lados son dibujados. Pero si haces una forma cerrada esto es inútil porque el lado trasero del triángulo nunca puede ser visto. En este caso puedes encender backface culling. Esto salva cerca de la mitad la cantidad del tiempo dibujando pero te deja con la tarea de definir tus polígonos de la manera correcta. Existe la siguiente función:
d3d_set_culling(separar)
Indica iniciar backface culling (true) o detener backface culling (false).
Dibujando formas básicas Existen varias funciones para dibujar formas básicas, como bloques y paredes. Nota que estas formas también funcionan correctamente con backface culling.
d3d_draw_block(x1,y1,z1,x2,y2,z2,texid,hrepeat,vrepeat)
Dibuja un bloque del color
actual con las esquinas opuestas indicadas usando la textura indicada. Usa -1 para no usar una textura. cara.
hrepeatindica que tan seguido la textura debe ser repetida a través del borde horizontal de cada
vrepeat hace lo mismo con el borde vertical.
d3d_draw_cylinder(x1,y1,z1,x2,y2,z2,texid,hrepeat,vrepeat,cerrado,steps) Dibuja un cilindro vertical usando el color actual en la caja de colisión indicada usando la textura indicada. Usa -1 para no usar una textura. cara.
vrepeat
hrepeat
indica que tan seguido la textura debe ser repetida a través del borde horizontal de cada
hace lo mismo con el borde vertical.
closed
indica si se debe cerrar la tapa y fondo del cilindro.
steps indica cuantos pasos rotacionales deben ser tomados. Un valor típico es 24.
d3d_draw_wall(x1,y1,z1,x2,y2,z2,texid,hrepeat,vrepeat)
Dibuja una pared vertical en
el color actual con las puntas dadas usando la textura indicada. Usa -1 para no usar una textura. tan seguido la textura debe ser repetida a través del borde horizontal de cada cara.
vrepeat
hrepeat indica que hace lo mismo con el
borde vertical.
d3d_draw_floor(x1,y1,z1,x2,y2,z2,texid,hrepeat,vrepeat) en el color actual con las esquinas dadas usando la textura indicada. ser repetida a través del borde horizontal de cada cara.
vrepeat
hrepeat
Dibuja un piso (inclinado)
indica que tan seguido la textura debe
hace lo mismo con el borde vertical.
La siguiente pieza de código dibuja dos bloques:
{ var ttt; ttt = background_get_texture(back); d3d_draw_block(20,20,20,80,40,200,ttt,1,1); d3d_draw_block(200,300,-10,240,340,100,ttt,1,1); }
Viendo el mundo Por defecto tu vista es a través del eje-z negativo hacia el medio del cuarto. En ocasiones en juegos 3D deseas poder cambiar la manera en que miras al mundo. Por ejemplo, en un juego de disparos en primera persona probablemente deseas tener la cámara mirando desde una posición un poco sobre el plano-xy a lo largo del plano-xy. En términos gráficos estás estableciendo la proyección correcta. Para cambiar la manera en que miras, las siguientes funciones existen.
d3d_set_projection(xfrom,yfrom,zfrom,xto,yto,zto,xup,yup,zup) mirar en el mundo. Especificas el punto desde dónde mirar, el punto a mirar y el rumbo ascendente.
Defines como
Esta función requiere alguna explicación. Para establecer la proyección primero necesitas la posición desde la cual miras. Esto está indicado por los parámetros (xfrom,yfrom,zfrom). En seguida debes especificar la dirección que miras. Esto se hace dando un segundo punto al cual mirar. Este es el punto (xto,yto,zto). Finalmente, incluso puedes rotar la cámara alrededor de la línea del punto de vista al punto observado. Para especificar esto debemos tener un rumbo ascendente, esto es, la dirección ascendente en la cámara. Esto es dado por los últimos tres parámetros (xup,yup,zup). Permítanme dar un ejemplo. Para mirar a través del plano-xy como en un primera persona puedes usar
{ d3d_set_projection(100,100,10,200,100,10,0,0,1); }
Así miras desde el punto (100,100) y 10 sobre el plano en dirección de (200,100). Los puntos del vector up es la dirección-z que requiere. Para hacer esto ligeramente más complicado, asumamos que tienes una instancia en tu cuarto que especifica la posición de la cámara. Esta tendrá una posición (x,y) actual y una dirección (y quizá incluso una velocidad). Ahora puedes especificar esto como tu cámara usando el siguiente código:
{ with (obj_camera) d3d_set_projection(x,y,10, x+cos(direction*pi/180),y-sin(direction*pi/180),10, 0,0,1); }
Esto puede lucir algo complicado. Miramos desde la posición de la cámara (x,y), 10 sobre el piso. Para determinar un punto en la dirección correcta necesitamos hacer algo de aritmética. Este punto está indicado por los tres siguientes parámetros. Finalmente usamos el vector up como antes.
¡Una observación importante! Cuando Game Maker comienza a dibujar un cuarto este pondrá el punto de vista de regreso a la posición por defecto. Así que la primera cosa que necesitas hacer cuando dibuja la escena es poner la proyección que desees. ¡Esto debe hacerse en un evento Draw!
Existe también una versión extendida de la función anterior:
d3d_set_projection_ext(xfrom,yfrom,zfrom,xto,yto,zto,xup,yup,zup,angle,a spect,znear,zfar)
Una versión extendida de esta función en la cual además especificas el ángulo definiendo el
campo de vista, el radio de aspecto entre el tamaño vertical y horizontal de la vista, y los planos cercanos y lejanos de recorte.
Los parámetros adicionales trabajan como sigue. Si especificaste la posición de la cámara, el punto a mirar, y el vector up, puedes todavía cambiar qué tan unidos están los lentes de la cámara. Esto es conocido como el campo de vista. Un valor razonable es 45 grados y esto es el valor por defecto tomado. Pero puedes cambiar esto si gustas. Después puedes especificar la relación de aspecto entre la proyección horizontal y vertical. Normalmente quieres usar el mismo como la radio de aspecto del cuarto o la vista, p.ej. 640/480. Finalmente puedes indicar los planos de recorte. Los objetos que son más cercanos que
znear
a la cámara no son
dibujados. Similar para objetos más lejos que zfar. Puede ser importante poner estos parámetros a valores razonables porque ellos también influyen en la precisión de las comparaciones de z. Si usted hace el rango demasiado grande la precisión empeora. Por defecto usamos 1 y 32000. ¡znear debe ser más grande que 0!
A veces necesitas temporalmente una proyección normal ortográfica como la usada cuando no hay 3D. Por ejemplo, cuando quieres dibujar alguna capa. Para esto puedes usar la función siguiente:
d3d_set_projection_ortho(x,y,w,h,ángulo)
Pone una proyección normal ortográfica del área indicada en el
cuarto, girando sobre el ángulo indicado.
Un uso estándar para esto es dibujar una capa para p.ej. mostrar el puntaje u otros aspectos. Para hacer esto ponemos una proyección ortográfica. También debemos desactivar hidden surface removal temporalmente porque queremos que la información sea dibujada independientemente del valor de profundidad actual. El ejemplo siguiente muestra como crear una capa con el puntaje.
{ draw_set_color(c_black); d3d_set_projection_ortho(0,0,room_width,room_height,0); d3d_set_hidden(false); draw_text(10,10,'Score: ' + string(score)); d3d_set_hidden(true); }
Transformaciones Las transformaciones te permiten cambiar el lugar donde las cosas son dibujadas en el mundo. Por ejemplo, la función para dibujar bloques sólo puede dibujar bloques paralelos de eje. Por primera opción una transformación de rotación puedes crear bloques girados. También los sprites siempre son dibujados paralelos al plano-xy. Estableciendo una transformación puedes cambiar esto. Hay dos tipos de funciones: las funciones que ponen la transformación y las funciones que añaden transformaciones.
d3d_transform_set_identity ()
Pone la transformación a la identidad (ninguna transformación).
d3d_transform_set_translation(xt,yt,zt) vector indicado.
Pone la transformación a una conversión sobre el
d3d_transform_set_scaling(xs,ys,zs)
Pone la transformación a un escalamiento con las cantidades
indicadas.
d3d_transform_set_rotation_x(ángulo)
Pone la transformación a una rotación alrededor del eje-x
con la cantidad indicada.
d3d_transform_set_rotation_y(ángulo)
Pone la transformación a una rotación alrededor del eje-y
con la cantidad indicada.
d3d_transform_set_rotation_z(ángulo)
Pone la transformación a una rotación alrededor del eje-z
con la cantidad indicada.
d3d_transform_set_rotation_axis(xa,ya,za,ángulo)
Pone la transformación a una rotación
alrededor del eje indicado por el vector con la cantidad indicada.
d3d_transform_add_translation(xt,yt,zt) d3d_transform_add_scaling(xs,ys,zs)
Añade una transformación sobre vector indicado.
d3d_transform_add_rotation_x(ángulo)
Añade un escalamiento con las cantidades indicadas. Añade una rotación alrededor del eje-x con la cantidad
indicada.
d3d_transform_add_rotation_y(ángulo)
Añade una rotación alrededor del eje-y con la cantidad
indicada.
d3d_transform_add_rotation_z(ángulo)
Añade una rotación alrededor del eje-z con la cantidad
indicada.
d3d_transform_add_rotation_axis(xa,ya,za,ángulo)
Añade una rotación alrededor del eje
indicado por el vector con la cantidad indicada. Comprende que la rotación y el escalamiento son con respecto al origen del mundo, no al respecto al objeto que debe ser dibujado. Si el objeto no está en el origen este también se moverá a un lugar diferente, que no es lo que queremos. Así para p.ej. hacer girar un objeto sobre su propio eje-x, primero debemos trasladar al origen, después hacerlo girar, y finalmente trasladarlo de regreso a su posición. Esto es para qué son las funciones de añadir transformaciones. Los ejemplos siguientes podrían explicar esto mejor. Asumiendo que tenemos un sprite spr que queremos dibujar en la posición (100,100,10). Podemos usar el código siguiente para hacer esto
{ d3d_transform_set_translation(100,100,10); draw_sprite(spr,0,0,0); d3d_transform_set_identity(); }
Nota que porque usamos una transformación ahora deberíamos dibujar el sprite en la posición (0,0). (¡Esto asume que la instancia actual tiene una profundidad de 0! Si no estas seguro, primero pon la profundidad.) Si usáramos esto en nuestro tirador en primera persona no veríamos el sprite. La razón es que es todavía paralelo al plano-xy. Queremos hacerlo girar más de 90 grados a lo largo
del eje-x (o el eje-y). Entonces tenemos que añadir una rotación. Recuerda el orden: primero debemos hacer girar el sprite y luego transformarlo. Entonces podemos usar el código siguiente.
{ d3d_transform_set_identity(); d3d_transform_add_rotation_x(90); d3d_transform_add_translation(100,100,10); draw_sprite(spr,0,0,0); d3d_transform_set_identity(); }
En ocasiones quieres guardar temporalmente la transformación actual, por ejemplo para añadir una transformación adicional y luego restaurar a la anterior (esto a menudo pasa dibujando modelos jerárquicos). Para este fin puedes empujar la transformación actual sobre un montón y luego sacarlo del montón para hacerlo la transformación actual de nuevo. Las funciones siguientes existen para esto:
d3d_transform_stack_clear()
Limpia el montón de transformaciones.
d3d_transform_stack_empty()
Devuelve si el montón de transformación está vacío.
d3d_transform_stack_push()
Empuja la transformación actual sobre el montón. Devuelve si hay espacio
sobre el montón para empujarlo allí (si olvidas sacar la transformación en algún momento te quedarás sin espacio en el montón).
d3d_transform_stack_pop()
Saca la transformación superior del montón y la hace la actual. Devuelve si
había una transformación sobre el montón.
d3d_transform_stack_top()
Hace a la transformación superior la actual, pero no lo quita del montón.
Devuelve si había tras una transformación sobre el montón.
d3d_transform_stack_discard()
Quita la transformación superior del montón, pero no lo hace la actual.
Vueltas si había tras una transformación en el montón.
La utilización de la transformación es un mecanismo poderoso. Pero sé cuidadoso y siempre restaura la transformación a la identidad una vez que terminaste.
Niebla La niebla puede ser usada en juegos de 3D para hacer que los objetos a la distancia luzcan borrosos o incluso desaparecer. Esto ayuda en la creación de la atmósfera y hace posible el no dibujar los objetos que están a lo lejos. Para habilitar o deshabilitar la niebla usa la función siguiente:
d3d_set_fog(habilitar,color,principio,fin)
Habilita o deshabilita el empleo de niebla. color
indica el color de la niebla. principio indica la distancia a la cual la niebla debe comenzar. fin indica la distancia a la cual la niebla es máxima y nada puede ser visto más allá.
Iluminación Las escenas que dibujas con las funciones anteriores parecen bastante planas porque no hay luz alguna. El color si las caras son iguales, independiente de su orientación. Para crear escenas que luzcan más realistas debes permitir la iluminación y poner las luces en los sitios correctos. La creación de escenas correctamente alumbradas no es fácil pero el efecto es muy bueno.
Para permitir la iluminación puedes usar la función siguiente;
d3d_set_lighting(habilitar)
Habilita o inhabilita el uso de iluminación.
Usando la iluminación, para cada vértice de un polígono el color es determinado. Después, el color de los píxeles internos está basado en el color de estos vértices. Hay dos modos que puede ser hecho: El polígono entero consigue el mismo color, o el color suavemente es interpolado sobre el polígono. Por defecto smooth shading es usado. Esto puede ser cambiado usando la función siguiente:
d3d_set_shading(smooth)
Establece si usar smooth shading o no.
Para usar la iluminación obviamente tienes que definir luces. Dos diferentes luces existen: luces direccionales (como el sol), y luces posiciónales. La luz tiene un color. (Sólo soportamos la luz difusa, no la reflexión especular.) Las funciones siguientes existen para definir y usar luces:
d3d_light_define_direction(ind,dx,dy,dz,col)
Define una luz dirigida. ind es el índice de la
luz (usa un pequeño número positivo). (dx,dy,dz) es la dirección de la luz. col es el color de la luz (a menudo quieres usar c_white. Esta función no enciende la luz.
d3d_light_define_point(ind,x,y,z,rango,col)
Define una luz de punto. ind es el índice de la luz
(usa un pequeño número positivo). (x,y,z) es la posición de la luz. rango indica qué lejos brilla la luz. La intensidad de la luz se disminuirá sobre este rango. col es el color de la luz. Esta función no enciende la luz.
d3d_light_enable(ind,permitir)
Habilita (true) o deshabilita (false) la luz número ind.
La manera en que un objeto refleja la luz depende del ángulo entre la dirección de la luz y el normal de la superficie, es decir el vector que señala lejos de la superficie. De ahí, para crear objetos iluminados no sólo tienes que proporcionar la posición de los vértices, sino también sus normales. Para estas cuatro funciones adicionales están disponibles para definir los vértices de primitivas:
d3d_vertex_normal(x,y,z,nx,ny,nz)
Añade el vértice (x,y,z) a la primitiva, con vector normal
(nx,ny,nz).
d3d_vertex_normal_color(x,y,z,nx,ny,nz,col,alpha)
Añade el vértice (x,y,z) a la primitiva,
con vector normal (nx,ny,nz), y con su propio color y valor alpha.
d3d_vertex_normal_texture(x,y,z,nx,ny,nz,xtex,ytex)
Añade el vértice (x,y) a la
primitiva, con vector normal (nx,ny,nz), y con la posición (xtex,ytex) en la textura, mezclándose con el color y valor alpha establecidos antes.
d3d_vertex_normal_texture_color(x,y,z,nx,ny,nz,xtex,ytex,col,alpha)
Añade
el vértice (x,y) a la primitiva, con vector normal (nx,ny,nz), y con la posición (xtex,ytex) en la textura, mezclándose con su propio color y valor alpha.
Note que para las formas básicas que puedes dibujar las normales automáticamente son puestas correctamente.
Creando modelos Cuando necesitas dibujar modelos complejos es muy costoso llamar a todas las funciones diferentes una y otra vez en cada step. Para evitarte esto, puedes crear modelos. Un modelo consiste de un número de primitivas y formas de dibujo. Una vez que creas un modelo puedes dibujarlo en diferentes lugares y en diferenes posiciones con una simple llamada a ese modelo.
Antes de listar las funciones de modelos es importante resaltar un aspecto: el manejo de texturas. Como ya se ha explicado antes, las texturas se toman de sprites y backgrounds. Los índices de las texturas pueden ser diferentes en cada momento, por lo que los modelos no contienen información sobre ellas. Sólo cuando dibujas un modelo debes especificar información sobre la textura. De esta forma, sólo puedes usar una textura en cada modelo. Si necesitas usar más texturas puedes combinar varias (y tener mucho cuidado con las coordenadas de cada una) o usar múltiples modelos. La ventaja de esto es que puedes dibujar sencillamente el mismo modelo con diferentes texturas.
Para crear, cargar, guardar y dibujar modelos se usan las siguientes funciones:
d3d_model_create()
Crea un nuevo modelo y devuelve su índice, que debe ser usado en las demás funciones.
d3d_model_destroy(ind) d3d_model_clear(ind)
Destruye el modelo especificado, liberando memoria.
Limpia el modelo especificado, eliminando todas sus primitivas.
d3d_model_save(ind,fname)
Salva el modelo ind al archivo especificado en fname.
d3d_model_load(ind,fname)
Carga el modelo desde el archivo especificado.
d3d_model_draw(ind,x,y,z,texid)
Dibuja el modelo en la posición (x,y,z). texid es la textura que se aplicará al
modelo. Usa -1 para no usar texturas. Si quieres rotar o escalar el modelo usa las rutinas de transformación descritas en el apartado de Transformaciones.
Para cada primitiva existe una función equivalente que la añade a un modelo. Estas funciones se usan igual que las que ya hemos visto en los capítulos anteriores, sólo que en lugar de especificar una textura ahora daremos el índice del modelo.
d3d_model_primitive_begin(ind,kind) kind:
Añade al modelo una primitiva 3D del tipo siguiente indicado en
pr_pointlist, pr_linelist, pr_linestrip, pr_trianglelist,
pr_trianglestrip opr_trianglefan. d3d_model_vertex(ind,x,y,z)
Añade el vértice (x,y,z) al modelo.
d3d_model_vertex_color(ind,x,y,z,col,alpha)
Añade el vértice (x,y,z) al modelo con su propio color y valor de
transparencia.
d3d_model_vertex_texture(ind,x,y,z,xtex,ytex)
Añade el vértice (x,y,z) al modelo con la posición (xtex,ytex)
en la textura.
d3d_model_vertex_texture_color(ind,x,y,z,xtex,ytex,col,alpha)
Añade el vértice (x,y,z) al modelo
con valores de textura y color.
d3d_model_vertex_normal(ind,x,y,z,nx,ny,nz)
Añade el vértice (x,y,z) al modelo con el vector normal (nx,ny,nz).
d3d_model_vertex_normal_color(ind,x,y,z,nx,ny,nz,col,alpha)
Añade el vértice (x,y,z) al modelo con
el vector normal (nx,ny,nz) y sus propios valores de color y transparencia.
d3d_model_vertex_normal_texture(ind,x,y,z,nx,ny,nz,xtex,ytex)
Añade el vértice (x,y,z) al modelo
con el vector normal (nx,ny,nz) y coordenadas de textura (xtex, ytex).
d3d_model_vertex_normal_texture_color(ind,x,y,z,nx,ny,nz,xtex,ytex,col,alpha)
Añade el
vértice (x,y,z) al modelo con el vector normal (nx,ny,nz) con valores de color y textura.
d3d_model_primitive_end(ind)
Finaliza la descripción de la primitiva en el modelo.
Además de primitivas también puedes añadir formas al modelo. Las funciones son análogas a las ya vistas usando el índice del modelo en lugar del de la textura:
d3d_model_block(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat)
Añade un bloque al modelo.
d3d_model_cylinder(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat,closed,steps)
Añade un cilindro al
modelo.
d3d_model_cone(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat,closed,steps) d3d_model_ellipsoid(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat,steps)
Añade un cono al modelo.
Añade una elipsoide al
modelo.
d3d_model_wall(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat)
Añade una pared al modelo.
d3d_model_floor(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat)
Añade un suelo al modelo.
El uso de modelos puede aumentar considerablemente la velocidad de los gráficos en los juegos 3D, así que deberías usarlo siempre que sea posible.
Palabras finales
Las funciones de 3D en Game Maker pueden ser usadas hacer algunos juegos agradables en 3D. Pero estas son limitadas en funcionalidad y todavía te dejan bastante trabajo. No esperes poder hacer tu propio Quake con esto. Game Makeres y sigue siendo sobre todo un paquete para hacer juegos de 2 dimensiones.
Apéndices Glosario Mensajes de error Créditos y agradecimientos
Glosario
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A •
alpha Transparencia. Es un parámetro que se utiliza en las funciones de dibujo avanzadas y que indica el nivel de transparencia de lo que se está dibujando: 0 es totalmente transparente y 1 es totalmente opaco. Los valores intermedios se usan para dibujar elementos parcialmente transparentes.
•
argumento Los argumentos son los datos que se le pasan a una función para que ésta opere con ellos. Por ejemplo, una función que sume dos números necesitará que le digas que números tiene que sumar. Esos números son losargumentos de la función.
B •
background Fondo. Es la imagen que se pone de fondo al room para que sea el escenario. Puedes agregar varias imágenes distintas y hacer que cada una se mueva a diferente velocidad cuando el personaje avance, haciendo que las imágenes más cercanas se muevan más rápido que las más lejanas. Así consigues un efecto de profundidad muy vistoso. Esta técnica se llama scroll parallax.
•
blending Ver image blending.
•
bmp Es un tipo de archivo de gráficos de alta calidad (mapa de bits). Sólo es aconsejable utilizar bmps para fondos transparentes.
•
boolean Booleano. Es un tipo de variable que sólo puede tener dos valores: true o false. Es decir, si una variable booleana no es true entonces es false.
D •
depth Profundidad. Es una propiedad de las instancias que sirve para decidir cuál debe dibujarse por encima de las demás cuando chocan, cuál se sitúa primero en el room...Puede ser positiva, negativa ó 0 y cuanto menor sea más al frente se situará la instancia.
F •
false Falso.
•
fps Frames por segundo. No es lo mismo que la room speed. La room speed es el valor ideal al que queremos que el juego
En Game Maker false=0, es decir, es lo mismo poner false que poner 0.
se actualice. Sin embargo, si ponemos muchas acciones en el evento step el juego puede ralentizarse, o si usamos unos sprites de mucha calidad puede que el juego necesite mucha memoria...esto provoca que el juego se ralentice y en lugar de dibujar todos los frames que queremos en cada segundo dibuje menos. Los fps son la medida real de la velocidad del juego en cada segundo. Te interesará que los fps estén siempre lo más cercano posible a la room speed.
•
frame Para generar la ilusión de animación, lo que se hace es dibujar la pantalla muchas veces (por ejemplo 60 veces por segundo) haciendo que su contenido cambie poco a poco. Así, al ver esos cambios de manera seguida parece que la imagen se esté moviendo. Cada instante en el que se dibuja la pantalla se denomina frame.
•
frame rate Es la velocidad con la que se pasa de un frame a otro. Cuanto mayor sea, más fluidas se verán las animaciones en la pantalla, pero se requerirá más potencia.
G •
gif Es un tipo de archivo de gráficos comprimido y animado. Ideal para sprites.
•
height Altura. Es un argumento muy común en las funciones de gráficos.
H
•
highscore El marcador más alto, el récord de puntuación obtenido en el juego. Puedes mostrar una lista con las puntuaciones más altas (highscore list) con la acción correspondiente.
I •
image blending
Mezclado de imágenes. Cuando dos imágenes se superponen (por ejemplo, cuando chocan dos sprites)
el programa debe decidir qué es lo que va a dibujar. Si la instancia de uno de los sprites tiene menor profundidad que el otro se dibujará éste por encima. Pero si tiene mayor depth se dibujará por debajo. Si uno de los sprites es parcialmente transparente, se verá parte del otro. Si el modo de mezcla está en suma se sumarán los colores de los dos spritesen la zona en la que chocan (por ejemplo para causar un efecto de brillo), pero si está en modo resta se restarán. Como ves, en la parte de los sprites que choca se decide qué hay que hacer según el modo de mezcla que esté activo (esto también afecta a los backgrounds). Con esta técnica se pueden crear efectos visuales muy espectaculares.
J •
jpg Es un tipo de archivo de gráficos de tamaño reducido, pero que no permite transparencias. Ideal para usarlo en fondos no transparentes o para sprite sheets.
L •
left Izquierda. Es un argumento muy común en las funciones que deben especificar una posición para indicar dónde debe situarse el borde izquierdo.
M •
midi Es un formato de sonido de muy pequeño tamaño. Los midis tienen menos calidad que los wav o mp3. Sin embargo su tamaño es mucho menor, lo que hace que no consuman casi memoria. Esto hace que los midis sean ideales para las músicas de fondo del juego.
P •
path Camino o trayectoria. Game Maker te permite dibujar una trayectoria para que luego la siga una instancia. Así puedes hacer que un enemigo se mueva siguiendo este camino, o hacer que en un juego de coches los participantes sigan la carretera.
•
png Un tipo de archivo de gráficos de tamaño muy reducido creado para ser transmitido por Internet (png significa "portable network graphics" o "gráficos transportables por la red").
•
pop-up Son los mensajes o ventanas que aparecen de repente y sirven para dar o pedir información al jugador. Por ejemplo, una ventana que se abra y le pregunte al jugador cómo se llama.
R
•
rar Es un tipo de archivo comprimido. Los archivos tipo rar consiguen una gran compresión aunque este formato no está tan extendido como el zip (ver zip).
•
recurso Es lo que utiliza el juego. En Game Maker los recursos se dividen en las siguientes categorías: sprites, backgrounds, sonidos y música, paths, scripts, time lines, fuentes, objetos y rooms.
•
room Habitación o cuarto. En el room es donde se sitúan todos los objetos y donde todo el juego tiene lugar. Un juego puede tener varias rooms y cada una puede ser un nivel distinto, una pantalla de menú, de ayuda...
•
room speed Es el frame rate que queremos que tenga un cuarto y se mide en frames por segundo. Por ejemplo, una room speed igual a 30 significa que en cada segundo se dibujan 30 frames.
S •
score
•
screenshot Es una foto de la pantalla en un momento determinado. Los screenshots son muy útiles para promocionar tu
Marcador. En el juego, puedes hacer que el marcador se incremente cuando el jugador recoja monedas u otros objetos.
juego o para usarlos en tablas de récords.
•
script
Es un trozo de código que puede recibir argumentos y devolver un valor. Los scripts se utilizan para generalizar
código repetido y así ahorrar espacio y ganar velocidad.
•
scroll Es el movimiento del fondo. Game Maker te permite añadir varios fondos distintos y asignar un movimiento a cada uno, para dar la impresión de que el decorado avanza cuando el personaje se mueve.
•
sprite Un sprite es la imagen que se asocia a un objeto y que se dibuja en la pantalla. Los sprites suelen tener varias imágenes, de forma que si en cada momento se dibuja una imagen distinta parece que se mueve. El formato más utilizado para los sprites es el de los archivos gif.
•
sprite sheet Una sprite sheet (o strip) es una imagen no animada de gran tamaño en la que aparecen muchas imágenes de un personaje (o varios) mostrando todos los frames de sus animaciones. El editor de sprites de Game Makerpermite crear sprites animados fácilmente a partir de una sprite sheet.
•
step
Paso. Los juegos que crees con Game Maker se ejecutan por pasos, de forma que si haces que se pase de un paso a otro
rápidamente dará la impresión de que todo se ejecuta continuamente (Ver frame).
•
strip Ver sprite sheet.
•
tile Para hacer un fondo, a veces es bueno utilizar imágenes pequeñas que, puestas una al lado de otra, forman un dibujo.
T Esta técnica se denomina tiling. Por ejemplo: divides el room en casillas del mismo tamaño y en cada una pones una imagen más pequeña (en una un árbol, en otra una casa,...) y haces que se repitan para llenar todo el room. Así puedes conseguir fondos muy originales y que consumen muy poca memoria.
•
tile set Ver tile sheet.
•
tile sheet Es una imagen muy grande de la que se pueden extraer imágenes más pequeñas para crear tiles.
•
time line Línea de tiempo. En una time line puedes añadir acciones en momentos concretos, de forma que estas acciones se ejecutarán en el orden que tú decidas y justo cuando quieras.
•
top Arriba. Es un argumento muy común en las funciones que deben especificar una posición para indicar dónde debe situarse el borde superior.
•
true Verdadero. En Game Maker true=1, es decir, es lo mismo poner true que poner 1.
•
wav Son archivos de sonido de gran calidad, pero que por lo tanto ocupan mucho tamaño y consumen bastante memoria. Los
w archivos wav se suelen utilizar para los efectos de sonido (explosiones, gritos, disparos...).
•
width Anchura. Es un argumento muy común en las funciones de gráficos.
•
zip Es un tipo de archivo comprimido muy corriente. Al comprimir tu juego, conseguirás que ocupe menos espacio y así podrás
Z distribuirlo más fácilmente por la red.
Mensajes de error En esta sección del manual veremos los mensajes de error que aparecen cuando estás programando o probando tu juego. Cuando te aparezca un error mira en esta sección para que puedas entenderlo y aprender a solucionarlo.
Cuando pruebas tu juego y aparece algún error se debe a que hay algún fallo en tu código o en las acciones D&D. Esta guía básica te ayudará a tratar con los errores:
Este es el mensaje típico de error que te aparecerá. COmo ves, tienes 2 opciones: Abort (abortar) e Iqnore (ignorar). Es recomendable que abortes el juego para poder solucionar el error. En la segunda línea te dice en qué acción se ha producido el error: action number 1. En este caso, se trata de la primera acción. A continuación puedes ver el evento en el que se ha producido el error: Step Event. La siguiente línea nos dice el nombre del objeto que
causó el error. Si estás usando el sistema de acciones de Game Maker, con esta información puedes ir a la acción que causó el error y comprobarla. Si por el contrario usas GML, La siguiente línea del mensaje te dirá en qué línea de tu código se produjo el error con la expresión que lo causó. La última línea te dice la posición exacta del error.
Para que puedas encontrar rápidamente tus mensajes de error en esta sección, la hemos dividido en 3 partes:
Mensajes de error críticos
Mensajes de error de compilación
Mensajes de error de ejecución
Por último, puedes ver una lista con los nombres de la gente que ha colaborado en la redacción de esta sección del manual:
Créditos
Mensajes de error críticos Estos mensajes de error pueden aparecer cuando compiles tu juego o durante su ejecución. Por ejemplo, puedes obtener el error "Division by zero" en compilación si en tu código pone algo como "variable=1/0". Pero también puedes obtener este error si tienes algo como "variable=1/my_variable". Si "my_variable" toma el valor 0 en cualquier momento durante el juego, el mensaje aparecerá en tiempo de ejecución.
Array index>=32000 Este mensaje indica que estás tratando de acceder a un elemento en un vector de índice mayor o igual que 32000. En Game Maker el tamaño máximo para un vector es de 32000 elementos, por lo que el índice del último elemento será 31999.
Cannot find the file Esto ocurre cuando tu archivo Game Maker se ha cambiado de sitio o ha sido borrado. Para solucionarlo, debe buscar el archivo de Game Maker file tú mismo.
Division by zero Este mensaje aparecerá siempre que intentes dividir un número entre 0. Una forma de evitar este error es haciendo un pequeño chequeo antes de realizar la operación:
if a!=0{ mi_variable=1/a; }
Error Creating Stand-Alone: Cannot find the required dlls Esto ocurre cuando el archivo dxdata está corrupto o ha sido borrado. Para solucionarlo, lo más fácil es reinstalar Game Maker.
Failed to compile the actions in the objects
Aparece cuando sucede algún error en tu juego y tienes
desactivada la opción "Display error messages" en Global Game Settings. Para solucionarlo vete a Global Game Settings,activa la opción y ejecuta el juego para ver el verdadero mensaje de error.
No action libraries have been found Este error ocurre cuando las librerías de acciones han sido borradas, renombradas o movidas de lugar. Las librerías de acciones de Game Maker son: 02_main1, 03_main2, 07_draw, 06_extra,05_score, 04_control y 01_move. Solución: Vuelve a situar las librerías en el mapa de librerías o reinstala Game Maker.
Error Creating Stand-Alone: Cannot find valid runner data Sucede cuando el archivo rundata está corrupto o ha sido borrado. Solución: reinstala Game Maker.
Negative array index Este error significa que estás intentando usar un índice negativo en un vector. El primer elemento de un vector es siempre el elemento con índice 0. No hay nada antes que él, así que usando un índice negativo estarías intentando acceder a un elemento que no existe.
Mensajes de error de compilación Estos mensajes aparecen antes de que el juego empiece a ejecutarse o cuando pulsas el botón Check the script for syntax errors en un script. Estos mensajes siemrpe aparecerán si algo va mal.
Assignment operator expected Aparece cuando usas una variable sin un operador de asignación (=): my_variable; Esta expresión no tiene ningún sentido y por eso aparece el error. Otra forma de que aparezca este error es si no pones los paréntesis al llamar a una función, por ejemplo:
instance_create; Para solucionarlo, simplemente debes poner los paréntesis con los argumentos que necesite la función, si es que usa alguno:
instance_create(x,y,object);
Failed to compile scripts Occurre si hay algún error en tus scripts y tienes desactivada la opción "Display error messages" en Global Game Settings. Para solucionarlo, vete a Global Game Settings, activa la opción y ejecuta tu juego para ver el verdadero mensaje de error.
Game has no rooms El juego necesita que exista por lo menos una habitación para ejecutarse. En las habitaciones es donde todo el juego tiene lugar, las instancias sólo pueden crearse dentro de una habitación, así que sin una habitación no se pueden ejecutar acciones o scripts de código.
Program ends before end of code Esto ocurre cuando hay código después de una llave de cierre: { show_message('Hola Mundo!'); } show_message('código que causa el error');
Para solucionarlo, comprueba tus llaves de cierre, seguramente hay una que está terminando el script demasiado pronto.
Symbol Expected En este caso, el error ocurre porque no has puesto un símbolo de cierre, por ejemplo "Symbol } expected" o "Symbol ) expected":
for (i=0; i<10; i+=1 show_message('Ouch'); O:
{ show_message('Esto también da error');
Aparece frecuentemente en bloques anidados, cuando olvidas poner un paréntesis o una llave de cierre en el lugar correcto.
Unexpected error occurred when running the game Este mensaje de error te avisa de que ha ocurrido algún fallo externo a Game Maker. Los fallos más comunes son falta de memoria gráfica o no tener instalado DirectX8.0 ó superior. Con este error, el juego puede que funcione correctamente en algunos ordenadores y en otros ni siquiera llegue a arrancar, ya que depende exclusivamente de la configuración del ordenador en el que se ejecute el juego. Otra forma de obtener este error es creando bucles infinitos o usando demasiada memoria.
Wrong number of arguments to function or script Ocurre cuando al llamar a una función o un script no especificas correctamente los argumentos que necesita:
function_name(argument_0, argument_1, argument_2) Comprueba la función concreta en el manual para ver la forma correcta de usarla.
Mensajes de error de ejecución Estos mensajes aparecen en un momento determinado del juego cuando se está ejecutando. Dependiendo de cómo programaste el juego puede que las acciones o eventos necesarios para que ocurran no lleguen a ejecutarse. Así mismo, algunos de estos errores dependen del ordenador en el que se ejecutan, como todos los errores referentes a la memoria gráfica.
Cannot compare arguments Ocurre cuando intentas comparar una cadena de texto y un número. Usa las funciones real() o string() para convertir uno de los argumentos al formato correcto.
Creating instance for non-existing object
La causa más común de este error es usar la
función instance_create(x,y,object) escribiendo incorrectamente el nombre del objeto. Comprueba que has escrito correctamente el nombre del objeto.
File is not opened for reading Aparece cuando intentas leer o escribir datos de un archivo de texto externo que no ha sido accedido correctamente. Para acceder a un archivo de texto debes usar la funciónfile_text_open_read("ruta_al_archivo/nombre_del_archivo.extension"). El fallo más común es indicar una ruta incorrecta al archivo o usar rutas absolutas. Las rutas absolutas como "C:\\Mi_directorio\\MiArchivo.txt" funcionarán en tu ordenador pero fallarán en los de otra gente si no tienen exactamente la misma estructura de archivos y directorios. Por ello, es mejor usar rutas relativas al directorio donde se encuentre tu juego.
Unknown function or script 'name of function'
Ocurre cuando escribes mal el nombre de una función o script
o cuando llamas a un script que no existe. Comprueba la ortografía.
Unknown variable 'variable_name'Este error aparece cuando intentas usar una variable que no ha sido inicializada. Ates de usar una variable en cualquier evento, debes inicializarla dándole un valor. También puedes activar la opción"Treat uninitialized variables as 0" en Game Options de forma que Game Maker inicializará automáticamente todas las variables a 0.
Variable name expected Ocurre cuando intentas crear una variable con el mismo nombre de uno de tus recursos (sonidos, sprites, fondos, fuentes, objetos...). La mejor forma de evitar esto es añadiendo un prefijo a los nombres de tus recursos según el tipo que sean: Objmiobjeto Sprmisprite Fntmifuente Sndmisonido
Wrong type of arguments to + Este error aparece cuando intentas añadir un número al final de una cadena de texto o al revés:
numero=1; show_message("1"+numero); Para solucionarlo, debes convertir el número en una cadena de texto con la función string():
numero=1; show_message("1"+string(numero));
Créditos Esta sección del manual se inició en Comunidad Game Maker (http://www.comunidadgm.com) y se completó en Game Maker Community (http://forums.gamemaker.nl) con la ayuda inestimable de las siguientes personas: ad134 akafinland correojon grimdaze Magicman657 paul23 scorpius Smarty Tuntis
Un enorme GRACIAS a todos!
Créditos y agradecimientos La versión original de este manual ha sido redactada por Mark Overmars, creador de Game Maker y puede encontrarse en la página oficial de Game Maker: http://www.gamemaker.nl
La traducción al español del manual del Game Maker 6.1 se ha basado en la traducción realizada por los miembros de Zona Makers del manual del Game Maker 5.0. Puedes encontrar esta versión, así como multitud de ejemplos, tutoriales y ayuda general en la página y los foros de Zona Makers: http://www.zonamakers.com
Los usuarios de Comunidad Game Maker y Zona Makers siguientes han participado en la traducción de este manual de manera totalmente desinteresada:
BrandNew Correojon Danito
Exe_mas Faxtrax Fenris Geo Lestad Lobizon Notos PR_Boy Rodeh85 Unknown_gamer Zurdopower
Desde Comunidad Game Maker y Zona Makers queremos agradecer a todos su colaboración y su ayuda en el esparcimiento del Game Maker más allá de la frontera que supone el idioma ¡Buen trabajo!
Si estás interesado en ayudarnos con otros proyectos, o simplemente quieres aprender más sobre Game Maker encontrarás más información y ayuda en la página y los foros de Comunidad Game Maker: http://www.comunidadgm.com
Así mismo, puedes encontrar la traducción no oficial al español del Game Maker 6.1 en la página de Estudios Valhalla: http://www.estudiosvalhalla.com