Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mensajes - calio

16
Necesitas ejecutar la función en el otro objeto.

Supongamos que tienes el siguiente array en un objeto llamado obj_test:

my_array[0,0] = 1;
my_array[0,1] = 2;
my_array[1,0] = 3;
my_array[1,1] = 4;
my_array[2,0] = 5;
my_array[2,1] = 6;

Vamos a usar el siguiente código para dibujar el valor de my_array[2,1] en otro objeto:

with (obj_test){ draw_text(0,0,variable_local_array2_get("my_array",2,1)); }

Y el resultado debiese ser que el objeto dibuja el número 6 en la esquina de la room. :)

Por algún motivo que no logro entender, el siguiente código también funciona

var bleh;
with (obj_test){bleh = variable_local_array2_get("my_array",2,1); }
draw_text(0,0,bleh);


Si alguien sabe exactamente por qué la variable local bleh funciona dentro del with, que me avise porque no lo termino de entender yo :p

Espero que haya resuelto tu duda :)
17
Acá va el ejemplo :)

La mayoría de los cambios en el código (como global.font, el screen_refresh() y el screen_redraw(), la variable keychange y cosas así) son meramente cambios estéticos, y sirven para mostrar en pantalla el texto :)

Ojalá te sirva.
18
acá hay una versión bastante rudimentaria del dble salto implementada con las variables que ya estás utilizando c:

//Primero, el código de la gravedad
if (place_free(x,y+1) == false)
{
gravity = 0;
//Si es que el objeto está en el piso y la variable salto no es 0...
if (salto != 0)
{
//...se le asigna el valor 0.
salto = 0;
}
}
else
{
gravity = 1;
//De lo contrario, si está en el aire y el valor de la variable es igual o menor a 0.
if (salto <= 0)
{
//...se le asigna el valor 1. Así evitamos que el jugador pueda dar más de un salto en el aire.
salto = 1;
}
}
if (keyboard_check_pressed(ord("W")) && (salto < 2))
{
//El código de abajo sólo se ejecuta si el valor de la variable salto es menor que 2, que es la cantidad máxima de saltos en el aire que el jugador puede dar.
if ((place_free(x,y+1) == false) && (salto == 0)) || ((place_free(x,y+1) == true))
{
//Si está en el piso y el valor de salto es 0, o bien si no lo está...
vspeed = -8;
salto += 1;
//...ejecutamos el salto.
}
}


Honestamente, no lo he probado, y lo programé acá mismo sin testearlo. Lo voy a probar y te hago un edit con una confirmación si es que funciona o con correcciones si es que no.

EDIT: Debería funcionar si ya tienes programado el evento de colisiones de tu objeto de jugador con el piso :)
19
Preguntas y respuestas / Re:Cambiar de sprite con if
Enero 14, 2013, 01:44:29 AM
El problema está donde dice...

if x=x+3

...y donde dice...

if x=x-3

...pues, básicamente, le estás pidiendo al programa que compruebe si la variable x es igual a si misma mas o menos tres, lo cual siempre va a ser falso, porque x siempre es igual a x.
Lo que necesitas hacer es revisar el valor de x con respecto al valor anterior de x, o lo que es lo mismo, xprevious.

Entonces, en el primer caso, donde x tiene que ser mayor a xprevious, mi solución es poner:

if (x > xprevious)

y así mismo, donde tiene que ser menor,

if (x < xprevious)


Espero que te haya ayudado :) me avisas si tienes problemas con el código.
20
¿Cuál es tu nivel de GML? Porque lo que te voy a escribir a continuación te puede parecer chino xD

Lo primero es desechar por completo detectar las teclas directamente. En su lugar, debes tener variables que almacenen el valor de las constantes que equivalen a cada tecla. Comencemos con un esquema de control de 4 botones y flechas direccionales. Definamos las siguientes variables en el evento Create del objeto de control que vayas a usar en tu juego:

global.dpad[0] = vk_left;
global.dpad[1] = vk_right;
global.dpad[2] = vk_up;
global.dpad[3] = vk_down;
global.button[0] = ord("Z");
global.button[1] = ord("X");
global.button[2] = ord("C");
global.button[3] = vk_enter;


Teniendo definidas las variables y su valor, ahora podemos guardar el valor de la tecla que queramos cambiar en algún lado :D

Para cambiar el valor de una tecla, te recomiendo llamar a un script que consista en lo siguiente:

var last_key;
last_key = 0;
io_clear();
while ((last_key == 0))
{
io_handle();
if (keyboard_key != 0)
{
last_key = keyboard_key;
}
}
global.button[argument0] = last_key;


Donde argument0 corresponde al botón que quieres cambiar dentro del array global.button.
De antemano, te digo que esto va a pausar el juego hasta que el jugador presione una tecla. Para crear un tiempo de respuesta entre que el jugador elija cambiar la tecla y finalmente la presione podrías utilizar una alarm, y para crear una tecla para que el jugador elija no cambiar la tecla basta con programar una excepción, que indique que si el jugador presiona cierta tecla el ciclo while se rompa sin cambiar el valor de la variable last_key.

Ojalá te haya sido de ayuda :D me avisas si necesitas esto en un ejemplo.
21
Cita de: Kamikaze en Enero 13, 2013, 08:12:36 PM
Cita de: Creador de juegos GM en Enero 13, 2013, 05:41:19 PM
Cita de: calio en Enero 13, 2013, 04:57:15 PM
Cuando has hecho clases de "cómo hacer juegos" (programación básica) a niños de menos de 10 años que jamás han tenido contacto con la programación, créeme que agradeces el Drag&Drop xD
Obivamente, les enseñas a mantener las expectativas bajas y les enseñas los conceptos básicos detrás de algunos de los géneros de videojuegos típicos, y la cara que ponen cuando hacen su primer "Mario" de verdad te hace agradecer el Drag&Drop xDD muchos conceptos que en código resultan en una curva de aprendizaje muy alta para niños muy pequeños se simplifican con Drag&Drop, y más adelante -me imagino, porque todavía no he llegado a ése punto- será cosa de explicarles que tal expresión es lo mismo que tal ícono, así como dibujar un árbol y escribir la palabra "árbol" hacen referencia a lo mismo, pero en sencillo xD

...Pero sí, para trabajar seriamente no hay de otra que trabajar con la última versión.
estas subestimando la capacidad de los niños. >:(.

No digo que no se pueda obviamente, pero hablaba de que hay gente que pensaba realizar un lineage/world of warcraft con D&D :P

PD: A mis 10 años de edad estaba haciendo el famoso juego del "ahorcado" en pascal (en la escuela tecnica) :P

Nos estamos llendo un poco del tema, ¿no? :p

Me imagino que ninguno de uds. empezó programando el ahorcado como proyecto Hola Mundo, ¿no?
A eso voy yo: el Drag&Drop de Game Maker permite hacer en una primera clase un "Hola Mundo" que consiste en algo que un niño de 10 años o menos que nunca había intentado programar antes puede observar, probar y sentir como un logro contundente.
Y ojo que me referí explícitamente a niños que jamás han tenido contacto con la programación. Es un poco ir a lo bruto y pretender en la primera clase que un muchacho que todavía ve el mundo de la programación como hackers que le hablan a un computador en código binario (palabras casi textuales :p) pueda salir con algo funcional. Al igual que en el lenguaje verbal, creo, a un niño se le comienza explicando de la forma más gráfica posible, y el Drag&Drop es una gran experiencia para al menos introducirlos en el tema de "al computador le das órdenes secuenciadas, lógicas y específicas" sin tener que entrar a explicarles qué es una función. Asumo que, tal como aprendí yo, una vez que entienden el concepto más básico de programar (concepto que no puede estar más alejado de escribir código, por cierto) el resto de las especificaciones como variables, objetos, clases, funciones, etc. las aprenden en la práctica, que se convierte en una experiencia de ver resultados inmediatos con D&D.

Pero nos estamos desviando por completo del tema xD
22
Cuando has hecho clases de "cómo hacer juegos" (programación básica) a niños de menos de 10 años que jamás han tenido contacto con la programación, créeme que agradeces el Drag&Drop xD
Obivamente, les enseñas a mantener las expectativas bajas y les enseñas los conceptos básicos detrás de algunos de los géneros de videojuegos típicos, y la cara que ponen cuando hacen su primer "Mario" de verdad te hace agradecer el Drag&Drop xDD muchos conceptos que en código resultan en una curva de aprendizaje muy alta para niños muy pequeños se simplifican con Drag&Drop, y más adelante -me imagino, porque todavía no he llegado a ése punto- será cosa de explicarles que tal expresión es lo mismo que tal ícono, así como dibujar un árbol y escribir la palabra "árbol" hacen referencia a lo mismo, pero en sencillo xD

...Pero sí, para trabajar seriamente no hay de otra que trabajar con la última versión.
23
Por cosas de trabajar en Mac OS X estoy obligado a utilizar GameMaker 7 (7.5 y un runner no convencional, más encima), sin embargo vengo usando GameMaker desde la versión 3 (¡uf!) y mis versiones favoritas sin dudas son la 5 y la 7. La 5 es la cima del Game Maker "clásico" por llamarlo de alguna forma, y debe ser aún hasta ahora una de las versiones más estables, y sin contar que todavía era gratis :D
La 7, por otro lado, es una versión más robusta y mejor equipada de la 6, que también fue muy buena pero por ser el salto más grande que había dado GameMaker hasta entonces (¡tomando en cuenta el salto desde la 3.x a la 4.x, y de la 4.x a la 5.x, claro!) todavía habían cosas que no terminaban de calzar por completo.
Si tuviese que recomendarle una versión a un principiante, probablemente le recomendaría empezar haciendo Drag&Drop en la versión 5, y luego lo haría pasar a la siguiente versión más nueva cuando quiera aprender código. Si la sintaxis del GML de la versión 5.x hacia abajo fuese igual al de la versión 6.x hacia arriba, probablemente le diría que no se preocupe y que siga aprendiendo con la versión 5.x hasta que se acostumbre. Por otro lado, si el tema fuese trabajar profesionalmente, de más está decir que la última versión del programa es menester para trabajar, sólo por el tema de soporte, bugfixes y mejoras con respecto a la versión anterior (incluso teniendo en cuenta todos los pasos en falsos con respecto a dichas versiones).
24
Preguntas y respuestas / Re:Teclado y cambio de room
Enero 13, 2013, 03:45:47 AM
Cita de: Wadk en Enero 13, 2013, 03:40:49 AM
Cita de: calio en Enero 13, 2013, 02:21:13 AM
No, si uno suelta la tecla y la vuelve a presionar, keyboard_check(vk_right) vuelve a ser true. Lo de la room subsiguiente es si el jugador mantiene presionada la tecla durante esas 3 rooms, caso bastante esperable a decir verdad ._.
Pregunté por keyboard_check_released...

Upa! Oh, qué error de mi parte ._.
Sí, keyboard_check_released() funciona.
25
Preguntas y respuestas / Re:Creador de enemigos
Enero 13, 2013, 03:03:48 AM
Hola :)

Dado que no hay muchos datos, asumiré que quieres un objeto que cree distintos objetos cada cierto tiempo.

Lo primero, creemos un objeto al que llamaremos obj_spawner

En su evento Create añadimos el siguiente código:


alarm[0] = room_speed;


Acá algo interesante: la mejor forma -y la más fiable, hasta donde se- de medir tiempo en Game Maker manualmente sin recurrir a métodos extraños es saber que room_speed == 1 segundo. Básicamente, la room_speed es la cantidad máxima de cuadros por segundo a la que corre la room, y como bien dice el nombre de la noción (cuadros por segundo), cada vez que pasa tal cantidad de cuadros, pasa un segundo :) Si quieres más de un segundo, sencillamente multiplica room_speed por la cantidad de segundos que quieres que pasen. Por ejemplo, si necesitas que algo suceda en 5 segundos y medio, multiplica room_speed * 5.5 y listo.
Esto es muy útil y todo el mundo debería saberlo. Bueno, no toooodo el mundo, pero sí toda la gente que ocupa GameMaker.

Entonces, tenemos un objeto que al ser creado activa la alarm[0] para ejecutarse en un segundo. Ahora necesitamos el código para lo que sucede cuando el contador llega a 0 y se ejecuta el evento Alarm 0.

switch (floor(random(6)))
{
case 0:
instance_create(x,y,obj_enemigo0);
break;
case 1:
instance_create(x,y,obj_enemigo1);
break;
case 2:
instance_create(x,y,obj_enemigo2);
break;
case 3:
instance_create(x,y,obj_enemigo3);
break;
case 4:
instance_create(x,y,obj_enemigo4);
break;
case 5:
instance_create(x,y,obj_enemigo5);
break;
}
alarm[0] = room_speed;

Básicamente, lo que hace éste código es elegir un número decimal al azar entre 0 y 6 y lo redondea hacia abajo (y dado que random nunca resulta ni en 0 ni en 6, podríamos decir que las posibilidades son sólo número enteros entre 0 y 5) y según el resultado crear una instancia distinta de un objeto de monstruo. Luego de eso, se reestablece el llamado a la ejecución de alarm[0] en 1 segundo.

Ojalá esto te haya servido de ayuda :D
26
Preguntas y respuestas / Re:Teclado y cambio de room
Enero 13, 2013, 02:21:13 AM
No, si uno suelta la tecla y la vuelve a presionar, keyboard_check(vk_right) vuelve a ser true. Lo de la room subsiguiente es si el jugador mantiene presionada la tecla durante esas 3 rooms, caso bastante esperable a decir verdad ._.

Y de tener funciones para leer las instancias que hay en rooms a las que no ha accedido, no las conozco. Se me ocurre un método bastante chungo de hacer un ciclo llendo por cada room y guardando la posición de objetos en grids para cada room, como una suerte de precarga, pero si tuviese que hacer eso mejor corto por lo sano y hago un sistema personalizado de rooms xD y eso es básicamente lo que estoy haciendo...

En fin, no se qué más agregar ._. si alguien sabe exactamente cómo solucionar el problema del estado de las teclas entre room y room sin recurrir a keyboard_check_direct() ni a keyboard_key_press()/keyboard_key_release(), por favor avíseme ;A;
27
Preguntas y respuestas / Re:Como hacer un checkpoint
Enero 13, 2013, 02:14:41 AM
Cita de: Wadk en Enero 13, 2013, 01:56:22 AM
¿por qué usás un switch para comprobar si una variable es verdadera? ¿por qué no un if?

Mera comodidad :p en realidad no tiene mucho sentido ahora que reviso mi código xD
Lo voy a cambiar para hacer más sencillo de leer :B
28
Preguntas y respuestas / Re:Teclado y cambio de room
Enero 13, 2013, 01:44:38 AM
Claro, guardar los datos de otra forma es esencial para solucionar el problema, aunque sea una consecuencia colateral :p

Por cierto, desde que me resigné a no usar el sistema nativo de rooms de GameMaker (léase ayer en la noche xD), he estado trabajando en esto :3



jujuju.

Cita de: brunoxzx en Enero 12, 2013, 04:15:09 AM
Por cierto no entendí muy bien lo que decías del room subsiguiente. cómo? se repara para el siguiente room, pero al ir al anterior vuelve a suceder?.

Claro, mira, considéralo así:

Tenemos 3 rooms, los vamos a llamar scn_room0, scn_room1 y scn_room2. Estos están secuenciados de tal forma que al salir por la derecha de scn_room0, el juego traslada el objeto del personaje a la esquina izquierda de scn_room1.
Del mismo modo, tenemos una variable llamada global.dpad[1] que almacena el valor de la tecla del modo explicado anteriormente.

Al salir de scn_room0 presionando la tecla vk_right, los valores devueltos por las siguientes funciones y variables son los siguientes:

global.dpad[1] == true;
keyboard_check(vk_right) == true;
keyboard_check_direct(vk_right) == true;


Al salir de scn_room0, el objeto ejecuta un script que guarda el valor de keyboard_check(vk_right) (y el resto de las teclas, claro) antes de ejecutar la función room_goto(scn_room1). Esto lo hace para que el juego actualice el valor de las variables si es que el jugador ha soltado la tecla justo antes de entrar a la siguiente room, evitando así que el jugador siga avanzando incluso si no hay ninguna tecla presionada.
Al entrar a scn_room1, el valor de las funciones y las variables son las siguientes:

global.dpad[1] == true;
keyboard_check(vk_right) == false;
keyboard_check_direct(vk_right) == false;

¿Por qué keyboard_check(vk_right) pasó a ser false? No tengo idea, ése es mi problema xD
¿Por qué global.dpad[1] sigue siendo true pese a que keyboard_check(vk_right) pasó a ser false? Porque el script que maneja los valores de global.dpad[1] funciona con keyboard_check_pressed(vk_right) y keyboard_check_released(vk_right), y dado que el juego no ha recibido ninguna órden de soltar la tecla vk_right, el valor de ésta variable sigue siendo true hasta que se suelte la tecla.

Ahora viene la parte problemática, y es lo que sucede al seguir caminando hacia scn_room2 desde scn_room1. Los valores devueltos por las variables y las funciones siguen siendo los mismos

global.dpad[1] == true;
keyboard_check(vk_right) == false;
keyboard_check_direct(vk_right) == false;

Y al salir de la room ejecuta nuevamente el script, siiiin embargo ésta vez -y por el bug presente en GameMaker- el valor de keyboard_check(vk_right) es false, por lo que global.dpad[1] pasa a ser false y los valores al entrar a scn_room2 desde scn_room1 son

global.dpad[1] == false;
keyboard_check(vk_right) == false;
keyboard_check_direct(vk_right) == false;

Haciendo que el código falle en la habitación subsiguiente. :(
29
Preguntas y respuestas / Re:Como hacer un checkpoint
Enero 13, 2013, 01:23:41 AM
Cita de: Wadk en Enero 13, 2013, 12:59:27 AM
Cita de: Creador de juegos GM en Enero 12, 2013, 05:21:34 PM
pero seria mas facil como digo y esto:
if checpoin2=true checpoin1=false
if checpoin3=true checpoin2=false
No lo creo... El método de calio lo podés programar una vez y después olvidarte. Simplmente posicionás las instancias del obj_checkpoint donde las quieras en el room y listo. Sin modificar el código, funciona para cualquier cantidad de checkpoints colocados de cualquier forma y en cualquier room.

Aunque también se podría hacer de forma más eficiente y con menos variables. El obj_checkpoint alcanza con que tenga un sprite con el que se pueda colisionar, y nada más. el objeto personaje debe tener la siguiente variable:
[gml]checkpoint = noone;[/gml]
También el siguiente código en el evento de colisión con obj_checkpoint:
[gml]checkpoint = other.id;[/gml]
Y el siguiente código que se ejecute cuando muera:
[gml]if (checkpoint == noone) {
    x = xstart;
    y = ystart;
} else {
    x = checkpoint.x;
    y = checkpoint.y;
}[/gml]

Heh :D esa es una buena solución también, mucho más elegante y sencilla de entender a simple vista, pero por lo que le entendí a nano06, el principal problema viene "cuando el jugador se sale del room", lo que entiendo como que cuando el jugador está en otra room, no tiene cómo volver al checkpoint anterior, porque la instancia sencillamente ya no existe.

Por cierto, me acabo de dar cuenta que la variable active en mi solución es completamente inutil xD aunque puede servir estética y funcionalmente para indicar cuando un checkpoint está activado, añadiendo algo así como

if (active == true)
{
//acá va el gráfico de cuando el checkpoint está activo
sprite_index = spr_ungrafico;
}
else
{
//acá va el gráfico que tiene por defecto, o lo que es lo mismo, cuando está desactivado
sprite_index = spr_otrografico;
}

//Si quieres implementar otros estados para un checkpoint además de encendido apagado (bloqueado, destruido, qué se yo...) te recomendaría hacerlo con un switch en lugar de un if/else


...pero ahí surge otro problema: cuando entras en una room, todos los checkpoints están desactivados. Dado que la forma de volver al último checkpoint se realiza exclusivamente en la instancia de jugador, esto no supone ningún problema fuera de uno estético. De todos modos, el siguiente código reemplazando el código del evento Create en obj_checkpoint debería solucionar el problema :D

active = false;
if (instance_exists(obj_player) == true)
{
//Doble condicional para que no arroje un error si es que no existe una instancia de obj_player
if (obj_player.checkpoint_room == room)
{
(instance_place(obj_player.checkpoint_x,obj_player.checkpoint_y,obj_checkpoint)).active = true;
}
}
30
Una solución elegante al problema de hacer un menú la aprendí sin querer buscando una solución a otro problema :D
Básicamente, necesitas una variable de control y una que mantenga la opción. No se qué tan avanzado sea tu nivel de GML, pero acá te propongo mi solución al problema :D

Lo primero es definir un par de variables y una lista, a la que le vamos a llamar menu_options y en la que vamos a añadir todas las opciones del menú.

global.menu = false;
menu_option_selected = 0;
menu_options = ds_list_create();
ds_list_add(menu_options,"Reiniciar");
ds_list_add(menu_options,"Salir");
ds_list_add(menu_options,"Volver");

Esto es preferible que lo hagas en el evento Create del objeto que utilices para inicializar y manejar las variables principales del juego.

Luego, en el evento Step necesitas implementar un ciclo while que se active sólo mientras la variable global.pause esté activada.

while (global.menu == true)
{
io_handle(); //Actualiza el estado del teclado
screen_redraw(); //Actualiza las tareas de dibujo en la pantalla
//Aca viene el control del menu
if (keyboard_check_pressed(vk_down))
{
if (menu_option_selected < ds_list_size(menu_options)-1)
{
menu_option_selected += 1;
}
else
{
menu_option_selected = 0;
}
}
if (keyboard_check_pressed(vk_up))
{
if (menu_option_selected > 0)
{
menu_option_selected -= 1;
}
else
{
menu_option_selected = ds_list_size(menu_options)-1;
}
}
if (keyboard_check_pressed(vk_space))
{
switch (menu_option_selected)
{
case 0:
//Reiniciar el nivel
global.menu = false;
room_restart();
break;
case 1:
//Salir del juego
global.menu = false;
game_end();
break;
case 2:
//Salir del menu de pausa
global.menu = false;
menu_option_active = -1
io_clear();
break;
}
}
if (keyboard_check_pressed(ord("P")))
{
global.menu = false;
menu_option_active = -1
io_clear();
}
}

//Esto ya es fuera del ciclo while, y sirve para llamar al menu de pausa dentro del juego
if (keyboard_check_pressed(ord("P")))
{
global.menu = true;
menu_option_selected = 0;
}


Ahora, para dibujar el menu de pausa en el juego, se hace lo siguiente dentro del evento Draw del objeto:

if (global.menu == true)
{
draw_set_alpha(0.5);
draw_set_color(c_black);
draw_rectangle(0,0,320,240,false);
draw_set_alpha(1);
draw_set_color(c_white);
draw_text(8,8,"-- Pausa --");
for (n = 0; n < ds_list_size(menu_options); n += 1)
{
if (menu_option_selected = n)
{
draw_set_color(c_red);
}
else
{
draw_set_color(c_white);
}
draw_text(8,24+(n*8),ds_list_find_value(menu_options,n));
}
screen_refresh(); //Actualiza el dibujado en pantalla. Esto es importante o si no no va a salir nada.
}                     


...Y con esto tienes un menú de pausa completamente funcional :D

Te dejo adjunta una versión funcional del menú de pausa que te acabo de explicar :)

Saludos, y ojalá te sirva :D