Está en la página 1de 213

Programando con Game Maker Si no tienes el programa bajo de www.yoyogames.com Estructura general del GML.

Como habrs ledo antes, el Game Maker contiene un lenguaje de programacin interno. Este lenguaje te da mucha ms flexibilidad y control que las acciones estndar. 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 accin de cdigo a un evento. En una accin de cdigo debes escribir un programa en GML. Tercero, en el room creation code. Y finalmente, en cualquier momento que necesites especificar algn valor en una accin, puedes tambin emplear una expresin en GML. Una expresin, como veremos ms adelante no es un programa completo, sino una pieza de cdigo que devuelve un resultado.

En este captulo describiremos la estructura bsica 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 slo consistan de letras, nmeros y el guin bajo "_". De otra forma no podrs referirte a ellas desde el programa. Mantente seguro que todos los recursos tengan nombres diferentes, tambin 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 continuacin. La estructura bsica del GML se trata con detalle en los siguientes captulos: Un programa. Un programa consiste de un sistema de instrucciones, llamados sentencias. Un programa debe comenzar con el smbolo { y terminar con el smbolo } . Las sentencias deben separarse con el smbolo ';'. La estructura global de todo programa es:

{ <sentencia >; <sentencia >; ... }

Hay un nmero de diferentes tipos de sentencias, de las cuales vamos a ver ms abajo.

Variables Como en cualquier lenguaje de programacin, el GML contiene variables. Las variables son las posiciones de memoria que guardan la informacin. Las variables pueden almacenar valores reales o cadenas de texto. Las variables no necesitan ser declaradas como en otros lenguajes. Hay un gran nmero de variables internas. Algunas son generales, como mouse_x y mouse_y, las cuales indican la posicin 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 posicin actual de la instancia. Una variable tiene un nombre que debe iniciar con una letra, y puede contener slo letras, nmeros, y el smbolo _ (La longitud mxima 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 (an del mismo objeto), aunque existe la posibilidad de hacer referencia a variables de otras instancias; mira ms abajo para mayor informacin.

Asignaciones Una asignacin pasa el valor de una expresin a una variable. Una asignacin tiene la siguiente forma:

<variable> = <expresin>;

Una expresin puede ser un simple valor pero tambin puede ser ms complicada. Adems de asignar un valor a una variable, tambin se le puede sumar usando +=, restar usando -=, multiplicarla usando *=, dividirla usando /=, o usando |=, &\ o ^=.

Expresiones Las expresiones pueden ser nmeros reales (p. Ej. 3.4), nmeros hexadecimales, comenzando con el signo $ (p. Ej. $00FFAA), cadenas entre comillas simples o dobles (p. Ej. hola o hola) u otras ms complicadas. Para las expresiones, existen los siguientes operadores binarios (en orden de prioridad):

&&, ||: funciones Booleanas (&& para la funcin and, || para la funcin) <, <=, ==, !=, >, >=: 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) +, -: adicin, sustraccin *, /, div, mod: multiplicacin, divisin, divisin entera y mdulo.

Nota que el valor operador

x div y

es el valor de

x/y redondeado en la direccin de cero al nmero entero ms cercano. El x (x

mod devuelve el resto obtenido dividiendo sus operandos. En otras palabras, x mod y =

div y) * y. Tambin, 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 nmeros, variables o funciones que devuelvan algn valor. Las sub-expresiones se pueden colocar entre parntesis. Todos los operadores funcionan para valores reales. Las comparaciones tambin 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 asignndoles un valor (no es necesario declararlas antes). Si simplemente usas un nombre de variable, la variable ser almacenada slo para la instancia actual. Por lo que no esperes encontrarla cuando manejes otro objeto (u otra instancia del mismo objeto). Tambin 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 estn dentro del actual piece of code o de un script. De esta manera evitas perder memoria y ests seguro que no hay ningn conflicto con los nombres. Esto es tambin ms rpido que usar variables globales. Para hacer esto debes declarar las variables en el comienzo del cdigo, usando la palabra var. Esta declaracin se ve as:

var <nombrevariable1>,<nombrevariable2>,<nombrevariable3>, ...

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 querrs acceder a variables en otra instancia. Por ejemplo, para detener el movimiento de todas las pelotas, o para mover al personaje principal a cierta posicin, o, en el caso de una colisin, 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 accin other: La otra instancia involucrada en un evento de colisin all: Todas las instancias noone: Ninguna instancia (tal vez te parezca raro pero puede ser til como veremos ms 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 ests preguntando lo que la ltima tarea realiza cuando hay ms 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 ms difcil. Cada instancia tiene un id nico. Cuando colocas instancias en un cuarto en el diseador, este id se muestra cuando colocas el ratn sobre la instancia. Estos nmeros son mayores o iguales a 100000. Puedes emplear estos nmeros como la parte a la izquierda del punto. Pero ten cuidado, el punto ser interpretado como el punto decimal en el nmero. Para evitarlo, colcalo entre parntesis. 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 vlido 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 indicacin antes del punto. Esto es completamente vlido. Djame explicarlo un poco mejor. Un punto es de hecho, un operador. Toma un valor como el operador de la izquierda y una variable (direccin) como el operador de la derecha, y devuelve la direccin 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 vlido:

{ 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 tambin 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 lmite de 32000 para cada ndice y 1000000 para el tamao 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 (<expresin>) <sentencia >

if (<expresin>) <sentencia> else <sentencia >

La sentencia tambin puede ser un bloque. La expresin se evaluar. Si el valor (redondeado) es <=0 (false) se ejecuta la sentencia despus del else, de otra forma (true) se ejecuta la otra sentencia. Es un buen hbito colocar siempre corchetes a las sentencias en la sentencia if. Por lo que mejor usa

if (<expresin>) { <Sentencia > } else { <Sentencia > }

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 (<expresin>) <sentencia >

La sentencia es repetida el numero de veces indicado por el valor redondeado de la expresin.

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 (<expresin>) <sentencia>

Mientras la expresin sea verdadera, la sentencia (que puede tambin ser un bloque) es ejecutada. Ten cuidado con tus ciclos while. Puedes fcilmente 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 posicin libre (esto es casi lo mismo que la accin para mover un objeto a una posicin aleatoria).

{ while (!place_free(x,y)) { x = random(room_width); y = random(room_height); } }

Sentencia Do La sentencia Do tiene esta forma:

do <sentencia> until(<expresin>)

La sentencia (que puede tambin ser un bloque) es ejecutada hasta que la expresin sea verdadera. La sentencia se ejecuta por lo menos una vez. Ten cuidado con los ciclos do. Puedes fcilmente 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 posicin libre (esto es lo mismo que mover un objeto en una posicin aleatoria)

{ do { x = random(room_width); y = random(room_height); } until (place_free(x,y)) }

Sentencia For Una sentencia For tiene esta forma:

for (<sentencia1> ; <expresin> ;<sentencia2>) <sentencia3>

Funciona de la manera siguiente. Primero se ejecuta la sentencia1. Entonces se evala la expresin. Si es verdadera, se ejecuta la sentencia3; entonces la sentencia2 y luego se evala nuevamente la expresin. Esto contina hasta que la expresin sea falsa.

Puede sonar complicado. Debes interpretarlo de la manera siguiente. La primera sentencia inicializa el ciclo for. La expresin prueba si el ciclo debiera terminar. La sentencia2 es la sentencia de paso hacia la evaluacin del siguiente ciclo.

El uso ms comn 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 querrs llevar a cabo alguna accin dependiendo de un valor en particular. Puedes lograrlo empleando varias sentencias if pero es ms sencillo si empleas la sentencia switch. Una sentencia switch tiene la siguiente forma:

switch (<expresin>) { case <expresin1>: <statement1>; ... ; break; case <expresin2>: <statement2>; ... ; break; ... default: <statement>; ... }
Funciona as: primero se ejecuta la expresin. Despus se compara con los resultados de las diferentes expresiones delante de las sentencias case. La ejecucin contina despus 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 ejecucin contina despus de la sentencia default. (No es necesaria la sentencia default. Nota que se pueden colocar mltiples sentencias

case para la misma sentencia. Tambin, no es necesaria la sentencia break. Si no existe una sentencia break, la ejecucin simplemente contina con el cdigo para la siguiente sentencia case.

Ejemplo El siguiente programa lleva a cabo una accin segn 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 ejecucin del programa/script actual. (No termina la ejecucin del juego! Para ello necesitas la funcin game_end(); ver ms abajo)

Funciones Una funcin tiene la siguiente estructura: nombre de la funcin, seguido por uno o varios argumentos entre parntesis, separados por comas (tambin puede no incluir ningn argumento).

<funcin>(<arg1>,<arg2>,...)

Hay dos tipos de funciones. En primer lugar, tenemos una gran cantidad de funciones internas, para controlar todos los aspectos del juego. Despus, cualquier scipt que definas en el juego puede ser usado como una funcin.

Nota que para una funcin sin argumentos an se necesitan los parntesis. Algunas funciones devuelven valores y pueden ser empleadas en expresiones. Otras simplemente ejecutan rdenes.

Nota que es imposible usar una funcin como el lado izquierda de una asignacin. Por ejemplo, no puedes escribir

instante_nearest(x,y,obj).speed = 0.

En lugar, debes escribir

(instance_nearest(x,y,obj)).speed = 0.

Scripts Cuando creas un script, querrs tener acceso a los argumentos enviados a l (ya sea cuando uses una accin script, o cuando llames al script como una funcin 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 mximo 16 argumentos. (Nota: cuando se llama un script desde una accin, slo se pueden especificar los primeros 5 argumentos). Pueden usar tambin argument[0], etc.

Los scripts tambin pueden devolver un valor, por lo que pueden ser empleados en expresiones. Para ello debes emplear la sentencia return:

return <expresin>

La ejecucin del script termina en la sentencia return!

Ejemplo Aqu esta la definicin de un script que calcula el cuadrado del argumento:

{ return (argument0*argument0); }

Para llamar un script desde una pieza de cdigo, solo hazlo como cuando se hacen las llamadas a funciones. Esto es, escribe el nombre del script con sus argumentos entre parntesis.

Construcciones With Como se indic antes, es posible leer y cambiar el valor de las variables en otras instancias. Pero en ciertos casos querrs hacer mucho ms con esas otras instancias. Por ejemplo, imagina que deseas mover todas las pelotas 8 pxeles hacia abajo. Pudieras pensar que eso se logra con el siguiente cdigo

pelota.y = pelota.y + 8;

Pero no es correcto. El valor a la derecha de la asignacin 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 declaracin. Entonces, cmo logramos esto? Para ello existe la declaracin with. Su forma general es

with (<expresin>) <sentencia>

<expresin> indica una o ms 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). <declaracin> 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 pxeles hacia abajo, puedes escribir

with (pelota) y += 8;

Si deseas ejecutar mltiples declaraciones, colcalas entre corchetes. Por ejemplo, para mover todas las pelotas a una posicin 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 posicin de la instancia actual, puedes usar

with (pelota) { x = other.x; y = other.y; }

El uso de la declaracin with es muy poderoso. A continuacin te muestro unos cuantos ejemplos ms. 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 lnea despus de // no se ejecuta. Puedes hacer tambin una multi-lnea de comentarios colocando el texto entre /* y */.

Funciones y variables en GML El GML contiene un gran nmero de funciones y variables internas. Con ellas puedes controlar cualquier parte del juego. Para todas las acciones existe una funcin correspondiente por lo que de hecho no necesitas emplear ninguna accin si prefieres emplear cdigo. Pero hay muchas ms funciones y variables que controlan aspectos del juego que no se pueden acceder slo empleando acciones. Por lo que si deseas crear juegos ms avanzados se te recomienda leer los siguientes captulos para tener un panorama general de todo lo que es posible lograr. Por favor nota que estas variables y funciones pueden tambin emplearse cuando se envan valores para las acciones. Por lo que an si no planeas emplear cdigo o escribir algn script, an obtendrs beneficios de esta informacin.

En los captulos siguientes se emplean las siguientes convenciones. Los nombres de variables marcados con un * son slo de lectura, es decir, no se puede cambiar su valor.

Los nombres de variables con [0...n] despus de ellos son arrays. Se da el intervalo posible de sus ndices.

Haciendo clculos
Game Maker contiene un gran nmero de funciones para realizar determinadas tareas. Aqu tienes una lista completa de estas funciones.

Esta seccin est dividida en los temas: Constantes Game Maker incluye las siguientes constantes matemticas:

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 nmeros 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 funcin acepta un
mximo 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 ms 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 raz cuadrada de X. sqr(x) Devuelve el cuadrado de X. power(x,n) Devuelve X elevado a la potencia N. exp(x) Devuelve
E elevado a X. que es la parte situada tras el punto decimal.

El valor no debe ser negativo.

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 funcin soporta 16 argumentos. Deben ser
todos nmeros reales o cadenas de texto.

max(val1,val2,val3,...) Devuelve el mayor de los valores. La funcin soporta 16 argumentos. Deben ser
todos nmeros reales o cadenas de texto.

mean(val1,val2,val3,...) Devuelve el promedio de los valores. La funcin soporta 16 argumentos.


Deben ser todos nmeros reales.

median(val1,val2,val3,...) Devuelve el valor intermedio de los argumentos introducidos. (Cuando el


nmero de argumentos es parejo, el menor de los dos valores intermedios, es el que devuelve la funcin. La funcin soporta 16 argumentos. Deben ser todos nmeros 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 direccin 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


direccin indicadas.

la longitud y

lengthdir_y(len,dir) Devuelve la componente vertical (y) del vector determinado por


direccin indicadas.

la longitud y

is_real(x) Averigua cuando X es un valor real.

(Diferencindolo de una cadena de texto). (Diferencindolo de un nmero real).

is_string(x) Averigua cuando X es una cadena de texto.

Funciones de cadenas de texto Estas son las funciones disponibles para trabajar con cadenas de texto:

chr(val) Devuelve una cadena con el carcter al que hace referencia el cdigo asci VAL. ord(str) Devuelve el cdigo asci del primer carcter de la cadena de texto STR. real(str) Convierte una cadena de texto
decimales o una parte exponencial. en un nmero real. STR puede contener signos negativos, puntos

string(val) Convierte el nmero real en una cadena de texto utilizando el formato estndar (sin decimales
cuando se trata de un nmero entero y un mximo de dos dgitos decimales en cualquier otro caso).

string_format(val,tot,dec) Convierte VAL en una cadena de texto utilizando nuestro propio formato:
TOT indica el mximo de dgitos y DEC el nmero de dgitos decimales.

string_length(str) Devuelve el nmero de caracteres de la cadena. string_pos(substr,str) Devuelve la posicin de SUBSTR en STR (0 No encontrado).

string_copy(str,index,count) Devuelve una subcadena de STR, partiendo de la posicin INDEX y de


una longitud definida por COUNT.

string_char_at(str,index) Devuelve el carcter

situado en la posicin 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


aadida en la posicin 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 nmero de ocurrencias de la subcadena SUBSTR existentes en


STR.

string_lower(str) Devuelve una copia en minsculas de la cadena STR. string_upper(str) Devuelve una copia en maysculas de la cadena STR. string_repeat(str,count) Devuelve una cadena con un nmero 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 nmeros de la cadena STR. string_lettersdigits(str) Devuelve una cadena que solo contiene los nmeros 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 nmero real. La parte entera es el nmero de das que han pasado desde 12/30/1899 y parte decimal de este valor es la fraccin de un da 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 vlidos.

date_valid_date(year,month,day) Muestra si la fecha indicada es vlida. date_valid_time(hour,minute,second) Muestra si la hora indicada es vlida.

date_inc_year(date,amount) Devuelve una nueva fecha N aos despus de la fecha indicada. N debe ser
un nmero entero.

date_inc_month(date,amount) Devuelve una nueva fecha N meses despus de la fecha indicada. N debe
ser un nmero entero.

date_inc_week(date,amount) Devuelve una nueva fecha N semanas despus de la fecha indicada. N


debe ser un nmero entero.

date_inc_day(date,amount) Devuelve una nueva fecha N das despus de la fecha indicada. N debe ser
un nmero entero.

date_inc_hour(date,amount) Devuelve una nueva fecha


ser un nmero entero.

N horas despus de la fecha indicada. N debe

date_inc_minute(date,amount) Devuelve una nueva fecha N minutos despus de la fecha indicada. N


debe ser un nmero entero.

date_inc_second(date,amount) Devuelve una nueva fecha N segundos despus de la fecha indicada. N


debe ser un nmero entero.

date_get_year(date) Devuelve el ao actual. date_get_month(date) Devuelve el mes actual. date_get_week(date) Devuelve la semana actual. date_get_day(date) Devuelve el da 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 da de la semana actual. date_get_day_of_year(date) Devuelve el da del ao especificado. date_get_hour_of_year(date) Devuelve la hora del ao especificado. date_get_minute_of_year(date) Devuelve el minuto del ao especificado. date_get_second_of_year(date) Devuelve el segundo del ao especificado. date_year_span(date1,date2) Devuelve el nmero de aos que hay entre las dos fechas. Reporta los
aos incompletos como una fraccin.

date_month_span(date1,date2) Devuelve el nmero de meses que hay entre las dos fechas. Reporta
los meses incompletos como una fraccin.

date_week_span(date1,date2) Devuelve el nmero de semanas que hay entre las dos fechas. Reporta
las semanas incompletas como una fraccin.

date_day_span(date1,date2) Devuelve el nmero de das que hay entre las dos fechas. Reporta los das
incompletos como una fraccin.

date_hour_span(date1,date2) Devuelve el nmero de horas que hay entre las dos fechas. Reporta las
horas incompletas como una fraccin.

date_minute_span(date1,date2) Devuelve el nmero de minutos que hay entre las dos fechas. Reporta
los minutos incompletos como una fraccin.

date_second_span(date1,date2) Devuelve el nmero de segundos que hay entre las dos fechas.
Reporta los segundos incompletos como una fraccin.

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 slo 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 slo 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 nmero de das que hay en el mes indicado. date_days_in_year(date) Devuelve el nmero de das que hay en el ao indicado. date_leap_year(date) Define si el ao indicado es un ao 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 creacin de instancias, el timing, y el manejo de los eventos.

La informacin sobre el game play se puede encontrar en las siguientes secciones: Movindose 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 posicin de la instancia. (Para ser precisos, indican el lugar donde se

encuentra el punto de origen del sprite). La posicin (0,0) es la esquina superior izquierda del cuarto. Puedes cambiar la posicin de la instancia al cambiar los valores de sus variables

x e y. Es lo que debes hacer si deseas movimientos

ms complicados. Este cdigo normalmente se coloca en el evento step del objeto.

Si el objeto se mueve con velocidad y direccin constantes, hay una manera ms fcil de lograrlo. Cada instancia tiene una velocidad horizontal (hspeed) y vertical (vspeed). Ambas se indican en pxeles 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 slo debes establecer estos valores una vez (por ejemplo en el evento de creacin) para dar al objeto un movimiento constante.

Hay otra manera muy diferente de especificar el movimiento, usando direccin (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 gravedad.

hspeed y vspeed). Tambin tenemos la friccin y la gravedad, y la direccin de la

Finalmente, tenemos la funcin

motion_add(dir,speed) para agregar movimiento al actual.

Para concluir, cada instancia tiene las siguientes variables y funciones referentes a su posicin y movimiento:

x y

Su posicin x. Su posicin y.

xprevious Su posicin x anterior. yprevious xstart


Su posicin y previa.

Su posicin x inicial en el cuarto.

ystart Su posicin y inicial en el cuarto. hspeed


Componente horizontal de la velocidad.

vspeed Componente vertical de la velocidad. direction Su direccin actual (0-360, contra las manecillas del reloj, 0 = a la derecha). speed Su velocidad actual (pxeles por step). friction Friccin actual (pxeles por step). gravity Cantidad actual de gravedad (pxeles por paso). gravity_direction Direccin de la gravedad (270 es hacia abajo). motion_set(dir,speed) Establece el movimiento a la velocidad speed y la direccin dir. motion_add(dir,speed) Agrega el movimiento al movimiento actual (como una suma vectorial).

Existe un gran nmero de funciones para ayudarte a definir el movimiento:

place_free(x,y) Devuelve si la instancia colocada en la posicin (x, y) est libre de colisin. Normalmente se
emplea para revisar antes de mover la instancia a la nueva posicin.

place_empty(x,y) Devuelve si la instancia colocada en la posicin (x, y) no se encuentra con nadie. Esta
funcin tambin toma en cuenta las instancias no slidas.

place_meeting(x,y,obj) Devuelve si la instancia colocada en la posicin (x,y) se encuentra con un el


objeto obj. obj puede ser un objeto en cuyo caso la funcin devuelve verdadero si se encuentra con una instancia de ese objeto. Tambin puede ser el

id de una instancia, o la palabra especial 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 posicin libre, y la alinea con los valores hsnap y vsnap,
al igual que la accin correspondiente.

move_snap(hsnap,vsnap) Alinea la instancia, como la accin 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 cunto debe

salir el origen de la instancia del room para teleportarse (es decir, un margen alrededor del room). Esta funcin 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 slidos, como la accin 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 slo con las slidas. move_contact_solid(dir,maxdist) Mover la instancia en la direccin dir hasta que haya contacto con
un objeto slido. Si no hay collision en la posicin actual, la instancia es colocada justo antes de donde ocurre una colisin. Si ya hay una colisin en la posicin actual, la instancia no se mueve. Puedes especificar la distancia mxima a mover la instancia maxdist (emplea un nmero negativo para indicar distancia arbitraria).

move_contact_all(dir,maxdist) Igual que la funcin anterior pero esta vez se detiene hasta que haya
contacto con cualquier objeto, no solo slidos.

move_outside_solid(dir,maxdist) Mueve la instancia en la direccin dir hasta que no est al alcance


de un objeto slido. Si no hay collision en la posicin actual, no se mueve la instancia. Puedes especificar la distancia mxima 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 slidos.

distance_to_point(x,y) Devuelve la distancia de la caja lmite de la instancia actual hacia el punto (x,y). distance_to_object(obj) Devuelve la distancia de la instancia actual a la instancia ms cercana del
objeto obj.

position_empty(x,y) Indica si no hay nada en la posicin (x,y). position_meeting(x,y,obj) Indica si en la posicin (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 ms flexibilidad:

path_start(path,speed,endaction,absolute) Comienza un path para la instancia actual. path


es el nombre del path que deseas iniciar.

speed es la velocidad

con la que la instancia debe moverse por el

path (una velocidad negativa indica que la instancia se mover al revs sobre el path).

endaction indica que

debera ocurrir cuando la instancia llegue al final del camino. Puedes usar los siguientes valores para esto:

0 : parase 1: continuar desde la posicin inicial del path (s el path no est cerrado saltamos a la posicin inicial) 2: continuar desde la posicin inicial 3: recorrer el path al revs (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 posicin actual de la instancia. Para ser ms precisos, si la velocidad es positiva el punto inicial del path se colocar en la posicin actual de la instancia y se seguir desde ah. Cuando la velocidad es negativa, el punto final del path se colocar en la posicin de la instancia y el path se seguir al revs 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 funcin path_start(path,speed,endaction,absolute). path_position Posicin 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 Posicin previa en el path. Esto se puede usar en eventos de colisin para colocar
la instancia en la posicin anterior antes de una colisin.

path_speed Velocidad (en pxels por paso) con la que la instancia sigue el path. Con una velocidad negativa el
path se recorre en sentido inverso.

path_orientation Orientacin (antihoraria) en la que se realiza el path. 0 es la orientacin normal del path. path_scale Escala del path. Aumntala para hacer el path ms grande. 1 es el valor normal del path. path_endaction La accin que se debe ejecutar al finalizar el path. Puedes indicar los valores explicados ms
arriba.

Planificacin del movimiento

La planificacin 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 situacin. 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 ms simple consiste en hacer que una instancia de un paso hacia la posicin final, intentando ir en lnea recta pero tomando otra direccin 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 funcin hace que la instancia de un paso hacia la


posicin (x,y). La longitud del paso se indica con el parmetro posicin no se mover. Si

stepsize. Si la instancia ya ha llegado a esa

checkall es true la instancia se parar cuando choque con una instancia de cualquier

objeto. Si es false, slo se parar al chocar con un objeto slido. Esta funcin no propone un camino alternativo, simplemente se parar si encuentra un obstculo. La funcin devuelve si se ha alcanzado el destino.

mp_linear_step_object(x,y,stepsize,obj) Igual que la anterior, pero esta vez slo 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 obstculos que encuentre. Cuando la instancia se choque con un obstculo cambiar su direccin para tratar de esquivar el objeto, movindose alrededor de l. Puede que no siempre se consiga llegar a la meta, pero la funcin siempre intentar acercar lo ms 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 slo 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 funcin anterior hace su


trabajo usando un nmero de parmetros que pueden ser cambiados con esta funcin. El mtodo funciona como sigue: primero la instancia intenta moverse en lnea recta hacia la meta. Para ello, mira un nmero de pasos adelante para ver si hay algn obstculo. Este nmero de pasos corresponde al valor

ahead (por defecto 3). Reduciendo este valor la

instancia comenzar a cambiar su direccin ms tarde si encuentra un obstculo. Aumentndolo cambiar antes de direccin. Si detectamos una colisin, la funcin mira a la derecha y a la izquierda para encontrar un camino libre. Esto se realiza en pasos de tamao

rotstep (por defecto 10). Reducindolo conseguimos que la instancia tenga ms maxrot
(por defecto 30) indica cunto

posibilidades para moverse pero la funcin ser ms lenta. El parmetro

puede cambiar como mximo la direccin en un paso. As que aunque pueda moverse en lnea recta hacia la meta no lo har si debe girar ms de lo indicado por este parmetro. Aumentndolo conseguimos que la instancia pueda girar ms en cada paso, haciendo que sea ms fcil encontrar un camino aunque ste ser menos uniforme. Disminuyendo su valor el camino ser ms suave pero la instancia realizar giros ms largos, haciendo que a veces no pueda llegar exactamente a la meta. Cuando la instancia no se puede mover en ninguna direccin el comportamiento depender del valor de

onspot. Si onspot es true la instancia rotar en su posicin la cantidad indicada por 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 slo usa informacin local. As que slo encontrar un camino si la informacin es suficiente para determinar la direccin 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 asignrselo a la instancia para que se mueva hacia la meta como si fuera un path normal que t hubieras creado. El clculo del camino tarda un poco pero una vez hecho la ejecucin del path es muy rpida. Por supuesto, esto es vlido si la situacin no cambia (por ejemplo, si los obstculos se mueven). Entonces necesitars volver a calcular el path. De nuevo, estas funciones pueden fallar en algunas circunstancias. Estas funciones slo estn disponibles en la versin 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 lnea recta para la


instancia desde su posicin hasta (xg,yg) usando el paso especificado en

stepsize. Usa pasos como en la funcin

mp_linear_step(). El path indicado debe existir con anterioridad a la llamada de la funcin y ser sobreescrito
por el nuevo path (consulta el captulo sobre cmo crear y destruir paths). La funcin devuelve si se ha encontrado un path. Si no consigue encontrar un camino, la funcin devolver un path hasta la posicin donde la instancia qued bloqueada.

mp_linear_path_object(path,xg,yg,stepsize,obj) Igual que la anterior, pero esta vez slo


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 funcin calcula un


camino para instancia desde su posicin actual y orientacin hasta (xg,yg) usando el paso especificado en

stepsize e intentando evitar colisionar con los obstculos. Utiliza pasos potenciales como la funcin mp_potential_step() y los parmetros se pueden configurar con mp_potential_settings(). El
path indicado debe existir con anterioridad a la llamada de la funcin y ser sobreescrito por el nuevo path (consulta el captulo sobre cmo crear y destruir paths). La funcin devolver si se ha encontrado un camino. Para evitar que la funcin contine calculando para siempre debes especificar un

factor mayor que 1. La funcin se detendr y

devolver un mensaje de error si no puede encontrar un camino que sea ms 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 funcin falla se crea el camino en direccin 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 slo se tienen en cuenta las instancias del objeto instancia particular.

obj. obj puede ser un objeto o una id de una

Las dems funciones usan un mecanismo mucho ms complejo basado en rejillas (un algoritmo A*). Tiene ms sexito a la hora de encontrar caminos y hacerlos ms cortos, pero requiere ms trabajo por tu parte. Adems, tambin 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 (ms lento) o ms espaciada. Despus, determinamos las celdas de la rejilla ocupadas por objetos relevantes (usando colisin precisa o la caja de contorno) y marcamos estas celdas como prohibidas. As que una celda estar prohibida si parte de un obstculo la est ocupando. Finalmente especificamos la posicin inicial y final, que deben estar en celdas libres de la rejilla y la funcin calcula el camino ms 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 tamao de las celdas con la mayor precisin posible. Tambin debes decidir qu objetos deben tomarse en cuenta y si es necesaria la colisin precisa o no. Todos estos parmetros afectan de manera muy notable a la eficiencia del mtodo.

En particular, el tamao 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 posicin 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 ms caminos diferentes podrs 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 mtodo de rejilla son:

mp_grid_create(left,top,hcells,vcells,cellwidth,cellheight) Esta funcin crea


la rejilla. Devuelve un ndice que debe ser usado en las dems funciones. Puedes crear y mantener varias rejillas al mismo tiempo.

left y top indican la posicin de la esquina superior izquierda de la rejilla y hcells y

vcells indican el nmero de celdas horizontales y verticales respectivamente. Finalmente, 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 funcin
cuando no necesites usar ms 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 rectngulo 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 rectngulo como prohibidas.

mp_grid_add_instances(id,obj,prec) Marca todas las celdas que intersectan una instancia del
objeto indicado como prohibidas. Tambin puedes especificar una id de una instancia concreta, o la palabra clave para indicar todas las instancias.

all

prec indica si hay que usar colisin precisa (slo funcionar si en el sprite de la

instancia est activada la misma opcin).

mp_grid_path(id,path,xstart,ystart,xgoal,ygoal,allowdiag) Calcula el path a


travs de la rejilla. El path indicado debe existir con anterioridad a la llamada de la funcin y ser sobreescrito por el nuevo path (consulta el captulo sobre cmo crear y destruir paths). path y

xstart e ystart indican el comienzo del

xgoal

ygoal las coordenadas de la meta. allowdiag indica si se permiten movimientos diagonales

entre celdas o slo horizontales y verticales. La funcin devuelve si consigui calcular un path (observa que el path es independiente de la instancia actual).

mp_grid_draw(id) Esta funcin dibuja la rejilla marcando las celdas libres y prohibidas (muy til para buscar
errores).

Deteccin 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 comn: el argumento

obj puede ser un objeto, la palabra clave all, o la id de una instancia. El argumento prec indica si se

debe usar colisin precisa o la caja de contorno de la instancia (la colisin precisa slo funciona si el sprite de la instancia tiene activada la misma opcin). El argumento

notme indica si no se debe tener en cuenta a la instancia que

llama a la funcin. Todas estas funciones devuelven la id de una de las instancias con las que se detecta colisin. Si no hay colisin devuelven un valor negativo.

collision_point(x,y,obj,prec,notme) Comprueba si hay una colisin en el punto (x,y) con


instancias del objeto obj.

collision_rectangle(x1,y1,x2,y2,obj,prec,notme) Comprueba si hay una colisin


rectngulo (slido) con las esquinas indicadas e instancias del objeto ver si un rea est libre de obstculos.

entre el

obj. Por ejemplo, puedes usar esta funcin para

collision_circle(xc,yc,radius,obj,prec,notme) Comprueba si hay una colisin


circunferencia (slido) con centro (xc,yc) y radio r e instancias del objeto un objeto est cerca de una posicin.

entre la

obj. Puedes usar esta funcin para ver si

collision_ellipse(x1,y1,x2,y2,obj,prec,notme) Comprueba si hay una colisin


elipse (slida) con las esquinas indicadas e instancias del objeto

entre la

obj.
entre la lnea

collision_line(x1,y1,x2,y2,obj,prec,notme) Comprueba si hay una colisin


que va de (x1,y1) a (x2,y2) e instancias del objeto

obj. Esta funcin es muy poderosa. Puedes usarla para

comprobar si una instancia puede ver a otra chequeando si entre ellas hay una pared

Instancias

Las unidades bsicas del juego son las instancias. Durante el juego, puedes cambiar varios aspectos de estas instancias. Tambin puedes crear o destruir instancias. Adems 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 ratn es
indicada). No se puede cambiar.

mask_index ndice de l sprite usado como mscara para las colisiones. Si indicas -1 la mscara ser igual al sprite
de la instancia.

solid Indica si la instancia es slida 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 fcil identificar una instancia concreta. No tienen un nombre. Cuando slo 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* Nmero de instancias que existen en el cuarto. instance_id[0..n-1]* La id de la instancia nmero n.


Observa que la asignacin 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 ms poderosa de todas. Puedes hacerlo con el siguiente cdigo:

{ maxid = -1; maxpower = 0; for (i=0; i<instance_count; i+=1) { iii = instance_id[i]; if (iii.object_index == unit) { if (iii.power > maxpower) {maxid = iii; maxpower = iii.power;} } } }

Despus del bucle maxid contendr la id de la instancia ms podersa (No destruyas instancias durante un bucle como ste porque se eliminarn inmediatamente y te saltars 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 o la palabra clave

all.

instance_number(obj) Devuelve el nmero 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 posicin (x,y). Cuando hay


varias instancias en esa posicin se devuelve la id de la prtimera. no existe se devuelve el objeto especial

obj puede ser un objeto o la palabra clave all. Si

noone

instance_nearest(x,y,obj) Devuelve la id de la instancia de tipo obj que est ms 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 ms 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 posicin (x,y). especial

obj puede ser un objeto o la palabra clave all. Si no existe se devuelve el objeto

noone.

Las siguientes funciones se usan para crear y destruir instancias:

instance_create(x,y,obj) Crea una instancia de obj en la posicin (x,y). La funcin 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 funcin 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 destruccin y creacin.

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 posicin indicada a otras del tipo obj. perf indica si se deben ejecutar los eventos de destruccin y creacin.

Desactivando instancias

Cuando creas un cuarto muy grande, por ejemplo en juegos de plataformas, con una vista (view) muy pequea, muchas instancias se quedan fuera de la vista. Aunque no sean visibles, estas instancias siguen ejecutando sus eventos. Tambin, al efectuar chequeos de colisin 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 cmo 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 ms rpido. 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 estn desactivadas no sern eliminadas! As, una llave que recoja el jugador no podr abrir una puerta que est desactivada, por ejemplo.

El error ms crucial que puedes hacer es el de desactivar la instancia que se encarga de activar las dems instancias. Para evitar esto algunas funciones permiten especificar si la instancia que desactiva a las dems 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.


Tambin 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 regin indicada (es decir, todas aquellas cuya caja de contorno est parcial o completamente dentro de la regin indicada). Si desactivadas. Si

inside es igual a false las instancias completamente fuera de la regin son

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.
Tambin 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 regin especificada. Si

inside es false las instancias fuera de la regin son activadas.

Por ejemplo, para desactivar todas las instancias fuera de la vista y activar las que estn dentro podemos poner este cdigo 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 regin 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, hacindolo ms difcil, agregando una muy pequea cantidad (como 0.001) a room_speed en cada step. Si tu mquina es lenta la velocidad del juego pudiera no alcanzarse. Esto puede comprobarse usando la variable fps que monitorea constantemente el nmero actual de cuadros por segundo. Finalmente, para un timing avanzado puedes usar la variable current_time que te da el nmero de milisegundos desde que la computadora fue iniciada. Aqu est la coleccin completa de variables disponibles (slo la primera puede ser cambiada):

room_speed Velocidad del juego en el cuarto actual (en steps por segundo). fps* Nmero de cuadros que son dibujados por segundo. current_time* Nmero de milisegundos que han pasado desde que el sistema fue iniciado. current_year* El ao actual. current_month* El mes actual. current_day* El da actual. current_weekday* El da actual de la semana (1=domingo, , 7=sbado). current_hour* La hora actual. current_minute* El minuto actual. current_second* El segundo actual.

Algunas veces querrs detener el juego por un corto periodo. Para esto, usa la funcin 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 lneas de tiempo (time lines). Cada instancia puede tener un recurso time line asociado con ella. Las siguientes variables estn 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 Posicin actual dentro de la time line. Puedes cambiarla para saltar o repetir ciertas
partes.

timeline_speed Normalmente, en cada step la posicin en la time line se incrementa en 1. Puedes cambiar esta
cantidad configurando esta variable a un valor diferente. Puedes usar nmeros reales, por ejemplo 0.5. Si el valor es mayor que uno, varios momentos pueden ocurrir dentro del mismo tiempo del step. Se realizarn en el orden correcto, por lo que no se saltar ninguna accin.

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 estn numerados en un orden consecutivo. Por lo que nunca sumes o restes un nmero de la variable room. En lugar de ello usa las funciones y variables indicadas abajo. Por lo que una tpica pieza de cdigo que usars sera:

{ 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 pxeles. room_height* Alto del cuarto en pxeles. room_caption Ttulo 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 automticamente cuando el jugador presiona <F5> para guardar y <F6> para cargar. Tambin puedes guardar y cargar juegos desde una pieza de cdigo (nota que la carga slo 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 slo los datos bsicos del juego son guardados. Por ejemplo, si guardas cuando una cancin est sonando, al cargar el juego la cancin no sonar desde ese momento. Los recursos editados tampoco son guardados, ni las partculas, los contenidos de las estructuras de datos ni la configuracin multijugador.

Score

Otro aspecto importante de muchos juegos es el score (marcador), la energa, y el nmero de vidas. El Game Maker mantiene el

score en la variable global score y el nmero de vidas en la variable global lives. Puedes

cambiar el score simplemente cambiado el valor de esta variable. Lo mismo se aplica para la energa 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 show_score, etc., a falso.

instancias. Si no quieres mostrar el score y las vidas en el ttulo, pon la variable

Tambin puedes cambiar el ttulo del marcador, de las vidas o de la energa. Para juegos ms complicados mejor muestra el score t mismo.

score El marcador actual. lives El nmero de vidas. health La energa actual (0-100). show_score Indica si se muestra el marcador en el ttulo de la ventana. show_lives Indica si se muestra el nmero de vidas en el ttulo de la ventana. show_health Indica si se muestra la energa en el ttulo de la ventana. caption_score El ttulo empleado para el marcador. caption_lives El ttulo empleado para el nmero de vidas. caption_health El ttulo para la energa.

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 creacin y destruccin ocurren cuando una instancia es creada o destruida. En cada step, el sistema maneja primero los eventos de alarma. Despus los eventos de teclado y ratn, y luego el siguiente evento step. Despus de esto las instancias son colocadas en su nueva posicin despus de lo cual se maneja el evento de colisin. Finalmente el evento draw se usa para dibujar las instancias (nota que cuando empleas mltiples vistas el evento draw es llamado varias veces en cada step). Tambin puedes aplicar un evento a la instancia actual desde una pieza de cdigo. 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 cdigo de tecla para la tecla.

Para los eventos de ratn 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 funcin 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 tambin puedes definir 16 eventos definidos por el usuario. Estos son

ejecutados solo si llamas esta funcin. Numb debe tener valores de 0 a 11.

event_inherited()

Ejecuta el evento heredado. Esto slo funciona si la instancia tiene un objeto padre.

Puedes obtener informacin sobre el evento actualmente ejecutado usando las siguientes variables de slo lectura:

event_type* El tipo del evento que se est ejecutando. event_number* El nmero 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 accin 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 }

Tambin 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 funcin :

set_program_priority(priority) Cambia la prioridad del programa. Debes indicar un valor


comprendido entre -3 y +3. Usando -3 el programa se ejecutar slo si no hay otro proceso que requiera tiempo de computacin. -2 y -1 son valores por debajo de lo normal, as que otros procesos tendrn 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 ms suavemente y a mayor velocidad. Otros procesos tendrn menos tiempo de computacin. +3 indica ejecucin en tiempo real: todo el tiempo de computacin se pone en disposicin del juego. Esto puede crear problemas con otras aplicaciones que se estn ejecutando en el ordenador. Adems, los eventos de teclado o pinchar en el botn para cerrar la ventana pueden dejar de ser atendidos por Windows. As que slo debes usar este valor si realmente necesitas todo el procesamiento posible. Se cuidadoso y no olvides guardar tu juego antes de ejecutarlo.

Interaccin con el usuario


No hay juego sin interaccin con el usuario. La manera estndar de interactuar con el usuario en el Game Maker es colocando acciones en los eventos del ratn o del teclado. Pero en ocasiones se necesita ms control. Desde una pieza de cdigo puedes chequear la posicin del ratn o si alguno de sus botones es presionado. Normalmente esto se chequea en el evento step de algn objeto controlador y llevas a cabo las acciones adecuadas. La informacin sobre este tema se encuentra en las secciones: El teclado Para interaccin con el teclado (keyboard) las siguientes funciones y variables existen:

keyboard_lastkey Cdigo de la ltima tecla presionada. Mira ms las constantes para los cdigos de tecla.
Puedes cambiarlo, p. ej, ponerlo a 0 si tu lo manipulaste.

keyboard_key Cdigo de tecla de la tecla presionada actualmente (mira mas abajo; 0 si no se presiona ninguna) keyboard_lastchar ltimo carcter presionado (como string) keyboard_string Cadena de caracteres de los ltimos 1024 caracteres tipeados. Esta cadena solo contendr
caracteres imprimibles en la pantalla. Tambin responde a la tecla de retroceso borrando el ltimo carcter.

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 numrico. En lugar de duplicar las acciones puedes mapear el teclado numrico a las teclas del cursor. Tambin 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 cdigo 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 botn del ratn en particular han sido presionados puedes emplear las siguientes funciones. Esto es til particularmente cuando se presionan varias teclas simultneamente.

keyboard_check(key) Indica si la tecla con el cdigo de tecla particular est presionado. keyboard_check_pressed(key) Indica si la tecla con el cdigo de tecla particular fue presionado desde el
ltimo step.

keyboard_check_released(key) Indica si la tecla con el cdigo de tecla particular dej de presionarse


desde el ltimo step.

keyboard_check_direct(key) Indica si la tecla con el cdigo de tecla es presionada chequeando el


hardware directamente. El resultado es independiente de la aplicacin enfocada. Esta funcin permite algunos chequeos ms. En este caso puedes emplear los cdigos 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 cdigo de tecla keyboard_key_release(key) Simulates a release of the key with the indicated keycode.

Las siguientes constantes para los cdigos de tecla son:

vk_nokey Cdigo de tecla que representa que no hay teclas presionadas vk_anykey Cdigo de tecla que representa que cualquier tecla ha sido presionada. vk_left Cdigo para tecla de la flecha izquierda vk_right Cdigo para tecla de la flecha derecha vk_up Cdigo para tecla de la flecha arriba vk_down Cdigo 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 Cdigos de tecla para las las teclas funcionales F1 hasta F12 vk_numpad0 ... vk_numpad9 Teclas numricas en el teclado numrico vk_multiply Tecla de multiplicacin en el teclado numrico vk_divide Tecla de divisin en el teclado numrico vk_add Tecla de suma en el teclado numrico vk_subtract Tecla de substraccin en el teclado numrico vk_decimal Tecla de punto decimal en el teclado numrico

Para las letras usa por ejemplo

ord('A'). (Letras Maysculas). Para los dgitos usa por ejemplo ord('5') para

obtener la tecla <5> (no en el teclado numrico). Las siguientes constantes solo sirven para

keyboard_check_direct: 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 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 cdigo 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)) if (keyboard_check(vk_down)) } y -= 4; y += 4;

Claro, esto es mucho ms fcil si simplemente lo ponemos en los eventos del teclado.

Hay algunas funciones adicionales relacionadas con la interaccin 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 ratn. io_handle() Maneja la entrada y salida por parte del usuario, actualizando los estados del teclado y del ratn. keyboard_wait() Espera hasta que el usuario presione una tecla del teclado.

El ratn Para ms interaccin, las siguientes variables y funciones existes:

mouse_x* Coordenada X del ratn. No puede cambiarse. mouse_y* Coordenada Y del ratn. No puede cambiarse. mouse_button Botn del ratn presionado actualmente. Como valores puedes emplear mb_none (ningn
botn),

mb_any (cualquier botn), mb_left (botn izquierdo), mb_middle (botn central) o mb_right

(botn derecho).

mouse_lastbutton ltimo botn presionado del ratn.

Para chequear si un botn particular del ratn se presion puedes usar estas funciones. Esto es muy til cuando muchas teclas se presionan simultneamente.

mouse_check_button(numb) Indica si se presiona el botn del ratn numb (como valores de numb emplea
mb_none, mb_left, mb_middle, o mb_right).

mouse_check_button_pressed(numb) Indica si el botn del ratn fue presionado desde el ultimo step. mouse_check_button_released(numb) Indica si el botn del ratn se solt desde el ltimo step.

Hay funciones adicionales relacionadas con la interaccin con el ratn:

mouse_clear(button) limpia el estado del botn del Mouse. Esto significa que no se generarn mas eventos
del ratn hasta que se vuelva a presionar otra vez.

io_clear() Limpia todos los estados del teclado y del ratn. io_handle() Maneja la entrada y salida por parte del usuario, actualizando los estados del teclado y del ratn. mouse_wait()Espera hasta que el usuario presione un botn en el ratn.

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 nmero de ejes del joystick. joystick_buttons(id) Devuelve el nmero de botones del joystick. joystick_has_pov(id) Indica si el joystick tiene capacidades point-of-view. joystick_direction(id) Devuelve el cdigo (vk_numpad1 a vk_numpad9) correspondiente a la direccin
del joystick id (1 o 2).

joystick_check_button(id,numb) Indica si el botn del joystick id es presionado (numb est en el


intervalo 1-32).

joystick_xpos(id) Devuelve la posicin (-1 a 1) del eje-x del joystick id. joystick_ypos(id) Devuelve la posicin y del joystick id. joystick_zpos(id) Devuelve la posicin z del joystick id (si es que cuenta con eje z). joystick_rpos(id) Devuelve la posicin del timn del joystick id (del cuarto eje). joystick_upos(id) Devuelve la posicin u del joystick id (del quinto eje).

joystick_vpos(id) Devuelve la posicin v del joystick id (del sexto eje). joystick_pov(id) Devuelve la posicin del point-of-view del joystick id. Este es un ngulo entre 0 y 360
grados. 0 es adelante, 90 a la derecha, 180 atrs y 270 a la izquierda. Cuando no se especifica la direccin del point-ofview devuelve 1.

Grficos del juego


Una parte importante de un juego son los grficos. 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 cdigo puedes controlar muchos ms aspectos. Este captulo muestra todas las variables y funciones disponibles para esto y da ms informacin sobre lo que est sucediendo realmente.

La informacin sobre la parte grfica se encuentra en las secciones siguientes: Imgenes y sprites Cada objeto tiene un sprite asociado. Puede ser una imagen simple o compuesta por varias subimgenes. 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 posicin (x,y) de la instancia. Cuando hay varias subimgenes, sta se reproduce a travs de las subimgenes para crear un efecto de animacin. 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 colisin; Simplemente no puedes verlas. Definir la visibilidad como falso es til para por ejemplo objetos controladores (hazlos tambin no slidos para evitar eventos de colisin 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 subimgenes del sprite actual de la instancia (no puede ser cambiado). image_index Cuando la imagen tiene varias subimgenes, el programa las recorre cclicamente. Esta variable
indica la subimagen dibujada actualmente (estn numeradas desde 0). Puedes cambiar la imagen actual cambiando esta variable. EL programa continuar reproduciendo el ciclo de subimgenes, 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 subimgenes. Un valor de 1 indica que en cada paso
se muestra la siguiente subimagen . Valores menores, reducirn la velocidad de visualizacin de la animacin, dibujando la misma subimagen varias veces. Valores mayores harn que se salten subimgenes para aumentar la velocidad de la animacin. A veces quieres que una subimagen en particular sea visible y no quieres que el programa muestre todas las dems subimgenes. 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 subimgenes para las diferentes orientaciones (en sentido contrario a las agujas del reloj) Puedes introducir el siguiente cdigo en el evento step:

{ image_index = direction * image_number/360; image_speed = 0; }

depth Normalmente las imgenes 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 ms al fondo se dibujar la instancia. (Tambin puedes utilizar valores negativos.) Las instancias con mayor profundidad permanecern debajo de las instancias con menor profundidad. Definiendo la profundidad garantizamos que las instancias son dibujadas en el orden que queremos. (Ej. El avin sobre la nube). Las instancias de fondo tendrn una alta profundidad (valor positivo) y las imgenes frontales tendrn una profundidad baja (valores negativos).

image_xscale Un valor de escala para hacer

mayores o menores las imgenes. Un valor de 1 indica el tamao

normal. Debes separar la escala horizontal xscale y la vertical yscale. Cambiando la escala tambin cambian el ancho y el alto de la imagen e influye en los eventos de collisin, como podras 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 tamao. 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. Un valor de 0 indica que no hay rotacin. Esta variable solo puede modificarse en la versin registrada!

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

Teido 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 tie de dicho color. Esto puede ser utilizado para colorear el personaje en tiempo de ejecucin. Esta variable solo puede modificarse en la versin 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, tambin puede tener un color de fondo. Todos los aspecto de estos fondos se pueden cambiar con cdigo usando las siguientes variables (observa que algunas son vectores con un rango de 0 a 7; este nmero indica el fondo al que se aplicarn 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 nmero 3 no debe mostrarse, deberamos hacerlo as: background_visible[3]=false;

background_foreground[0..7] Indica si el fondo est en primer plano (se dibujar encima de todo lo
dems, tapando todo lo que quede por debajo).

background_index[0..7] Imagen de fondo asignada al fondo indicado. background_x[0..7] Posicin x del fondo. background_y[0...7] Posicin 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 nmero entre 0 y 1 har la imagen
ms pequea y un nmero mayor que 1 la har ms grande. (Debe ser un valor positivo)

background_yscale[0..7] Factor de escalado vertical del fondo: un nmero entre 0 y 1 har la imagen
ms pequea y un nmero mayor que 1 la har ms grande. (Debe ser un valor positivo)

background_hspeed[0..7] Velocidad horizontal de scrolling del fondo, en pxeles 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 pxeles 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 teido usado al dibujar el fondo. El valor por defecto es c_white. Esta
variable slo se puede usar en la versin 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 tambin puedes usar el evento draw. para dibujar otras cosas. Esta seccin y las dos siguientes te darn informacin 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 grfica del juego y te permiten hacer cosas como dibujar slo 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 posicin (x,y) sin teirlo de ningn color y sin usar transparencia. del sprite

draw_sprite_stretched(sprite,subimg,x,y,w,h) Dibuja la subimagen subimg


con ndice

sprite

de forma que llene la regin con esquina superior-izquierda en (x,y), anchura

w y altura h.

draw_sprite_tiled(sprite,subimg,x,y) Dibuja el sprite repitindolo horizontal y verticalmente de


forma que llene toda la pantalla. (x,y) es la posicin 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

left

top (coordenadas de la esquina superior-izquierda) y width y height (anchura y altura del trozo que

queremos dibujar).

draw_background(back,x,y) Dibuja el fondo en la posicin (x,y), sin teirlo de ningn color y sin
transparencia.

draw_background_stretched(back,x,y,w,h) Dibuja el fondo escalado de forma que ocupe la


regin indicada.

draw_background_tiled(back,x,y) Dibuja el fondo repitindolo 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 posicin (x,y).

Las funciones siguientes son versiones extendidas de las funciones anteriores. Estas funciones slo estn disponibles en la versin registrada de Game Maker.

draw_sprite_ext(sprite,subimg,x,y,xscale,yscale,rot,color,alpha) Dibuja el
sprite escalado con factores antihorario.

xscale (horizontal) e yscale

(vertical) y rotado

rot grados en sentido

color indica el color con el que queremos teir el sprite (usa el color blanco c_white si no quieres teir alpha indica el factor de transparencia. Un valor igual a 0 hace la imagen totalmente

el sprite de ningn color) y

transparente y un valor igual a 1 la hace totalmente opaca. Con valores intermedios conseguirs que la imagen sea parcialmente transparente. Con esta funcin se pueden crear efectos muy espectaculares como explosiones semitransparentes.

draw_sprite_stretched_ext(sprite,subimg,x,y,w,h,color,alpha) Dibuja el sprite

escalado de forma que ocupe la regin indicada: esquina superior izquierda en (x,y), anchura indica el color de teido y

w y altura h. color

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 teido y factor de transparencia.

draw_sprite_part_ext(sprite,subimg,left,top,width,height,x,y,xscale,ys cale,color,alpha) Dibuja la parte indicada del sprite con factores de escala, color de teido y factor de
transparencia.

draw_sprite_general(sprite,subimg,left,top,width,height,x,y,xscale,ysc ale,rot,c1,c2,c3,c4,alpha) La funcin ms 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

posicin (x,y) y con factores de escala, ngulo de rotacin, un color de teido 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)

Dibuja el fondo

escalado, rotado, teido del color especificado (usa c_white si no quieres teirlo) y con factor de transparencia

alpha (0-1). draw_background_stretched_ext(back,x,y,w,h,color,alpha) Dibuja el fondo escalado


de forma que ocupe la regin indicada con color de teido 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 teido 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 posicin (x,y) con
factores de escala, color de teido y factor de transparencia.

draw_background_general(back,left,top,width,height,x,y,xscale,yscale,r ot,c1,c2,c3,c4,alpha) La funcin ms general para dibujar fondos. Dibuja la parte indicada del fondo
situando su esquina superior-izquierda en la posicin (x,y) con factores de escala, ngulo de rotacin, un color de teido para cada una de las cuatro esquinas (en el orden arriba-izquierda, arriba-derecha, abajo-derecha y abajoizquierda) 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 coleccin de funciones para dibujar diferentes formas. Tambin hay otras funciones para dibujar texto (consulta el captulo siguiente). Estas funciones de dibujo slo 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 segn sus sprites y sus mscaras de colisin y no segn lo que cada instancia dibuja en la pantalla. Las funciones siguientes sirven para dibujar las formas bsicas:

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 lnea desde (x1,y1) hasta (x2,y2). draw_rectangle(x1,y1,x2,y2,outline) Dibuja un rectngulo. outline indica si slo debe
dibujarse el borde (true) o si el rectngulo debe estar relleno (false).

draw_roundrect(x1,y1,x2,y2,outline) Dibuja un rectngulo redondeado. outline indica si slo


debe dibujarse el borde (true) o si el rectngulo debe estar relleno (false).

draw_triangle(x1,y1,x2,y2,x3,y3,outline) Dibuja un tringulo. outline indica si slo debe


dibujarse el borde (true) o si debe estar relleno (false).

draw_circle(x,y,r,outline) Dibuja un crculo con su centro en (x,y) y radio r. outline indica si


slo debe dibujarse el borde (true) o si debe estar relleno (false).

draw_ellipse(x1,y1,x2,y2,outline) Dibuja una elipse. outline indica si slo 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 tamao
de la flecha en pxeles.

draw_button(x1,y1,x2,y2,up) Dibuja un botn. up indica si est pulsado (0) o no (1). draw_path(path,x,y,absolute) Con esta funcin puedes dibujar el path indicado en el cuarto con su
comienzo en la posicin (x,y). Si valores de x e y son ignorados.

absolute es true el path se dibuja en la posicin en la que fue definido y los

draw_healthbar(x1,y1,x2,y2,amount,backcol,mincol,maxcol,direction,show back,showborder) Con esta funcin puedes dibujar una barra de vida (o una barra que indique cualquier otra
cosa como poder, magia,). Los parmetros x1, y1, x2 e y2 indican el rea total de la barra. porcentaje de la barra que debe estar relleno (debe estar entre 0 y 100).

amount indica el

backcol es el color de fondo de la barra.

mincol

maxcol indican el color cuando el porcentaje de llenado (parmetro amount) es 0 y 100

respectivamente. Para un porcentaje intermedio el color se interpola entre estos dos. As puedes crear fcilmente una barra que vaya de verde a rojo, por ejemplo.

direction es la direccin en la que la barra se dibuja: 0 significa que showback indica si debe mostrarse

la barra est fijada a la izquierda, 1 a la derecha, 2 arriba y 3 abajo. Finalmente, una caja de fondo y

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 en 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:

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, tambin 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, saturacin 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 saturacin 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 parmetro

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.

Tambin puedes utilizar las siguientes funciones miscelneas:

draw_getpixel(x,y) Devuelve el color del pxel en la posicin (x,y) del cuarto. Esta funcin no es muy rpida,
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 modificacin de recursos). Para dibujar texto disponemos de varias funciones distintas. En todas ellas debes indicar el texto a ser dibujado y la posicin del mismo. Adems, existen dos funciones para definir la alineacin del texto en horizontal y vertical respecto a esa posicin.

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 alineacin horizontal del texto. Debes indicar uno de los siguientes
valores:

fa_left

izquierda centrada derecha

fa_center fa_right

draw_set_valign(valign) Indica la alineacin vertical del texto. Debes indicar uno de los siguientes
valores:

fa_top

arriba centrada abajo

fa_middle fa_bottom

draw_text(x,y,string) Dibuja el texto indicado en la posicin (x,y) usando el color y el factor de


transparencia de dibujo generales. Los smbolo #, chr(13) o chr(10) (tecla ENTER o de salto de lnea) son interpretados como caracteres de salto de lnea. De esta forma puedes dibujar textos de varias lneas (Usa \# para dibujar el smbolo #).

draw_text_ext(x,y,string,sep,w) Similar a la funcin anterior pero ahora puedes especificar 2 cosas


ms. Primero de todo,

sep indica la distancia de separacin entre las lneas del texto si es que tiene varias lneas. Usa w indica la anchura del texto en pxeles. Las lneas ms largas que

-1 para obtener la distancia por defecto. Por ltimo,

esta distancia se dividen en nuevas lneas cuando encuentren un espacio en el texto o el smbolo -. Utiliza el valor -1 si no quieres que el texto se divida automticamente en varias lneas.

string_width(string) Anchura que el texto indicado ocupara si se dibujara con la fuente actual usando la

funcin

draw_text(). Puedes usar esta funcin para posicionar los grficos con precisin.

string_height(string) Altura que el texto indicado ocupara si se dibujara con la fuente actual usando la
funcin

draw_text(). Puedes usar esta funcin para posicionar los grficos con precisin.

string_width_ext(string,sep,w) Anchura que el texto indicado ocupara si se dibujara con la fuente


actual usando la funcin

draw_text_ext(). Puedes usar esta funcin para posicionar los grficos con precisin.

string_height_ext(string,sep,w) Altura que el texto indicado ocupara si se dibujara con la fuente


actual usando la funcin

draw_text_ext(). Puedes usar esta funcin para posicionar los grficos con precisin.

Las siguientes funciones te permiten dibujar texto escalado o rotado e incluso aplicarle gradientes de color. Estas funciones slo estn disponibles en la versin registrada de Game Maker!

draw_text_transformed(x,y,string,xscale,yscale,angle) Dibuja el texto indicado en la


posicin (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

multilneas 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 transparencia

alpha (0-1).

draw_text_ext_color(x,y,string,sep,w,c1,c2,c3,c4,alpha) Similar a draw_text_ext() pero con vrtices coloreados. draw_text_transformed_color(x,y,string,xscale,yscale,angle,c1,c2,c3,c4 ,alpha) Similar a draw_text_transformed()pero con vrtices coloreados. draw_text_ext_transformed_color(x,y,string,sep,w,xscale,yscale,angle,c 1,c2,c3,c4,alpha) Similar a draw_text_ext_transformed()pero con vrtices coloreados.

Funciones avanzadas de dibujo Esta funcionalidad slo est disponible en la versin registrada de Game Maker

En los captulos anteriores hemos descrito las funciones bsicas de dibujo. En este captulo veremos funciones ms avanzadas que te otorgan muchas ms posibilidades para crear los grficos de tus juegos. Primero, hay unas funciones que sirven para dibujar formas coloreadas con gradientes o efectos de difuminado. Despus veremos las funciones que sirven para dibujar polgonos bsicos y por ltimo veremos la forma de dibujar polgonos texturizados.

Las siguientes funciones son versiones extendidas de las funciones de dibujo bsicas. Todas ellas admiten parmetros 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 posicin (x,y) con el color indicado. draw_line_color(x1,y1,x2,y2,col1,col2) Dibuja una lnea 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
rectngulo. Los cuatro colores indican los colores de los vrtices superior-izquierdo, superior-derecho, inferior-derecho e inferior-izquierdo respectivamente. ste debe estar relleno (false).

outline indica si slo debe dibujarse el contorno del rectngulo (true) o si

draw_roundrect_color(x1,y1,x2,y2,col1,col2,outline) Dibuja un rectngulo


redondeado.

col1 es el color en el centro del rectngulo y col2 en el borde. outline indica si slo debe

dibujarse el contorno del rectngulo (true) o si ste debe estar relleno (false).

draw_triangle_color(x1,y1,x2,y2,x3,y3,col1,col2,col3,outline) Dibuja un
tringulo. Los tres colores son los colores en los vrtices del tringulo (el color se interpola en las dems zonas entre estos tres colores). (false).

outline indica si slo debe dibujarse el contorno del tringulo (true) o si ste debe estar relleno

draw_circle_color(x,y,r,col1,col2,outline) Dibuja un crculo en (x,y) con radio r. col1


es el color en el centro y

col2 en el borde. outline indica si slo debe dibujarse el contorno del crculo (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 slo debe dibujarse el contorno de la elipse (true) o si ste

debe estar rellena (false).

Dibujando superficies

Esta funcionalidad slo est disponible en la versin registrada de Game Maker

En algunas situaciones puede que no quieras dibujar directamente en la pantalla sino en un lienzo que ms 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 funcionara, 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. Tambin podras querer usar una textura que cambie con el tiempo, crear un efecto de transiciones entre cuartos, efectos de iluminacin

Las superficies hacen posibles cosas como stas. Las superficies son muy sencillas de usar: primero creas una superficie indicando su tamao. Luego indicas que vas a dibujar sobre la superficie. Desde este momento, todas las funciones de dibujo se aplicarn a la superficie. Cuando termines de dibujar, indicas que ya no vas a dibujar ms en la superficie. Ya tienes lista la superficie, ahora puedes dibujarla directamente en la pantalla, usarla como texturaConsulta el final del captulo 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 funcin devuelve la id de la
superficie que debe ser usada en las dems 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 funcin 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 informacin 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 actuarn sobre la superficie. Simplemente resetea la proyeccin para que cubra slo 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 funcionarn normalmente No olvides llamar a esta funcin cuando termines de dibujar sobre la superficie!

Las funciones siguientes nos permiten manejar las superficies:

surface_getpixel(id,x,y) Devuelve el color del pxel en la posicin (x,y) de la superficie. Esta funcin no
es muy rpida as que sala con moderacin.

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 funcin anterior, pero esta vez slo 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 posicin (x,y). draw_surface_stretched(id,x,y,w,h) Dibuja la superficie en la posicin (x,y) y escalada de forma
que tenga la anchura y altura indicadas.

draw_surface_tiled(id,x,y) Dibuja la superficie en la posicin (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 posicin (x,y).

draw_surface_ext(id,x,y,xscale,yscale,rot,color,alpha) Dibuja la superficie en la


posicin (x,y), con factores de escala, rotacin, transparencia y tiindola con el color indicado (utiliza c_white si no quieres teir la superficie).

draw_surface_stretched_ext(id,x,y,w,h,color,alpha) Dibuja la superficie en la posicin


(x,y) escalada para que ocupe la regin indicada con factor de transparencia y tiindola del color especificado.

draw_surface_tiled_ext(id,x,y,xscale,yscale,color,alpha) Dibuja la superficie


repitindola para que ocupe todo el cuarto pero con factores de escala, transparencia y tiindola 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 posicin (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,alpha) La funcin ms general de dibujo. Dibuja la parte indicada de la superficie con su origen en
la posicin (x,y), con factores de escala, transparencia y rotada

rot grados en sentido antihorario. Adems 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 posicin (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 posicin (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.

Tambin puedes crear sprites y fondos de superficies. Esto se explica con ms detalle en la seccin de modificacin de recursos.

Al usar superficies debes tener algunas cosas en cuenta:

Nunca debes cambiar el objetivo de dibujo mientras dibujas ests 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 proyeccin.

Las superficies no funcionan correctamente en modo 3D. Puedes usarlas mientras no ests en modo 3D (llamando a la funcin d3d_end() antes de usarlas) pero una vez que empieces a usar el modo 3D de nuevo las superficies se destruirn automticamente.

Por motivos de velocidad, las superficies se mantienen en la memoria de video constantemente. Como resultado de esto, podras perder las superficies al cambiar la resolucin de la pantalla o cuando salte el salvapantallas.

Las superficies no se guardarn al guardar un juego.

Tiles Como ya debes saber, puedes aadir 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 ms rpido 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 grficos 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 rectngulo. La parte del fondo que queda dentro de este rectngulo pasa a ser una tile.

Puedes aadir tiles al disear el room, pero tambin puedes hacerlo mientras el juego se ejecuta. Puedes cambiar su posicin, 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. Posicin 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 tamao normal es 1). blend. Color de teido 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 informacin. Pero tambin existen funciones para conocer la id de una tile en una posicin particular.

Las funciones siguientes sirven para manejar tiles:

tile_add(background,left,top,width,height,x,y,depth) Aade una nueva tile al cuarto


con las propiedades indicadas. Esta funcin devuelve la id de la nueva tile que se puede usar ms 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 informacin sobre las tiles:

tile_get_x(id) Devuelve la posicin x de la tile con la id especificada. tile_get_y(id) Devuelve la posicin 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 teido 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 posicin x,y. tile_set_region(id,left,top,width,height) Cambia la regin 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 teido de la tile con la id especificada. Slo disponible en
la versin 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 funcin se puede usar para capas de tiles mviles.

tile_layer_find(depth,x,y) Devuelve la id de la tile con la profundidad indicada que se encuentra en la


posicin (x,y). Si no se encuentra ninguna tile la funcin devuelve -1. Cuando se encuentran varias tiles en esa posicin 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


posicin (x,y). Si se encentran varias tiles en esa posicin 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 funcin puedes mover capas enteras de tiles a otra profundidad.

El display El display es todo el rea del monitor. Tiene varias caractersticas como el tamao (tpicamente 1024x768 1280x1024), la profundidad de color (que es el nmero de bits que se utilizan para representar 1 pxel) y suele ser de 16 bits (color de alta densidad) 32 bits (color verdadero) y la frecuencia de refresco, que es el nmero de veces por segundo que se refresca el display, es decir, cuntas veces por segundo se vuelven a dibujar los pxeles en la pantalla (tpicamente entre 60 y 120). Estos parmetros 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 pestaa Game Settings. Para cambiar estos parmetros durante el juego Game Maker dispone de un grupo de funciones que veremos a continuacin. Debes tener en cuenta que al cambiar estos parmetros el sistema necesitar un poco de tiempo para volver a ajustarlo todo. Las funciones para cambiar el modo slo estn disponibles en la versin registrada de Game Maker.

display_get_width() Devuelve la anchura del display en pxeles. display_get_height()Devuelve la altura del display en pxeles. 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 funcin
devuelve true si los cambios se aplicaron con xito y false en caso contrario (Debes tener en cuenta que slo algunas combinaciones estn permitidas, por ejemplo 800x600, 1024x768 1280x1024).

display_set_colordepth(coldepth) Cambia la profundidad de color a la especificada. En general slo


se permite usar profundidad de color de 16 32 bits. La funcin 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.


Slo unas pocas frecuencias estn 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 funcin 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 funcin 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 estn

permitidos. La funcin no aplica los valores al display, slo chequea si son vlidos. Para los valores que no quieras cambiar usa el valor -1. La funcin devuelve true si los cambios se pueden aplicar y false en caso contrario.

display_reset() Resetea las caractersticas del display a los originales, es decir, a los que estaban presentes
cuando se inici el programa.

A veces es til poder conocer la posicin 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 posicin 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 opcin Game Settings. Pero tambin 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 dems. window_set_sizeable(sizeable) Indica si el jugador puede cambiar el tamao de la ventana. El
jugador slo 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 tamao de la ventana. window_set_caption(caption) Indica el ttulo de la ventana. Normalmente esto se especifica al definir el
room y se cambia usando la variable room_caption. Por ello, esta funcin no es til a no ser que dibujes t mismo el room en lugar de dejar que Game Maker lo haga automticamente. El ttulo de la ventana slo es visible cuando sta tiene borde visible y no est a pantalla completa.

window_get_caption() Devuelve el ttulo 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 funcin 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 mximo valor dentro de la ventana que le permita seguir conservando su relacin de aspecto entre altura y anchura. El segundo parmetro, adaptwindow, indica si el tamao de la ventana debe adaptarse al cuarto si ste, una vez escalado, no entra por completo dentro de la misma. Esto slo suele ser til cuando el primer parmetro (el que indica el escalado del cuarto) es positivo.

window_get_region_scale() Devuelve el factor de escala de la regin de dibujo.

La ventana tiene una posicin en la pantalla y un tamao. Cuando hablamos de posicin y tamao siempre nos referimos a la ventana sin los bordes. Puedes cambiar estos valores aunque raramente querrs utilizarlo desde el juego. Normalmente, se determinan automticamente o el jugador escoge los que le interesan. Las funciones siguientes te permiten cambiar estos aspectos de las ventanas. Observa que estas funciones slo funcionarn si la ventana no est a pantalla completa. Si la ventana est a pantalla completa los cambios no se aplicarn hasta que la ventana vuelva al modo normal.

window_set_position(x,y) Indica la posicin de la ventana. window_set_size(w,h) Indica el nuevo tamao de la ventana. Observa que si el tamao indicado es menor
que la regin de dibujo se mantendr lo suficientemente grande como para que la regin entre por completo dentro de l.

window_set_rectangle(x,y,w,h) Indica la nueva posicin 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 tamao y posicin (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 automticamente.

En algunas ocasiones puede que quieras conocer la posicin del ratn respecto a la ventana (normalmente se usa la posicin del ratn 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 posicin del puntero en la ventana.

Vistas

Como ya deberas saber puedes definir hasta 8 vistas diferentes al disear un cuarto. Una vista se define por su rea en el cuarto y por su puerto o viewport en la pantalla (la regin de dibujo dentro de la ventana). Usando vistas puedes mostrar diferentes partes del cuarto en diferentes lugares de la pantalla. Adems, puedes asegurar que un objeto concreto siempre permanezca visible en una vista.

Puedes controlar las vistas con cdigo. Puedes hacerlas visibles o invisibles, cambiar su posicin o tamao dentro de la regin de dibujo o en el cuarto (lo cual es muy til cuando no indicas ningn objeto que deba ser seguido por la vista). Puedes cambiar el tamao 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 ms poderoso) puede que las vistas siguientes no lo sigan correctamente. Para solucionar esto, puedes indicar este cdigo en el evento de creacin 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 actan 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 estn activadas en el cuarto actual. view_current* La vista que actualmente se est dibujando (0...7). Usa esta variable slo en el evento draw. Por
ejemplo, puedes chequear el valor de esta variable para dibujar algo slo 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] Posicin X de la vista en el cuarto. view_yview[0..7] Posicin 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] Posicin X del puerto en la regin de dibujo. view_yport[0..7] Posicin Y del puerto en la regin de dibujo. view_wport[0..7] Anchura del puerto en la regin de dibujo. view_hport[0..7] Altura del puerto en la regin de dibujo. view_angle[0..7] ngulo de rotacin usado para la vista en el cuarto (grados en sentido antihorario). view_hborder[0..7] Tamao en pxeles del borde horizontal alrededor del objeto a seguir por la vista. view_vborder[0..7] Tamao en pxeles del borde vertical alrededor del objeto a seguir por la vista. view_hspeed[0..7] Velocidad horizontal mxima de la vista. view_vspeed[0..7] Velocidad vertical mxima 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 tamao 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 tamao de la pantalla con las siguientes funciones:

window_set_region_size(w,h,adaptwindow) Indica la anchura y altura de la regin de dibujo en


la ventana. adaptwindow indica si el tamao de la ventana debe adaptarse si la regin de dibujo no cabe dentro de ella. La ventana siempre se adaptar si usas escalado fijo (Consulta la funcin window_set_region_scale() en el captulo La ventana).

window_get_region_width() Devuelve la anchura actual de la regin de dibujo. window_get_region_height()Devuelve la altura actual de la regin de dibujo.

A veces necesitars conocer la posicin del ratn. Normalmente puedes hacer esto con las variables mouse_x y mouse_y. Cuando hay muchas vistas, estas variables dan la posicin del ratn respecto a la vista en la que el ratn se encuentra. Pero puede ser que en alguna ocasin necesites conocer la posicin del ratn respecto a una vista concreta, incluso cuando el ratn 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 ratn respecto a la vista indicada. window_view_mouse_get_y(id) Devuelve la coordenada y del ratn respecto a la vista indicada. window_view_mouse_set(id,x,y) Indica la posicin del ratn respecto a la vista indicada. window_views_mouse_get_x()Devuelve la coordenada x del ratn 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 ratn respecto a la vista en la que se

encuentra (es lo mismo que mouse_y).

window_views_mouse_set(x,y) Indica la posicin del ratn respecto a la primera vista que es visible.

Transiciones Al moverse de una room a otra puedes seleccionar una transicin. Tambin puedes seleccionar la transicin que se utilizar en el frame siguiente sin tener que cambiar de cuarto. Para esto usamos la variable transition_kind. Asignndole un valor entre 1 y 13 se usar la transicin correspondiente. Si usamos un valor igual a 0 significa que no se aplicar ninguna transicin. La transicin slo se aplicar la prxima vez que se dibuje un frame.

transition_kind Indica la transicin al prximo frame:


0 = sin transicin 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 rectngulo negro que tape toda la pantalla y hacer que su factor de transparencia vaya aumentando poco a poco. O puedes cambiar la posicin y el tamao de una vista para mover el cuarto fuera de la zona visible. Utilizando superficies y partculas 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 perodo 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 operacin. 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 funcin es necesario ver cmo trabaja internamente el mecanismo de dibujo. Internamente existe una imagen donde se dibuja todo. Esta imagen no es visible en la pantalla. Slo al final de un paso del juego, cuando se ha dibujado todo, la imagen de la pantalla se reemplaza por esta imagen interna (esta tcnica se conoce como double buffering). La primera funcin scrren_redraw() dibuja la imagen interna y luego refresca la imagen de la pantalla. La segunda funcin screen_refresh() slo refresca la imagen de la pantalla, pero no actualiza la imagen interna.

Ahora deberas 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, dibujaras 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 habas dibujado en la imagen interna. Pero cuando usas screen_refresh() despus de dibujar algo, la imagen se volver visible en la pantalla. Por ejemplo, podemos crear un trozo de cdigo que dibuje un texto en la pantalla, llame a la funcin 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 slo puedes dibujar en la imagen interna, nunca en una vista! As que las coordenadas que usas sern las mismas que si no hubiera vistas. Ten cuidado al usar esta tcnica: asegrate de que has entendido bien como funciona y ten en cuenta que el refresco de la pantalla tarda un poco de tiempo.

Cuando ests dibujando el propio cuarto puede ser til no dejar que se dibuje automticamente. Por ejemplo, puedes querer que el cuarto slo se dibuje cada 5 pasos. Para ello puedes usar la funcin siguiente:

set_automatic_draw(value) Indica si el cuarto se debe dibujar automticamente (true por defecto) o no


(false).

Finalmente, hay una funcin 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.

Tambin puedes obligar a que el programa espere hasta la prxima sincronizacin vertical:

screen_wait_vsync() Espera hasta la siguiente sincronizacin vertical del monitor.

Msica 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 asegrate de que los nombres que uses sean nombres de variable vlidos. Como ya habrs ledo, puedes indicar cuatro diferentes tipos de sonido: normal, msica de fondo, 3D, y sonidos que deben ser reproducidos a travs 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 mltiples instancias del mismo sonido a la vez) y se caracterizan por podrseles aplicar cualquier tipo de efectos en ellas.

El sonido de fondo comnmente consiste en archivos MIDI pero algunas veces tambin pueden usarse WAV y a estos tambin 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 haba estado reproduciendo es parado.

El uso y caractersticas del sonido 3D son descritos ms adelante, en el subcaptulo Sonidos 3D. Son sonidos mono (WAV o MIDI). Finalmente, si quieres usar otro tipo de sonido, en partculas 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 ms 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). Tambin puede haber retardos en reproducirlos. Se recomienda altamente no usar este tipo de media, ya que hay algunas computadoras que probablemente no estn capacitadas para reproducirlos).

Puedes encontrar informacin sobre las funciones de audio en las secciones siguientes: Funciones bsicas de sonido Existen cinco funciones bsicas relacionadas con sonido: 2 para reproducir un sonido, una para ver si un sonido se est reproduciendo, y dos ms para parar el sonido. La mayora necesita el ndice del sonido como argumento. El nombre del sonido representa su ndice, pero tambin puedes almacenar el ndice en una variable, y usarla como argumento.

sound_play(index) Reproduce el sonido indicado una vez. Si el sonido es msica de fondo, la actual es
parada.

sound_loop(index) Reproduce el sonido indicado, rebobinndolo continuamente. Si el sonido es msica de


fondo, la actual es parada.

sound_stop(index) Para el sonido indicado. Si hay varios sonidos con este ndice reproducindose

simultneamente, todos son parados.

sound_stop_all() Para todos los sonidos. sound_isplaying(index) Devuelve si (una copia de) el sonido indicado se esta reproduciendo. Ntese que
esta funcin devuelve true cuando el sonido realmente esta reproducindose a travs de los altavoces (lnea de salida). Despus de llamar la funcin de reproducir un sonido, no llega a los altavoces inmediatamente, lo que quiere decir que mientras esto no suceda, esta funcin devolver false. Parecido es si cuando el sonido es parado y lo escuchas por un tiempo ms (p.e. por el eco), la funcin 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 travs 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 msica 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 ms rpido, menores a un tempo ms lento. Debe oscilar entre 0.01 y 100.

A dems de los archivos MIDI y WAV (y mp3) existe un cuarto tipo de archivo que puede ser reproducido: archivos direct music. Tienen la extensin .sgt. Dichos archivos frecuentemente se refieren a otros archivos describiendo p.e. banda o gnero. Para encontrar estos archivos, el sistema de sonido debe saber donde se localizan. Con este propsito, puedes usar las siguientes funciones para estableces el directorio de bsqueda de archivos. NOTA: Debes agregar los archivos tu mismo. Game Maker no incluye automticamente 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 versin registrada de Game Maker.

Los efectos de sonido pueden ser usados para cambiar la manera en que los sonidos normales y msica de fondo, suena. Ten en cuenta que los efectos de sonidos solo aplican en archivos WAV y MIDI, no a los mp3. Esta seccin describe las funciones que existen para usar y cambiar efectos de sonido. Ten tambin en cuenta que para poder usar

estas funciones necesitas una buena comprensin de cmo el sonido y los sintetizadores trabajan. No se han agregado explicaciones de los diferentes parmetros que se dan. Busca en la web o en libros para ms informacin.

Para aplicar un efecto de sonido a un sonido en particular, puedes indicarlo cuando definas el sonido como recurso o puedes usar la siguiente funcin:

sound_effect_set(snd,effect) Establece una (combinacin 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 combinacin de efectos, sumando los valores. Entonces, por ejemplo, puedes usar:

sound_effect_set(snd,se_echo+se_reverb);
para obtener una combinacin 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 despus estableces sus parmetros. Una vez que reapliques los efectos al sonido, la configuracin se borra y necesitas establecerla de nuevo. Ntese que todos los parmetros deben oscilar en un rango en particular, segn se indique a continuacin. Las siguientes funciones existen para cambiar la configuracin de los efectos de sonido: *Al final de cada parmetro, entre parntesis 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,pha se) Establece los parmetros para el efecto de chorus al sonido indicado. Los siguientes parmetros son requeridos:
WETDRY Radio de la seal wet (procesada) a la seal 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 seal 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 (nmero) 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 parmetros para el efecto de echo al sonido indicado. Los siguientes parmetros son requeridos: WETDRY Radio de la seal wet (procesada) a la seal dry (no procesada).(0 a 100,pred.50) FEEDBACK .Porcentaje de seal 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,ph ase) Establece los parmetros para el efecto de flanger al sonido indicado. Los siguientes parmetros son requeridos:
WETDRY Radio de la seal wet (procesada) a la seal 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 seal 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 (nmero) 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 parmetros para el efecto de gargle al sonido


indicado. Los siguientes parmetros son requeridos:

RATE Variable de modulacin,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 parmetros para el efecto de


reverb al sonido indicado. Los siguientes parmetros son requeridos:

GAIN Seal ganada por la entrada, en decibels (dB) (-96 a 0,pred.0) MIX Mezcla de la repeticin, en dB. (-96 a 0,pred.0) TIME Tiempo de la repeticin, 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 parmetros para el efecto de compressor al sonido indicado. Los siguientes parmetros son requeridos:

GAIN Seal de salida ganada despus de la compresin (-60 a 60, pred.0)


ATTACK Tiempo antes de que la compresin termine (0.01 a 500,0.01) RELEASE Velocidad a la que la entrada es parada despus 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 (nmero) 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 parmetros para el


efecto de equalizer al sonido indicado. Los siguientes parmetros 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 versin registrada de Game Maker.

Sonido 3D se refiera al sonido que tiene una posicin (y velocidad) con respecto al oyente. A pesar de que es ms prominente usarlo en juegos 3D, tambin puede ser efectivamente aplicado en juegos 2D. La idea es que el sonido tenga una posicin en el espacio. En todas las funciones, se asume que el oyente est en una posicin (0,0,0). El sistema calcula como el receptor estara 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 tambin funciona en altavoces pequeos.

Adems de una posicin, el sonido tambin puede tener una velocidad. Esto lleva al muy conocido efecto Doppler, que estn correctamente modelado. Finalmente el sonido puede tener una orientacin y, una vez ms, el sonido es adaptado por consiguiente. Game Maker cuenta con la modalidad de sonido 3D, a travs 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 estreo).

sound_3d_set_sound_position(snd,x,y,z)

Establece la posicin al sonido indicado con respecto

a la posicin 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 or 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 posicin cambie. La velocidad es usada slo para calcular efectos doppler. Entonces, si quieres mover un sonido debes cambiar tu mismo la posicin del sonido.

sound_3d_set_sound_distance(snd,mindist,maxdist)

Establece la distancia mnima a la

cual el sonido est en su mxima amplitud, y la distancia mxima a la cual el sonido ya no se debe oir. Entonces, cuando la distancia oscila entre 0 y la mxima distancia, el sonido esta en su mxima amplitud. Cuando se oscile entre la distancia mnima y la mxima, la amplitud decrece lentamente hasta que la distancia mxima es alcanzada, o el sonido ya no es audible. Por predeterminado (default), la distancia mnima es 1 metro y la mxima 1 billn 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 direccin 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 nmero negativo que indica el nmero de cientos de decibeles que deben ser sustrados del volumen interior. Entre el ngulo interior y exterior, el volumen decrece gradualmente.

Msica desde el CD Esta funcionalidad esta disponible nicamente en la versin registrada de Game Maker.

Existen tambin funciones para tratar con la reproduccin de msica 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 nmero 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 posicin actual en el CD en milisegundos. cd_track_position().Devuelve la posicin 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 reproduccin. cd_resume().Continua la reproduccin. cd_set_position(pos). Establece la posicin en el CD, en milisegundos. cd_set_track_position(pos). Establece la posicin 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 funcin general para acceder la funcionalidad multimedia de Windows:

MCI_command(str) Esta funcin enva 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 funcin

para controlar cualquier tipo de hardware multimedia. Para ms informacin sobre este comando, consulta la ayuda de Windows. Por ejemplo,

MCI_command('play cdaudio from 1') pone a sonar el cd (despus de

inicializalo correctamente). Esta funcin es slo para uso avanzado.

Ventanas, highscores, y otros pop-ups


En esta seccin vamos a aprender algunas funciones que pueden ser usadas para mostrar ventanas con videos, imgenes, etc...para mostrar mensajes y preguntas al jugador, y mostrar la tabla de mayores puntajes. Esta seccin est dividida en los temas: Ventanas Muchos juegos tienen ventanas, las cuales pueden mostrar un video, una imagen o algn texto. Frecuentemente son usadas al principio del juego (como intro), al principio de un nivel, o al final del juego (p.e. los crditos). En Game Maker, dichas ventanas con texto, imgenes 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. Tambin, cuando crees una versin independiente del juego (stand-alone), 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 informacin del juego. load_info(fname) Carga la informacin del juego con el nombre de archive FNAME, el cual debera 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 dilogo en el cual el jugador puede insertar un nmero, 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 dilogo con el string STR como
mensaje, ms un mximo de 3 botones. But1,but2 y but3 contienen el texto de cada botn. Un string vaco significa

que el botn no se mostrar. En los textos puedes usar el smbolo & para indicar que el siguiente carcter debe ser usado como acceso directo a ese botn (p.e. &Acepto, si se presiona A se simula la presin del botn). Esta funcin devuelve el nmero del botn 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 nmero al jugador por medio de un cuadro de dilogo. STR es el


mensaje, DEF es el nmero predeterminado que se mostrar.

get_string(str,def) Pregunta un string al jugador en un cuadro de dilogo. STR es el mensaje, DEF es el


valor predeterminado.

message_background(back) Establece la imagen de fondo par a los cuadros de dilogo para cualquiera de
las funciones arriba. BACK debe ser uno de los archivos definidos en el juego. Si BACK es parcialmente transparente, tambin lo ser el cuadro de dilogo (solo para Windows 2000 o superior).

message_alpha(alpha) Establece la traslucidez de los cuadros de dilogo para cualquiera de las funciones
anteriores. ALPHA debe oscilar entre 0 (completamente traslcido) y 1 (completamente opaco) (solo para WIN2000 o superior).

message_button(spr) Establece el sprite usado para los botones en los cuadros de dilogo. SPR debe ser un
sprite consistiendo de 3 imgenes, la primera indica el botn cuando no esta presionado y el mouse est alejado, el Segundo indica el botn cuando el mouse est sobre el pero no presionado, y el tercero cuando del botn es presionado.

message_text_font(name,size,color,style) Establece la fuente para el texto de los cuadros de


dilogo (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 dilogo. 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 dilogo. 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 dilogo
cuando el mouse est sobre ellos.

message_input_color(col) Establece el color para el fondo del campo de entrada en los cuadros de
dilogo.

message_caption(show,str) Establece el ttulo del cuadro de dilogo. SHOW indica si


el borde (1) o no (0) y STR indica el ttulo cuando el borde si es mostrado.

se debera mostrar

message_position(x,y) Establece la posicin para los cuadros de dilogo en la pantalla. message_size(w,h) Arregla el tamao de los cuadros de dilogo 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 basndose en el nmero de lneas 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

opcin es seleccionada, se devuelve un 0, para la segunda un 1, etc. Cuando ninguna opcin es seleccionada, el valor predeterminado def es devuelto.

show_menu_pos(x,y,str,def) Muestra un men popup, como en la funcin anterior, pero en la posicin


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|mscara1|nombre2|mscara2 . Una mscara 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 vaco es devuelto.

get_save_filename(filter,fname) Pide un archivo para guardarlo, con el filtro dado. Si el jugador


presiona Cancel, un string vaco es devuelto.

get_directory(dname) Pide un directorio. DNAME es el nombre predeterminado. Si el usuario presiona


Cancel, un string vaco es devuelto.

get_directory_alt(capt,root) Una forma alternativa de preguntar por un directorio. CAPT es el titulo


a mostrar. ROOT es la raz del diagrama del directorio a mostrar. Usa un string vaco para mostrar el diagrama completo. Si el usuario presiona Cancel, un string vaco es devuelto.

show_error(str,abort) Muestra un mensaje de error estndar (y/o escribe el error al archivo de registros).
ABORT indica si el juego debera cerrarse (true-abortar, false-ignorar).

Tablas de rcords

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 dems entradas. entradas.

highscore_set_strings(caption,nobody,escape) Cambia los diferentes strings


predeterminados usados al mostrar la tabla de highscores. CAPTION es el ttulo 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 (tambin 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 dems entradas. NAME es el nombre de la fuente a usar, y SIZE es el tamao 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. Tambin 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 captulo encontrars un nmero de opciones que actan sobre estos recursos, para modificarlos u obtener informacin de ellos en tiempo real. Los recursos se dividen en los siguientes tipos: Sprites Las funciones siguientes te dan informacin 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 nmero de subimgenes 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 lmite izquierdo del sprite (bounding box) con el ndice
especificado.

sprite_get_bbox_right(ind) Devuelve el valor del lmite derecho del sprite (bounding box) con el ndice
especificado.

sprite_get_bbox_top(ind) Devuelve el valor del lmite superior del sprite (bounding box) con el ndice
especificado.

sprite_get_bbox_bottom(ind) Devuelve el valor del lmite 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 colisin precisa (precise
collision checking).

Sonidos Las funciones siguientes te dan informacin 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 slo pueden guardar y hacer sonar un nmero limitado de ellos. Si haces un juego muy grande, deberas llevar un control sobre los sonidos que se cargan en la memoria de audio en cada momento. Podras desactivar la opcin Preload para asegurarte de que los sonidos no se carga hasta que van a ser usados (aunque este mtodo puede originar cierto retraso la primera vez que se escuche el sonido). Adems, 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 darn informacin 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 informacin 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 carcter de la fuente con el ndice especificado. font_get_last(ind) Devuelve el ltimo carcter de la fuente con el ndice especificado.

Paths Las funciones siguientes te proporcionarn informacin 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 precisin utilizado para paths redondeadas. path_get_number(ind) Devuelve el nmero 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 posicin pos del path (pos debe estar comprendida
entre 0 y 1).

path_get_y(ind,pos) Devuelve la coordenada y en la posicin pos del path (pos debe estar comprendida
entre 0 y 1).

path_get_speed(ind,pos) Devuelve la velocidad en la posicin pos del path (pos debe estar comprendida
entre 0 y 1).

Scripts Las siguientes opciones te darn informacin 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 informacin 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 proporcionarn informacin 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 slido 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 sealado es persistente. object_get_mask(ind) Devuelve el ndice de la mscara del objeto con el ndice dado (-1 si no tiene
mscara 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 darn informacin acerca de una habitacin:

room_exists(ind) Devuelve si el cuarto con el ndice sealado existe. room_get_name(ind) Devuelve el nombre de la habitacin con el ndice dado.

Observa que como las habitaciones cambian durante el juego hay otras rutinas para obtener informacin de la habitacin actual

Modificando los recursos


Estas funciones slo estn disponibles en la versin registrada de Game Maker. Es posible crear nuevos recursos durante el juego. Tambin se pueden cambiar recursos existentes. Las posibilidades se muestran en este captulo. Pero se debe tener cuidado: la modificacin de recursos fcilmente puede llevar a errores en los juegos!!! Al modificar recursos, se deben seguir las siguientes reglas: No cambies recursos que estn 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 ms tarde se carga el juego, los recursos modificados podran 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 ejecucin, los recursos modificados no son reestablecidos a su forma original. En general, cuando se manipulan recursos ya no se puede hacer uso de la accin o de la funcin para reiniciar el juego.

La manipulacin de recursos puede ser muy lenta. Por ejemplo, el cambiar sprites o fondos es relativamente lento. Por lo que no es cambiarlos durante la ejecucin del juego.

La creacin de recursos durante la ejecucin del juego (en particular los sprites y fondos) fcilmente 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 animacin y decides crear 36 copias rotadas estars usando 36x32x128x128x4 = 36 MB de memoria!

Se deben eliminar los recursos que ya no son utilizados. De otra forma pronto se ocupara 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 habitacin.

Las funciones para modificar recursos se dividen en las siguientes secciones: Sprites Las siguientes funciones permiten modificar las propiedades de los sprites:

sprite_set_offset(ind,xoff,yoff) sprite_set_bbox_mode(ind,mode)
automtica, 1 = imagen completa, 2 = manual).

Establece el offset del sprite.

Establece a mode el tipo de caja de colisin del sprite (0 =

sprite_set_bbox(ind,left,top,right,bottom)
ndice ind. Funciona solo cuando es manual el modo de caja de colisin.

Configura la caja de colisin del sprite con

sprite_set_precise(ind,mode)
(true o false).

Establece si el sprite con ndice ind usa chequeo de colisin precisa

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 algn 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 fcilmente 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, agregndolas al final de

este ultimo. Si los tamaos no corresponden los sprites son encogidos. No se elimina el sprite ind2!

sprite_add(fname,imgnumb,precise,transparent,smooth,preload,xorig,yori g)
Agrega a los recursos sprites la imagen del archivo fname. Solo se pueden agregar imgenes bmp, jpg y gif.

Cuando se trata de un bmp o jpg la imagen puede ser una tira que contenga las subimgenes del sprite una junto a la otra. Se usa

imgnumb

para indicar el nmero de subimgenes (1 para una sola). Este argumento no es empleado

con imgenes gif (animadas); se emplea el nmero de imgenes del archivo gif. de colisin precisa. los bordes.

precise

indica si se usar chequeo indica si se alisarn indican la

transparent

indica si la imagen es parcialmente transparente.

smooth

preload

indica si se precargar la imagen en la memoria de texturas.

xorig y yorig

posicin de origen en el sprite. La funcin devuelve el ndice del nuevo sprite. Si ocurre algn error devuelve -1.

sprite_replace(ind,fname,imgnumb,precise,transparent,smooth,preload,xo rig,yorig)
Lo mismo que la anterior pero en este caso se reemplaza al sprite con ndice ind. El valor devuelvo

por la funcin indica si tuvo xito la operacin.

sprite_create_from_screen(x,y,w,h,precise,transparent,smooth,preload,x orig,yorig)
Crea 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 an se puede hacer de manera que no sea visible si no se refresca la pantalla). Los dems parmetros son similares a los indicados en las anteriores funciones. La funcin 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 accin 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 funcin devuelve el ndice del nuevo sonido, que puede utilizarse para reproducirlo. (O devolver -1 si ocurriera algn 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 funcin indica si tuvo xito la operacin.

sound_delete(index)
recuperarlo

Elimina el sonido index, liberando toda la memoria asociada con l. Ya no es posible

Fondos Las siguientes rutinas pueden ser empleadas para crear nuevas imgenes 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 algn error se devuelve -1.

background_assign(ind,back)

Asigna el fondo back al fondo ind. Esto es, crea una copia del fondo. Agrega la imagen almacenada en el

background_add(fname,transparent,smooth,preload)

archivo fname al juego de recursos background. Solo se pueden manejar imgenes bmp y jpg. indica si la imagen es parcialmente transparente.

transparent
indica si se

smooth

indica si se alisarn los bordes.

preload

precargar la imagen en la memoria de texturas. La funcin 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 habitacin actual. Devuelve -1 cuando ocurre algn 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 funcin devuelve un valor indicando si tuvo xito la operacin. Cuando el fondo reemplazado es visible en la habitacin ser reemplazado.

background_create_color(w,h,col,preload)

Crea un nuevo fondo del tamao dado (w=ancho,

h=alto) con el color col. Devuelve el ndice del nuevo fondo, -1 si ocurre algn error.

background_create_gradient(w,h,col1,col2,kind,preload)

Crea un fondo del tamao

indicado (w=ancho, h=alto) coloreado con un gradiente. col1 y col2 indican los dos colores. kind es un nmero entre 0 y 5 que indica el tipo de gradiente: 0=horizontal, 1=vertical, 2=rectngulo, 3=elipse, 4=doble horizontal, 5=doble vertical. Esta funcin devuelve el ndice del nuevo fondo, -1 si ocurre algn 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 funcin permite crear cualquier fondo que se desee. Se dibuja la imagen en pantalla usando las funciones de dibujo y a continuacin 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 parmetros son similares a los de las anteriores funciones. La funcin devuelve el ndice del nuevo fondo. Se requiere algo de cuidado aqu. Aunque se habla de la pantalla, lo que importa es la regin 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 accin 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 despus del cambio).

font_add(name,size,bold,italic,first,last)

Agrega una nueva fuente y devuelve su ndice.

Se indica el tamao (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 carcter. first indica el ndice del primer carcter en el sprite. Por ejemplo, se puede usar ord('0') si el sprite solo contiene los dgitos. prop indica si la fuente es

proporcional. En una fuente proporcional, para cada carcter el ancho de la caja de colisin es utilizado como el ancho del mismo. Finalmente, sep indica la distancia que debe separar a los caracteres horizontalmente. Un valor tpico debiera estar entre 2 y 8 dependiendo del tamao de la fuente.

font_replace(ind,name,size,bold,italic,first,last)

Reemplaza la fuente ind con una

nueva fuente, indicando el nombre (name), tamao (size) si es negrita (bold) o cursive (italic) y el primer y ltimo carcter que deben crearse.

font_replace_sprite(ind,spr,first,prop,sep)
fuente basada en el sprite spr.

Reemplaza la fuente ind con una nueva

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)
(0=straight, 1=smooth).

Establece el tipo de conexiones de la trayectoria ind (0=recta, 1=suave)

path_set_closed(ind,closed)

Establece si la trayectoria ind debe ser cerrada (true) o abierta (false). Establece la precisin con la que se calcula la suavidad de la trayectoria

path_set_precision(ind,prec)
(prec debe estar entre 1 y 8).

path_add()

Agrega una nueva trayectoria vaca. Devuelve el ndice de la trayectoria. Elimina la trayectoria con ndice ind. Crea un duplicado de la trayectoria ind. Devuelve el ndice de la nueva trayectoria. Asigna la trayectoria path a la trayectoria ind. Por tanto, crea una copia de la

path_delete(ind)

path_duplicate(ind)

path_assign(ind,path)

trayectoria. De esta manera se puede fcilmente 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 posicin (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 reduccin 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 posicin (x,y) y con factor de velocidad speed.

path_change_point(ind,n,x,y,speed)
con factor de velocidad speed.

Cambia el punto n de la trayectoria ind a la posicin (x,y) y

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, volvindola una trayectoria vaca.

Invierte la trayectoria ind.

Voltea horizontalmente la trayectoria ind (con respecto a su centro).

Voltea verticalmente la trayectoria ind (con respecto a su centro). Rota angle grados la trayectoria ind en contra de las manecillas del reloj

path_rotate(ind,angle)
(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 ejecucin del juego. Los scripts son una parte de la lgica del juego. La modificacin de los mismos llevara a una autoreescritura de cdigo que muy fcilmente llevara a errores. Hay otras formas de hacer algo parecido. Si realmente se necesita ejecutar una pieza de cdigo no conocida en tiempo de diseo (p. ej. Desde un archivo) se pueden hacer uso de las siguientes funciones:

execute_string(str) execute_file(fname)

Ejecuta el fragmento de cdigo en la cadena str. Ejecuta el cdigo 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 funcin

script_execute(scr,arg0,arg1,...)

Ejecuta el script con ndice scr con los argumentos indicados.

Time lines Las siguientes rutinas permiten la creacin y modificacin de las time lines. No se deben alterar las lneas de tiempo que estn en uso!

timeline_add()

Agrega una nueva lnea de tiempo. Devuelve el ndice de la misma. Elimina la lnea de tiempo con ndice ind. Debe asegurarse que ninguna instancia

timeline_delete(ind)

emplee dicha lnea de tiempo en ninguna habitacin.

timeline_moment_add(ind,step,codestr)

Agrega una accin de cdigo a la lnea de tiempo en el

instante step. codestr contiene el cdigo para las acciones. Si el step no existe se crea. Por lo que pueden agregarse mltiples acciones de cdigo para el mismo instante.

timeline_moment_clear(ind,step)

Se puede utilizar esta funcin para borrar todas las acciones de

una lnea de tiempo (ind) en un instante (step) en particular

Objetos Tambin los objetos pueden ser manipulados y creados en tiempo de ejecucin. 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)
objeto el sprite actual.

Establece el sprite para el objeto con ndice ind. El valor -1 remueve del

object_set_solid(ind,solid)
slidas (true o false).

Establece si al crear instancias del objeto ind debern considerarse

object_set_visible(ind,vis)
defecto (true o false).

Establece si las instancias creadas del objeto ind deben ser visibles por

object_set_depth(ind,depth)

Establece la profundidad (depth) por defecto de las instancias creadas

del objeto ind.

object_set_persistent(ind,pers)
persistentes por defecto (true o false).

Establece si las instancias creadas del objeto deben ser

object_set_mask(ind,spr)

Establece el sprite para la mscara del objeto con ndice ind. Para que la

mscara 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 modificacin 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. Despus 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 cdigo. Se debe indicar el objeto (ind), el tipo de evento (evtype), el nmero de evento (evnumb, se pueden usar las constantes indicadas antes para la funcin event_perform()). Por ultimo se proporciona la cadena de cdigo que debe ejecutarse (codestr). Se pueden agregar mltiples acciones a cada evento.

object_event_clear(ind,evtype,evnumb)
acciones para un evento en particular.

Se puede emplear esta funcin para borrar todas las

La creacin de objetos es en particular muy til cuando se estn diseando scripts o bibliotecas de acciones. Por ejemplo, un script de inicializacin 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 estndar

Rooms La manipulacin de habitaciones en tiempo de ejecucin 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 habitacin en turno y hay muchas rutinas descritas en anteriores secciones para manipular las instancias, los fondos y los tiles en la habitacin actual. Pero los cambios en la habitacin active se mantendrn si dicha habitacin es persistente. Entonces, nunca se debieran manipular elementos de la habitacin en turno o de cualquier otra habitacin que sea persistente y que ya haya sido visitada antes. Tales cambios en general no sern percibidos pero en ocasiones podran ocasionar errores inesperados. Debido al hecho de que las habitaciones estn enlazadas de manera complicada no hay ninguna rutina que permita eliminar una habitacin.

Las siguientes funciones estn disponibles

room_set_width(ind,w)

Establece el ancho (w) para la habitacin con ndice ind. Establece la altura (h) para la habitacin con ndice ind. Establece el ttulo (caption) para la habitacin con ndice ind. Establece si la habitacin con ndice ind ser persistente o no (val).

room_set_height(ind,h)

room_set_caption(ind,str)

room_set_persistent(ind,val) room_set_code(ind,str)

Configura el cdigo de inicializacin (str) para la habitacin con ndice ind. Configura las propiedades de color para la habitacin

room_set_background_color(ind,col,show)

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,vs peed,alpha)
Establece el fondo con ndice bind (0-7) como fondo para la habitacin 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 posicin 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 = slido y ms rpido).

room_set_view(ind,vind,vis,xview,yview,wview,hview,xport,yport,wport,h port,hborder,vborder,hspeed,vspeed,obj)
Establece la vista con ndice vind (0-7) para la

habitacin con ndice ind. vis indica si la vista es visible. xview, yview, wview y hview indican la posicin de la vista en la habitacin. xport, yport, wport y hport indican la posicin en pantalla. Cuando la vista debe seguir a un objeto hborder y vborder indican el borde mnimo visible que debe mantenerse alrededor del objeto. hspeed y vspeed indican la mxima 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)
ndice ind.

Establece si las vistas deben habilitarse para la habitacin con

room_add()

Agrega una nueva habitacin. Devuelve el ndice de la misma. Se debe notar que la habitacin no

formar parte del orden de habitaciones. Por lo que la nueva habitacin no cuenta con habitaciones previa ni siguiente. Si se desea moverse a una habitacin agregada se debe indicar el ndice de la misma.

room_duplicate(ind)
habitacin.

Agrega una copia de la habitacin con ndice ind. Devuelve el ndice de la nueva

room_assign(ind,room)
habitacin.

Asigna la habitacin room al ndice ind. Por tanto, esta funcin crea una copia de la

room_instance_add(ind,x,y,obj)

Agrega a la habitacin ind una nueva instancia del objeto obj,

colocndola en la posicin x, y. Devuelve el ndice de la instancia.

room_instance_clear(ind)

Elimina todas las instancias dentro de la habitacin ind.

room_tile_add(ind,back,left,top,width,height,x,y,depth) Agrega un nuevo tile a la


habitacin en la posicin 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 posicin del tile en la habitacin 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 tambin 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 habitacin indicada.

Archivos, registro, y ejecucin de programas


En juegos ms avanzados probablemente querrs 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 tambin quieras guardar informacin 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 informacin sobre estos temas en las secciones siguientes: Archivos Es til utilizar archivos externos en juegos. Por ejemplo, podras hacer un archivo que describe qu ciertas cosas deben suceder en qu momento. Tambin puedes querer salvar la informacin para la prxima 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 funcin devuelve la id del archivo
que debes utilizar en el resto de funciones. Puedes abrir hasta un mximo de 32 archivos simultneamente. No olvides cerrar los archivos una vez que no los necesites.

file_text_open_write(fname) Abre el archivo fname para escritura, crendolo si no existe. La funcin


devuelve la id del archivo que debes usar en las dems funciones.

file_text_open_append(fname) Abre el archivo fname para agregar datos al final, crendolo si no


existe. La funcin devuelve la id del archivo que debes usar en las dems 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 carcter de nueva lnea en el archivo. file_text_read_string(fileid) Lee una cadena del archivo y devuelve esta cadena. Una cadena
termina al final de la lnea.

file_text_read_real(fileid)

Lee un valor real del archivo y devuelve este valor.

file_text_readln(fileid) Salta el resto de la lnea en el archivo e inicia al principio de la siguiente lnea. 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
mscara mask y los atributos attr. Si no existe tal archivo, devuelve una cadena vaca. La mscara 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 mscara). Puedes agregar las siguientes constantes para ver el tipo de archivos que desees:

fa_readonly archivos de slo 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 mscara y los atributos indicados
previamente. Si no existe tal archivo, devuelve una cadena vaca.

file_find_close() Debe ser llamada despus 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 combinacin 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 extensin pero sin la ruta. filename_path(fname) Devuelve la ruta al archivo indicado, incluyendo la ltima barra de separacin. filename_dir(fname) Devuelve el directorio del archivo, que normalmente suele ser igual que la ruta pero
sin la ltima barra de separacin.

filename_drive(fname) Devuelve la informacin de la unidad del archivo. filename_ext(fname) Devuelve la extensin del archivo, incluyendo el punto. filename_change_ext(fname,newext) Devuelve el nombre del archivo con la extensin sustituida por
newext. Si indicas una cadena de texto vaca para newext puedes eliminar la extensin 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 parmetro mod indica qu se


puede hacer con el archivo: 0=leer, 1=escribir y 2= leer y escribir. La funcin devuelve la id del archivo que debe utilizarse en las dems funciones. Puedes abrir hasta un mximo de 32 archivos simultneamente, 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
sita 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 tamao en bytes del archivo indicado. file_bin_position(fileid) Devuelve la posicin actual en el archivo en bytes (0 es el principio del
archivo).

file_bin_seek(fileid,pos) Mueve la posicin en el archivo a la posicin indicada por pos. Para aadir
contenido al final de un archivo, usa el valor file_bin_size(fileid) para el parmetro 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 slo puedes acceder a los archivos en la carpeta de la aplicacin p. Ej. para escribir en ellos.

Las siguientes tres variables de slo 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. Sern
eliminados cuando el juego finalice.

En ciertas situaciones podras dar al jugador la posibilidad de introducir argumentos mediante la lnea de comandos al juego que estn ejecutando (para por ejemplo activar trucos o modos especiales). Para obtener estos argumentos puedes usar las siguientes dos rutinas:

parameter_count() Devuelve el nmero de parmetros de la lnea de comandos (nota que el nombre del
programa es uno de ellos).

parameter_string(n) Devuelve los parmetros n de la lnea de comandos. El primer parmetro tiene ndice 0
y es el nombre del programa.

Por ltimo, puedes leer el valor de las variables de entorno con la siguiente funcin:

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 pequea cantidad de informacin entre cada ejecucin del juego hay un mecanismo ms 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 vaca).

registry_read_real(name) Devuelve el valor real almacenado en la entrada name. (El nombre debe
existir, de otra forma se devuelve el nmero 0).

registry_exists(name) Indica si la entrada name existe.

En realidad, los valores en el registro estn 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 informacin sobre el sistema en el que se est ejecutando el juego. Tambin puedes leer valores en otras claves. Puedes escribir valores en ellas pero ten mucho cuidado. PUEDES FCILMENTE DESTRUIR TU SISTEMA de esta forma. (La escritura no se permite en modo seguro). Nota que las claves tambin estn colocadas en grupos. Las siguientes rutinas trabajan por defecto con el grupo HKEY_CURRENT_USER. Pero si quieres puedes cambiar este grupo raz 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 vaca).

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 nmero 0).

registry_exists_ext(key,name) Indica si el nombre name existe dentro de la clave key. registry_set_root(root) Configura la raz 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 parmetros a un programa es corriente utilizar los archivos INI. Los archivos INI contienen secciones y cada seccin contiene un nmero 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 seccin 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 fciles 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 seccin indicada como section. Cuando no existe la llave o la seccin 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 seccin


indicada como section. Cuando no existe la llave o la seccin 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 seccin indicada con section.

ini_write_real(section,key,value) Escribe el valor real value en la llave indicada con key en la


seccin indicada con section.

ini_key_exists(section,key) Devuelve si la llave indicada existe en la seccin indicada. ini_section_exists(section) Devuelve si existe la seccin indicada. ini_key_delete(section,key) Elimina la llave indicada de la seccin indicada. ini_section_delete(section) Elimina la seccin indicada.

Ejecucin de programas

Game Maker tambin tiene la posibilidad de iniciar programas externos. Hay dos funciones disponibles para esto: execute_program y execute_shell. La funcin 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 funcin execute_shell abre un archivo. Puede ser cualquier archivo para cuyo tipo est definida una asociacin, p. Ej. un

archivo html, un archivo de Word, etc. O puede ser un programa. No puede esperar a que se termine la ejecucin por lo que el juego contina.

execute_program(prog,arg,wait) Ejecuta el programa prog con los argumentos arg. wait indica si se
debe esperar a que termine la aplicacin.

execute_shell(prog,arg) Ejecuta el programa (o archivo) en el entorno.

Ambas funciones no funcionarn 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 ejecutndose en modo seguro.

Estructuras de datos
Esta funcin slo est disponible en la versin registrada de Game Maker.

En los juegos normalmente necesitas guardar informacin. 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 ms complicadas, como ordenar los datos o buscar un tem determinado, necesitas escribir grandes trozos de cdigo en GML, que pueden ser lentos al ejecutarse.

Para remediar esto, Game Maker dispone de un nmero 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 funcin 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, debers crear tu propio sistema.

Al comparar valores, por ejemplo al ordenar una lista, Game Maker debe decidir cundo dos valores son iguales. Al usar cadenas de texto y valores enteros esto es evidente, pero para valores reales, debido a errores de redondeo, nmeros iguales pueden convertirse en diferentes. Por ejemplo, (5/3)*3 no ser igual a 5. Para evitar esto, puedes especificar la precisin que deseas usar. Cuando la diferencia entre dos nmeros es menor que esta precisin, los dos nmeros se consideran iguales. Por defecto se utiliza una precisin de 0.0000001.Puedes cambiar este valor con las funciones siguientes:

ds_set_precision(prec) Especifica la precisin usada en comparaciones.

Esta precisin 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 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 dems 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 funcin devuelve un nmero entero con la id de la pila para usarla
en las diferentes funciones. Puedes crear varias pilas.

ds_stack_destroy(id)
ya no necesites la pila.

Destruye la pila, liberando la memoria usada. No olvides usar esta funcin cuando

ds_stack_clear(id) Limpia la pila, borrando todos los valores que contiene pero no la destruye. ds_stack_size(id) Devuelve el nmero de valores en la pila. ds_stack_empty(id) Devuelve true si la pila est vaca. Es lo mismo que chequear si el nmero 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 dems tendrn 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 funcin devuelve un nmero 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 funcin 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 nmero de valores en la cola. ds_queue_empty(id) Devuelve true si la cola est vaca. Es lo mismo que chequear si el nmero 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 coleccin de valore en un orden determinado. Puedes aadir valores a la lista a la posicin que desees. Por eso, puedes acceder acceder a los valores usando un ndice de su posicin en la lista. Tambin 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 cdigo compilado son mucho ms rpidas que los arrays.

ds_list_create()Crea una nueva lista. La funcin devuelve un nmero 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 funcin 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 nmero de valores en la lista. ds_list_empty(id) Devuelve true si la lista est vaca. Es lo mismo que chequear si el nmero 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 posicin pos. La primera posicin es 0 y la ltima es
igual al tamao de la lista menos 1.

ds_list_replace(id,pos,val) Reemplaza el valor en la posicin pos por val. ds_list_delete(id,pos) Elimina el valor en la posicin pos. ds_list_find_index(id,val) Devuelve la posicin 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 posicin 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 nmero 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, ordenndolos por la llave. Puedes aadir valores al mapa y buscar uno concreto usando las llaves. Como las llaves tambin estn ordenadas, puedes

encontrar los valores correspondientes a la llave siguiente o anterior. A veces es til usar un mapa para guardar llaves sin ningn valor asignado. En este caso puedes asignarles a todas las llaves el valor 0.

ds_map_create()Crea un nuevo mapa. La funcin devuelve un nmero 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 funcin 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 nmero de parejas llave-valor en el mapa. ds_map_empty(id) Devuelve true si el mapa est vaca. Es lo mismo que chequear si el nmero de valores en
el mapa es cero.

ds_map_add(id,key,val) Aade 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 slo 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 segn su prioridad.

ds_ priority _create()Crea una nueva cola. La funcin devuelve un nmero 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 funcin
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 nmero de valores en la cola. ds_ priority _empty(id) Devuelve true si la cola est vaca. Es lo mismo que chequear si el nmero de
valores en la cola es cero.

ds_priority_add(id,val,prio) Aade 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 tambin puedes dar valores por regiones, aadirlos y encontrar los valores mximo, mnimo o medio de una regin. 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 ms rpidas.

ds_grid_create(w,h) Crea una rejilla con la anchura especificada en w y la altura especificada en h. La


funcin devuelve la id de la rejilla que debe usarse en las dems funciones.

ds_grid_destroy(id) Destruye la rejilla, liberando la memoria usada. No olvides usar esta funcin cuando ya
no necesites la rejilla.

ds_grid_resize(id,w,h) Aumenta el tamao 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 nmero 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. Slo se puede usar con nmeros. ds_grid_set_region(id,x1,y1,x2,y2,val) Todas las celdas de la regin especificada toman el
valor especificado.

ds_grid_add_region(id,x1,y1,x2,y2,val)Suma el valor a la regin 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


regin (slo para valores numricos).

ds_grid_set_disk(id,xm,ym,r,val) Da el valor especificado a toda las celdas dentro del crculo de


centro xm,ym y radio r.

ds_grid_add_disk(id,xm,ym,r,val) Suma el valor a la regin especificada por el crculo. 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 regin (slo


para valores numricos).

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 regin

especificada. Slo funciona con valores numricos.

ds_grid_get_max(id,x1,y1,x2,y2) Devuelve el mximo valor de las celdas de la regin especificada.


Slo funciona con valores numricos.

ds_grid_get_min(id,x1,y1,x2,y2) Devuelve el mnimo valor de las celdas de la regin especificada.


Slo funciona con valores numricos.

ds_grid_get_mean(id,x1,y1,x2,y2) Devuelve el valor medio de las celdas de la regin especificada.


Slo funciona con valores numricos.

ds_grid_get_disk_sum(id,xm,ym,r) Devuelve la suma de los valores de las celdas de la regin


circular especificada. Slo funciona con valores numricos..

ds_grid_get_disk_min(id,xm,ym,r) Devuelve el mnimo valor de las celdas de la regin circular


especificada. Slo funciona con valores numricos.

ds_grid_get_disk_max(id,xm,ym,r) Devuelve el mximo valor de las celdas de la regin circular


especificada. Slo funciona con valores numricos.

ds_grid_get_disk_mean(id,xm,ym,r) Devuelve el valor medio de las celdas de la regin circular


especificada. Slo funciona con valores numricos.

ds_grid_value_exists(id,x1,y1,x2,y2,val) Devuelve true si el valor especificado existe en la


regin.

ds_grid_value_x(id,x1,y1,x2,y2,val) Devuelve la coordenada x de la celda de la regin 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 regin 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


regin circular.

ds_grid_value_disk_x(id,xm,ym,r,val) Devuelve la coordenada x de la celda de la regin 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 regin circular


en la que aparece el valor especificado

Creando partculas
Esta funcin solo est disponible en la versin registrada de Game Maker.

Los sistemas de partculas se emplean para crear efectos especiales. Las partculas son pequeos elementos (ya sean representados por un pequeo sprite, un pxel o una pequea forma). Tales partculas se mueven de acuerdo a reglas predefinidas y pueden cambiar su color mientras se mueven. Muchas partculas juntas pueden crear p. Ej. Fuegos artificiales, flamas, lluvia, nieve, campos estelares, polvo, etc.

Game Maker contiene un extenso sistema de partculas que puede ser empleado para crear grandes efectos. Aunque no es sencillo de utilizar por lo que mejor lee cuidadosamente esta seccin antes de probarlo. Los sistemas de partculas tienen muchos parmetros y no siempre es fcil entender cmo crear los efectos que se desean. Si lo encuentras demasiado difcil, Game Maker tambin dispone de un sistema de efectos para crear explosiones, humo, lluvia e incluso fuegos artificiales.

Primero que nada hay tipos de partculas. Un tipo de partcula define una clase de partculas en especfico. Tales tipos pueden tener muchos parmetros que describen la forma, el tamao, color y movimiento de las partculas.

Despus tenemos los sistemas de partculas. Puede haber diferentes sistemas de partculas en un juego. Un sistema de partculas puede tener partculas de diferentes tipos. Un sistema de partculas cuenta con emisores que crean las partculas, ya sea continuamente o en estallidos. Tambin puede contar con atractores que atraen las partculas. Finalmente, puede tambin tener destructores que destruirn las partculas. Una vez que se ha creado una partcula en un sistema, sta ser automticamente dibujada y actualizada por el sistema.

La informacin sobre partculas se divide en las secciones siguientes:

Efectos simples

La forma ms sencilla de crear partculas es usando el mecanismo de efectos. Los efectos se crean usando partculas, pero t no tienes que preocuparte de eso. Simplemente eliges el tipo de efecto, la posicin donde debe crearse, su color y su tamao 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 slo necesitars crearlos una vez (como la explosin) mientras que otros debers 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 posicin que especifiques para ellos ser irrelevante.

Aunque esto pueda sonar limitado, se pueden conseguir efectos muy espectaculares. Por ejemplo, creando una pequea 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

posicin especificada. size es el tamao del efecto segn la convencin siguiente: 0 = pequeo, 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)

Igual que la funcin anterior, pero esta vez el

efecto se crea encima de la instancia, con una profundidad igual a-100000.

Para eliminar todos los efectos usa la funcin:

effect_clear()

Detiene y elimina todos los efectos.

Tipos de partculas

Tipos de partculas
Un tipo de particular define la forma, color y movimiento de una clase de partculas. Slo necesitas definir un tipo de partcula una vez durante el juego, una vez hecho esto puede ser usado por cualquier sistema de partculas. Los tipos de partculas tienen un gran nmero de caractersticas que pueden ser cambiadas para alterar su apariencia o comportamiento. Con la eleccin adecuada puedes crear cualquier tipo de efecto. Las funciones para crear y destruir tipos de partculas 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 partcula, 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 funcin cuando ya no se necesite

el tipo de partcula 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 partcula


Las partculas tienen una forma. Esta forma se indica mediante un sprite. Puedes usar cualquier sprite que quieras para tus partculas pero debes saber que adems hay 15 tipos de sprites ya definidos. Estos sprites son todos de tamao 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 (lnea) pt_shape_star (estrella) pt_shape_circle (crculo) pt_shape_ring (anillo) pt_shape_sphere (esfera) pt_shape_flare (brillo) pt_shape_spark (chispa) pt_shape_explosion (explosin) pt_shape_cloud (nube) pt_shape_smoke (humo) pt_shape_snow (nieve)

Para indicar la forma debes usar la funcin:

part_type_shape(ind,shape)

Aplica la forma tipo shape a la partcula ind.

Tambin puedes usar tu propio sprite con la funcin:

part_type_sprite(ind,sprite,animate,stretch,random)

Asigna el sprite para el tipo de

particular ind. Con la opcin animate puedes indicar si el sprite debe ser animado. Con stretch indicas si la animacin debe repetirse durante el tiempo de vida de la partcula. 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 partcula puedes elegir el tamao de ste. Un tamao de 1 significa el tamao normal del sprite. Un tipo de partcula se puede definir para que todas las partculas tengan el mismo tamao o para que tengan tamaos distintos. Tambin puedes especificar un rango de tamaos, si el tamao debe variar durante la vida de la partcula 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

parmetros de tamao para el tipo de partcula. Debes indicar el tamao inicial, el tamao 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 tamao no cambia).

Las partculas tambin tienen una orientacin que se indica en grados en sentido antihorario. Al igual que el tamao, la orientacin puede crecer, disminuir y puede ser la misma para todas las partculas o diferente para cada una.

part_type_orientation(ind,ang_min,ang_max,ang_incr,ang_wiggle,ang_rela tive) Aplica la orientacin al tipo de partcula. Debes indicar la orientacin inicial, final, el incremento o decremento
en cada step, si la orientacin 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 orientacin de la partcula seguir el camino que sta describa.

Color y blending
Las partculas tendrn un color. Hay diferentes maneras de especificar un color para una partcula. La ms simple es especificar solamente un color. Pero tambin puedes especificar dos tres colores que se interpolarn a lo largo de la vida de la partcula. Por ejemplo, una partcula puede crearse siendo blanca y poco a poco irse convirtiendo en negra. Otra posibilidad es indicar que el color de cada partcula 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)

Indica un slo color para la partcula. Especifica dos colores entre los que se interpolar. Ahora los colores representan el color incial,

part_type_color2(ind,color1,color2)

part_type_color3(ind,color1,color2,color3)
medio y final

.
El color ser seleccionado de una mezcla aleatoria de

part_type_color_mix(ind,color1,color2)

estos dos colores y permanecer inalterado durante la vida de la partcula.

part_type_color_rgb(ind,rmin,rmax,gmin,gmax,bmin,bmax)

Se puede usar para

especificar que cada partcula 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)
esta vez el rango se especifica en modo hsv.

Igual que la anterior, pero

Adems del color, tambin puedes especificar un valor de transparencia. As puedes conseguir que las partculas desaparezcan poco a poco.

part_type_alpha1(ind,alpha1)

Aplica un nico valor de transparencia (entre 0 y 1) al tipo de partcula. Igual que la anterior, pero esta vez la transparencia en

part_type_alpha2(ind,alpha1,alpha2)

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 partculas se mezclan con el fondo igual que los sprites. Pero tambin 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)
para el tipo de partcula.

Indica si se debe utilizar additive blending (1) or normal blending (0)

Vida y muerte
Las partculas viven durante un tiempo limitado, despus, desaparecen. La vida de las partculas se mide en steps. Puedes indicar su vida, o un rango para cada tipo de partculas. Adems, las partculas pueden crear otras partculas en cada step o cuando mueren. Vigila que el nmero de partculas total no sea demasiado elevado.

part_type_life(ind,life_min,life_max)
partcula (Ambos son 100 por defecto).

Establece los lmites del tiempo de vida para el tipo de

part_type_step(ind,step_number,step_type)

Establece el nmero y tipo de partculas que

deben ser generadas en cada step para el tipo indicado de particula. Si usas un nmero negativo para step_number, por ejemplo -5, se generar una partcula cada 5 steps.

part_type_death(ind,death_number,death_type)

Establece el nmero y tipo de partculas 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 funcin anterior. La partcula slo crear otras partculas al llegar al final de su vida y no cuando sea destruida por un destructor (lee ms adelante).

Movimiento de las partculas


Las partculas se pueden mover durante su vida. Pueden tener velocidad inicial y direccin y cambiar durante su vida. Tambin 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 partcula. (Todos los valores son 0 por defecto). Especificas un valor mnimo y mximo para la partcula y cuando sta sea creada se escoger un valor aleatorio entre ellos. Puedes especificar un valor negativo en speed_incr para hacer que la partcula 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 direccin para el tipo de partcula, en grados antihorarios (0-360). (Todos los valores son 0 por defecto).

part_type_gravity(ind,grav_amount,grav_dir)
tipo de partcula. (Por defecto no hay valor de gravedad).

Establece las propiedades de gravedad para el

Sistemas de partculas

Las partculas tienen vida en sistemas de partculas. Por lo que para tener partculas en tu juego necesitas crear uno o ms sistemas de partculas. Puede haber muchos tipos diferentes de sistemas de partculas. Por ejemplo, si tu juego tiene varias pelotas y cada pelota debiera tener una cola de partculas, lo ms probable es que cada pelota tenga su sistema de partculas. La manera ms fcil para manejar los sistemas de partculas es crear uno y luego crear partculas en l, usando los tipos partculas que especificaste antes. Pero, como veremos a continuacin, los sistemas de partculas pueden contener emisores que automticamente producen partculas, atractores que las atraen y destructores que las eliminan.

Una vez que las partculas se aaden a un sistema son dibujadas y actualizadas en cada step automticamente. Para definir si las partculas se deben dibujar delante o detrs de las dems instancias, los sistemas de partculas poseen una profundidad.

Los sistemas de partculas no se eliminarn aunque reinicies el juego, para eliminarlos debes usar la funcin adecuada. As que asegrate de hacerlo cuando ya no los necesites.

Las siguientes funciones permiten manejar los sistemas de partculas:

part_system_create()

Crea un nuevo sistema de partculas. Devuelve el ndice del sistema creado. Este

ndice debe emplearse en las llamadas a las funciones siguientes para configurar las propiedades del sistema de partculas.

part_system_destroy(ind)
del sistema para ahorrar espacio.

Destruye el sistema de partculas ind. Llama a esta funcin si ya no hars uso

part_system_exists(ind) part_system_clear(ind)

Devuelve si el sistema de partculas ind existe.

Devuelve el sistema ind a sus valores por defecto, removiendo todas las

partculas, emisores y atractores en l.

part_system_draw_order(ind,oldtonew)

Establece el orden en el que el sistema dibuja las

partculas. Cuando oldtonew es true las partculas ms viejas son dibujadas primero y las nuevas se dibujan sobre ellas (valor por defecto). De otra forma las partculas ms recientes son dibujadas primero. Esto puede resultar en varios efectos diferentes.

part_system_depth(ind,depth)

Especifica la profundidad del sistema de partculas. Especifica la posicin en la que se dibuja el sistema de partculas. Si

part_system_position(ind,x,y)

quieres dibujar el sistema relativo a un objeto puedes usar sus coordenadas.

Como ya hemos visto, los sistemas de partculas se dibujan y actualizan automticamente. Pero a veces puedes no querer que esto sea as. Las siguientes funciones te permiten controlar estos aspectos:

part_system_automatic_update(ind,automatic)
automticamente (1) o no (0).

Indica si el sistema debe actualizare

part_system_automatic_draw(ind,automatic)
automticamente (1) o no (0).

Indica si el sistema debe dibujarse

part_system_update(ind)

Esta funcin actualiza el sistema y permite a los emisores crear partculas.

Puedes llamar a esta funcin cuando no uses actualizacin automtica, o para acelerar un poco el sistema al inicio.

part_system_drawit(ind)

Esta funcin dibuja el sistema de partculas si has desactivado la opcin

automtica. Debes llamar a esta funcin desde el evento draw de algn objeto.

Las siguientes funciones se encargan de las partculas de un sistema de partculas:

part_particles_create(ind,x,y,parttype,number)
tipo ind en la posicin (x,y) dentro del sistema.

Esta funcin crea number partculas del

part_particles_create_color(ind,x,y,parttype,color,number)

Esta funcin crea

number partculas del tipo ind en la posicin (x,y) dentro del sistema con el color indicado. Esto es til cuando el tipo de partcula slo usa un color o no define ninguno.

part_particles_clear(ind) part_particles_count(ind)

Esta funcin elimina todas las partculas del sistema.

Esta funcin devuelve el nmero de partculas en el sistema.

Emisores

Los emisores crean partculas. Pueden crear un flujo continuo de partculas o pueden lanzar un cierto nmero de partculas usando la funcin adecuada. Un sistema de partculas puede tener un nmero arbitrario de emisores. Un emisor tiene las siguientes propiedades:

xmin, xmax, ymin, ymax shape o o o o

indican la extensin de la regin en la cual se generan las partculas.

indica la forma de la regin. Puede tener uno de los siguientes valores:

ps_shape_rectangle ps_shape_ellipse ps_shape_diamond ps_shape_line


indica la distribucin usada para general las partculas. Puede tener uno de los

distribution
siguientes valores:

ps_distr_linear

indica una distribucin lineal, esto es que en toda la regin se tiene la

misma oportunidad de que aparezca una partcula

ps_distr_gaussian

indica una distribucin Gaussiana en la cual se generan ms

partculas en el centro que en las orillas de la regin

particle type number

indica el tipo de partculas que sern generadas

indica el nmero de partculas 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 partculas. Nota que cada una de ellas necesita el id del sistema de partculas al que pertenecen como primer argumento.

part_emitter_create(ps)

Crea un nuevo emisor en el sistema de partculas 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 partculas ps. Llama a esta

funcin si no necesitas ms 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 partculas 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 regin y distribucin del emisor.

part_emitter_burst(ps,ind,parttype,number)
forma de estallido (una sola vez) desde el emisor ind.

Emite number partculas del tipo partype en

part_emitter_stream(ps,ind,parttype,number)

Desde este momento se crearn number

partculas de tipo partype desde el emisor ind en cada step. Si indicas un nmero 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

Adems de los emisores, un sistema de partculas tambin puede contener atractores. Un atractor atrae a las partculas (o las aleja). Un sistema de partculas puede tener mltiples atractores. Aunque se te recomienda solo usar unos pocos porque alentarn el procesamiento de las partculas. Un atractor tiene las siguientes propiedades:

x,y

indican la posicin del atractor. indican la fuerza de atraccin del atractor. El cmo acte la fuerza sobre las partculas depende de

force

los siguientes parmetros.

dist

indica la mxima distancia a la cual el atractor tiene efecto. Solo las partculas con una distancia al

atractor menor que dist sern atradas.

kind

indica el tipo de atractor. Se tienen los siguientes valores

o o

ps_force_constant ps_force_linear

indica que la fuerza es constante independientemente de la distancia.

indica una fuerza que aumenta linealmente. A la distancia mxima la

fuerza es 0 mientras que en la posicin del atractor la fuerza tiene el valor force indicado.

ps_force_quadratic

indica que la fuerza aumenta de manera cuadrtica.

additive

indica si la fuerza se suma a la velocidad y direccin en cada step (true) o si solo se aplica a la

posicin 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 partculas al cual pertenecen.

part_attractor_create(ps)

Crea un nuevo atractor en el sistema de partculas 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 partculas ps. Llama

a esta funcin si ya no necesitas el atractor para ahorrar espacio.

part_attractor_destroy_all(ps)
de partculas ps.

Destruye todos los atractores que hayan sido creados en el sistema

part_attractor_exists(ps,ind)
partculas ps.

Devuelve true si el atractor ind existe dentro del sistema de

part_attractor_clear(ps,ind)

Devuelve los valores del atractor a sus valores por defecto. Establece a (x,y) la posicin del atractor ind. Establece las propiedades de

part_attractor_position(ps,ind,x,y)

part_attractor_force(ps,ind,force,dist,kind,aditive)
fuerza del atractor ind.

Destructores

Los destructores destruyen las partculas cuando aparecen dentro de su regin. Un sistema de partculas puede tener un nmero arbitrario de destructores. Un destructor cuenta con las siguientes propiedades:

xmin, xmax, ymin, ymax shape o o o

indican la extensin de la regin en la cual se destruyen las partculas.

indica la forma de la regin. Puede tener uno de los valores siguientes:

ps_shape_rectangle ps_shape_ellipse 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 partculas al que pertenece el destructor.

part_destroyer_create(ps)

Crea un nuevo destructor en el sistema de partculas 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 partculas ps.

Llama a esta funcin cuando ya no hagas uso del destructor para ahorrar espacio.

part_destroyer_destroy_all(ps)
sistema de partculas ps.

Destruye todos los destructores que hayan sido creados en el

part_destroyer_exists(ps,ind)
partculas ps.

Devuelve true si el destructor ind existe dentro del sistema de

part_destroyer_clear(ps,ind)

Devuelve el destructor a sus valores por defecto. Establece la regin del

part_destroyer_region(ps,ind,xmin,xmax,ymin,ymax,shape)
destructor.

Deflectores

Los deflectores desvan a las partculas cuando aparecen dentro de su regin. Un sistema de partculas puede tener un nmero arbitrario de deflectores. Un deflector tiene las siguientes propiedades:

xmin, xmax, ymin, ymax indican la extensin de la regin en la cual las partculas son desviadas. kind o
indica el tipo de deflector. Puede tener uno de los siguientes valores:

ps_deflect_horizontal
para paredes verticales

refleja las partculas horizontalmente; normalmente usado

ps_deflect_vertical
paredes horizontales

refleja las partculas verticalmente; normalmente usado para

friction

la cantidad de friccin como resultado de un impacto con el deflector. Entre mayor sea este

valor ms 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 partculas al cual pertenece el deflector.

part_deflector_create(ps)

Crea un nuevo deflector en el sistema de partculas 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 partculas ps. Llama a esta

funcin cuando ya no necesites el deflector para ahorrar espacio.

part_deflector_destroy_all(ps)
de partculas ps.

Destruye todos los deflectores que hayan sido creados en el sistema

part_deflector_exists(ps,ind)
partculas ps.

Devuelve true si el deflector ind existe dentro del sistema de

part_deflector_clear(ps,ind)

Devuelve el deflector a sus valores por defecto.

part_deflector_region(ps,ind,xmin,xmax,ymin,ymax) Establece la regin para el


deflector.

part_deflector_kind(ps,ind,kind)

Establece el tipo de deflector. Establece la friccin del deflector.

part_deflector_friction(ps,ind,friction)

Cambiadores

Los cambiadores cambian ciertas partculas cuando aparecen dentro de su regin. Un sistema de partculas puede tener un nmero arbitrario de cambiadores. Un cambiador tiene las siguientes propiedades:

xmin, xmax, ymin, ymax


cambiadas.

indican la extensin de la regin en la cual las partculas son

shape o o o

indica la forma de la regin. Puede tener uno de los valores siguientes:

ps_shape_rectangle ps_shape_ellipse ps_shape_diamond


indica el tipo de partcula a ser cambiado. indica el tipo de partcula al que se cambiar.

parttype1 parttype2 kind o

indica el tipo del cambiador. Puede tener uno de los siguientes valores:

ps_change_motion

slo cambia los parmetros de movimiento de la partcula, no el color o

forma ni las propiedades de tiempo de vida

ps_change_shape
color y forma

slo cambia los parmetros de forma de la partcula como el tamao, el

ps_change_all

cambia todos los parmetros, bsicamente significa que la partcula 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 partculas al que pertenece el cambiador.

part_changer_create(ps)

Crea un nuevo cambiador en el sistema de partculas 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 partculas ps. Llama a esta

funcin si ya no necesitas el cambiador para ahorrar espacio.

part_changer_destroy_all(ps)
de partculas ps.

Destruye todos los cambiadores que hayan sido creados en el sistema

part_changer_exists(ps,ind) part_changer_clear(ps,ind)

Devuelve true si el cambiador ind existe en el sistema de partculas ps.

Devuelve las propiedades del cambiador a sus valores por defecto.

part_changer_region(ps,ind,xmin,xmax,ymin,ymax,shape)
cambiador.

Establece la regin para el

part_changer_types(ps,ind,parttype1,parttype2)
ser cambiado y el tipo al que debe ser cambiado.

Establece el tipo de partcula que debe

part_changer_kind(ps,ind,kind)

Establece el tipo de cambiador.

Ejemplo de fuegos artificiales

Aqu tienes un ejemplo de un sistema de partculas que crea unos fuegos artificiales. Hace uso de dos tipos de partculas: uno que forma el cohete y otro que forma los fuegos artificiales en si. El cohete genera las partculas de los fuegos artificiales cuando se destruye. Tambin tenemos un emisor en el sistema de partculas que emite regularmente partculas del cohete desde la parte baja de la pantalla. Para hacer que esto funcione necesitas un objeto. En su evento de creacin colocamos el siguiente cdigo que crea los tipos de partculas, un sistema de partculas y el emisor:

{ // Crear el sistema de partculas 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); morir*/ /* Crear el fuego artificial al

// 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); }


Listo! Asegrate de que el sistema de partculas (y tal vez los tipos de partculas) se destruyen al cambiar de room o el efecto durar para siempre.

// Crear 1 cada 4 steps

Juegos multijugador
Esta funcionalidad slo est disponible en la versin registrada de Game Maker. Jugar contra la computadora es divertido. Pero jugar contra oponentes humanos puede serlo mucho ms. Es relativamente fcil 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 algn otro dispositivo de entrada, pero es mucho ms interesante cuando cada jugador est detrs de su propia computadora. O an mejor, un jugador se encuentra del otro lado del ocano. 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 difcil. Este captulo da una breve descripcin de las posibilidades. En el sitio web hay un tutorial con ms informacin.

La ayuda sobre este tema se encuentra en las siguientes secciones: Configurando la conexin Para que dos computadoras se comuniquen necesitarn cierto protocolo de conexin. Como la mayora de los juegos, el Game Maker ofrece cuatro diferentes tipos de conexin: IPX, TCP/IP, Mdem y Serial. La conexin IPX (para ser ms 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 documentacin de Windows. O ve a la opcin 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 direccin IP. Una conexin modem se realiza a travs del modem.

Tienes que introducir cierta informacin del modem (una cadena de inicializacin y un nmero telefnico) para usarla. Finalmente, al usar la lnea serial (una conexin 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 conexin IPX. mplay_init_tcpip(addr)inicializa una conexin TCP/IP. addr es una cadena que indica la direccin web o
IP, p. Ej. 'www.gameplay.com' o '123.123.123.12', posiblemente seguida por un nmero de puerto (p. Ej. ':12'). Slo se necesita la direccin para unirse a una sesin (ve a continuacin). En una red local no se necesitan direcciones.

mplay_init_modem(initstr,phonenr)inicializa una conexin va mdem. initstr es la cadena de


inicializacin para el mdem (puede estar vaca). phonenr es una cadena que contiene el nmero telefnico a marcar (p. Ej. '0201234567'). Slo se necesita el nmero telefnico al unirse a una sesin (ve a continuacin).

mplay_init_serial(portno,baudrate,stopbits,parity,flow) inicializa una conexin en


serie. portno es el nmero de puerto (1-4). baudrate es la velocidad a emplear en baudios (100-256K). stopbits indica el nmero 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 funcin devuelve si la conexin se efectu con xito. Una llamada tpica a esta funcin es mplay_init_serial(1,57600,0,0,4). Si especificas 0 al primer argumento se abre un dilogo para que el usuario pueda cambiar la configuracin manualmente. Tu juego debe llamar una de estas funciones una sola vez. Todas las funciones indican si han tenido xito (si se logra la conexin). No tiene xito si el protocolo en particular no est instalado o soportado por tu mquina. Para checar si hay una conexin exitosa disponible puedes emplear la siguiente funcin

mplay_connect_status()devuelve el estado de la conexin actual. 0=no hay conexin, 1=conexin IPX,


2=conexin TCP/IP, 3=conexin va mdem, y 4=conexin serial.

Para finalizar la conexin llama a la funcin

mplay_end() finaliza la conexin actual.

Cuando empleas una conexin TCP/IP tal vez quieras decirle a la persona con la que deseas jugar cul es la direccin ip de tu computadora. La siguiente funcin te ser de ayuda:

mplay_ipaddress()devuelve la direccin IP de tu mquina (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 unindose a sesiones Cuando te conectas a una red, puede haber mltiples juegos ejecutndose 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 identificacin cambia. De esta forma puedes evitar que personas con versiones anteriores de tu juego jueguen contra personas que cuentan con versiones ms recientes.

Si quieres iniciar un nuevo juego multijugador necesitas crear una nueva sesin. Para esto puedes emplear la siguiente rutina:

mplay_session_create(sesname,playnumb,playername) Crea una nueva nueva sesin en la


conexin actual. sesname es una cadena que indica el nombre de la sesin. playnumb indica el nmero mximo de jugadores permitidos para este juego (usa 0 para un nmero arbitrario de jugadores). playname es tu nombre como jugador. Indica si ha tenido xito.

Una instancia del juego debe crear la sesin. La(s) otra(s) instancia(s) del juego deben unirse a esta sesin. Esto es un poco ms complicado. Primero debes ver las sesiones disponibles y luego elegir a la que te unirs. Hay tres rutinas importantes para esto:

mplay_session_find()
sesiones encontradas.

Busca todas las sesiones que an aceptan jugadores y devuelve el nmero de

mplay_session_name(numb) Devuelve el nombre de la sesin nmero numb (0 es la primer sesin). Esta


rutina puede ser llamada slo despus de haber llamado a la anterior.

mplay_session_join(numb,playername)

Con esta rutina te unes a la sesin nmero numb (0 es la

primer sesin). playername es tu nombre como jugador. Indica si ha tenido xito.

Hay una rutina ms que puede cambiar el modo de la sesin. Debe llamarse antes de crear una sesin:

mplay_session_mode(move) Indica si se mueve la sesin 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 sesin actual puedes usar la siguiente funcin

mplay_session_status() Devuelve el estado de la sesin actual. 0 = no hay sesin, 1 = sesin creada, 2 =


se uni a la sesin.

Un jugador puede detener una sesin empleando la siguiente rutina:

mplay_session_end() Finaliza la sesin para este jugador.

Jugadores Cada instancia del juego que se una a una sesin es un jugador. Como se indic antes, los jugadores tienen nombres. Hay tres rutinas referentes a los jugadores:

mplay_player_find()
encontrados.

Busca todos los jugadores en la sesin actual y devuelve el nmero de jugadores

mplay_player_name(numb)

Devuelve el nombre del jugador nmero numb (0 es el primer jugador, el cual

siempre eres t). Esta rutina puede slo ser llamada despus de haber llamado a la anterior.

mplay_player_id(numb)

Devuelve el id nico del jugador nmero numb (0 es el primer jugador, el cual

siempre eres t). Esta rutina puede llamarse slo despus de haber llamado la primera. Este id es usado al enviar y recibir mensajes de otros jugadores.

Datos compartidos La comunicacin mediante datos compartidos es probablemente la mejor forma de sincronizar el juego. Todo el proceso de comunicacin 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 nmero real o una cadena. Slo hay dos rutinas:

mplay_data_write(ind,val)
10000).

Escribe el valor val (cadena o real) en la ubicacin ind (ind entre 0 y

mplay_data_read(ind)
valores son 0.

Devuelve el valor en la ubicacin ind (ind entre 0 y 10000). Inicialmente todos los

Para sincronizar la informacin en las diferentes mquinas puedes ya sea usar un modo garantizado (guaranteed mode) que asegura que el cambio llegue a la otra mquina (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 transmisin garantizada para los datos compartidos. guar
debe ser true (valor por defecto) o false.

Mensajes El segundo mecanismo de comunicacin que el Game Maker soporta es el envo y la recepcin 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 ests seguro de que llegarn (pero puede ser lento) o en modo no garantizado, el cual es ms rpido.

Existen las siguientes rutinas de mensajes:

mplay_message_send(player,id,val) Enva 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 nmero real o una cadena). El mensaje es enviado en modo no garantizado. Si val contiene un mensaje de texto la longitud mxima del mensaje es de 30000 caracteres.

mplay_message_send_guaranteed(player,id,val) Enva 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 nmero real o una cadena). Este es un envo garantizado. Si val contiene un mensaje de texto la longitud mxima 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 nmero 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 slo a un usuario en particular, necesitars conocer el id del jugador. Como se indic antes puedes obtener este id con la funcin mplay_player_id(). Este identificador del jugador tambin 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 slo llegar al primero.

En segundo lugar, podras preguntarte porqu cada mensaje tiene un entero identificador. La razn es que esto ayuda a tu aplicacin 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 causara serios problemas).

Usando DLLs

Esta funcin solo est disponible en la versin 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 dinmico). En este archivo DLL se pueden definir funciones. Tales funciones pueden ser programadas en cualquier lenguaje que soporte la creacin de DLLs (p. Ej. Delphi, C, C++, etc.). Aunque se necesita contar con ciertas habilidades de programacin para poder hacerlo. Las funciones plug-in deben tener un formato especfico. Pueden tener entre 0 y 11 argumentos, cada uno de los cuales puede ser un nmero real (double en C) o una cadena terminada en un carcter nulo. (Para ms de 4 argumentos, slo se soporta argumentos reales). Estas funciones deben devolver ya sea un valor real o una cadena terminada en carcter nulo.

En Delphi se puede crear una DLL seleccionando New en el men File y luego eligiendo DLL. A continuacin tienes un ejemplo de una DLL escrita en Delphi que puede ser empleada con Game Maker. (Esto es cdigo de Delphi no GML!)

library MyDLL;

uses SysUtils, Classes;

function MyMin(x,y:double):double; begin

cdecl;

if x<y then Result := x else Result := y; end;

var res : array[0..1024] of char;

function DoubleString(str:PChar):PChar; cdecl; begin StrCopy(res,str); StrCat(res,str); Result := res; end;

exports MyMin, DoubleString;

begin end.

Esta DLL define dos funciones: MyMin toma dos argumentos reales y devuelve el de menor valor, y DoubleString que duplica una cadena. Cabe recordar que se debe ser cuidadoso con el manejo de la memoria. Esta es la razn por la que declar la cadena resultante como global. Tambin nota el uso de la convencin de llamada cdecl. Puedes emplear las convenciones de llamada cdecl o stdcall. Una vez que crees la DLL en Delphi tendrs el archivo MyDLL.DLL. Este archivo debe ser colocado en la carpeta de tu juego. (O en cualquier otro lugar donde Windows pueda encontrarlo).

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 funcin en el GML:

external_define(dll,name,calltype,restype,argnumb,arg1type,arg2type, )
Define una funcin externa. dll es el nombre del archivo dll. name es el nombre de las funciones. calltype es la

convencin de llamada empleada. Usa dll_cdecl o dll_stdcall. restype es el tipo del resultado. Usa ty_real o ty_string. argnumb es el nmero de argumentos (0-11). Despus, para cada argumento debes especificar su tipo. Para ello usa nuevamente ty_real o ty_string. Cuando hay ms de 4 argumentos todos ellos deben ser de tipo ty_real.

Esta funcin devuelve el id de la funcin externa que debe emplearse para llamarla. En el ejemplo de arriba, al inicio del juego usaras el siguiente cdigo 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 funcin:

external_call(id,arg1,arg2,)

Llama a la funcin externa con el id y los argumentos dados.

Necesitas proporcionar el nmero correcto de argumentos del tipo correcto (real o string). La funcin devuelve el resultado de la funcin externa.

As, por ejemplo, escribiras:

{ aaa = external_call(global.mmm,x,y); sss = external_call(global.ddd,'Hello'); }

Si ya no utilizars la DLL, lo mejor sera 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 preguntars cmo hacer una funcin en una DLL que haga algo en el juego. Por ejemplo, podras querer una DLL que agregue instancias de objetos a tu juego. La forma ms fcil es dejar que la funcin DLL devuelva una cadena que contenga una pieza de cdigo GML. Esta cadena que contiene una pieza de GML puede ser ejecutada usando la siguiente funcin del GML

execute_string(str)

Ejecuta la pieza de cdigo en la cadena str.

Alternativamente puedes dejar que la DLL cree un archivo con un script que puede ser ejecutado (esta funcin tambin puede ser empleada para luego modificar el comportamiento del juego).

execute_file(fname)

Ejecuta el cdigo en el archivo fname.

Ahora puedes llamar una funcin 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 funcin 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 funcin extremadamente poderosa. Pero por favor haz uso de ellas slo si sabes lo que ests haciendo

Grficos 3D

Esta funcin slo est disponible en la versin registrada de Game Maker.

Game Maker es un programa destinado para crear juegos en 2 dimensiones e isomtricos. Sin embargo existen algunas funciones para crear grficos 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 grfica. No hay ms soporte para otras funciones 3D. Una vez que comiences a usar grficos 3D posiblemente tendrs 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 podrs usar backgrounds ni foregrounds en tus rooms (La razn es que son usados como mosaicos para llenar la imagen pero con proyecciones de perspectiva esto ya no funciona correctamente). o Ya no podrs usar la posicin del ratn. El ratn no ser transformado a las coordenadas 3D. An puedes obtener la posicin del ratn en la pantalla (en la vista) pero tendrs que hacer clculos con esto por ti mismo (o no usar el ratn del todo). o o Ya no podrs usar tiles. Lo ms posible es que los tiles ya no encajen correctamente. La comprobacin de colisiones todava usa las posiciones 2-d de las instancias en el cuarto. As que no hay deteccin de colisiones en 3D. En ocasiones an podrs usar esto (si utilizas el cuarto como una representacin de un mundo plano (peje. para carreras o juegos FPS) pero en otras circunstancias tendrs que hacer las cosas por ti mismo.

Todas las funciones 3D son a travs de cdigo. Debes estar algo familiarizado con el lenguaje GML. Adems debes entender bastante acerca de como funciona Game Maker de lo contrario te meters en dificultades.

Necesitas tener conocimiento bsico acerca de grficos 3D. En particular usar trminos como proyecciones de perspectiva, hidden surface removal, iluminacin, y niebla, sin mucha explicacin.

No hay modelado 3D en Game Maker. Adems que no planeo aadir soporte para cargar modelos 3D. Es preciso que trabajes con cuidado para mantener una velocidad razonable. Adems, esto no est realmente optimizado en velocidad.

Si todo esto no te desanim, contina leyendo.

Esta seccin se divide en los siguientes temas: Rumbo al modo 3D

Rumbo al modo 3D
Si deseas usar el modo 3D antes necesitas poner Game Maker en modo 3D. Despus 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 pxel en la pantalla slo 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. Asegrate que las instancias que pueden sobreponerse no tengan la misma profundidad!

En segundo lugar, la proyeccin ortogrfica es remplazada por una perspectiva. Esto significa lo siguiente. Normalmente el tamao de las instancias en la pantalla es independiente de su profundidad. Con una proyeccin en perspectiva las instancias que poseen mayor profundidad parecern ms pequeas. Cuando la profundidad es 0 al viejo tamao (a menos que cambies la proyeccin; velo mas adelante). El punto de vista para la cmara es puesta a una distancia sobre el cuarto. (Esta distancia es igual al ancho del cuarto; la cual da una proyeccin por defecto razonable.) Slo las instancias que estn frente la cmara 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 posicin (0,0) est en la esquina superiorizquierda de la vista, en el modo 3D la posicin (0,0) est en la posicin inferior-izquierda, lo cual es normal para las vistas 3-dimensionales.

En realidad puedes cambiar hidden surface removal (eliminar las superficies ocultas) y la proyeccin de perspectiva encendido o apagado usando las siguientes funciones.

d3d_set_hidden (habilita)
(false).

Habilita eliminar superficie oculta (true) o la deshabilita

d3d_set_perspective(habilita)
(true) o la deshabilita (false).

Habilita el uso de una proyeccin en perspectiva

Dibujo fcil Una vez que haz cambiado al modo 3D puedes usar Game Maker como sueles hacerlo (excepto por las remarcas hechas al principio). Slo los objetos aparecern en diferentes tamaos basados en profundidad. Incluso puedes usar vistas. Una funcin adicional puede ser usada. Si dibujas cierto nmero de cosas en una pieza de cdigo 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 polgonos en 3D El problema de dibujar de la vieja manera es que un sprite o polgono siempre se encuentra en un plano-xy, esto es, todas las esquinas tienen la misma profundidad. Para 3D verdadero debes ser capaz de tener vrtices 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 versin 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)


Aade el vrtice (x,y,z) a la primitiva, usando color y valor alfa

especificados con anterioridad.

d3d_vertex_color(x,y,z,col,alpha)

Aade el vrtice (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( )
dibuja.

Finaliza la descripcin de la primitiva. Esta funcin realmente la

Por ejemplo, para dibujar un tetraedro (pirmide de tres lados) situada en el plano z=0 con su punta en z = 200, puedes usar el siguiente cdigo:

{ 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 ms posible es que slo vers un triangulo en la pantalla porque la punta del tetraedro estar en frente del punto de vista. Aparte, usando slo un color, sera difcil de ver las diferentes caras. Adelante veremos maneras de cambiar el punto de vista. Asignando colores lo cual puede hacerse como antes aadiendo la funcin draw_set_color(col) entre las vrtices.

Tambin puedes usar polgonos texturizados en 3D. Funciona de la misma manera como est descrito en las funciones de dibujado avanzado en la documentacin. Pero en esta ocasin necesitas variantes 3D de las funciones bsicas. De una cosa te debes dar cuenta. En una textura la posicin (0,0) es la esquina superiorizquierda. Pero en ocasiones, cuando se usan proyecciones (como se indica adelante), la esquina inferiorizquierda es (0,0). En ese caso necesitas girar la textura verticalmente.

d3d_primitive_begin_texture(tipo,texid)
indicado con la textura indicada.

Inicia una primitiva 3D del tipo

d3d_vertex_texture(x,y,z,xtex,ytex)

Aade el vrtice (x,y,z) a la primitiva con

posicin (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)

Aade el

vrtice (x,y,z) a la primitiva con posicin (xtex,ytex) en la textura, mezclando con su propio color y valor alpha.

d3d_primitive_end()
dibuja.

Finaliza la descripcin de la primitiva. Esta funcin en realidad la

As que, por ejemplo puedes usar el siguiente cdigo 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 tringulo tiene una cara frontal y una trasera. La cara frontal est definida para ser el lado donde los vrtices son definidos en orden contrario al reloj. Normalmente ambos lados son dibujados. Pero si haces una forma cerrada esto es intil porque el lado trasero del tringulo 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 polgonos de la manera correcta. Existe la siguiente funcin:

d3d_set_culling(separar)
culling (false).

Indica iniciar backface culling (true) o detener backface

Dibujando formas bsicas Existen varias funciones para dibujar formas bsicas, como bloques y paredes. Nota que estas formas tambin 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.

hrepeat indica que tan seguido la textura debe ser repetida a travs vrepeat hace lo mismo con el borde vertical.

del borde horizontal de cada cara.

d3d_draw_cylinder(x1,y1,z1,x2,y2,z2,texid,hrepeat,vrepeat,ce rrado,steps)
Dibuja un cilindro vertical usando el color actual en la caja de colisin indicada

usando la textura indicada. Usa -1 para no usar una textura.

hrepeat

indica que tan seguido la hace lo mismo con

textura debe ser repetida a travs del borde horizontal de cada cara. el borde vertical.

vrepeat

closed

indica si se debe cerrar la tapa y fondo del cilindro. steps indica cuantos

pasos rotacionales deben ser tomados. Un valor tpico 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.

hrepeat indica que tan seguido la textura debe ser repetida a travs del borde vrepeat
hace lo mismo con el borde vertical. Dibuja

horizontal de cada cara.

d3d_draw_floor(x1,y1,z1,x2,y2,z2,texid,hrepeat,vrepeat)
un piso (inclinado) en el color actual con las esquinas dadas usando la textura indicada.

hrepeat

indica que tan seguido la textura debe ser repetida a travs del borde horizontal de cada cara.

vrepeat

hace lo mismo con el borde vertical.

La siguiente pieza de cdigo 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 travs 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 cmara mirando desde una posicin un poco sobre el plano-xy a lo largo del plano-xy. En trminos grficos ests estableciendo la proyeccin correcta. Para cambiar la manera en que miras, las siguientes funciones existen.

d3d_set_projection(xfrom,yfrom,zfrom,xto,yto,zto,xup,yup,zup )
Defines como mirar en el mundo. Especificas el punto desde dnde mirar, el punto a mirar y el

rumbo ascendente.

Esta funcin requiere alguna explicacin. Para establecer la proyeccin primero necesitas la posicin desde la cual miras. Esto est indicado por los parmetros (xfrom,yfrom,zfrom). En seguida debes especificar la direccin que miras. Esto se hace dando un segundo punto al cual mirar. Este es el punto (xto,yto,zto). Finalmente, incluso puedes rotar la cmara alrededor de la lnea del punto de vista al punto observado. Para especificar esto debemos tener un rumbo ascendente, esto es, la direccin ascendente en la cmara. Esto es dado por los ltimos tres parmetros (xup,yup,zup). Permtanme dar un ejemplo. Para mirar a travs del planoxy 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 direccin de (200,100). Los puntos del vector up es la direccin-z que requiere. Para hacer esto ligeramente ms complicado, asumamos que tienes una instancia en tu cuarto que especifica la posicin de la cmara. Esta tendr una posicin (x,y) actual y una direccin (y quiz incluso una velocidad). Ahora puedes especificar esto como tu cmara usando el siguiente cdigo:

{ 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 posicin de la cmara (x,y), 10 sobre el piso. Para determinar un punto en la direccin correcta necesitamos hacer algo de aritmtica. Este punto est indicado por los tres siguientes parmetros. Finalmente usamos el vector up como antes.

Una observacin importante! Cuando Game Maker comienza a dibujar un cuarto este pondr el punto de vista de regreso a la posicin por defecto. As que la primera cosa que necesitas hacer cuando dibuja la escena es poner la proyeccin que desees. Esto debe hacerse en un evento Draw!

Existe tambin una versin extendida de la funcin anterior:

d3d_set_projection_ext(xfrom,yfrom,zfrom,xto,yto,zto,xup,yup ,zup,angle,aspect,znear,zfar)
Una versin extendida de esta funcin en la cual

adems especificas el ngulo definiendo el campo de vista, el radio de aspecto entre el tamao vertical y horizontal de la vista, y los planos cercanos y lejanos de recorte.

Los parmetros adicionales trabajan como sigue. Si especificaste la posicin de la cmara, el punto a mirar, y el vector up, puedes todava cambiar qu tan unidos estn los lentes de la cmara. 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. Despus puedes especificar la relacin de aspecto entre la proyeccin 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 ms cercanos que

znear

a la cmara no son

dibujados. Similar para objetos ms lejos que zfar. Puede ser importante poner estos parmetros a valores

razonables porque ellos tambin influyen en la precisin de las comparaciones de z. Si usted hace el rango demasiado grande la precisin empeora. Por defecto usamos 1 y 32000. znear debe ser ms grande que 0!

A veces necesitas temporalmente una proyeccin normal ortogrfica como la usada cuando no hay 3D. Por ejemplo, cuando quieres dibujar alguna capa. Para esto puedes usar la funcin siguiente:

d3d_set_projection_ortho(x,y,w,h,ngulo)
del rea indicada en el cuarto, girando sobre el ngulo indicado.

Pone una proyeccin normal ortogrfica

Un uso estndar para esto es dibujar una capa para p.ej. mostrar el puntaje u otros aspectos. Para hacer esto ponemos una proyeccin ortogrfica. Tambin debemos desactivar hidden surface removal temporalmente porque queremos que la informacin 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 funcin para dibujar bloques slo puede dibujar bloques paralelos de eje. Por primera opcin una transformacin de rotacin puedes crear bloques girados. Tambin los sprites siempre son dibujados paralelos al plano-xy. Estableciendo una transformacin puedes cambiar esto. Hay dos tipos de funciones: las funciones que ponen la transformacin y las funciones que aaden transformaciones.

d3d_transform_set_identity ()
transformacin).

Pone la transformacin a la identidad (ninguna

d3d_transform_set_translation(xt,yt,zt)
conversin sobre el vector indicado.

Pone la transformacin a una

d3d_transform_set_scaling(xs,ys,zs)
escalamiento con las cantidades indicadas.

Pone la transformacin a un

d3d_transform_set_rotation_x(ngulo)
alrededor del eje-x con la cantidad indicada.

Pone la transformacin a una rotacin

d3d_transform_set_rotation_y(ngulo)
alrededor del eje-y con la cantidad indicada.

Pone la transformacin a una rotacin

d3d_transform_set_rotation_z(ngulo)
alrededor del eje-z con la cantidad indicada.

Pone la transformacin a una rotacin

d3d_transform_set_rotation_axis(xa,ya,za,ngulo)

Pone la

transformacin a una rotacin alrededor del eje indicado por el vector con la cantidad indicada.

d3d_transform_add_translation(xt,yt,zt)
vector indicado.

Aade una transformacin sobre

d3d_transform_add_scaling(xs,ys,zs)
cantidades indicadas.

Aade un escalamiento con las

d3d_transform_add_rotation_x(ngulo)
con la cantidad indicada.

Aade una rotacin alrededor del eje-x

d3d_transform_add_rotation_y(ngulo)
con la cantidad indicada.

Aade una rotacin alrededor del eje-y

d3d_transform_add_rotation_z(ngulo)
con la cantidad indicada.

Aade una rotacin alrededor del eje-z

d3d_transform_add_rotation_axis(xa,ya,za,ngulo)
rotacin alrededor del eje indicado por el vector con la cantidad indicada.

Aade una

Comprende que la rotacin 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 tambin 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, despus hacerlo girar, y finalmente trasladarlo de regreso a su posicin. Esto es para qu son las funciones de aadir transformaciones. Los ejemplos siguientes podran explicar esto mejor. Asumiendo que tenemos un sprite spr que queremos dibujar en la posicin (100,100,10). Podemos usar el cdigo 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 transformacin ahora deberamos dibujar el sprite en la posicin (0,0). (Esto asume que la instancia actual tiene una profundidad de 0! Si no estas seguro, primero pon la profundidad.) Si usramos esto en nuestro tirador en primera persona no veramos el sprite. La razn es que es todava paralelo al plano-xy. Queremos hacerlo girar ms de 90 grados a lo largo del eje-x (o el eje-y). Entonces tenemos que aadir una rotacin. Recuerda el orden: primero debemos hacer girar el sprite y luego transformarlo. Entonces podemos usar el cdigo 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 transformacin actual, por ejemplo para aadir una transformacin adicional y luego restaurar a la anterior (esto a menudo pasa dibujando modelos jerrquicos). Para este fin puedes empujar la transformacin actual sobre un montn y luego sacarlo del montn para hacerlo la transformacin actual de nuevo. Las funciones siguientes existen para esto:

d3d_transform_stack_clear() d3d_transform_stack_empty() d3d_transform_stack_push()

Limpia el montn de transformaciones. Devuelve si el montn de transformacin est vaco.

Empuja la transformacin actual sobre el montn.

Devuelve si hay espacio sobre el montn para empujarlo all (si olvidas sacar la transformacin en algn momento te quedars sin espacio en el montn).

d3d_transform_stack_pop()

Saca la transformacin superior del montn y la hace la

actual. Devuelve si haba una transformacin sobre el montn.

d3d_transform_stack_top()

Hace a la transformacin superior la actual, pero no lo

quita del montn. Devuelve si haba tras una transformacin sobre el montn.

d3d_transform_stack_discard()

Quita la transformacin superior del montn, pero

no lo hace la actual. Vueltas si haba tras una transformacin en el montn.

La utilizacin de la transformacin es un mecanismo poderoso. Pero s cuidadoso y siempre restaura la transformacin 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 creacin de la atmsfera y hace posible el no dibujar los objetos que estn a lo lejos. Para habilitar o deshabilitar la niebla usa la funcin 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 mxima y nada puede ser visto ms all.

Iluminacin

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 orientacin. Para crear escenas que luzcan ms realistas debes permitir la iluminacin y poner las luces en los sitios correctos. La creacin de escenas correctamente alumbradas no es fcil pero el efecto es muy bueno.

Para permitir la iluminacin puedes usar la funcin siguiente;

d3d_set_lighting(habilitar)

Habilita o inhabilita el uso de iluminacin.

Usando la iluminacin, para cada vrtice de un polgono el color es determinado. Despus, el color de los pxeles internos est basado en el color de estos vrtices. Hay dos modos que puede ser hecho: El polgono entero consigue el mismo color, o el color suavemente es interpolado sobre el polgono. Por defecto smooth shading es usado. Esto puede ser cambiado usando la funcin siguiente:

d3d_set_shading(smooth)

Establece si usar smooth shading o no.

Para usar la iluminacin obviamente tienes que definir luces. Dos diferentes luces existen: luces direccionales (como el sol), y luces posicinales. La luz tiene un color. (Slo soportamos la luz difusa, no la reflexin 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 pequeo nmero positivo). (dx,dy,dz) es la direccin de la luz. col es el color de la luz (a menudo quieres usar c_white. Esta funcin 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 pequeo nmero positivo). (x,y,z) es la posicin 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 funcin no enciende la luz.

d3d_light_enable(ind,permitir)
ind.

Habilita (true) o deshabilita (false) la luz nmero

La manera en que un objeto refleja la luz depende del ngulo entre la direccin de la luz y el normal de la superficie, es decir el vector que seala lejos de la superficie. De ah, para crear objetos iluminados no slo tienes que proporcionar la posicin de los vrtices, sino tambin sus normales. Para estas cuatro funciones adicionales estn disponibles para definir los vrtices de primitivas:

d3d_vertex_normal(x,y,z,nx,ny,nz)
vector normal (nx,ny,nz).

Aade el vrtice (x,y,z) a la primitiva, con

d3d_vertex_normal_color(x,y,z,nx,ny,nz,col,alpha)

Aade el vrtice

(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)

Aade el

vrtice (x,y) a la primitiva, con vector normal (nx,ny,nz), y con la posicin (xtex,ytex) en la textura, mezclndose con el color y valor alpha establecidos antes.

d3d_vertex_normal_texture_color(x,y,z,nx,ny,nz,xtex,ytex,col ,alpha)
Aade el vrtice (x,y) a la primitiva, con vector normal (nx,ny,nz), y con la posicin

(xtex,ytex) en la textura, mezclndose con su propio color y valor alpha.

Note que para las formas bsicas que puedes dibujar las normales automticamente 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 nmero 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 informacin sobre ellas. Slo cuando dibujas un modelo debes especificar informacin sobre la textura. De esta forma, slo puedes usar una textura en cada modelo. Si necesitas usar ms texturas puedes combinar varias (y tener mucho cuidado con las coordenadas de cada una) o usar mltiples 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()
funciones.

Crea un nuevo modelo y devuelve su ndice, que debe ser usado en las dems

d3d_model_destroy(ind) d3d_model_clear(ind)

Destruye el modelo especificado, liberando memoria.

Limpia el modelo especificado, eliminando todas sus primitivas. Salva el modelo ind al archivo especificado en fname. Carga el modelo desde el archivo especificado. Dibuja el modelo en la posicin (x,y,z). texid es la textura que se

d3d_model_save(ind,fname) d3d_model_load(ind,fname)

d3d_model_draw(ind,x,y,z,texid)

aplicar al modelo. Usa -1 para no usar texturas. Si quieres rotar o escalar el modelo usa las rutinas de transformacin descritas en el apartado de Transformaciones.

Para cada primitiva existe una funcin equivalente que la aade a un modelo. Estas funciones se usan igual que las que ya hemos visto en los captulos anteriores, slo que en lugar de especificar una textura ahora daremos el ndice del modelo.

d3d_model_primitive_begin(ind,kind)
indicado en kind:

Aade al modelo una primitiva 3D del tipo siguiente

pr_pointlist, pr_linelist, pr_linestrip, pr_trianglelist,

pr_trianglestrip o pr_trianglefan. d3d_model_vertex(ind,x,y,z)


Aade el vrtice (x,y,z) al modelo. Aade el vrtice (x,y,z) al modelo con su

d3d_model_vertex_color(ind,x,y,z,col,alpha)
propio color y valor de transparencia.

d3d_model_vertex_texture(ind,x,y,z,xtex,ytex)
posicin (xtex,ytex) en la textura.

Aade el vrtice (x,y,z) al modelo con la

d3d_model_vertex_texture_color(ind,x,y,z,xtex,ytex,col,alpha)
vrtice (x,y,z) al modelo con valores de textura y color.

Aade el

d3d_model_vertex_normal(ind,x,y,z,nx,ny,nz)
vector normal (nx,ny,nz).

Aade el vrtice (x,y,z) al modelo con el

d3d_model_vertex_normal_color(ind,x,y,z,nx,ny,nz,col,alpha)
(x,y,z) al modelo con el vector normal (nx,ny,nz) y sus propios valores de color y transparencia.

Aade el vrtice

d3d_model_vertex_normal_texture(ind,x,y,z,nx,ny,nz,xtex,ytex)
vrtice (x,y,z) al modelo con el vector normal (nx,ny,nz) y coordenadas de textura (xtex, ytex).

Aade el

d3d_model_vertex_normal_texture_color(ind,x,y,z,nx,ny,nz,xtex,ytex,col ,alpha)
Aade el vrtice (x,y,z) al modelo con el vector normal (nx,ny,nz) con valores de color y textura. Finaliza la descripcin de la primitiva en el modelo.

d3d_model_primitive_end(ind)

Adems de primitivas tambin puedes aadir formas al modelo. Las funciones son anlogas 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)
modelo.

Aade un bloque al

d3d_model_cylinder(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat,closed,steps)
Aade un cilindro al modelo.

d3d_model_cone(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat,closed,steps)
un cono al modelo.

Aade

d3d_model_ellipsoid(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat,steps)
elipsoide al modelo.

Aade una

d3d_model_wall(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat)

Aade una pared al modelo. Aade un suelo al modelo.

d3d_model_floor(ind,x1,y1,z1,x2,y2,z2,hrepeat,vrepeat)

El uso de modelos puede aumentar considerablemente la velocidad de los grficos en los juegos 3D, as que deberas usarlo siempre que sea posible

Crear script.
Lo primero antes de crear un script hay que entender que es un script. Un script es un trozo de codigo que nos sirve por ejemplo para acortar una accion que usaremos en varios objetos para no tener qu ir todo el rato copiando y pegando el codigo y resumirlo en una sola linea. Por ejemplo en tu script que se llama draw pones: draw_sprite(pers,1,x,y) y cuando quieras aplicarlo en vez de poner draw_sprite pones draw. En este ejemplo no nos sirve de mucho pero mas adelante vereis como si influye. Lo segundo que debemos tener en cuenta es la finalidad de nuestro script antes de empezar es decir debemos saber para que haremos nuestro script. No es lo mismo hacer un script para calcular la hipotenusa de un triangulo (xd quizas me pase un poco) o crear un script para dibujar un rectangulo (demasiado facil). Vamos que si es la primera vez que creas un script no intentes hacer algo dificil. Lo tercero Hay que tener unos conocimientos minimos del gml no se puede usar lo de arrastrar y soltar por que no funciona aqui solo codigo. Los conocimientos de gml van en proporcion a la dificultad de lo que quieras hacer. Volviendo al punto 2 si no tienes muchos conocimientos y quieres hacer algo muy dificil vas a tener que estar preguntando. Lo cuarto debes saber como se aplica un script. Si no sabes a continuacion te lo explico: Puedes usarlo usando arrastrar y soltar es un icono en la pestaa code o poniendo en el codigo (usamos el script que he puesto arriba) draw() lo de los parentesis es para poner los arguments pero eso ya lo explicare. Y la quinta cosa que debes tener en cuenta es en que evento aplicaras el script si lo pondras en step o en create. Esto importa mucho ya que si lo pones en create se hara nada mas se cre el personaje si lo pones en step lo estara haciendo continuamente. Otro ejemplo si lo pones en animation end lo ejecutara cuando se acabe la animacion.

Arrays. Imaginemos que el usuario debe entrar 5 nmeros para hacer un promedio. Podramos usar las variables num1, num2, num3, num4 y num5, por ejemplo. Pero si el usuario tuviera que introducir 100 valores a lo largo de la partida, la cosa ya sera ms difcil. Para ello tenemos las arrays. Una array es una estructura de valores ordenada de forma secuancia. una forma grfica de expresar un array sera esta:

Como una tabla de una lnea que espera valores.Esta puede contener los valores que queramos solo que aqu la he hecho de 5 celdas para ahorrar espacio. A los valores de la array podemos acceder de esta manera: Array[1]=7 Array[2]=672 Array[5]=1 7 672 1

Y podemos modificarlos a nuestro antojo Array[1]-=3 Array[3]=-4 4 -4 1

Vamos a hacer un programa que nos va a pedir 10 valores y seguidamente har el promedio. Aade un objeto y en su evento de creacin aade el cdigo necesario para que nos pida los valores y haga la mediana: numero[1]=get_integer("Introduce numero[2]=get_integer("Introduce numero[3]=get_integer("Introduce numero[4]=get_integer("Introduce numero[5]=get_integer("Introduce el el el el el primer numero","") segundo numero","") tercer numero","") quarto numero","") quinto numero","")

numero[6]=get_integer("Introduce el sexto numero","") numero[7]=get_integer("Introduce el septimo numero","") numero[8]=get_integer("Introduce el octavo numero","") numero[9]=get_integer("Introduce el noveno numero","") numero[10]=get_integer("Introduce el decimo numero","") mediana=mean(numero[1],numero[2],numero[3],numero[4],numero [5],numero[6],numero[7],numero[8],numero[9],numero[10]) Ahora ne su evento de dibujo aade el cdigo necesario para que se dibuje la variable de la mediana: draw_text(50,50,string(mediana)) Y "voil". Aunque viendo este ejemplo no pueda parecer de utilidad, las arrays nos pueden evitar de usar muchas variables y hacernos un lo.

Lectura / Escritura de Archivos INI.


Los archivos *.ini son archivos especialmente diseados para trabajar con los datos organizados en registros y variables. Para empezar, los archivos *.ini estn divididos en registros que a su vez estan divididos en variables. Un ini comn: [HP] hp = 375 maxhp = 500 [nivel] exp = 5075 nivel = 4 Este ini tiene dos registros, HP y nivel. Cada uno de ellos tiene dos variables. HP tiene las variables hp y maxhp, con los valores 375 y 500, respectivamente. nivel tiene las variables exp y nivel, con los valores 5075 y 4.

Game Maker proporciona funciones para leer y escribir datos fcilmente en los archivos *.ini. Para empezar, hay que abrirlo con: ini_open(fname); Donde fname es un string conteniendo la direccin relativa o absoluta del archivo. Una vez abierto, podemos realizar dos tipos de operaciones con l: Operaciones de escritura: Mediante las funciones de escritura podemos escribir reales o strings. Las funciones son: ini_write_real(key, var, value); ini_write_string(key, var, value); Estas funciones escriben el valor value en la variable var del registro key. Para escribir valores reales recomiendo usar la funcin de escritura de strings mediante un cast del valor a string mediante la funcin string(x). Operaciones de lectura: Mediante las funciones de lectura, podemos leer valores del ini. Son: ini_read_real(key, var, def); ini_read_string(key, var, def); Estas funciones devuelven el valor de la variable var del registro key. Si no se puede ejecutar la lectura, devuelven el valor def. Una vez se ha acabado de ejecutar operaciones con el ini, hay que cerrarlo mediante la funcin: ini_close();

Bucles

Hola a todos, hoy explicar los bucles. Los bucles son unas sentencias que permiten repetir un determinado conjunto de rdenes tantas veces como queramos, ya sean 1, 3, 7, 10, 57, 94 o infinitas. Hay 3 tipos de bucles: Bucle bsico, tambin conocido como while. Llamado as por la sentencia que lo ejecuta. El bucle while permite ejecutar un conjunto de instrucciones mientras una instruccin se cumple. Se ejecuta as: while (/*cond*/) { //acciones } Mientras la sentencia /*cond*/ devuelva diferente de 0 (true), se ejecutar la(s) sentencia(s) //acciones. Bucle do while. Bsicamente es lo mismo que el bucle bsico, pero ejecuta las instrucciones antes de comprovar la condicin. Para ejecutarlo el cdigo es: do { //acciones }while(/*cond*/); Bsicamente la explicacin es la misma que el while, pero se ejecuta //acciones antes de comprobar /*cond*/. Bucle for. Es un bucle bastante ms avanzado. Incluye una incializacin, una condicin y una actualizacin. Se ejecuta mediante la sentencia: for (/*init*/; /*cond*/; /*act*/) { //acciones }

Esto equivaldra a: /*init*/ while (/*cond*/) { //acciones /*act*/ } Este bucle permite ejecutar una serie de acciones (//acciones) mientras se cumpla una condicin /*cond*/, que viene inicializada por /*init*/ y se actualiza con /*act*/. Sentencia repeat. Es una sentencia exclusiva del GML que es un "pseudobucle". Se usa as: repeat (/*num*/) { //acciones } Repite /*num*/ veces la(s) accion(es) //acciones. Es considerado un pseudobucle porque no utiliza una condicin para regular su uso.

FSM IA (inteligencia Artificial)


sobre Inteligencia Artificial. Lo primero que veremos es la arquitectura de mquina de estados finitos. Esta arquitectura es la ms usada para programar la IA en los juegos profesionales y muchos otros mbitos como la rob?tica, los automatismos o la simulacin. Qu es una mquina de estados finitos? Una mquina de estados finitos (Finite State Machine, FSM)se compone de las siguientes partes: Estados Transiciones Acciones As, puede decirse que una FSM es un sistema que tiene varios estados, pasa de uno a otro por unas transiciones y realiza una serie de acciones. Por ejemplo, una bombilla puede tener dos estados:

encendida y apagada. Para pasar de un estado a otro (transicin), hay que accionar un interruptor. Por ltimo, la bombilla puede realizar acciones cuando se encuentre en un estado concreto. Por ejemplo, si est encendida realizar la accin de iluminar una habitacin. Estados Los estados son el ncleo de las FSMs. Una FSM puede tener tantos estados como definamos, pero solamente podr estar en uno de ellos a la vez. En el ejemplo anterior de la bombilla, sta puede estar encendida o apagada, pero no puede estar encendida y apagada a la vez. Es decir, los estados de la bombilla sern encendida y apagada. Transiciones Las transiciones llevan a la FSM de un estado a otro. Para que ocurra una transicin, deben cumplirse unas condiciones. Ejemplo: En nuestro RPG hay un minero que tiene 2 estados: buscar oro en la mina y descansar. Cuando est buscando oro el minero se va cansando. Al llegar a un nivel de fatiga, el minero pasar al estado de descanso hasta que recupere las fuerzas. As, tenemos 2 condiciones: Si ests cansado->Descansa Si te has recuperado->Vuelve a buscar oro La primera condicin Si ests cansado indica que si estamos en el estado de buscar oro pasemos al estado de descanso. La segunda condicin Si te has recuperado indica que si estamos en el estado de descanso volvamos al estado de buscar oro. Observad que cada condicin slo tiene sentido si se aplica cuando el minero est en el estado correcto. Es decir, si el minero est en el estado de descanso no tiene sentido comprobar si est cansado, ya que aunque fuera cierto, no haramos ms que decir al minero que se pusiera en estado de descanso..pero el minero ya est en ese estado! Cuando tenemos varios estados, puede que desde un estado podamos pasar a varios estados distintos dependiendo de qu condiciones se cumplan. Para llevar un control sobre esto y no perdernos cuando tengamos ms estados y varias transiciones posibles, se suele crear una tabla de transiciones:

Condicin\Estado actual A B C 1 2 3 C C X X A X X X B

En esta tabla vemos lo siguiente: Si estamos en el estado A o B y se cumple la condicin 1 pasamos al estado C Si estamos en el estado B y se cumple la condicin 2 pasamos al estado A Si estamos en el estado C y se cumple la condicin 3 pasamos al estado B Ejemplo: El minero del ejemplo anterior tiene ahora 3 estados: Buscar oro Descansar Comer El paso de un estado a otro se define con esta tabla de transiciones: Condicin\Estado actual Buscar oro Descansar Comer Cansado Recuperado Hambriento Saciado Descansar X Comer X X Comer X X X Buscar oro Buscar oro X

Esta tabla nos dice lo siguiente: Si el minero est en el estado de Buscar oro y est cansado, pasa al estado Descansar. Si el minero est en el estado de Descansar y se ha recuperado, pasa al estado Buscar oro. Si el minero est en el estado de Buscar oro o en el de Descansar y est hambriento, pasa al estado Comer. Si el minero est en el estado de Comer y ya se ha saciado, pasa al estado Buscar oro. Las condiciones que lanzan transiciones de un estado a otro pueden ser tan complejas como queramos. Por ejemplo, podemos decir que un jugador de ftbol slo tire a portera si tiene el baln, est dentro del rea, el portero est en el centro de la portera y no tiene a ningn compaero para pasarle el baln.

Acciones Una accin es la descripcin de una actividad que la FSM puede ejecutar en un momento concreto. Lgicamente, las acciones dependern del estado en el que nos encontremos. Ejemplo: El minero puede realizar la accin encender linterna, si se encuentra buscando oro en la mina y todo est muy oscuro. Es decir, si se encuentra en el estado Buscar oro. Sin embargo esta accin no tendr sentido si se encuentra en los estados Comer o Descansar. Las acciones se dividen en 4 tipos: Entrada: son las acciones que se ejecutan al entrar a un estado concreto. Salida: son las acciones que se ejecutan al salir de un estado concreto. Estado: son las acciones que se ejecutan regularmente por estar en un estado. Transcin: son las acciones que se ejecutan al pasar de a un estado concreto a otro. Ejemplo: Si el minero est en el estado Buscar oro realizar la accin Cavar para cavar y buscar oro. Esta accin se realizar regularmente, o sea que es una accin de estado. Cuando el minero va a descansar, antes de tumbarse a dormir se quita las botas para estar ms cmodo (accin Descalzarse). Cuando est durmiendo ronca (accin Roncar) y cuando se despierta se vuelve a poner las botas slo si va a volver a buscar ms oro (accin Calzarse). Al despertarse, el minero siempre soltar un gran bostezo (accin Bostezar). As: La accin Descalzarse es una accin de entrada, ya que la ejecutaremos siempre una vez al entrar en el estado Descansar. La accin Roncares una accin de estado, ya que la ejecutaremos repetidamente mientras estemos en el estado Descansar. La accin Calzarse es una accin de transicin, ya que slo la ejecutaremos una vez si pasamos del estado Descansar al estado Buscar oro.

La accin Bostezares una accin de salida, ya que la ejecutaremos siempre una vez al salir del estado Descansar.

Estados globales Nuestra FSM puede tener unos estados que sean capaces de interrumpir los dems y ejecutarse inmediatamente. Normalmente son estados que realizan una accin y luego vuelven al estado que se estaba ejecutando. Ejemplo: Nuestro minero acaba de ganar un nuevo estado global: Ir al bao. Este estado tiene prioridad absoluta, cuando el minero tenga ganas de ir al bao (es decir, cuando se cumpla la condicin que lanza la transicin a este estado, por ejemplo vejiga llena) dejar lo que est haciendo e ir al bao de inmediato. Despus, volver a lo que estaba haciendo, como si nada hubiera pasado. Para hacer esto posible, necesitaremos que el sistema recuerde el estado en el que se encontraba antes de entrar al estado global, para as volver a ese estado una vez que finalize la ejecucin del estado global. FSMs dentro de FSMs Las FSMs son herramientas muy potentes, pero conforme crezca la complejidad del sistema ser ms difcil entender cmo funciona el sistema. Para simplificar esto, podemos tener FSMs dentro de otras FSMs. Por ejemplo, en el juego Unreal 2 hay una FSM general para controlar a cada enemigo. Pero adems dentro de cada estado existen otras FSMs para realizar tareas especficas, como defender una zona de ataques enemigos o explorar el nivel. Consideraciones finales Las mquinas de estados finitos son muy utilizadas pese a ser un sistema algo viejo. Las razones principales son las siguientes: Son rpidas y fciles de implementar. Son fciles de depurar para buscar errores Usan poco tiempo de procesamiento, debido a su sencillez Son intuitivas y faciles de comprender por la mente humana Son flexibles, se pueden expandir facilmente y se acoplan muy bien a otros mtodos (redes neuronales, algoritmos genticos...) para crear sistemas hbridos Los juegos profesionales utlizan FSMs en todo momento,

combinndolas adems con otros mtodos para tareas que requieran un nivel de inteligencia ms desarrollado. Las FSMs se basan en reglas simples (condiciones if), por ello se suele decir que el sistema realmente no "piensa". Sin embargo, una FSM correctamente desarrollada y detallada puede dar esa impresin. Su gran rapidez hace que sean perfectas para tareas sencillas y repetitivas en las que no se necesite un alto nivel de inteligencia, como por ejemplo buscar caminos, realizar tareas repetitivas...Adems, para las tareas que requieran inteligencia ms avanzada se pueden integrar perfectamente con otros mtodos. Un ejemplo clarsimo es el juego Los Sims, en el que prcticamente todo el comportamiento de los personajes se ha programado con FSMs. Hasta aqu la introduccin a las mquinas de estados finitos. En la pr?xima entrega veremos cmo implementar una FSM en GML. Para finalizar veremos cmo hacer un ejemplo completo de un topdown shooter (juego de disparos visto desde arriba). Con el fn de hacer el ejemplo lo ms sencillo posible usaremos GM6 registrado para poder usar las funciones para calcular paths en laberintos. De todas formas, a parte de esto el ejemplo ser igual para GM6 sin registrar o GM5. Descripcin general Vamos a hacer un juego de disparos visto desde arriba en el que el jugador puede moverse por un mapa enorme buscando la salida mientras se enfrenta a multitud de enemigos. Ser una especie de Quake pero visto desde arriba. Antes de nada, vamos a crear el escenario. Paredes Creamos un objeto y lo llamamos objPared. Creamos un sprite que ser un cuadrado de 32x32 de color negro y no transparente y se lo asignamos a este objeto. Bien, ya estamos listos para definir al jugador. Jugador El jugador ser una mquina de estados finitos. Hasta ahora habamos visto cmo usar la arquitectura de las FSM en personajes controlados por el ordenador. Sin embargo ahora vamos a usar una

FSM para un personaje controlado por el jugador. Recordad que las FSM se rigen por condiciones que hacen que el personaje pase de un estado a otro. Primero, debemos definir sus caractersticas. El jugador tendr 2 estados: Vivo: el estado normal del jugador, en el que podr moverse y disparar. Muerto: el jugador se quedar muerto en el campo de batalla y lgicamente no podr disparar ni moverse. Pasado un tiempo, volver al estado Vivo perdiendo una vida. Necesitaremos 2 caractersticas para controlar estos estados: Salud: la salud que tiene el jugador. Vidas: nmero de vidas que tiene el jugador. Tiempo de muerte: tiempo que el jugador permanece en el estado Muerto antes de volver al estado Vivo. La tabla de transiciones del jugador ser bastante sencilla: Condicin\Estado actual Salud<=0 Vivo Muerto Vivo Muerto X

Vidas>0 & Tiempo de muerte=0 X

Viendo esta tabla sabemos que: Si el jugador est en el estado Vivo y su salud se agota (Salud<=0) pasa al estado Muerto. Si el jugador est en el estado Muerto y ya ha cumplido su tiempo de muerte (Tiempo de muerte=0) y todava le quedan vidas (Vidas>0) pasa al estado Vivo. Bueno, ya podemos empezar a programar el jugador. Creamos un objeto y lo llamamos objPlayer. Creamos un sprite y lo llamamos sprPlayerVivo. Este sprite ser un crculo azul de tamao 32x32 y centro en (16,16). Copiamos el sprite, le cambiamos el color a negro y lo llamamos sprPlayerMuerto. Ahora volvemos al sprite sprPlayerVivo y lo editamos, dibujando una lnea amarilla horizontal desde el punto (16,16) hasta el punto (31,16). Esto nos servir para poder ver la direccin en la que mira el jugador en todo momento. En el Evento Create del objeto especificamos las caractersticas de la FSM:

/*CARACTERISTICAS DE LA FSM*/ estado = "Vivo"; execute_string(estado+"(0)");

Y a continuacin declaramos las caractersticas del jugador:

/*CARACTERISTICAS DEL JUGADOR*/ vidas = 5; saludMax = 100; salud = saludMax; tiempoMuerteMax = 150; tiempoMuerte = tiempoMuerteMax;

En el Evento Step como siempre, definimos el funcionamiento de la FSM:

execute_string(estado+"(1)"); image_angle = direction;//rotar el sprite (s?lo GM6)

Ahora vamos a definir los estados. Empezamos por el estado Muerto:

switch argument0{ case 0://Entrar //Aqu podemos hacer que el personaje grite, o crear una explosin... tiempoMuerte = tiempoMuerteMax; sprite_index = sprPlayerMuerto; break; case 1://Ejecutar tiempoMuerte -= 1; if (tiempoMuerte = 0){ if (vidas > 0){ vidas -= 1; salud = saludMax;

estado = "Vivo"; execute_string(estado+"(0)"); }else game_end(); } break; case 2://Salir break; case 3://Transicin break; }

Ahora creamos el estado Vivo:

switch argument0{ case 0://Entrar sprite_index = sprPlayerVivo; break; case 1://Ejecutar if (salud <= 0){ estado = "Muerto"; execute_string(estado+"(0)"); exit; } scrAndar(keyboard_check(vk_up), keyboard_check(vk_down), keyboard_check(vk_left), keyboard_check(vk_right), velocidad); scrDisparar(keyboard_check(ord('C'))); break; case 2://Salir break; case 3://Transicin break; }

En este estado, el jugador realizar 2 acciones, Disparar y Andar. Creamos un script y lo llamamos scrAndar:

//scrAndar(avanzar, retroceder, izquierda, derecha, velocidad) var avanzar, retroceder, izquierda, derecha, vel; avanzar = argument0; retroceder = argument1; izquierda = argument2; derecha = argument3; vel = argument4; if (izquierda) direction += 5; else if (derecha) direction -= 5; if (avanzar) retroceder = false; if ((avanzar)||(retroceder)){ var i; for (i=0;i<=vel;i+=1){ if (place_meeting(x+(i+1)*cos(degtorad(direction+retroceder*180)), y-(i+1)*sin(degtorad(direction+retroceder*180)), objPared)){ x += i*cos(degtorad(direction+retroceder*180)); y -= i*sin(degtorad(direction+retroceder*180)); break; }else if (i = vel){ x += vel*cos(degtorad(direction+retroceder*180)); y -= vel*sin(degtorad(direction+retroceder*180)); } } }

Este script es bastante sencillo: se chequean las teclas de entrada y en funcin de ellas se calcula la direccin y se mueve al personaje si es que no choca contra una pared. Observad que las teclas se pasan como argumento al script (scrAndar(keyboard_check(vk_up), keyboard_check(vk_down), keyboard_check(vk_left), keyboard_check(vk_right), velocidad);) con lo que este script servir para mover al personaje con cualquier combinacin de teclas que queris. Podis incluso usarlo para un segundo jugador que utilice las teclas WASD: scrAndar(keyboard_check(ord('W')),

keyboard_check(ord('S')),keyboard_check(ord('A')),keyboard_check( ord('D')), velocidad); Slo tenis que fijaros en el orden en el que se ponen las teclas en el script (avanzar-retroceder-izquierda-derecha). Si os habis fijado, el script toma comom argumento una variable llamada velocidad. Podramos hacer que esta variable fuera local del script (var) y definirla ah mismo, pero resulta mejor hacer que la velocidad sea una caracterstica del jugador, as podremos hacer que jugadores con distintas velocidades puedan usar este mismo script. Para ello, volvemos al Evento Create y ponemos: velocidad = 4; El siguiente paso es crear el script scrDisparar: //scrDisparar(disparar) if (tiempoDisparo = 0){ if (argument0){ with (instance_create(x, y ,objBala)){ speed = 8; direction = direction; parent = id; } tiempoDisparo = tiempoDisparoMax; } }else tiempoDisparo -=1;

Ahora debemos definir la variable tiempDisparo que dir el tiempo entre dos disparos sucesivos. Vamos de nuevo al Evento Create de objPlayer y ponemos: tiempoDisparoMax = 15; tiempoDisparo = 0;

Listo, este script crea una bala que se mueve a una velocidad de 8 pxeles por step en la direccin en la que mire la instancia que llame al script. Adems, le asignamos la id de la instancia a la variable

parent de la bala recin creada. Esto nos servir para poder sabe luego quin ha disparado cada bala. Ya hemos terminado con el jugador, ha sido sencillo, no? ;) Balas Lgicamente, para poder disparar necesitamos crear un objeto y llamarlo objBala. Adems, creamos un sprite que ser un crculo rojo de 5x5 y con el centro en (2,2). En este nuevo objeto, vamos al Evento de Colisin con el objeto objPared y ponemos el siguiente cdigo: instance_destroy();

Tambin aadimos el Evento de Colisin con el objeto objPlayer y aadimos lo siguiente: if ((parent != other.id)&&(other.estado != "Muerto")){ other.salud -=1; instance_destroy(); }

Lo que hacemos es ver si la bala est chocando con el jugador y el juagdor no ha sido quien la ha disparado ni est muerto. Entonces, disminuimos la salud del jugador. Este mismo cdigo nos servir ms adelante. Listo! Ya podemos crear un room, poner una instancia de objPlayer, unas cuantas paredes y darnos una vuelta disparando :D Enemigos (I) Por fn hemos llegado al meollo del asunto: los enemigos. Como siempre, empezamos definiendo sus estados: Atacar: en este estado el enemigo se acercar al jugador hasta una distancia en la que empezar a disparar. Si su salud es menor que la mitad de la salud del personaje mandar un mensaje por radio a la instancia ms cercana para que venga a ayudarle. Huir: Si su salud es menor que la cuarta parte de la salud del jugador intentar huir a un lugar seguro siempre que no est solo. Patrullar: el enemigo simplemente ir caminando por el laberinto.

Ayudar: cuando reciba una petici?n de ayuda ir corriendo a socorrer a su compaero en apuros. EnemigoMuerto: en esta ocasin ser un estado global que podr interrumpir todos los dems. Para controlar estos estados necesitaremos las siguientes caractersticas: Salud. Jugador visible: si puede ver al jugador. Solo: indica si el enemigo se encuentra solo o va acompaado por ms enemigos. Ya podemos crear la tabla de transiciones: Condicin\Est ado actual Salud < salud del jugador/4 & Solo Jugador no visible Compaero cerca Mensaje "Ayuda" Recibir balazo Salud <= 0 Ataca Huir r Huir X X Patrull Ayuda **EnemigoMuert ar r o** X Atacar X X X

Jugador visible X

Atacar X X X X X X X X X

Patrull X ar X X X

Patrull X ar X X Ayudar Atacar

EMuert EMuert EMuert EMuerto X o o o

Bueno, ya podemos empezar a definir el enemigo. Creamos el objeto objEnemy y definimos sus caractersticas: /*CARACTERISTICAS DE LA FSM*/ estado = "Patrullar"; estado_global = ""; mensaje = -1; /*CARACTERISTICAS DEL ENEMIGO*/ saludMax = 100; salud = saludMax; recibirBalazo = false;

/*PROPIEDADES*/ velocidadNormal = 4; velocidadRapida = 6; tiempoDisparoMax = 15; tiempoDisparo = 0;

Observad que no hemos definido las caractersticas solo ni jugadorVisible. Esto es debido a que estas caractersticas necesitan de varias operaciones para chequear si son verdaderas o falsas, por ello es mejor realizar unos scripts que devuelvan true o false y as podremos usarlos como si se trataran de variables. Dicho, esto, comenzamos por definir el script jugadorVisible. Este script ver si el enemigo puede ver al jugador, lanzando una lnea recta y viendo si intersecta con alguna pared. Si esta lnea no se cruza con nada, significar que podemos ver al jugador. Adems, tendremos en cuenta hacia dnde est mirando el enemigo. Es decir, el enemigo no podr? ver al jugador si est de espaldas a ste: //scrJugadorVisible() if (instance_exists(objPlayer)){ var target; target = instance_nearest(x, y, objPlayer); if ((collision_line(x, y, target.x, target.y, objPared, false, true) < 0)&& (abs(point_direction(x, y, target.x, target.y)-direction) <= 60)) return true; else return false; }else return false;

Ahora creamos el script scrSolo que servir para ver si el enemigo est slo o tiene algn compaero cerca en estado de ataque o de ayuda:

//scrSolo() var i, enemigo; for (i=0;i

Ya podemos definir el funcionamiento de la FSM. En el Evento step

ponemos lo de siempre (atencin que esta vez s tenemos un estado global, el estado EnemigoMuerto): if (estado_global != "") execute_string(estado_global+"(1)"); else{ if (salud <= 0){ estado_global = "EnemigoMuerto"; execute_string(estado_global+"(0)"); }else execute_string(estado+"(1)"); } image_angle = direction;

Ya podemos empezar a definir los estados. Empezamos por el estado Patrullar:

switch argument0{ case 0://Entrar break; case 1://Ejecutar if ((scrJugadorVisible())||(recibirBalazo)){ recibirBalazo = false; direction = point_direction(x, y, objPlayer.x, objPlayer.y); estado = "Atacar"; }else if (mensaje = 0){ estado = "Ayudar"; execute_string(estado+"(0)"); }else scrVagar(); break; case 2://Salir break; case 3://Transicin break;

En ausencia de condiciones el enemigo se dedicar a vagar por el escenario. Definimos esta accin en el script scrVagar: //scrVagar() if (place_meeting(x+2*velocidadNormal*cos(degtorad(direction)), y2*velocidadNormal*sin(degtorad(direction)), objPared)){ var i; for (i=-1;i<=1;i+=2){ if (!place_meeting(x+2*velocidadNormal*cos(degtorad(direction+i*90) ), y-2*velocidadNormal*sin(degtorad(direction+i*90)), objPared)){ direction += i*90; break; }else if (i = 1) direction += 180; } } x += velocidadNormal*cos(degtorad(direction)); y -= velocidadNormal*sin(degtorad(direction));

Este script hace que el enemigo se mueva en la direccin en la que va. Si ve que siguiendo en esa direccin chocar con una pared, intenta moverse en una direccin perpendicular. Si an as choca con otra pared, se mueve en la otra direccin perpendicular. Si vuelve a chocar, se da la vuelta y vuelve por donde haba venido. Observad que para realizar los chequeos usamos 2*velocidadNormal. De esta forma podemos hacer que el enemigo "vea el futuro" y podr moverse de una manera ms realista, ya que si usramos el valor velocidadNormal tendra menos tiempo de reaccin y siempre ira pegado a las paredes. Para saber si hemos recibido un balazo nos serviremos del objeto objBala. En l, creamos el Evento de colisin con el objeto objEnemy y ponemos lo siguiente:

if ((parent.object_index != other.object_index)&&(other.estado_global = "")){ other.salud -=1; other.recibirBalazo = true; instance_destroy(); }

Como vis, es casi igual que el del jugador. Ahora definimos el estado Atacar:

switch argument0{ case 0://Entrar break; case 1://Ejecutar if (!scrJugadorVisible()) estado = "Patrullar"; else if ((scrDebil(4))&&(scrSolo())){ estado = "Huir"; execute_string(estado+"(0)"); }else{ if (!scrAcercarse(objPlayer)) scrPelear(); if ((scrDebil(2))&&(scrSolo())) scrEnviarMensaje(scrNearestFriend()); } break; case 2://Salir break; case 3://Transicin break; }

El script scrDebil se encargar de chequear si el enemigo tiene

menos de la energa indicada del jugador: //scrDebil(energia) if (instance_exists(objPlayer)){ if (salud < objPlayer.salud/argument0) return true; } return false;

El script scrNearestFriend devuelve la id del compaero ms cercano que no est muerto: var i, dist_min, nearest; dist_min = room_width; nearest = 0; for (i=0; i var friend, dist; friend = instance_id[i]; if ((friend.object_index = object_index)&&(friend.id != id)){ if (friend.estado_global = ""){ dist = distance_to_object(friend); if (dist nearest = friend; } } } } return nearest;

Por ltimo, el script scrAcercarse se encarga de acercarse al personaje hasta la distancia de ataque. Esto puede resultar bastante complejo ya que muchas veces el enemigo no podr ir directamente hasta donde se encuentre el jugador, ya que puede que haya paredes entre ellos. Para solucionar este problema vamos a usar las potentes funciones de planificaci?n de movimientos que incorpora GM. Con el fn de reducir el uso de memoria y aumentar la velocidad del juego, vamos a crear un objeto controlador para esto. Navegacin Creamos un objeto y lo llamamos objControlador. Este objeto se encargar de calcular los caminos libres que seguirn los enemigos. Su funcionamiento ser el siguiente: en un momento determinado un enemigo le pedir que calcule un camino para ir de un lugar a otro.

Este objeto calcular el camino y lo devolver como una path asociada a la instancia que le hizo la peticin. Ahora, la instancia slo tiene que seguir ese path y llegar a su destino de forma segura. Para realizar todo esto vamos a usar la versin de GM del famoso algoritmo A*. En el evento de creacin del objeto ponemos: var width, height; width = sprite_get_width(sprEnemyVivo); height = sprite_get_height(sprEnemyVivo); rejilla = mp_grid_create(0, 0, floor(room_width/width),floor(room_height/height), width, height); mp_grid_add_instances(rejilla, objPared, false); Con esto creamos una rejilla que divide el room en celdas del tamao de los enemigos y marcamos las celdas ocupadas por una pared como prohibidas. Si ponis este cdigo en el Evento Draw de este objeto podris ver la rejilla con las celdas marcadas, que coincidirn con donde habis puesto las paredes:

mp_grid_draw(rejilla);

Ahora, cuando desde un enemigo queramos pedirle que calcule un camino desde la posicin actual hasta la posicin del jugador tendremos que hacer: with (objControlador) mp_grid_path(rejilla, other.path, other.x, other.y, objPlayer.x, objPlayer.y, true);

Esta funcin crea un path y lo guarda en other.path, e decir, en la variable path de la instancia de objEnemy que la llam. Por ello, tenemos que crear esta variable en objEnemy:

path = path_add();//creamos un path vac?o

Ahora ya podemos crear el script scrAcercarse: //scrAcercarse(objetivo) if (instance_exists(argument0)){ if (distance_to_object(argument0) > 100 ){ if (path_index != path){ with (objControlador) mp_grid_path(rejilla, other.path, other.x, other.y, argument0.x, argument0.y, true); path_start(path, velocidadRapida, 0, true); }else if (path_position = 1) path_end(); return true; }else path_end(); } return false;

El script devuelve false si el enemigo est suficientemente cerca como para atacar y true si todava debe acercarse (adems calcula un path y se lo asigna al enemigo). El siguiente script que necesitamos es scrPelear:

direction = point_direction(x, y, objPlayer.x, objPlayer.y ); var i; if (esquiva = 0) { giro *= -1; esquiva = esquivaMax; }else esquiva -= 1; if (place_meeting(x+2*velocidadNormal*cos(degtorad(direction+giro)), y-2*velocidadNormal*sin(degtorad(direction+giro)),objPared)) esquiva = 0; else{

x += velocidadNormal*cos(degtorad(direction+giro)); y -= velocidadNormal*sin(degtorad(direction+giro)); } scrDisparar(true);

El enemigo apunta al jugador y comienza a disparar mientras se va moviendo alrededor de l y cambiando de direccin. Para poder manejar este script necesitamos declarar las variables siguientes:

giro = 90; tiempoGiroMax = 150; tiempoGiro = tiempoGiroMax;

Enemigos (II) El siguiente estado es Huir. En este estado el enemigo intentar huir hasta la posicin del compaero ms cercano:

switch argument0{ case 0://Entrar break; case 1://Ejecutar if (!scrAcercarse(scrNearestFriend())) estado = "Patrullar"; break; case 2://Salir break; case 3://Transici?n break; }

Listo!

Ahora creamos el estado global EnemigoMuerto: switch argument0 { case 0://Entrar sprite_index = sprEnemyMuerto; break; case 1://Ejecutar break; case 2://Salir break; case 3://Transicin break; }

Podemos hacer una copia del sprite sprEnemyVivo, oscurecerlo un poco y guardarlo como sprEnemyMuerto. Ya hemos llegado al ltimo estado, Ayudar. En este estado el enemigo se dirige hasta el compaero que le pidi ayuda para socorrerle. Pero antes de crearlo, vamos a hacer primero el sistema de mensajes. Sistema de mensajes El sistema de mensajes estar controlado por el objeto objControlador que ya habamos creado. En su Evento Create definimos el sistema:

mensajes = ds_queue_create(); mensaje_id=0 mensaje_remitente=ds_map_create(); mensaje_destino=ds_map_create();

En esta ocasin slo tenemos un tipo de mensaje. Adem?s, no vamos a mostrar el texto as que no necesitamos inclu?rlo. Y como todos los

mensajes van a tener la misma prioridad podemos usar una cola normal y corriente. Creamos ahora nuestro script para enviar mensajes, scrEnviarMensaje

//scrEnviarMensaje(Destino) var Id, Remitente, Destino; Id = objControlador.mensaje_id; Remitente = id; Destino = argument0; ds_queue_enqueue(objControlador.mensajes, Id); //Aadir las caractersticas asociadas al mensaje a los mapas de memoria ds_map_add(objControlador.mensaje_remitente, Id, Remitente); ds_map_add(objControlador.mensaje_destino, Id, Destino); //aumentar el identificador del mensaje objControlador.mensaje_id +=1;

Igual que hicimos en el tutorial anterior, el objeto controlador se encargar de leer los mensajes con el script scrRecibirMensaje:

if !ds_queue_empty(mensajes){ var Id, Remitente, Destino; Id = ds_queue_dequeue(mensajes); Remitente = ds_map_find_value(mensaje_remitente,Id); ds_map_delete(mensaje_remitente,Id); Destino = ds_map_find_value(mensaje_destino,Id); ds_map_delete(mensaje_destino,Id); Destino.mensaje = 0; Destino.remitente = Remitente; }

En este caso, guardamos el remitente en una variable de la instancia a la que mandamos el mensaje (Destino.remitente = Remitente;). Por ello, debemos definir esta variable en objEnemy:

remitente = 0;

En el Event Step de objControlador indicamos que lea los mensajes:

scrRecibirMensaje();

Ahora ya podemos crear el ltimo estado, Ayudar:

switch argument0{ case 0://Entrar mensaje = -1; break; case 1://Ejecutar if (!scrAcercarse(remitente)){ remitente = 0; estado = "Patrullar"; } break; case 2://Salir break; case 3://Transicin break; }

Ya hemos terminado con la IA! :D Creando un nivel Lo nico que nos falta es crear un nivel y ponernos a jugar. Creamos una room y en Creation code inicializamos el room, creando el objeto controlador, el objeto del jugador, inicializando las propiedades de la vista y rodeando el nivel de paredes:

var w, h; w = sprite_get_width(sprPared); h = sprite_get_height(sprPared); instance_create(0, 0, objControlador); var i; for (i=0;i instance_create(i, 0, objPared); instance_create(i, room_height-h, objPared); } for (i=0;i instance_create(0, i, objPared); instance_create(room_width-w, i, objPared); } instance_create(2*w, room_height-2*h, objPlayer); view_hborder[0] = ((view_wview[0]sprite_get_width(sprPlayerVivo))/2) -1; view_vborder[0] = ((view_hview[0]sprite_get_height(sprPlayerVivo))/2) -1;

En la pestaa de las views tendremos que activar la View 0 y hacerla visible al comienzo del room. Ahora desde el editor de rooms aadimos unas cuantas paredes para crear un nivel laberntico con algunas zonas despejadas para pelear y ponemos unos cuantos enemigos. Ejecutamos el juego e intentamos sobrevivir :D Conclusiones Hemos creado un Quake sencillo en 2D basndonos en la arquitectura de FSM. Hemos usado un montn de scripts, de forma que los estados de las entidades que tenan ms o menos esta forma:

switch estado{ case 0: break; case 1:

if (condicion1){ estado = "NuevoEstado1"; }else if (condicion2){ estado = "NuevoEstado2"; }else{ //acciones } break; }

De esta forma la IA se puede programar muy sencillamanete ya que bsicamente se reducen a una serie de if(){}else if(){}else if (){}.... Esto adems hace que sea tremendamente sencillo aadir nuevos estados o modificar la lgica de los ya presentes. En juegos como Unreal o Quake se usa este mismo sistema para programar la IA de los bots (los enemigos). Pero adems, utilizan otros mtodos para hacer que los bots "aprendan" e intenten sorprender al jugador en cada partida. Para ello, se modifica la lgica de los estados usando mtodos como los algoritmos genticos, las redes neuronales o las secuencias de reglas SOAX. En prximos tutoriales veremos cada una de estas tcnicas y aprenderemos a implementarlas para crear personajes verdaderamente inteligentes. correojon, 27 de Mayo de 2006

OCT

22

2007

IA: FSM III

by Fenris78 | 159 Views | 0 Comments | Rating: (0 rates)

En esta nueva entrega del curso de FSMs continuaremos con el ejemplo anterior y lo haremos un poco ms complejo introduciendo la capacidad de enviar y recibir mensajes. Para empezar, aadiremos la Central de Polica, capaz de comunicarse con el polica. Descripcin La Central de Polica podr enviar diferentes tipos de mensajes:

"Atraco en el banco": un aviso que har que el polica deje lo que est haciendo y vaya al banco a parar el atraco. "Informacin sobre un criminal": con este mensaje el polica recibir un aviso para ir a la comisara y recibir informacin sobre un criminal, lo que le facilitar su captura. El Polica slo recibir este mensaje si se encuentra patrullando. Adems, el polica podr enviar mensajes a la Central: "Mandar una unidad": si el polica est ocupado y presencia un delito, enviar un mensaje a la Central para que manden una unidad a hacerse cargo. El polica tendr ahora 2 nuevos estados, IrAlBancoYDetenerAtraco e IrALaCentralYRecibirInfo. Su tabla de transiciones ser ahora:

Condicin\Es BuscarY Entregar IrAlBAr IrAlBan IrALaCe *IrACa tado Atrapar Criminal YBeber co ntral sa* Agresividad>= Entregar X Agresividad Criminal criminal Detenciones= Detenciones X requeridas Detenciones Mensaje "Atraco!" Mensaje "Informaci?n" X X X X X

IrAlBarY X Beber BuscarY X Atrapar

X X

X X

X X

IrAlBanc IrAlBanc IrAlBan X o o co IrALaCe X ntral X IrACasa X X X X

IrAlBan X co X X

Agresividad>= X 7 Cansancio>= Cansancio_ma IrACasa x Cansancio=0 & Detenciones> X =Detenciones requeridas Atraco X

BuscarY X Atrapar

IrACas IrACasa IrACasa X a

BuscarY Atrapar X

IrAlBarY X

detenido Atraco no detenido X X X

Beber BuscarY X Atrapar X

Recordad que el estado IrACasaYDormir es un estado global y que al salir de l se puede volver al estado anterior que se estaba ejecutando. He tenido que acortar los nombres de los estados para que la tabla no saliera demasiado grande. Recordad que los estados del polica eran: BuscarYAtraparCriminales EntregarCriminal IrAlBaryBeber **IrACasaYDormir** IrAlBancoYDetenerAtraco IrALaCentralYRecibirInfo Para que el polica responda cuando recibe un mensaje, aadimos una nueva caracterstica en su Evento Create junto con las que ya habamos definido en el tutorial anterior: [code] mensaje = -1; [/code] Esta variable tomar distintos valores dependiendo del mensaje que reciba el polica, as podremos chequear qu valor tiene y actuar en consecuencia. Bueno, es hora de ver cmo haremos el sistema de mensajes. Sistema de mensajes Antes de definir el sistema de mensajera, hay que describir las caractersticas que tendrn los mensajes en s: Id: identificador del mensaje. Remitente: quien lo enva (id de la instancia que enva el mensaje). Destino: a quin va dirigido (id de la instancia que recibir el mensaje). Tipo: tipo de mensaje (0=Aviso de atraco, 1=Recibir informacin, 2=Avisar de un delito"). Los campos Remitente y Destino son muy importantes. Usando las

ids de las instancias podremos decir exactamente a qui?n va dirigido el mensaje. Adems, si en nuestro juego existe ms de un polica o ms de una central ser imperativo determinar a quin queremos enviarle el mensaje. Usando la variable id de GM podemos hacerlo sin mayores complicaciones. Para el sistema de mensajes vamos a utilizar una cola de prioridad. Una cola de prioridad es una estructura de datos de GM que permite introducir valores asignndoles una prioridad. As, podemos poner una prioridad alta a los mensajes importantes para que sean atendidos antes que los mensajes menos importantes. Adems, para manejar todo el sistema de mensajes usaremos un objeto controlador. Creamos un nuevo objeto y lo llamamos obj_ControlMensajes. En su Evento Create ponemos el siguiente cdigo: [code] mensajes = ds_priority_create(); mensaje_id=0; [/code] Con esto creamos nuestra lista de prioridad e inicializamos la variable mensaje_id que nos servir para ir asignando a cada mensaje un identificador nico. As podremos distinguir los mensajes entre s. Para guardar las caractersticas de los mensajes usaremos mapas de memoria, que son otra estructura de datos de GM. Los mapas nos permiten aadir un valor y asociarlo a una clave. As, podremos guardar las caractersticas de cada mensaje y asociarlas al identificador del mensaje para poder acceder a ellas cuando las necesitemos. Aadimos lo siguiente: [code] mensaje_remitente=ds_map_create(); mensaje_destino=ds_map_create(); mensaje_tipo=ds_map_create(); [/code] Por ltimo creamos un vector que guardar el texto del mensaje. Los mensajes podran ser de 3 tipos (0, 1 ? 2), as: [code] mensaje_texto[0] = "Se esta produciendo un atraco en el banco!"; mensaje_texto[1] = "Dirigete a la central para recibir informacion"; mensaje_texto[2] = "Se esta produciendo un delito, enviad una unidad!"; [/code]

Puede que os parezca que utilizar un objeto para esto es un gasto intil, ya que podra hacerse con variables globales y que cada instancia se encargara de sus mensajes. Sin embargo si lo hacemos de esa forma tendremos muchos problemas cuando tengamos varias instancias, ya que todas ellas estarn accediendo a la vez a los mismos recursos (la lista de prioridad y los mapas de memoria), con lo que facilmente podremos provocar errores. De esta otra forma, con un objeto controlador, dejamos todo el sistema de mensajes en sus manos con lo que ser muy difcil que algo vaya mal. Adems as ser mucho ms facil incluir nuevos objetos que puedan enviar y recibir mensajes (veris esto de froma mucho ms evidente segun avance el tutorial). Enviar mensajes Con todo esto, ya podemos crear el script enviarMensaje que servir para (quin lo dira? :P) enviar mensajes. Este script ser ejecutado directamente por las instancias del polica y la central: [code] //enviarMensaje(Destino, Tipo) var Id, Remitente, Destino, Tipo; Id = obj_ControlMensajes.mensaje_id; Remitente = id; Destino = argument0; Tipo = argument1; var prioridad; switch Tipo{//Calcular la prioridad del mensaje dependiendo del tipo case 0: prioridad = 3; break; case 1: prioridad = 1; break; case 2: prioridad = 2; break; } /Aadir el mensaje a la cola de prioridad ds_priority_add(obj_ControlMensajes.mensajes, Id, prioridad); //Aadir las caracter?sticas asociadas al mensaje a los mapas de

memoria ds_map_add(obj_ControlMensajes.mensaje_remitente, Id, Remitente); ds_map_add(obj_ControlMensajes.mensaje_destino, Id, Destino); ds_map_add(obj_ControlMensajes.mensaje_tipo, Id, Tipo); //aumentar el identificador del mensaje obj_ControlMensajes.mensaje_id +=1; //Mostrar el mensaje show_message("Mensaje enviado:#"+obj_ControlMensajes.mensaje_texto[Tipo]); [/code] Observad que para enviar un mensaje slo necesitamos pasarle 2 argumentos al script: Destino y Tipo. Esto es debido a que el valor de la Id del mensaje se coge de la variable obj_ControlMensajes.mensaje_id y por tanto no hace falta pasrsela como argumento al script ya que ste podr acceder a ella directamente. Como slo har 1 nica instancia del objeto obj_ControlMensajes no habr lugar a errores. A su vez, el Remitente ser la id de la instancia que enva el mensaje, es decir, la id de la instancia que ejecute el script enviar_mensaje(). Por lo tanto, esta variable tambin ser accesible directamente desde el script. El siguiente paso ser (cmo no? :P) crear el sistema para recibir y leer los mensajes. Recibir y leer mensajes El objeto obj_ControlMensajes se encargar de chequear la cola de prioridad de mensajes para ver si hay mensajes nuevos. Si es as, coger el mensaje con mayor prioridad y lo enviar al destino adecuado. Creamos un script llamado recibirMensaje y ponemos lo siguiente: [code] if !ds_priority_empty(mensajes){//Si hay mensajes en la cola var Id, Remitente, Destino, Tipo; //encontrar la id del mensaje con ms prioridad y borrarlo de la cola Id = ds_priority_delete_max(mensajes); //obtener las caracter?sticas del mensaje y borrarlas de los mapas

Remitente = ds_map_find_value(mensaje_remitente,Id); ds_map_delete(mensaje_remitente,Id); Destino = ds_map_find_value(mensaje_destino,Id); ds_map_delete(mensaje_destino,Id); Tipo = ds_map_find_value(mensaje_tipo,Id); ds_map_delete(mensaje_tipo,Id); //Notificar al remitente de que tiene un mensaje Destino.mensaje = Tipo; //Mostrar el mensaje show_message("Mensaje recibido:#"+mensaje_texto[Tipo]); } [/code] Es muy importante llevar un control estricto de los mensajes, eliminndolos cuando los leemos y borrando sus valores de todos los mapas de memoria para ahorrar memoria y evitar errores. Observad que en este caso concreto no hemos usado para nada el valor del Remitente. Sin embargo me ha parecido interesante incluirlo para que veis cmo se pueden manejar los datos a travs del mensaje. Adems, como el valor de Remitente es la id de la instancia que envi el mensaje, podis usarlo para acceder a cualquier caracterstica de esta instancia. Por ejemplo, podrs modificar el cdigo para mostrar el mensaje y que incluyera el nombre de la instancia que lo enva. Por ejemplo, si la Central tiene una caracterstica que es nombre e indica el nombre de la comisara, podrais mostrarlo haciendo: [code] show_message("Mensaje recibido de "+Remitente.nombre+":#"+mensaje_texto[Tipo]); [/code] Y as el mensaje que se mostrara en pantalla podra ser algo como: [quote="Mensaje recibido"] Mensaje recibido de Comisara del Norte: Se esta produciendo un atraco en el banco!! [/quote] Tambin podis usar este valor para actuar sobre las caractersticas de la otra instancia. Si el polica encuentra a un criminal y no tiene agresividad suficiente para detenerlo puede enviar un mensaje pidiendo refuerzos. La central recibira el mensaje y con la id del Remitente podra aumentar al agresividad de ste: [code]Remitente.agresividad += 1;[/code]

Lo nico que nos queda es ir al [b]Evento Step[/b] del [b]obj_ControlMensajes[/b] y decirle que realize el chequeo de mensajes: [code] recibirMensaje(); [/code] Listo! Bueno, con esto ya hemos terminado el sistema de mensajes! Lo siguiente que haremos ser modificar la IA del polica para que reaccione a los mensajes que le lleguen y para que l mismo enve sus propios mensajes. Actualizacin de la IA del polica Para que tengis ms a mano la tabla de transiciones la vuelvo a poner aqu, estudiarla atentamente para poder entender el comportamiento del polica:

Condicin\Es BuscarY Entregar IrAlBAr IrAlBan IrALaCe *IrACa tado Atrapar Criminal YBeber co ntral sa* Agresividad>= Entregar X Agresividad Criminal criminal Detenciones= Detenciones X requeridas Detenciones Mensaje "Atraco!" X X X X X

IrAlBarY X Beber BuscarY X Atrapar

X X

X X

X X

IrAlBanc IrAlBanc IrAlBan X o o co X X X X

IrAlBan X co X X

Mensaje IrALaCe X "Informacin" ntral Agresividad>= X 7 Cansancio>= Cansancio_ma IrACasa x Cansancio=0 X & Detenciones> X IrACasa

BuscarY X Atrapar

IrACas IrACasa IrACasa X a X X X BuscarY Atrapar

=Detenciones requeridas Atraco detenido Atraco no detenido X X X X X X IrAlBarY X Beber BuscarY X Atrapar X X

Como hemos dicho al principio, el polica tendr ahora 2 nuevos estados. El primero de ellos ser IrAlBancoYDetenerAtraco. En este estado, el agente ir al banco e intentar detener el atraco con una probabilidad de xito del 50% ([b]floor(random(2))[/b]). Si lo consigue se ir al bar a celebrarlo, si no, volver a patrullar para buscar a los culpables: [code] switch argument0{ case 0://Entrar show_message("Voy corriendo!"); break; case 1://Ejecutar if (floor(random(2))){ show_message("Alto! Nadie va a robar este banco en mi turno"); execute_string(estado+"(2)");//ejecutar acciones de salida estado="IrAlBarYBeber"; }else{ show_message("He llegado demasiado tarde...voy a buscar a los culpables de esto!"); estado="BuscarYAtraparCriminales"; } break; case 2://Salir show_message("Conseguido! Esto hay que celebrarlo"); break; case 3://Transicin break; } [/code] El otro estado del polica es IrALaCentralYRecibirInfo. En este estado el polica acudir a la central para recibir informacin sobre los malhechores. Su agresividad ir aumentando, de forma que tendr

ms xito al detener criminales. Cuando su agresividad crezca lo suficiente, volver a patrullar las calles: [code] switch argument0{ case 0://Entrar show_message("Voy corriendo a la central"); break; case 1://Ejecutar if (agresividad>=7){ show_message("Esta informaci?n me va a resultar muy util para detener criminales");? estado="BuscarYAtraparCriminales"; }else{ show_message("Necesito mas informacion..."); agresividad+=1; } break; case 2://Salir break; case 3://Transicin break; } [/code] Lo ltimo que nos falta es modificar el cdigo del [b]Evento Step[/b] del polica para que pueda recibir mensajes: [code] if (keyboard_check(vk_escape)){ game_end(); } if (estado_global != ""){ execute_string(estado_global+"(1)"); }else{ cansancio += 1; if (cansancio >= cansancio_max){? estado_global = "IrACasaYDormir";? execute_string(estado_global+"(0)");? }else{ if (mensaje=0){ estado = "IrAlBancoYDetenerAtraco";

execute_string(estado+"(0)"); mensaje = -1; } execute_string(estado+"(1)"); } } [/code] El polica poda recibir 2 tipos de mensajes: 0: Atraco en el banco 1: Informacin sobre un criminal Si el mensaje es de tipo=0 (Atraco en el banco) el polica dejar lo que est haciendo y se dirigir al banco. En cierta forma, es como si el estado IrAlBancoYDetenerAtraco fuera un estado global, ya que puede interrumpir a todos los dems excepto al estado global IrACasaYdormir. Por eso, resulta ms sencillo implementarlo en el cdigo general de la FSM (el polica) en el evento step, en lugar de ir al cdigo de cada estado y aadir la misma condicin una y otra vez. Observad que volvemos a poner [b]mensaje = -1[/b] porque el mensaje ya se ha recibido y se ha actuado, con lo que ya nos podemos librar de l. Sin embargo el otro mensaje (tipo=1, Informacin sobre un criminal) slo tendr sentido en el estado BuscarYAtraparCriminales. As que vamos al cdigo de este estado y lo modificamos: [code]switch argument0{ case 0://Entrar show_message("Me faltan "+string(detenciones_maxdetenciones)+" detenciones"); break; case 1://Ejecutar if (mensaje=2){ estado = "IrALaCentralYRecibirInfo"; execute_string(estado+"(0)"); }else{ agresividad_criminal = floor((random(10))); if (agresividad >= agresividad_criminal){ show_message("He detenido a un criminal"); detenciones += 1; //CAMBIAMOS DE ESTADO? estado = "EntregarCriminal";

execute_string(estado+"(0)");//Ejecutar las acciones de entrada al nuevo estado }else{ show_message("Se me ha escapado un criminal. El tenia agresividad "+string(agresividad_criminal)+" y yo solo "+string(agresividad)); agresividad += 1; } } break; case 2://Salir break; case 3://Transicin break; } [/code] Con esto hemos terminado con el sistema de recepcin de mensajes pero tambin queremos que el polica los enve. El polica enviar un mensaje de tipo 2 (informar de un delito) cuando se encuentre en el estado EntregarCriminal y vea un delito. As que vamos al cdigo del estado EntregarCriminal: [code] switch argument0{ case 0://Entrar show_message("Voy a la comisaria a entregar al criminal"); if (!floor(random(3))){ enviarMensaje(obj_central,2); } break; case 1://Ejecutar if (detenciones >= detenciones_max){ show_message("Ya he cumplido con mi labor, creo que ire a celebrarlo al bar."); estado = "IrAlBarYBeber"; }else{ show_message("Ya llevo "+string(detenciones)+" detenciones"); estado = "BuscarYAtraparCriminales"; } execute_string(estado+"(0)");

break; case 2://Salir break; case 3://Transicin break; } [/code] El polica enviar un mensaje con una probabilidad del 33%. Observad que en este caso slo existe una instancia del objeto obj_central, con lo que podemos enviar el mensaje usando el nombre del objeto (obj_central) como destino del mensaje (enviarMensaje(obj_central,2);). Cuando haya ms de una instancia del mismo objeto tendremos que usar la id para mandar el mensaje a la instancia correcta. Si usramos el nombre del objeto, el mensaje se enviara a todas las instancias del objeto (lo que tambi puede ser algo til, por ejemplo para avisar a todos los policas a la vez para que vayan al banco a detener el atraco). El polica ahora es capaz de recibir mensajes, actuar segn ellos y enviar los suyos propios. Como habis visto, para poder usar el sistema de mensajes casi no hemos hecho cambios. Estos es gracias a que hemos puesto toda la funcionalidad de los mensajes en el objeto [b]obj_ControlMensajes[/b]. As podremos poner cualquier otro personaje en el juego y darle facilmente la capacidad de enviar y recibir mensajes. Y como prueba de esto ltimo, vamos a aadir por fn la Central de polica. La Central de polica La Central de polica ser algo muy sencillo: bsicamente mandar mensajes al polica aleatoriamente y enviar unidades cuando el polica se lo pida. Como siempre, pimero definimos sus estados: Vigilar: en este estado la central mandar mensajes al polica de forma aleatoria para que vaya al banco o acuda a recibir informacin. EnviarUnidad: la central enviar una unidad de polica a investigar los avisos del polica. Para controlar estos estados, necesitaremos unas caractersticas:

Tiempo de envo: un contador de tiempo para enviar mensajes. As, la tabla de transiciones de la central ser: Condicin\Estado actual Vigilar EnviarUnidad Mensaje "Mandar una unidad" EnviarUnidad X Como veis, es muy sencilla. Al recibir un mensaje enviar una unidad. Despus, volver al estado Vigilar. Bien, creamos un objeto llamado obj_central y su Create Event definimos las caractersticas de la FSM como hicimos con el polica: [code] /*CARACTERISTICAS DE LA FSM*/? estado = "Vigilar";? mensaje = -1; [/code] En este caso no necesitamos definir ningn estado global. A continuacin definimos las caractersticas de la central: [code] tiempo_envio = 15+floor(random(15)); [/code] En el Evento Step definimos el funcionamiento de la FSM: [code] execute_string(estado+"(1)"); [/code] Y ahora definimos los estados. Creamos el script EnviarUnidad: [code] switch argument0{ case 0://Entrar break; case 1://Ejecutar show_message("Enviamos una unidad a investigar"); estado = "Vigilar"; break; case 2://Salir break; case 3://Transicin break; }

[/code] Y el script Vigilar: [code] switch argument0{ case 0://Entrar break; case 1://Ejecutar if (mensaje = 2){ estado = "EnviarUnidad"; mensaje = -1; }else{ if (tiempo_envio>1){ tiempo_envio -= 1; }else{ enviarMensaje(obj_policia,floor(random(2))); tiempo_envio = 15+floor(random(15)); } } break; case 2://Salir break; case 3://Transicin break; } [/code] Listo! Ya hemos terminado con nuestro sistema de FSM con mensajera! :D Mejoras y ampliaciones En el ejemplo que hemos creado los mensajes se envan y reciben instant?neamente. Podis aadir mensajes con retardo, de forma que el destinatario no los reciba inmediatamente sino que se guarden en la cola durante un tiempo (sera una nueva caracterstica de los mensajes y requerira de otro mapa de memoria). As podrais ver cmo funciona el sistema cuando hay varios mensajes circulando a la vez. Crear varias instancias de los policas y hacer que se enven mensajes entre ellos. Por ejemplo, hacer que pidan ayuda al polica con mayor agresividad.

Ahora que ya tenemos un objeto controlador (obj_ControlMensajes) del slo existir un instancia podemos quitar el cdigo para salir del juego pulsando Escape del evento step del polica y ponerlo en el evento step de este objeto. Consideraciones finales Los sistemas de mensajes son una caracter?sica muy importante en los juegos. Seguramente no habais odo hablar antes de ellos, pero seguro que os suenan si los llamo por su otro nombre: Eventos. As es, los juegos profesionales utilizan este sistema para crear y controlar los eventos del juego, como en GM. Cualquier objeto que use el sistema de mensajes podr comunicarse con los dems. Con unos ejemplos ver?is muy clara la importancia de esto: Cuando un personaje intenta abrir una puerta, le manda un mensaje a sta dicindole "Abrete!". La puerta recibe el mensaje y puede abrirse o responder con otro mensaje diciendo que est cerrada y que para abrirla necesita una llave. Un jugador empuja una caja. La caja recibe el mensaje de que est siendo empujada y debe moverse. Una bala golpea a un enemigo. La bala manda un mensaje al enemigo diciendo que debe morir y ste cambia su animacin, emite un grito... Un jugador de un equipo de ftbol avanza con el baln. Puede mandar un mensaje a los delanteros para que se desmarquen, otro a los defensas para que cubran su posicin y otro a un compaero para avisarle de que le va a pasar el baln. Resumiendo, para poder crear vuestra propia IA es indispensable saber manejar los eventos. GM nos proporciona muchas ventajas por su sistema de eventos, pero con este mtodo podris crear vuestros propios eventos especficos para cada juego consiguiendo unas IA ms complejas pero ms sencillas de programar que con el sistema de GM. correojon, 25 de Mayo de 2006 22 2007 IA: FSM III

OCT

by Fenris78 | 666 Views | 0 Comments | Rating: (0 rates)

Seguimos con la serie de artculos sobre Inteligencia Artificial. En esta ocasin, veremos cmo implementar un mquina de estados finita en GML. Para este ejemplo haremos un ejemplo sencillo, sin grficos ni nada, en el que la salida sern mensajes de texto.

Descripcin general En este ejemplo crearemos un polica que patrulla las calles buscando criminales. Si encuentra un criminal intentar atraparlo. Si lo consigue, lo llevar a comisara y lo meter a la crcel. Si no lo consigue, el polica se volver ms agresivo. Cuando consiga 5 detenciones el polica habr cubierto su cupo de detenciones diarias y podr irse al bar a celebrar el cumplimiento de su trabajo. Adems de todo esto, el polica se ir cansando con lo que llegado el momento, dejar lo que est haciendo y volver a su casa a dormir. Planificacin Antes de nada, hay que definir primero los estados de nuestro polica: BuscarYAtraparCriminales: en este estado el polica buscar criminales. Si encuentra uno, intentar atraparlo. EntregarCriminal: cuando detenga a un criminal, el polica lo llevar a la comisara. IrACasaYDormir: ir a casa cuando est cansado a echar un sueecillo. Este ser un estado global, capaz de interrumpir cualquier otro estado para ejecutarse. IrAlBarYBeber: ir al bar a tomar unas merecidas copas. Para poder pasar de un estado a otro deben cumplirse unas condiciones. Para ello, necesitaremos conocer las caractersticas del polica: Cansancio: nivel de cansancio actual del polica. Cansancio mximo: nivel mximo de cansancio que puede soportar el polica. Detenciones: nmero de detenciones que ha realizado. Detenciones requeridas: nmero de detenciones que necesita realizar para terminar su jornada laboral. Agresividad: agresividad del polica. Necesaria para atrapar criminales. Agresividad criminal: agresividad del criminal. Si es mayor que la del polica se escapar. Una vez que hemos definido todo esto, ya podemos escribir la tabla de transiciones del polica: Condicin\Estad BuscarYAtraparCri EntregarCriminal o actual minales IrAlBArYB eber

Agresividad>=Agre EntregarCriminal sividad criminal Detenciones=Dete X nciones requeridas Detenciones<> X

X IrAlBarYBeber

X X

BuscarYAtraparCri X minales

Como veis, en la tabla no aadimos la condicin para entrar al estado global IrACasaYdormir. Podra ponerse, pero sera algo tonto ya que sera igual para todos los estados: si Cansancio>=Cansancio mximo->IrACasaYdormir. Bueno, una vez que tenemos todo esto ya podemos empezar a programar. Caractersticas del polica Creamos el objeto obj_policia y en su Create Event inicializamos las caracter?sticas de la mquina de estados finitos: [code] /*CARACTERISTICAS DE LA FSM*/ estado = "BuscarYAtraparCriminales"; estado_global = "IrACasaYDormir"; [/code] Al comienzo del juego el polica se encontrar durmiendo en su casa. Cuando se ejecute el estado global interrumpir cualquier estado que estuviramos llevando a cabo. Una vez que finalize este estado, volveremos al estado anterior. Por ltimo, decimos que el estado global en este momento es IrACasaYDormir. De esta forma, este estado interrumpe al estado actual que definimos en la primera lnea (estado = "BuscarYAtraparCriminales") y as conseguiremos que inicialmente el polica se encuentre en casa durmiendo. A continuacin inicializamos las caractersticas del polica: [code] /*CARACTERISTICAS DEL POLICIA*/ cansancio = 0; cansancio_max = 10; detenciones = 0; detenciones_max = 5; agresividad = floor(random(10)); agresividad_criminal = 0; [/code]

Inicialmente el polica no est cansado (cansancio = 0). Adems, no ha realizado ninguna detencin (detenciones = 0). Su agresividad es aleatoria (agresividad = floor(random(10))). As cada vez que ejecutemos el juego el polica se comportar de manera diferente. Muy bien, ahora slo nos falta hacer que cada estado se ejecute. Para ello, en el Evento Step ponemos lo siguiente: [code] if (estado_global != ""){ ?execute_string(estado_global+"(1)"); }else{ ?execute_string(estado+"(1)"); } [/code] Veremos este cdigo con ms detalle cuando creemos la lgica de los estados, pero de modo genreal podemos decir que hace lo siguiente: Si hay un estado global (if (estado_global != "")) se ejecuta. Si no, ejecutamos el estado actual. Para ello, tenemos que crear unos scripts con los nombres de los estados. Dentro de estos scripts definiremos las acciones que realizar cada uno. Acciones Como ya vimos en el tutorial bsico sobre FSMs, las acciones dependen del estado actual. Tambin vimos que haba varios tipos de acciones (de entrada, de salida, de transicin y de ejecucin). Por ello, cada estado se comportar de forma diferente al entrar en l, salir de l, pasar a otro estado o ejecutarse normalmente. Creamos un script llamado BuscarYAtraparCriminales y ponemos lo siguiente: [code] switch argument0{ case 0://Entrar break; case 1://Ejecutar break; case 2://Salir break; case 3://Transicin break; }

[/code] Este script tendr 1 argumento, que controlar las acciones que se ejecuten. As: Si argument0 = 0 se ejecutarn las acciones de entrada. Si argument0 = 1 se ejecutarn las acciones de ejecucin. Si argument0 = 3 se ejecutarn las acciones de transicin. En este estado no habr acciones de salida. Describimos las acciones que se realizarn en el estado BuscarYAtraparCriminales: Al entrar en el estado el polica nos dir cuantas detenciones le faltan por hacer para cubrir su cupo. Al ejecutar el estado el polica intentar detener a los criminales. Si lo consigue, los llevar a la comisara, si no, aumentar su agresividad. Al salir del estado el polica no har nada, es decir, no habr acciones de salida. En este estado no habr acciones de transicin. Ahora que ya hemos definido las acciones, las metemos en el script: [code] switch argument0{ case 0://Entrar show_message("Me faltan "+string(detenciones_maxdetenciones)+" detenciones"); break; case 1://Ejecutar agresividad_criminal = floor((random(10))); if (agresividad >= agresividad_criminal){ show_message("He detenido a un criminal"); detenciones += 1; //CAMBIAMOS DE ESTADO estado = "EntregarCriminal"; execute_string(estado+"(0)");//Ejecutar las acciones de entrada al nuevo estado }else{ show_message("Se me ha escapado un criminal. El tenia agresividad "+string(agresividad_criminal)+" y yo solo "+string(agresividad)); agresividad += 1; } break; case 2://Salir

break; case 3://Transicin break; } [/code] Ahora vamos a programar el estado EntregarCriminal. En este estado el polica simplemente llevar al criminal a comisara, ver cuntas detenciones ha hecho y entonces decidir si captura ms criminales o se va al bar a tomarse unas copas: [code] switch argument0{ case 0://Entrar show_message("Voy a la comisaria a entregar al criminal"); break; case 1://Ejecutar if (detenciones >= detenciones_max){ show_message("Ya he cumplido con mi labor, creo que ire a celebrarlo al bar."); estado = "IrAlBarYBeber"; }else{ show_message("Ya llevo "+string(detenciones)+" detenciones"); estado = "BuscarYAtraparCriminales"; } execute_string(estado+"(0)"); break; case 2://Salir break; case 3://Transici?n break; } [/code] Bien, el siguiente estado ser IrAlBarYBeber. En este estado el polica simplemente se tomar unas copas hasta que est cansado y se quiera ir a casa. [code] switch argument0{ case 0://Entrar show_message("Jeje, ya estoy en el bar, se acabo el trabajo

por hoy!"); detenciones = 0; break; case 1://Ejecutar show_message("Hmmm...este whisky esta delicioso"); break; case 2://Salir break; case 3://Transicin break; } [/code] Como veis, este estado es muy sencillo y no necesita comentarios :) Ahora ya slo nos falta el estado global "IrACasaYDormir": [code] switch argument0{ case 0://Entrar show_message("Uff, que cansado estoy! Voy a dormir un rato"); break; case 1://Ejecutar if (cansancio > 0){ show_message("ZZzzzzzz...."); cansancio -= 1;//recuperarse }else{ show_message("Que bien me ha venido este descanso"); execute_string(estado_global+"(2)");//ejecutar acciones de salida if (detenciones = 0){ estado = "BuscarYAtraparCriminales"; } execute_string(estado+"(0)");//volver al estado anterior } break; case 2://Salir if (detenciones >= detenciones_max){ show_message("Listo para un nuevo dia de trabajo!"); detenciones = 0; }else{ show_message("Ya solo me quedan

"+string(detenciones_max-detenciones)); } estado_global = ""; break; case 3://Transicin break; } [/code] Casi hemos terminado, slo nos queda hacer que el polica se vaya cansando y que lance el estado global IrACasaYDormir cuando est demasiado cansado. Volvemos al Evento Step y modificamos el cdigo que tenamos: [code] /*SI MANTENEMOS PULSADO ESCAPE SALIMOS DEL JUEGO*/ if (keyboard_check(vk_escape)){ game_end(); } if (estado_global != ""){ execute_string(estado_global+"(1)"); }else{ cansancio += 1; if (cansancio >= cansancio_max){ estado_global = "IrACasaYDormir"; execute_string(estado_global+"(0)"); }else{ execute_string(estado+"(1)"); } } [/code] Listo! Ya hemos creado nuestra primera FSM en GML! :D Ampliaciones Podis practicar con este ejemplo, a?adiendo cosas como: Una nueva caracterstica llamada lugar que indique dnde se encuentra el polica en cada momento. As, esta variable podr tener los valores "casa", "comisaria", "calle" y "bar". Hacer que el polica diga cundo va de un sitio a otro (tendris que usar las acciones de entrada y salida de cada estado). Por ejemplo, en la

accin de salida del estado BuscarYAtraparCriminales el polica dir "Me voy a la comisaria" (si es que va a la comisara ;) ) y en la accin de entrada del estado EntregarCriminal dir algo como "Ya estoy en la comisaria". Nuevos estados, como Comer, Investigar (para encontrar informacin sobre dnde se encuentran los criminales)...Tendris que definir nuevas caractersticas para controlar estos estados, por ejemplo hambre para controlar el estado Comer. Comportamiento avanzado: por ejemplo, aadiendo el estado Investigar podis poner una nueva caracterstica llamada inteligencia. Si el polica tiene ms inteligencia que agresividad tal vez decida investigar un poco antes de intentar detener criminales. Si fracasa al intentar detener un criminal podis hacer que su inteligencia se reduzca. Hacer que la agresividad se reduzca despus de descansar y que la inteligencia aumente. Tambin podis hacer que el polica descanse un tiempo aleatorio, as no ser capaz de recuperarse del todo, la agresividad no se reducir siempre lo mismo ni la inteligencia crecer lo mismo...de esta forma las caractersticas del polica cambiarn constantemente y cada vez se comportar de una manera diferente! Os animo a que pongis aqu vuestros experimentos! Consideraciones finales De una manera sencilla hemos creado una IA, bastante simple pero muy robusta. Adems, se puede ampliar muy facilmente aadiendo nuevos estados y acciones. En la prxima entrega introduciremos la Central de Polica, capaz de enviar mensajes al polica dndole informacin sobre los criminales...por ejemplo, podremos despertar al polica con un aviso urgente para que vaya a detener el robo de un banco!

Listas.
veremos qu son las listas, cmo se usan y porqu resultan una herramienta tan poderosa. Definicin Extrado del Manual Online de CGM: Una lista guarda una coleccin de valores en un orden determinado. Puedes aadir valores a la lista en la posicin que desees. Por eso,

puedes acceder acceder a los valores usando un ndice de su posicin en la lista. Tambin 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 cdigo compilado son mucho ms rpidas que los arrays. A priori se puede decir que una lista es como un array: una coleccin de valores que se guardan en orden. Sin embargo las listas poseen unas funciones que hacen que sean una de las estructuras ms utilizadas para el manejo de grandes cantidades de datos de manera eficiente. Para poder usar una lista, primero debemos crearla con la funcin ds_list_create(). Esta funcin nos devuelve la id de la nueva lista creada, que tendremos que usar para llamar a las dems funciones de la lista. Para conocer las propiedades de la lista tenemos 2 funciones: ds_list_size(idLista) Devuelve el nmero de valores en la lista. ds_list_empty(idLista) Devuelve true si la lista est vaca. Para saber si la lista est vaca tenemos 2 opciones: llamar a la funcin ds_list_empty(idLista) o chequear si su tamao es igual a 0: //Este cdigo if (ds_list_empty(idLista){...} //es lo mismo que este otro if (ds_list_size(idLista) = 0){...} Para inicializar una lista, tenemos la funcin: ds_list_clear(idLista) Limpia la lista, borrando todos los valores que contiene pero no la destruye. Por ltimo, cuando ya no necesitemos la lista tenemos que eliminarla, ya que si la dejamos en la memoria nos estara ocupando espacio intilmente. Para ellos usamos la funcin: ds_list_destroy(idLista) Destruye la lista, liberando la memoria usada. Con estas funciones ya podemos crear una lista, ver su tamao, ver si est vaca y eliminarla. Ahora veremos las funciones para usar realmente las listas. Funciones ds_list_add(idLista,val) Inserta el valor al final de la lista. ds_list_insert(idLista,pos,val) Inserta el valor en la posicin pos. La primera posicin es 0 y la ltima es igual al tamao de la lista menos 1. ds_list_replace(idLista,pos,val) Reemplaza el valor en la posicin pos por val.

ds_list_delete(idLista,pos) Elimina el valor en la posicin pos. ds_list_find_index(idLista,val) Devuelve la posicin en la lista del valor val. Si no encuentra el valor en la lista devuelve -1. ds_list_find_value(idLista,pos) Devuelve el valor en la posicin pos. ds_list_sort(idLista,ascend) Ordena los valores de la lista. Si ascend es true o 1 los ordena de forma ascendente (de menor a mayor), en caso contrario los ordena de manera descendente (de mayor a menor). Con estas funciones podemos hacer muchas cosas de manera mucho ms sencilla y efectiva que usando arrays. Por ejemplo, para ordenar los valores de la lista de mayor a menor basta con poner esto: ds_list_sort(idLista, false); Recorriendo una lista Para recorrer una lista, lo hacemos igual que como lo haramos con un array: var i; for (i=0; i[ds_list_size(idLista); i+=1){ miValor = ds_list_find_value(idLista, i); draw_text(x, y+8*i, miValor);//Imprimimos los valores uno debajo de otro } Pero esta vez tenemos una gran ventaja y es que no necesitamos conocer el tamao de la lista. Con un array tendramos que saber el tamao exacto que tiene para poder coger todos los valores, pero con una lista la funcin ds_list_find_size(idLista) ya nos da esa informacin. Ejemplo: Programa sencillo de dibujo Para entender bien el funcionamiento de las listas, vamos a ver un ejemplo sencillo. Vamos a crear un panel en el que usuario podra dibujar formas sencillas. Cada vez que haga click con el botn izquierdo se aadir un punto y cada vez que haga click con el botn derecho se borrar el ltimo punto aadido. Evento create //Creamos las listas que guardarn las coordenadas de los puntos listaPuntosX = ds_list_create(); listaPuntosY = ds_list_create(); Al hacer click con el botn izquierdo aadimos un punto: Evento Mouse Global Left Pressed //Aadimos el punto al final de la lista ds_list_add(listaPuntosX, mouse_x); ds_list_add(listaPuntosY, mouse_y); Y al hacer click con el botn derecho borramos el ltimo punto

aadido Evento Mouse Global Right Pressed //Quitamos el ltimo punto de la lista ds_list_delete(listaPuntosX, ds_list_size(listaPuntosX)-1); ds_list_delete(listaPuntosY, ds_list_size(listaPuntosY)-1); Como vis, no hace falta llevar una cuenta de cuntos puntos hemos metido o quitado. Por ltimo, unimos todos los puntos con una lnea y los dibujamos: Evento Draw if (ds_list_size(listaPuntosX) ] 1){//si hay dos ms puntos en la lista draw_set_color(c_black); draw_primitive_begin(pr_linestrip); var i; for (i=0; i[ds_list_size(listaPuntosX); i+=1){ draw_vertex(ds_list_find_value(listaPuntosX, i),ds_list_find_value(listaPuntosY,i)); } draw_primitive_end(); } draw_set_color(c_red); var i; for (i=0;i[ds_list_size(listaPuntosX); i+=1){//dibujar los puntos draw_circle(ds_list_find_value(listaPuntosX, i),ds_list_find_value(listaPuntosY,i), 2, false); } Ya est, poned este objeto en una room vaca y cread arte XD. La principal ventaja que vemos en este ejemplo de las listas sobre los arrays es que no hace falta que llevemos la cuenta de los puntos que metemos en la lista. As mismo, tampoco necesitamos chequear nada cuando quitamos puntos. Si lo hubiramos hecho con arrays, tendramos que haber chequeado antes de borrar un punto de la lista que el array tena algn elemento o nos huberia salido un error de ndice negativo en el array. A parte de esto, otra clara ventaja de las listas es la de poder ordenar todos los valores con una simple llamada a la funcin ds_list_sort(idLista, ascend). Con arrays tendramos que programar un algoritmo de ordenacin que, adems, sera mucho menos eficiente. Tambin podemos saber en qu lugar de la lista se encuentra un valor con la funcin ds_list_find_index(idLista, pos), algo que con arrays sera tremendamente complicado de hacer. Tambin podemos insertar valores en cualquier posicin de la lista,

desplazando los dems con ds_list_insert(idLista, pos, val). De nuevo, esto sera bastante ms trabajoso de hacer con arrays. Colas. veremos otra estructura de memoria que podemos usar con GM: las colas. Es recomendable aunque no necesario haber ledo antes el artculo sobre listas. Definicin Extrada del Manual Online de CGM: 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 sera el primero en ser atendido y los dems tendrn que esperar su turno en orden. Los ltimos en llegar se situarn al final de la cola y tendrn que esperar a que sean atendidos todos los que tengan delante. Las primeras 5 funciones de las colas para crearlas, eliminarlas, vaciarlas o ver su tamao son iguales que las que vimos en las listas. ds_queue_create() Crea una nueva cola. La funcin devuelve un nmero 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 funcin 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 nmero de valores en la cola. ds_queue_empty(id) Devuelve true si la cola est vaca. Es lo mismo que chequear si el nmero de valores en la cola es cero. Funciones ds_queue_enqueue(id,val) Introduce el valor en la cola. ds_queue_dequeue(id) Devuelve el ltimo valor de la cola (el ltimo 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. Las funciones de las colas nos permiten hacer muchsimas cosas de manera muy sencilla, como veremos a continuacin. Recorriendo una cola Para recorrer una cola lo podemos hacer de manera muy sencilla

mientras vamos eliminando los valores: var d; d = 0; while (!ds_queue_empty(idCola)){ draw_text(x, y+8*d, ds_queue_dequeue(idCola));//Imprimimos los valores uno debajo de otro d += 1; } Observad que la variable temporal d slo la usamos para poder dibujar los valores de la cola uno debajo de otro. Para cualquier otra cosa no la necesitaramos! Es decir, que ni siquiera necesitamos un bucle for para recorrer una cola! Tambin hay que darse cuenta de que al final del bucle la cola estara vaca, ya que al usar la funcin ds_queue_dequeue(idCola) vamos borrando los valores de la cola. Entonces para qu sirve esto? Las colas se utilizan cuando hay que calcular algo en cada step y luego utilizar los resultados 1 sola vez. Ejemplo: Elegir a un enemigo sin repetir En este ejemplo vamos a hacer que el jugador, pulsando una tecla, apunte automticamente a un enemigo. Esto es muy sencillo de hacer pero, y si tenemos varios enemigos a la vez en pantalla? Y si adems queremos que al volver a pulsar la tecla, el jugador apunte a otro enemigo distinto? Vamos a ver cmo se hace esto usando colas: Creamos un objeto y lo llamamos objEnemigo: Evento Draw: -Dibujar un crculo rojo draw_set_color(c_red); draw_circle(x, y, 16, false); Muy bien, ahora creamos otro objeto y lo llamamos objJugador: Evento Create: -Crear la cola -Inicializar variables enemigos = ds_queue_create(); objetivo = 0; Evento Key Press Control: -Si la cola est vaca metemos los enemigos en la cola -Elegimos un enemigo y lo borramos de la cola if (ds_queue_empty(enemigos)){ with (objEnemigo){ ds_queue_enqueue(other.enemigos, id); } }

objetivo = ds_queue_dequeue(enemigos); Evento Draw: -Dibujar un tringulo azul apuntando al objetivo direction = point _direction(x, y, objetivo.x, objetivo.y); var d, dir; d = 16; dir = degtorad(direction); draw_set_color(c_blue); draw_primitive_begin(pr_trianglestrip); draw_vertex(x+(2*d)*cos(dir)+0*sin(dir), y+0*cos(dir)(2*d)*sin(dir)); draw_vertex(x+(-d/2)*cos(dir)+(-d)*sin(dir), y+(-d)*cos(dir)-(d/2)*sin(dir)); draw_vertex(x+(-d/2)*cos(dir)+d*sin(dir), y+d*cos(dir)-(d/2)*sin(dir)); draw_primitive_end(); Listo! Crear un room, poner uno o varios objetos jugadores, varios enemigos y probarlo. Cada vez que pulsis Control los jugadores irn apuntando a un enemigo diferente sin repetir! Las colas son muy rpidas y usan muy poca memoria si se utilizan correctamente, ya que tienen la capacidad de acceder y eliminar los valores que guardan al momento. Y para recorrerlas ni siquiera necesitamos acceder al ndice de cada elemento! Colas de prioridad. Las colas de prioridad son otra estructura de memoria, muy similares a las colas pero con algunas diferencias. Es recomendable aunque no necesario haber ledo antes el artculo sobre colas. Definicin Extrado del Manual Online de CGM: 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 segn su prioridad. Es decir, las colas de prioridad funcionan igual que las colas normales pero adems poseen una nueva caracterstica llamada prioridad que nos permite acceder a los valores de la cola de otra forma. Las primeras 5 funciones de las colas de prioridad para crearlas, eliminarlas, vaciarlas o ver su tamao son iguales que las que vimos en las listas y en las colas: ds_priority_create() Crea una nueva cola. La funcin devuelve un

nmero 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 funcin 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 nmero de valores en la cola. ds_priority_empty(id) Devuelve true si la cola est vaca. Es lo mismo que chequear si el nmero de valores en la cola es cero. Funciones ds_priority_add(id,val,prio) Aade 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. Como vis, ahora podemos acceder a los valors segn su prioridad. En el caso de que varios valores tengan la misma prioirdad la cola funionar como una cola normal, devolviendo el primero que introdujimos en la cola. Recorriendo una cola de prioridad Para recorrer una cola de prioridad lo ms sencillo es hacerlo por orden de prioridad. As, podemos elegir ir sacando primero los valores con menos prioridad: var d; d = 0; while (!ds_priority_empty(idCola)){ draw_text(x, y+8*d, ds_priority_delete_min(idCola));//Imprimimos los valores uno debajo de otro d += 1; } o sacando primero los valores con mayor prioridad: var d;

d = 0; while (!ds_priority_empty(idCola)){ draw_text(x, y+8*d, ds_priority_delete_max(idCola));//Imprimimos los valores uno debajo de otro d += 1; } Al igual que ocurra con las colas normales la variable temporal d slo la usamos para poder dibujar los valores de la cola uno debajo de otro. Para cualquier otra cosa no la necesitaramos! Es decir, que ni siquiera necesitamos un bucle for para recorrer una cola! Tambin hay que darse cuenta de que al final del bucle la cola estar vaca, ya que al obtener los valores los vamos borrando de la cola. Ejemplo: Elegir a un enemigo segn la distancia Para ver la utilidad de las colas de prioridad vamos a modificar el ejemplo que hicimos para las colas: en esta ocasin haremos que el personaje vaya apuntando en orden a los enemigos segn estn ms cerca o ms lejos. Es decir, primero apuntaremos al enemigo ms cercano, luego al segundo ms cercano, luego al tercero...y as hasta que hayamos apuntado a todos, momento en el que volveremos a apuntar al primero. Para ello slo necesitaremos editar un poco el cdigo del objPersonaje: Evento Create: -Crear la cola de prioridad -Inicializar variables enemigos = ds_priority_create(); objetivo = 0; Evento Key Press Control: -Si la cola est vaca metemos los enemigos en la cola, asignndoles como prioridad su distancia a objPersonaje -Elegimos un enemigo por oden de cercana y lo borramos de la cola if (ds_priority_empty(enemigos)){ with (objEnemigo){ ds_priority_add(other.enemigos, id, distance_to_object(other)); } } objetivo = ds_priority_delete_min(enemigos); Con esta pequea modificacin hemos conseguido que ahora el personaje elija a los enemigos segn su prioridad, que ser igual a la la distancia del enemigo al personaje. As, eligiendo a los enemigos en orden de prioridad mnima (objetivo = ds_priority_delete_min(enemigos)) vamos elegiendo primero a los ms cercanos.

Las colas de prioridad tienen un montn de usos. Por ejemplo, si aadimos varios valores a la cola y en el momento de aadirlos les damos una prioridad aleatoria sera como si los estuviramos desordenando, ya que no sabemos qu prioridad tendr cada valor. As, al acceder a los valores por prioridad podemos hacer una especie de sorteo: Aadiendo un valor con prioridad aleatoria: ds_priority_add(idCola, valor, random(10)); Eligiendo un valor por sorteo: resultado = ds_priority_find_min(idCola); As podemos el resolver el tpico problema de "tengo varios objetos y quiero coger algunos al azar, pero una vez que elija uno ste no debe volver a salir". Mapas de Memorias. Los mapas de memoria son una estructura que nos puede facilitar muchsimo la escritura de cdigos complicados. Definicin Extrado del Manual Online de CGM: 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 nmero 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, ordenndolos por la llave. Puedes aadir valores al mapa y buscar uno concreto usando las llaves. Como las llaves tambin estn ordenadas, puedes encontrar los valores correspondientes a la llave siguiente o anterior. A veces es til usar un mapa para guardar llaves sin ningn valor asignado. En este caso puedes asignarles a todas las llaves el valor 0. Como siempre, las primeras 5 funciones de los mapas sirven para crearlos, eliminarlos, vaciarlos o ver su tamao: ds_map_create() Crea un nuevo mapa. La funcin 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 funcin cuando ya no necesites el mapa. ds_map_clear(id) Limpia el mapa, borrando todos las parejas llavevalor que contiene pero no lo destruye. ds_map_size(id) Devuelve el nmero de parejas llave-valor en el mapa.

ds_map_empty(id) Devuelve true si el mapa est vaca. Es lo mismo que chequear si el nmero de valores en el mapa es cero. Funciones ds_map_add(id,key,val) Aade 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 slo 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. Con los mapas de memoria el sistema cambia mucho respecto a lo que habamos visto en las listas y colas. Los mapas se usan para guardar muchos valores y tenerlos de forma ordenada de manera que sea fcil acceder exactamente al valor que queremos. Ejemplo: Creando varios tipos de disparos Vamos a crear un ejemplo en el que el personaje pueda disparar 3 tipos de disparos diferentes. Pulsando + y - cambiaremos el tipo de disparo y con Espacio dispararemos. Creamos el objeto objJugador Evento Create: -Crear la variable que guarda el tipo de disparo usado -Crear el mapa de memoria con los tipos disparo = 0; disparos = ds_map_create(); ds_map_add(disparos, 0, "normal"); ds_map_add(disparos, 1, "doble"); ds_map_add(disparos, 2, "triple"); Evento Press Keypad +: -Usar el siguiente tipo de disparo disparo = ds_map_find_next(disparos, disparo); Evento Press Keypad -: -Usar el tipo de disparo anterior disparo = ds_map_find_previous(disparos, disparo);

Evento Press Space: -Crear las balas segn el tipo de disparo tipo = ds_map_find_value(disparos, disparo); with (instance_create(x, y, objBala)){//crear la bala ?tipo = other.tipo;//definir el tipo de la bala ?event_perform(ev_other, ev_user0);//Inicializar caractersticas de la bala } Evento Draw: -Dibujar al jugador draw_set_color(c_blue); draw_circle(x, y, 16, false); Ahora creamos el objeto objBala: Evento Create: -Definir los mapas con las caractersticas de cada tipo de disparo /*COLORES*/ colores = ds_map_create(); ds_map_add(colores, "normal", c_black); ds_map_add(colores, "doble", c_red); ds_map_add(colores, "triple", c_white); /*VELOCIDADES*/ velocidades = ds_map_create(); ds_map_add(velocidades, "normal", 4); ds_map_add(velocidades, "doble", 8); ds_map_add(velocidades, "triple", 16); Evento User Defined 0: -Inicializar las caractersticas de la bala speed = ds_map_find_value(velocidades, tipo); Evento Draw: -Dibujar la bala segn su tipo draw_set_color(ds_map_find_value(colores, tipo)); draw_circle(x, y, 4, false); Las ventajas de este mtodo son muy importantes: -Podemos identificar facilmente en el cdigo la parte de cada bala, ya que las variables se llaman "normal", "doble", "triple" o como queramos. -El sistema es facilmente ampliable: slo hay que definir las caractersticas de los nuevos tipos de balas que queramos aadir el indicarlo en el evento Create del objeto jugador. El resto (aplicar velocidad a la bala, color, cmabiar de arma...) se hace automticamente!

Esto mismo se puede usar para crear nuevos tipos de personajes con caractersticas diferentes, niveles, objetos... DLL. vamos a hablar de DLLs. DLL es el acronimo de "Dinamic Link library" (Biblioteca de enlace dinamico), para ser breves y claros, podemos definirla como un peque?o programa hecho en un lenguaje compatible (Delphi, C/C++, Pascal... ) que contiene funciones que pueden ser llamadas desde GM y nos sirven para cubrir aquellas necesidades que no pueden ser satisfechas con GM o que pueden ser optimizadas. (Como reproducir diferentes archivos de audio, ver animaciones flash, embeber paginas html en tus juegos... etc) Como cada DLL contendra diferentes funciones, su uso varia, ya que el numero de argumentos que recoja cada funcion y el tipo de dato devuelto sera diferente. En cualquier caso, el uso especifico de cada DLL en particular siempre debe venir documentado junto con el archivo. Entonces nos vamos a limitar a explicar que es una DLL y nada mas? No, vamos a dar un pasito mas. Vamos a explicar el procedimiento basico para utilizar dos DLLs ficticias, para que os vayais familiarizando con la definicion y llamada de DLLs en GML. Primero es necesario definir la DLL, para ello GM nos proporciona la siguiente funcion: external_define (dll,name,calltype,restype,argnumb,arg1type,arg2type, ) Define una funcin externa. dll es el nombre del archivo dll. name es el nombre de las funciones. calltype es la convencin de llamada empleada. Usa dll_cdecl o dll_stdcall. restype es el tipo del resultado. Usa ty_real o ty_string. argnumb es el nmero de argumentos (0-11). Despus, para cada argumento debes especificar su tipo. Para ello usa nuevamente ty_real o ty_string. Cuando hay ms de 4 argumentos todos ellos deben ser de tipo ty_real. Despues de definir la DLL, ya podemos hacer uso de sus funciones, invocandolas con la siguiente funcion: external_call(id,arg1,arg2,)

Llama a la funcin externa con el id y los argumentos dados. Necesitas proporcionar el nmero correcto de argumentos del tipo correcto (real o string). La funcin devuelve el resultado de la funcin externa. Nota: Como habreis observado, GM solo envia y recibe argumentos del tipo numero real o cadenas de texto. Tened esto en cuenta a la hora de desarrollar vuestras DLLs. Ahora voy a exponer dos ejemplos de definicion y llamada de dos DLLs, una se llama "Mensaje.DLL" y mostraria una ventana con el titulo y texto especificados en los argumentos de entrada tipo "string". La segunda DLL trabaja con datos numericos "Divide.DLL" toma dos numeros reales como argumentos y los divide, devolviendonos el resultado. Vemos ambos codigos de llamada al completo: //Aqu tienes el cdigo de llamada para la DLL Mensaje : { global.Mensaje= external_define(Mensaje.DLL','_Mensaje',dll_stdcall,ty_string, 2,ty_string,ty_string); external_call(global.Mensaje,"Titulo","Texto") } //c?digo de llamada para la DLL divide : { global.divide= external_define('divide.DLL','divide',dll_stdcall,ty_real,2,ty_re al,ty_real); result = external_call(global.divide,12,12) }

Bueno, con este pequeo articulo "Como se hace?" espero que hayais podido ampliar un poco mas vuestros conocimientos sobre el uso de DLLs con GM. Si creeis que se ha quedado algo importante en el tintero, no dudeis en responder y compartirlo con nosotros. Estamos aqui para aprender juntos.

Taller de Programacin con GM PLANIFICACI?N DEL JUEGO Y CREACI?N DE SPRITES

En este taller aprenderemos a realizar nuestro propio videojuego: nuestra visi?n del famoso y archiconocido comecocos (PACMAN). Para ello nos valdremos de dos programas principalmente, GraphicsGale para la creaci?n de sprites (los personajes del videojuego) y Gamemaker, la aplicaci?n con la que programaremos y montaremos nuestro videojuego. Programar un videojuego no es una tarea sencilla, no se trata de ponernos a ello y sale s?lo. Es necesaria toda una planificaci?n detallada, visualizar el videojuego en nuestra mente y cada uno de los detalles que intervienen en ?l antes de empezar a programarlo y plasmarlo sobre papel, hacer un gui?n en el que no debemos dejar nada al azar: Historia, personajes, escenarios, N?mero de fases, elementos que intervienen, puntuaci?n, vidas Y lo m?s importante, las reglas del juego. Pensemos en nuestro juego. Historia: No es muy complicada. Pacman, un comecocos (monstruillo que come cocos) recorre unos escenarios de estructura laber?ntica engullendo todos los cocos que encuentra a su paso. El objetivo de nuestro amigo es comerse todos los cocos para pasar de nivel. Pero en el escenario hay otros monstruillos, los fantasmas, a los que no les hace ninguna gracia que Pacman se zampe los cocos de su territorio. Los fantasmas intentaran impedirle a Pacman que se coma los cocos y lo perseguir?n sin tregua por toda la pantalla para com?rselo. Pero Pacman podr? defenderse: Repartidos por la pantalla hay un peque?o n?mero de supercocos que s?per vitaminizan a Pacman por un peque?o espacio de tiempo y que lo hacen invulnerable y con la capacidad de comerse a los fantasmas. Reglas del juego: - Cada vez que pacman toca un coco se lo come sumando 10 puntos a su marcador de puntuaci?n. - Si pacman toca un fantasma o un fantasma toca a pacman si que este est? s?per vitaminizado pacman muere y se descuenta una vida del contador de vidas. - Si pacman est? s?per vitaminizado y toca a un fantasma o un fantasma lo toca a ?l el fantasma morir? y pacman sumar? 50 puntos a su marcador de puntuaci?n. - Cuando pacman muere vuelve a aparecer en el punto de inicio de pacman.

- Cuando un fantasma muere vuelve a aparecer en el ?rea de salida de fantasmas. - Si pacman muere tres veces acaba la partida. - Si pacman logra comerse todos los cocos de un escenario pasa al siguiente escenario. - Si pacman come una fruta especial suma 10 puntos a su marcador de puntuaci?n. Escenario y elementos que intervienen: Esta historia se desarrolla en un escenario y con unos elementos que vamos a definir. - Un escenario de estructura laber?ntica cuyos pasillos est?n sembrados de cocos. Definimos de cuantos escenarios constar? nuestro juego: 4 - Un punto de inicio de pacman donde aparecer? el personaje que controla el jugador al inicio de cada pantalla y donde reaparecer? si este muere. Definimos donde estar? el punto de inicio: En el centro, en la parte inferior de la pantalla. - Un ?rea de salida de fantasmas que ser? el punto de inicio de los fantasmas. Desde all? empiezan a perseguir al comecocos al inicio de cada pantalla y all? aparecer?n cuando mueren. Definimos donde estar? el ?rea de salida de los fantasmas: En la parte superior de la pantalla, en el centro. Definimos el n?mero de fantasmas: 4 (uno de cada color: verde, azul, rojo, lila). Definimos cuantos supercocos habr? en cada escenario y donde se encontrar?n: 4, en las esquinas. Todos estos elementos que hemos visto se encuentran en el ?rea de juego, que es donde se desarrolla la acci?n. Hay otra ?rea, el ?rea de marcadores, que se encontrar? en la parte superior de la pantalla y donde colocaremos los siguientes elementos: - Marcador de vidas restantes. Nos indica cuantas vidas nos quedan. Empezamos la partida con 3 vidas.

- Marcador de puntuaci?n. Nos indica en todo momento nuestra puntuaci?n. En la creaci?n de un videojuego intervienen tres apartados bien diferenciados que tendremos que tener en cuenta a la hora de planificar nuestro videojuego: El apartado gr?fico, el apartado sonoro y el apartado de programaci?n. Veamos que necesitaremos para nuestro juego en cada apartado: APARTADO GR?FICO - Unos personajes: nuestro amigo el comecocos y los fantasmas que lo persiguen. - Unos objetos que no son otros que los cocos, los supercocos y las frutas que recolecta el comecocos por el escenario. - Unos muros que forman los pasillos del laberinto por donde se mueven los personajes. - Unas pantallas donde se encuentran el ?rea de juego y el ?rea de marcadores. - Un marcador de puntuaci?n que nos indica cuantos puntos llevamos en la partida. - Un marcador de vidas que nos indica las vidas restantes. APARTADO SONORO - Un tema musical para cada escenario. - Efectos sonoros para las siguientes acciones: comer coco, comer fantasma, morir, comer supercoco, acabar partida, pasar de pantalla. Para el apartado sonoro no nos complicaremos la vida. Bajaremos tanto los temas musicales como los efectos sonoros de Internet. APARTADO DE PROGRAMACI?N Esta es la parte m?s complicada. Necesitaremos programar unas rutinas que hagan lo siguiente: IA de los personajes

- Los fantasmas persigan al comecocos. - Si el comecocos esta s?per vitaminizado los fantasmas huyen de ?l. Rutinas de detecci?n de colisi?n de sprites - Si el fantasma intercepta al comecocos y este no esta s?per vitaminizado el comecocos muere. - Si el comecocos intercepta al fantasma sin estar s?per vitaminizado el comecocos muere. - Si el comecocos est? s?per vitaminizado y intercepta al fantasma este ?ltimo muere. - Si un fantasma topa con un muro del escenario no se queda bloqueado y sigue su camino persiguiendo al comecocos. - Si el comecocos intercepta un coco se lo come y sube 10 puntos el marcador de puntuaci?n. - Si el comecocos intercepta un supercoco se lo come y sube 50 puntos el marcador de puntuaci?n a la vez que puede comer fantasmas y estos huyen de ?l. Otros que ya iremos viendo. CREACI?N DE SPRITES CON GRAPHICSGALE Con el programa GraphicsGale procederemos a crear los siguientes elementos gr?ficos del juego: El Comecocos Los Fantasmas Los cocos Los supercocos La fruta

Todos los elementos los crearemos en un lienzo con una resoluci?n de 32 x 32 p?xeles a 8 bits (256 colores) y los guardaremos en formato tga. La creaci?n de los personajes en este caso es sencilla. Hemos de pensar que en el caso del comecocos y el fantasma debemos de crear una imagen diferente para cada pose: Cuando suben por un pasillo, cuando baja, cuando van hacia la derecha, cuando van hacia la izquierda.

??Manos a la obra!!! INTRODUCCI?N A GAMEMAKER. SPRITES, OBJETOS Y ROOMS. Game Maker es un programa con un intuitivo y f?cil interfaz que nos permite crear nuestros propios juegos r?pidamente. Podemos importar y crear im?genes, los sprites (im?genes animadas) y los sonidos y utilizarlos. Tambi?n podemos definir f?cilmente los objetos del juego e indicar su comportamiento, definir pantallas atractivas con fondos en movimiento. Mediante un sencillo lenguaje de programaci?n tendremos control completo sobre lo que va ocurriendo en nuestro juego. Esta es la pantalla que nos encontramos al ejecutar Game Maker. Vamos a explicar los diferentes elementos del interfaz. A la izquierda nos encontramos las carpetas siguientes: Sprites, Sounds, Backgrounds, Paths, Scripts, Fonts, Time Lines, Objects,Rooms. Nos centraremos de momento en las siguientes: Sprites: Las im?genes (animadas) que se utilizan para representar los objetos en nuestro juego. Objetos: Todas las cosas que se ven en el juego (a excepci?n del fondo) son objetos. Los personajes, los monstruos, las bolas, las paredes, etc. son todos los objetos. Tambi?n puede haber objetos que no se ven pero que controlan ciertos aspectos del juego. Tiene que quedar clara la diferencia entre los sprites y los objetos. Los Sprites son las im?genes (animadas) que no tienen ning?n comportamiento. Los objetos tienen normalmente un sprite para representarlas pero los objetos tienen un comportamiento. Rooms: Las pantallas en las que se desarrolla el juego. Sounds: Los sonidos que se utilizan, como la m?sica de fondo o los efectos sonoros. Backgrounds: Las im?genes usadas como fondo de las pantallas (Rooms). En el men? de archivo (file) puedes encontrar las opciones de cargar y guardar archivos, m?s algunas especiales:

Nuevo. Elije esta opci?n para comenzar a crear un nuevo juego. Abrir. Abre un archivo de un juego. Los archivos de los juegos tienen gm6 como extensi?n. Archivos Recientes. Utiliza este submen? para abrir de nuevo archivos del juego que se abrieron recientemente. Guardar. Guarda el dise?o del juego bajo su nombre actual. Si no se especific? ning?n nombre antes, te pide un nuevo nombre. Guardar como. Guarda el archivo del dise?o del juego bajo el nombre que le queramos dar. Crear Ejecutable. Una vez que tu juego este listo deber?s distribuirlo en forma de ejecutable para que otros puedan jugarlo. Modo Avanzado. Cambia entre el modo simple y avanzado. En modo avanzado los comandos y los recursos adicionales est?n disponibles. El modo avanzado s?lo se encuentra disponible en la versi?n de pago de GameMaker. Salir. Para salir de GameMaker. El men? de edici?n (Edit) contiene un n?mero de opciones que se relacionan con el recurso actualmente seleccionado (objeto, sprite, sonido, etc.). Dependiendo del tipo de recurso algunos de las opciones pueden no estar disponibles. Insertar. Inserta un nuevo elemento del tipo que este actualmente seleccionado. Se abrir? una ventana en la cual podremos cambiar las caracter?sticas de este elemento. Duplicar. Hace una copia del elemento actualmente seleccionado y la agrega. Borrar. Suprime el elemento actualmente seleccionado (o el grupo de elementos). Renombrar. Para dar al elemento un nuevo nombre. Propiedades. Utiliza esta opci?n para cambiar las propiedades de cualquier elemento. El men? de agregar (Add) nos permite agregar nuevos elementos de cada uno de los diferentes tipos: Sprites, sonidos, fondos

El men? ejecutar (Run) se utiliza para hacer funcionar el juego. Hay dos maneras de hacer funcionar un juego. Funcionamiento normal o en modo debug para revisar el funcionamiento del juego paso a paso y corregir errores. A?ADIENDO SPRITES Para a?adir un sprite, elije a?adir Sprite del men? a?adir, o utiliza el bot?n correspondiente en la barra de herramientas. Te aparecer? una ventana. En esta ventana podr?s indicar el nombre del sprite. Todos los sprites (y el resto de los elementos que intervienen en nuestro juego) tienen un nombre que tendremos que dar de forma descriptiva. Para cargar el gr?fico de un sprite, haz click en el bot?n Load Sprite. Una vez cargada la imagen se demuestra a la derecha. La opci?n transparente indica si el fondo rectangular de la imagen del sprite se debe considerar como transparente. La mayor?a de los sprites son transparentes. Con el bot?n Editar Sprite puedes corregir el sprite, o crear uno totalmente nuevo. DEFINIENDO LOS OBJETOS DEL JUEGO Los objetos son los elementos del juego que hacen cosas. La mayor?a del tiempo tienen un sprite como representaci?n gr?fica de modo que se pueden ver. Tienen comportamiento porque pueden reaccionar a ciertos acontecimientos. Todas las cosas que ves en el juego (a excepci?n del fondo) son objetos. Los personajes, los monstruos, las bolas, las paredes, son todos objetos. Tambi?n puede haber ciertos objetos que no se ven pero que controlan ciertos aspectos del juego. Para Agregar un objeto a tu juego, elije agregar objeto del men? de agregar (Add). Aparecer? la siguiente pantalla: A la izquierda hay informaci?n de car?cter general sobre el objeto. En el centro hay la lista de los eventos que pueden suceder al objeto. En la derecha hay las diversas acciones que el objeto puede realizar. Lo primero que tienes que hacer es darle al objeto un nombre. Despu?s elegir el sprite para el objeto. Luego indicaras si el objeto es visible (en la mayor?a de los casos si lo es) y si es s?lido (como una pared). CREANDO LAS PANTALLAS (ROOMS) Elegimos a?adir room del men? de a?adir (Add). Indicaremos el tama?o de las celdas de la rejilla. Tambi?n podemos indicar si queremos que la rejilla se muestre o si no, si queremos que el fondo se muestre o que quede oculto, etc. A veces es ?til ocultar temporalmente ciertos elementos del cuarto para trabajar mejor.

Deberemos fijar la medida de la pantalla. Esto se hace desde la pesta?a Settings. Desde la pesta?a Objects a?adiremos todos los objetos a la pantalla. Desde la pesta?a Backgrounds podremos a?adir las im?genes de fondo para la pantalla. A la derecha de la ventana vemos la pantalla. Al principio esta vac?a y s?lo vemos un fondo gris. Para agregar objetos al cuarto, primero selecciona la pesta?a de los objetos, despu?s el objeto que desees agregar. La imagen del objeto aparecer? a la izquierda. Ahora selecciona con el bot?n izquierdo del rat?n el sitio de la pantalla (a la derecha) donde quieres que aparezca el objeto. Veras como el objeto aparece alineado a la rejilla. Puedes borrar objetos de la pantalla haciendo click sobre ellos con el bot?n derecho del rat?n. Puedes arrastrar objetos por la pantalla si mantienes pulsado el bot?n Control del teclado m?s el bot?n izquierdo del rat?n. Desde la pesta?a settings, adem?s de fijar la anchura y la altura de la pantalla podemos fijar la velocidad del juego. ?ste es el n?mero de frames por segundo. Cuanta m?s alta es la velocidad, mas suave es el movimiento. Tambi?n deberemos fijar un nombre y una descripci?n para cada una de las pantallas que creemos. Sigue las indicaciones del profe. Procederemos a crear las pantallas de nuestro juego. PROPIEDADES DE LOS OBJETOS: EVENTOS Y ACCIONES A?ADIENDO MUSICA Y SONIDO SCORE E INDICADOR DE VIDAS EVENTOS 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. 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 (Las acciones). 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. 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.

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. Todas las acciones se encuentran en las p?ginas / fichas 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. A la derecha de la ventana de propiedades de objeto podemos ver las siete pesta?as correspondientes a los diferentes tipos de acciones. Cuando mantienes el rat?n sobre una de las acciones, se muestra una breve descripci?n para recordar su funci?n. 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. Nota del autor: La descripci?n de los eventos y las acciones est? sacada de la traducci?n del manual original de Game Maker 5.0 del ingl?s al castellano realizada por ZonaMakers.com

Iremos viendo los eventos y acciones a medida que los vayamos utilizando. A?ADIENDO MUSICA Y SONIDO Deberemos bajar 4 temas musicales en formato mid, uno por cada nivel de los que consta nuestro juego. Estos temas musicales seran las m?sicas de fondo de los diferentes niveles. En la siguiente direcci?n de Internet encontrareis gran variedad de archivos mid: http://www.midiworld.com/ Bajaremos tambi?n efectos sonoros para cada una de las siguientes acciones: - Para cuando el comecocos come un coco - Para cuando el comecocos come un supercoco - Para cuando el comecocos se come a un fantasma - Para cuando el comecocos se come una cereza - Para cuando el fantasma se come al comecocos - Para cuando pasamos de nivel En la siguiente direcci?n de Internet encontrareis tambi?n multitud de efectos de sonido que bajaremos en formato wav: http://www.flashkit.com/soundfx/ Despu?s a?adiremos las m?sicas y las carpetas dentro de la secci?n Sounds de la misma forma que a?ad?amos las im?genes dentro de la secci?n Sprites (bot?n derecho del rat?n encima de Sounds y Add Sound). Crearemos una carpeta para los efectos sonoros tal como vemos en la imagen de abajo (Add Group). Ahora trabajaremos con las m?sicas de fondo, los archivos mid. Los efectos sonoros se manejan por medio de acciones, por lo que los dejaremos para m?s adelante. Para incluir una m?sica de fondo en uno de nuestros niveles (pantallas) basta con ir a esa pantalla (Room) y hacer clic en la pesta?a Settings. Dentro de esta pantalla haremos clic en el bot?n Creation code y a?adiremos lo siguiente: Donde Fase1 es el nombre que di?ramos a el archivo mid que corresponde a la primera pantalla. La instrucci?n sound loop indica que la m?sica se repita cuando el tema llegue a su fin de forma que no acabe de sonar hasta que no

indiquemos lo contrario con otra instrucci?n. Repetiremos la operaci?n con cada una de las pantallas (rooms) SCORE E INDICADOR DE VIDAS A continuaci?n haremos la parte de la pantalla donde aparecen la puntuaci?n del jugador (score) y las vidas que le quedan (indicador de vidas) para finalizar la partida. - Crearemos e insertaremos en nuestro juego un sprite que servira de fondo a la zona donde se mostraran los indicadores de score y vidas. Se llamar? controlvidas. El sprite no ser? m?s que una imagen igual de ancha que nuestra room y que no sea m?s alta que la zona que habilitamos cuando hicimos la habitaci?n para dar cabida a estos indicadores. En una room de 800 por 600 pixeles la imagen tendr?a unas dimensiones de 800 pixeles de ancho por 48 de alto aproximadamente: Dentro de las propiedades del sprite s?lo debe de estar marcada la casilla Preload texture. - Crearemos un objeto con el sprite controlvidas F?jate en las propiedades del objeto. Tienes que quedar igual: - Visible - Depth -10000 - Persistente (El objeto no se destruye al pasar de un nivel a otro, la puntuaci?n sigue sumando en vez de empezar de cero en cada pantalla). Iremos explicando cada opci?n en clase. A continuaci?n seguiremos los siguientes pasos: Clic en Add Event y luego en Create. Haremos clic en la pesta?a Score Arrastraremos la acci?n Set the escore a la ventana de Actions. Haremos doble clic en el icono y daremos un valor de inicio al score de 0. Arrastraremos la acci?n Set the number of lives a la ventana de Actions. Haremos doble clic en el icono y fijaremos las vidas del jugador en 3. Arrastraremos la acci?n Set the Windows caption info a la ventana de Actions. Haremos doble clic en el icono y la editaremos de forma que quede as?: A?adiremos otro evento (clic en Add Event y luego en Other) Dentro del men? que se nos aparece seleccionaremos No more lives. As? le indicaremos al programa qu? tiene que hacer cuando al jugador no le queden m?s vidas.

Arrastramos a la ventana de Actions las siguientes acciones: Show the high score table de la pesta?a Score. Restart the game de la pesta?a main 2. De esta forma le indicamos al programa que si el jugador se queda sin vidas le muestre la pantalla de records y luego vuelva a empezar otra partida reiniciando el juego. Ahora a?adimos un nuevo evento: Draw Una vez lo hayamos hecho arrastramos las siguientes acciones a su ventana de acciones: Draw a sprite image de la pesta?a Draw. Lo editamos (doble clic) de forma que quede as?: A continuaci?n arrastramos las siguientes acciones (pesta?a Score): Draw the value of score Draw the lives as image As?, mediante las coordenadas (x,y) indicamos la posicion en pantalla de los indicadores de puntuaci?n y de vidas. Otras acciones que podemos a?adir para este evento son: Set the font Set the color De esta forma podremos variar el tama?o y color del indicador de puntuaci?n(Score). Previamente tendremos que haber a?adido una fuente en fonts. Vamos a probar a?adiendo la fuente Jokerman a tama?o 18. A continuaci?n editamos el primero de nuestros niveles. En las propiedades de room, objects seleccionamos el objeto controlvidas y lo colocamos en alg?n lugar de la pantalla como vemos en la imagen (es el circulito con el interrogante): Veamos como va quedando nuestro juego (apretamos tecla F5 para ejecutarlo). PREPARADO LAS ROOMS Colocaremos nuestros objetos en sus posiciones de inicio en las rooms: Seleccionamos cada objeto desde la pesta?a Objects de la ventana de edici?n de la room, mediante el men? de la parte inferior: Una vez seleccionado tan solo debemos hacer clic en el lugar de la room donde deseemos colocar dicho objeto. EVENTOS Y ACCIONES DE NUESTROS OBJETOS A estas alturas deber?amos haber definido los siguientes objetos: Veamos las propiedades, eventos y acciones de cada uno: Ladrillo: Visible. S?lido. Coco: Visible. Supercoco: Visible. Comecocos: Visible, Depth -1

CREATE Create > Change sprite into comecocos_quiet Indicamos que el comecocos aparece inicialmente con la forma del sprite Comecocos_quiet y a velocidad 0.5. STEP Step>If the number of instances is a value Indicamos que si el numero del objeto coco es igual a 0 Inicio de bloque Ejecutar sonido de nivel acabado Sleep 2000 miliseconds (esperar 2 segundos). Si existe una siguiente room. Ir a la siguiente room Aqu? podemos definir una transici?n: Un efecto que se produce al cambiar de pantalla. De lo contrario (De lo contrario, de no haber mas rooms significaria que el jugador ha terminado el juego, por lo tanto) Inicio de un bloque. Ense?ar la tabla de records. Reiniciar el juego. Final del bloque 1. Final del bloque 2. COLLISION EVENT WITH OBJECT LADRILLO Si el comecocos colisiona con un ladrillo: (con speed 1) COLLISION EVENT WITH OBJECT COCO Cuando el comecocos se come un coco que suene el sonido de comerse un coco. (Applies to other) Se destruye el coco. (Relative) Se aumenta el marcador de puntos en 10. COLLISION EVENT WITH OBJECT FANTASMA Que suene el sonido de muerte del comecocos Esperar segundo y medio. Que todos los fantasmas vuelvan a la posici?n de inicio. Que todos los fantasmas miedosos vuelvan a la posici?n de inicio.

(Relative)

COLLISION EVENT WITH OBJECT FANTASMA_ASUSTADO

COLLISION EVENT WITH OBJECT SUPERCOCO

MOVIMIENTO DEL COMECOCOS KEYBOARD EVENT FOR LEFT Obligamos al objeto a estar centrado en la cuadricula de nuestra room.

Si el objeto esta alineado con la cuadricula (32*32) y apretamos la flecha izquierda del teclado el objeto avanza hacia la izquierda a velocidad 4. El sprite que representa al objeto pasa a ser comecocos_izq (comecocos avanzando hacia la izquierda). Procederemos a realizar los mismos pasos con Up, Rigth y Down. OUTSIDE ROOM Si el objeto sale fuera de la pantalla ejecutar el script outside_wall (o como se llame nuestro script). Fantasmas (para todos) CREATE Cambia el sprite que representa al objeto a normal, esto es, a cuando el comecocos no ha comido un supercoco.

STEP (32*32) Si el objeto est? alineado con la rejilla ejecutar el script adap_direction que indica al fantasma hacia donde tiene que moverse.

COLLISION EVENT WITH OBJECT LADRILLO Si el fantasma colisiona con un ladrillo

Cambia la direcci?n hacia el lado contrario, tanto horizontal como verticalmente.

OUTSIDE ROOM Si el objeto sale fuera de la pantalla ejecutar el script outside_wall (o como se llame nuestro script). FANTASMA ASUSTADO ALARM 0

BONUS CREATE

ALARM 0

ALARM 1

COLLISION EVENT WITH OBJECT COMECOCOS

[b]SCRIPTS[/b] OUTSIDE_WRAP { if (x < 0 && hspeed <0> room_width && hspeed > 0) x = sprite_width + sprite_xoffset; if (y < 0 && vspeed <0> room_height && vspeed > 0) y = sprite_height + sprite_yoffset; } ADAPT_DIRECTION

{ if (hspeed == 0) { if (random(3)<1 && place_free(x-4,y)) { hspeed = -4; vspeed = 0;} if (random(3)<1 && place_free(x+4,y)) { hspeed = 4; vspeed = 0;} } else { if (random(3)<1 && place_free(x,y-4)) { hspeed = 0; vspeed = -4;} if (random(3)<1 && place_free(x,y+4)) { hspeed = 0; vspeed = 4;} } }

Glosario.

A
alpha Transparencia. Es un parmetro 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 funcin para que sta opere con ellos.
Por ejemplo, una funcin que sume dos nmeros necesitar que le digas que nmeros tiene que sumar. Esos nmeros son los argumentos de la funcin.

B
background Fondo. Es la imagen que se pone de fondo al room para que sea el escenario. Puedes
agregar varias imgenes distintas y hacer que cada una se mueva a diferente velocidad cuando el personaje avance, haciendo que las imgenes ms cercanas se muevan ms rpido que las ms lejanas. As consigues un efecto de profundidad muy vistoso. Esta tcnica se llama scroll parallax.

blending Ver image blending. bmp Es un tipo de archivo de grficos de alta calidad (mapa de bits). Slo es aconsejable utilizar bmps para
fondos transparentes.

boolean Booleano. Es un tipo de variable que slo puede tener dos valores: true o false. Es decir, si una
variable booleana no es true entonces es false.

depth Profundidad. Es una propiedad de las instancias que sirve para decidir cul debe dibujarse por
encima de las dems cuando chocan, cul se sita primero en el room...Puede ser positiva, negativa 0 y cuanto menor sea ms al frente se situar la instancia.

F
false Falso.
En Game Maker false=0, es decir, es lo mismo poner false que poner 0.

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 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 estn siempre lo ms cercano posible a la room speed.

frame Para generar la ilusin de animacin, 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, ms fluidas se
vern las animaciones en la pantalla, pero se requerir ms potencia.

G
gif Es un tipo de archivo de grficos comprimido y animado. Ideal para sprites.

H
height Altura. Es un argumento muy comn en las funciones de grficos. highscore El marcador ms alto, el rcord de puntuacin obtenido en el juego. Puedes mostrar una lista
con las puntuaciones ms altas (highscore list) con la accin correspondiente.

I
image blending
Mezclado de imgenes. Cuando dos imgenes 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 sumarn los colores de los dos sprites en la zona en la que chocan (por ejemplo para causar un efecto de brillo), pero si est en modo resta se restarn. Como ves, en la parte de los sprites que choca se decide qu hay que hacer segn el modo de mezcla que est activo (esto tambin afecta a los backgrounds). Con esta tcnica se pueden crear efectos visuales muy espectaculares.

J
jpg Es un tipo de archivo de grficos de tamao reducido, pero que no permite transparencias. Ideal para
usarlo en fondos no transparentes o para sprite sheets.

L
left Izquierda. Es un argumento muy comn en las funciones que deben especificar una posicin para
indicar dnde debe situarse el borde izquierdo.

M
midi Es un formato de sonido de muy pequeo tamao. Los midis tienen menos calidad que los wav o
mp3. Sin embargo su tamao es mucho menor, lo que hace que no consuman casi memoria. Esto hace que los midis sean ideales para las msicas 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 grficos de tamao muy reducido creado para ser transmitido por Internet (png
significa "portable network graphics" o "grficos transportables por la red").

pop-up Son los mensajes o ventanas que aparecen de repente y sirven para dar o pedir informacin al
jugador. Por ejemplo, una ventana que se abra y le pregunte al jugador cmo se llama.

R
rar Es un tipo de archivo comprimido. Los archivos tipo rar consiguen una gran compresin 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 categoras:
sprites, backgrounds, sonidos y msica, paths, scripts, time lines, fuentes, objetos y rooms.

room Habitacin o cuarto. En el room es donde se sitan 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.

score

Marcador. En el juego, puedes hacer que el marcador se incremente cuando el jugador recoja

monedas u otros objetos.

screenshot Es una foto de la pantalla en un momento determinado. Los screenshots son muy tiles
para promocionar tu juego o para usarlos en tablas de rcords.

script

Es un trozo de cdigo que puede recibir argumentos y devolver un valor. Los scripts se utilizan

para generalizar cdigo repetido y as ahorrar espacio y ganar velocidad.

scroll Es el movimiento del fondo. Game Maker te permite aadir varios fondos distintos y asignar un
movimiento a cada uno, para dar la impresin 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 imgenes, de forma que si en cada momento se dibuja una imagen distinta parece que se mueve. El formato ms utilizado para los sprites es el de los archivos gif.

sprite sheet Una sprite sheet (o strip) es una imagen no animada de gran tamao en la que
aparecen muchas imgenes de un personaje (o varios) mostrando todos los frames de sus animaciones. El editor de sprites de Game Maker permite crear sprites animados fcilmente 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 rpidamente dar la impresin de que todo se ejecuta continuamente (Ver frame).

strip Ver sprite sheet.

T
tile Para hacer un fondo, a veces es bueno utilizar imgenes pequeas que, puestas una al lado de otra,
forman un dibujo. Esta tcnica se denomina tiling. Por ejemplo: divides el room en casillas del mismo tamao y en cada una pones una imagen ms pequea (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 imgenes ms pequeas para crear
tiles.

time line Lnea de tiempo. En una time line puedes aadir acciones en momentos concretos, de forma
que estas acciones se ejecutarn en el orden que t decidas y justo cuando quieras.

top Arriba. Es un argumento muy comn en las funciones que deben especificar una posicin para indicar
dnde debe situarse el borde superior.

true Verdadero. En Game Maker true=1, es decir, es lo mismo poner true que poner 1.

w
wav Son archivos de sonido de gran calidad, pero que por lo tanto ocupan mucho tamao y consumen
bastante memoria. Los archivos wav se suelen utilizar para los efectos de sonido (explosiones, gritos, disparos...).

width Anchura. Es un argumento muy comn en las funciones de grficos.

Z
zip Es un tipo de archivo comprimido muy corriente. Al comprimir tu juego, conseguirs que ocupe menos
espacio y as podrs distribuirlo ms fcilmente por la red.

Este tutorial es cortesa de www.tutoek.tk www.comunidadgm.org

y Gracias a la gran comunidadgm

También podría gustarte