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

1
Juegos completos / Rescue in Faraway Fields
Febrero 20, 2021, 08:00:42 PM


Rescue in Faraway Fields


Plataformas


GM:Studio

En un tranquilo llano alejado de todo descansa una marmota todas las horas del día, hasta que un fatídico día un mal invade las vidas del paraje: ¡Un robot-pirata flotante ha raptado al heredero al trono animal! ¡No se puede descansar con todo este alboroto! Así que armado tal solo con rocas y a paso lento pero seguro, la marmota atlética se abre paso para dar desenlace a esta desventura y salvar así a la víctima de las maquinaciones oscuras del malvado robot pirata.

Secillo juego de plataformas en el estilo de los juegos arcade de principios de los '80s. Dos modos de juego y más de un loop. ¡En inglés y en español!







https://gatod.itch.io/rescue
https://www.newgrounds.com/portal/view/759867


Juraría haber posteado antes este juego, pero no encontré el post.

2
Juegos en desarrollo / RetroShooti
Febrero 20, 2021, 07:26:23 PM


RetroShooti


Shooter


GM: Studio

Una nave espacial y el misterio de la vuelta a su hogar después del trabajo. 16 power-ups (dependiendo de tu definición de power-up) y música hasta en la pantalla de selección de niveles. El demo tiene 4 jefes, momentos emotivos, momentos graciosos, animales, items coleccionables, muertes injustas, escort missions, etc.

(Comedia, PG, entre 10 y 20 min. ¡En inglés y en español!)







https://store.steampowered.com/app/1390290/RetroShooti/
https://mmzgames.itch.io/retroshooti (Disponible en HTML5)
https://www.newgrounds.com/portal/view/760336 (Disponible en HTML5)


A finales de Marzo vamos a sacar una versión más larga que vamos a ir actualizando hasta completar los cuatro actos que comprende el viaje, pero la demo gratuita (que incluye todo el acto I) es un buen rato por sí sola. Ojalá les guste! Me interesa leer sus opiniones al respecto de este juego en el que hemos estado trabajando.

Acá hay un trailer que le hice
Este trailer era un videoclip al principio pero luego necesitabamos un trailer así que lo reciclé.

3
Desarrollo de Scripts / Re:explode()
Marzo 05, 2014, 02:28:01 AM
Ni idea qué podrá ser... Quizás si lo estás ejecutando en GM:Studio puede ser que no funcione de forma correcta. Yo probé éste script en GM 7 y 8 y en ambos funciona de forma correcta, hasta donde recuerdo.
Por cierto, las últimas versiones de GM:S permiten devolver arrays en un return, así que lo voy a actualizar un poco:
Esta versión sólo funciona en GM:S, procura estar trabajando desde la última versión disponible para que los resultados funcionen de forma correcta.


Ok, algunos cambios en los argumentos.
explode(separator, string);
separator es el string a ocupar como separador.
string es el string a separar.
La función devuelve un array.


///explode(separator, string);
var i, str, separator, seps, substr;
str = argument[1];
separator = argument[0];
seps = string_count(separator, str);
if (seps == 0)
{
substr[0] = str;
return substr;
}
else
{
for (i = 0; i < (seps + 1); i++)
{
    if (i < seps)
    {
    substr[i] = string_copy(str, 1, string_pos(str,separator)-1);
    }
    else
    {
    substr[i] = str;
    }
    str = string_delete(str, 1, string_length(string(substr[i])+string(sep)));
}
return substr;
}


Y usando el mismo código de antes, el siguiente ejemplo

var array, string;
string = "Hola,Esto,Es,Una,String";
array = explode(",", string);
}
show_message(array[4]); //Ésto debiese mostrar un mensaje que diga "String".


No lo he probado aún, pero apenas pueda lo pruebo. Si sigue mostrándote un error, envíame un mensaje privado y te contesto por ahí. :)

Saludos.
4
Me pareció muy muy extraño que no te funcionase D: así que hice un ejemplo :)

Todo el código está comentado, así que puedes ignorar todas las partes referentes a mecánicas y físicas :D
Dado que estoy acostumbrado a trabajar así, mi código de plataformas no utiliza ni la variable gravity ni la variable vspeed, así que ten en cuenta eso al adaptar el código a tu caso :). De todos modos, insisto, TODO el código está comentado.

Ojalá ahora sí te sirva :D
5
(la única forma que se me ocurre de ejecutar código desde una instancia en el evento de otra instancia es utilizando la función object_event_add(), donde

object_event_add(obj2,ev_other,ev_end_of_path,"sound_play(sfx_tusonido)");

en el evento Create después de crear mano_izq y mano_der añadiría ese código al objeto obj2 (la función sólo funciona para añadir código en los eventos del objeto, no en instancias, y no hay forma de crear un evento sólo para una instancia. el primer argumento en la función DEBE ser un indice de objeto, no de instancia)
Mi único problema es que me parece que ésta función es poco fiable, pues las funciones que en general añaden código dinámicamente utilizando strings que luego son ejecutadas durante el juego suelen ser funciones muy incompatibles con el código compilado. Sólo para aclarar, esto debiese ser imposible, pues en ningún lenguaje compilado se puede escribir código aparte y luego dejar que el programa lo interprete después de ser compilado. El uso de éstas funciones (como string_execute() que ejecuta código a lo bruto desde una string, las familias de funciones variable_local_ y variable_global_ que ejecutan código para definir y buscar variables escritas como strings) está completamente desaconsejado, resulta en tiempos de ejecución absurdamente lentos y ayudan a crear malos hábitos de programación.

Pero no me hagan caso, yo estoy durmiendo :D)
6
Preguntas y respuestas / Re:Doble salto
Enero 17, 2013, 01:57:53 AM
¿En serio? ¿Probaste el ejemplo?
Cuéntame tu problema, o si es posible muestra tu código y vemos exactamente cuál es el problema :)

La premisa del doble salto es que en lugar de ser un booleano (true o false), la variable de control tiene que ser un número entero. Eso es todo.
7
Preguntas y respuestas / Re:Doble salto
Enero 16, 2013, 07:31:02 PM
Lo contesté acá :D

Va con un ejemplo :3 ojalá te sirva.
8
No te preocupes, estoy muerto de sueño y apenas puedo contarme los dedos de una mano. Explicarle a alguien el uso de arrays sería una brutalidad y probablemente sólo acabe sembrando caos xD y tampoco es que yo sea el único que por derecho puede contestar dudas, no por nada esto es una comunidad ;) en tu posición hubiese hecho lo mismo.

Es una muy buena explicación, y es verdad que al principio pueden parecer una tontería, porque para qué usar un array que sea boton[0] y boton[1] si puedo hacer dos variables que se llamen boton1 y boton2. Sin embargo, un array es una sola variable almacenando distintos valores en diferentes espacios, como si fuese una cajonera de variables, por lo que además de ser código mucho más ordenado te permite hacer cosas como:

for (n = 0; n < 100; n += 1)
{
array[n] = n*n;
}

Sin arrays, tendrías que hacer esto:

variable1 = 0;
variable2 = 1;
variable3 = 4;
variable4 = 9;
variable5 = 16;
...
variable97 = 9216;
variable98 = 9409;
variable99 = 9604;
variable100 = 9801;

Cien líneas de código aburrido y lineal frente a cuatro líneas de un ciclo sencillo que hace exactamente lo mismo :D

¿Por qué estaba hablando de esto? Ah, sí. Teclas.

Imaginate quieres hacer una opción que te haga elegir consecutivamente nuevas teclas para cada botón en tu juego. Sin arrays tendrías que escribir muchas líneas de código para hacer referencia a cada variable por separado, sin embargo si usas un array sencillamente puedes hacer un ciclo for que haga esto por ti.

for (n = 0; n < 4; n += 1)
{
mensaje = string("Presiona una nueva tecla para el botón ") + string(n + 1);
keyboard_wait();
set_key(n);
}
//y luego en draw
draw_text(0,0,mensaje);


Por cierto... la única corrección que haría a la magistral explicación de brunoxzx es que el script set_key() no devuelve ningún valor, por lo que hacer que usarlo así

tDir[1]=set_key();

va a dejar las variables vacías. O quizás tire un error, no se. Es script se utiliza sencillamente llamándolo y pasándole como argumento el índice (el numerito que va entre corchetes) del array al que la tecla corresponde. Me pareció que era más sencillo hacerlo así, aunque hacer que devuelva un valor en lugar de definir el valor dentro del script mismo lo hace más dinámico, a decir verdad... Quizás lo reformule y lo ponga en el foro de Scripts :D si lo hago, te doy los agradecimientos correspondientes, brunoxzx. Pero primero debería dormir.
9
Estuve metiéndome en el asunto. Está bastante complicado (y no haber dormido mucho ni muy bien tampoco ayuda mucho, a decir verdad...) y no tengo idea si es cosa del intérprete de Mac de Game Maker o si realmente sucede así en todos lados.

Hay una variable que se llama path_position. Básicamente, es una variable que indica la posición dentro del path que lleva la instancia, siendo 0 el principio y 1 el final, con todos los números decimales indicando el entre medio.

Primer problema: al menos en Mac, la variable path_position nunca es un número entero a menos que el path_endaction (la acción a ejecutar al terminar el path) sea 0, es decir, que la instancia que sigue el path se detenga.

Lo quise resolver amplificando el valor de la variable redondeada, lo que sólo resultó en darme cuenta que la variable nunca terminaba en el mismo numero; la amplifiqué por 10 y el valor final siempre era 9, pero nunca 10. Amplificado por 100 el valor oscilaba entre 99 y 97.

Decidí que a lo mejor podía trabajar manualmente cada uno de los estados, estableciendo una variable que actuase como path_endaction, pero escribiendo el código que cada acción debería tomar, y darle por valor a path_endaction 0, pues es el único valor en que path_position equivale a 1 en algún momento.

En teoría es sencillo, si path_position es 1 y:
- La variable personalizada es 0 (detener el path), cambia el speed del path a 0.
- Si la variable es 1 (volver al punto inicial) establece el valor de path_position a 0.
- Si la variable es 2 (reiniciar el path desde el punto en que se encuentra la instancia), termina el path y lo vuelve a llamar, provocando que empiece desde allí.
- Si la variable es 3 (hacer el path a la inversa), multipica la velocidad del path por -1

Segundo problema: Al llegar al final del path, escribiese lo que escribiese, el objeto se detiene. Al principio pensé que tenía sentido porque path_endaction equivalía a 0, y a lo mejor eso preponderaba a cualquier otra órden que le diese a la instancia que seguía el path, sin embargo según el manual de Game Maker sí se pueden modificar éstos valores. Ni path_speed ni path_position parecen reaccionar, incluso si los cambio manualmente en modo debug.

Si no necesitas que tus instancias de mano_der y mano_izq hagan algo luego de acabar el path, la solución es:

with (mano_der)
if (path_position == 1)
{
sound_play(sfx_tusonido);
}


De lo contrario, te pediría por favor que debuggearas lo que te escribí anteriormente. Si la variable path_position vale 0 al comienzo y 1 al final en el intérprete de Windows de Game Maker 8 en otros comportamientos del path, la solución es tan sencilla como comprobar si es que la variable equivale a 1 y en ese caso reproducir el sonido. De lo contrario, ojalá que ésta experiencia fallida te ayude en algo ._.

Tengo la sensación de que estoy pasando por alto algo muy obvio y estúpido, pero no logro fijarme en qué ._.

Necesito dormir =_=
10
Si por controlar te refieres a ejecutar el evento End of Path desde obj1:

with (obj2) //Hacemos que el código se ejecute en todas las instancias de obj2, de otro modo se va a ejecutar en obj1
{
event_perform_object(obj2,ev_other, ev_end_of_path); //Manualmente llamamos al evento End of Path de obj2.
}
//Si quieres ejecutarlo únicamente dentro de una instancia de obj2, debes guardar en una variable el valor del id de la instancia de obj2 al crearla. Esto se hace anteponiendo a la función instance_create() donde creas la instancia de obj2 una variable seguida del signo de equivalencia.
//Por ejemplo: obj2_id = instance_create(x,y,obj2);
//Luego, en lugar de with(obj2), escribes with(obj2_id). Así el código sólo se ejecuta en esa instancia.

Eso ejecutará el evento End of Path en obj2. Ten en cuenta que esto va a ejecutar el código del evento sin necesidad de que se cumpla la condición normal de ejecución del código, es decir, sin necesidad de que la instancia haya llegado al final del path.

Si por controlar te refieres a introducir código en el End of Path de obj2 desde obj1, es un poco más complicado. Si pudieses aclarar exactamente a qué te refieres con "controlar el evento", es decir, si te refieres a su contenido o a su ejecución, te puedo escribir un ejemplo para lograr el cometido :)
11
Preguntas y respuestas / Re:Espejar Sprite
Enero 15, 2013, 05:18:13 PM
Con la segunda duda no se si pueda ayudarte; nunca he ocupado ninguna extensión ._. los dramas de haber saltado de Game Maker 6 en Windows a Game Maker 7 en un Mac con un hiato de años entre medio xD Y el hecho de que la mayoría de las extensiones sean incompatibles con Mac no ayuda en nada :3

Pero con la primera claro que te puedo ayudar :) existen dos variables que controlan el scaling del sprite directamente en Game Maker. Estas son image_xscale e image_yscale.

Por defecto, éstas variables llevan por valor 1, lo que significa que el sprite está en proporción 1:1, o dicho de otro modo, x1.00.
Como te imaginarás, aumentar el valor de éstas variables hace que el sprite se vaya agrandando, por lo que darle un valor de 2 a ambas hará que el sprite esté en proporción 2:1 / x2.00 y se vea al doble de su tamaño original, así sucesivamente.

Ahora, el momento en que ésta función comienza a responder tu duda es cuando se hace escalado negativo :)

Al escalar negativamente un sprite, éste se voltea y se espeja, por lo que darle un valor de -1 a cualquiera de las variables hace que éste se voltee con respecto al eje que cada una maneja.

Dado que lo que necesitas es hacer el espejado en horizontal, necesitas modificar el escalado del sprite para que image_xscale sea equivalente a 1 cuando vaya a la derecha y -1 cuando vaya a la izquierda. ¿Por qué no al revés? Pues porque la numeración de la variable X va subiendo hacia la derecha y disminuyendo hacia la izquierda en Game Maker, y una hspeed positiva moverá el objeto a la derecha y una negativa a la izquierda. De hacerlo así te será más fácil utilizar cualquier variable como referencia.

Dos cosas a considerar:

  • Si vas a utilizar una expresión como image_xscale = sign(hspeed) o image_xscale = sign(x - xprevious) para hacer el espejado del sprite sin tener que manejarlo manualmente, ten en cuenta que en muchos de éstos casos esa expresión resulta en 0, y cuando el escalado de un sprite equivale a 0 éste, bueno, se ve en proporción 0:1 o x0.00, o lo que es lo mismo, no se ve :p
  • El escalado se hace utilizando como centro el punto de origen del sprite, por lo que si lo dejas tal cual viene por defecto, en 0,0, el sprite se va a escalar hacia la izquierda. Tu quieres que el sprite se escale desde el centro, así que considera cambiar el punto de origen del sprite si es que no quieres recurrir a una función draw_sprite_ext() para dibujar el sprite espejado en pantalla
12
Bueh, sabía que me podía equivocar xD pasa que he tenido un par de complicaciones utilizando other fuera de un evento de colisión, y cuando leí en el manual que sólo devolvía el id del otro objeto en esos eventos supuse que era por eso :p

Cita de: brunoxzx en Enero 15, 2013, 02:14:33 AM
[gml]var a;
with(obj){
     other.a=variable_local_array2_get("array", 1, 2);
}[/gml]

y éste código -tomando en cuenta que other sí funciona- parece la versión más limpia :D

...y para evitar hacer más posts, te voy a explicar una manera ingeniosa de chequear qué instancias tienen o no definidas qué variables sin que provoque error :D esto me salvó una par de veces cuando tuve que dejar de ocupar ésta función y su hermana _set.

Lo primero es crear una lista.

global.defined_ids = ds_list_create();

y en cada vez que tengas que definir éstas variables que sólo algunas instancias poseen, escribes lo siguiente al final del código:

ds_list_add(global.defined_ids,id);

añadiendo la id del objeto en cuestión a la lista.

Ahora, cada vez que tengas que hacer la comprobación (léase donde llamas a la función variable_local_array2_get()), en lugar de chequear si la variable existe o no, sencillamente compruebas lo siguiente:

if (ds_list_find_index(global.defined_ids,id_de_la_instancia_en_cuestion) > 0)
{
...
}

Así compruebas que el objeto tiene la variable en cuestión :)

Ahora, si tus rooms no son persistentes, necesitas limpiar esa lista cada vez que la room acabe. En el evento Room End vas y pones:

ds_list_clear(global.defined_ids);

Y listo :D

Ahora, si lo que necesitas realmente es leer y escribir en variables pasadas como string por un motivo u otro, mi solución propuesta es crear un map que nos va a ayudar a mantener éstas variables ubicables por su nombre como string. ¿Cómo lo hacemos? pues así:
Primero creamos el map en cada objeto

vars = ds_map_create();

Y ahora creemos algunos scripts para escribir y leer "variables" dentro de este map.
var_set(id,name,val);

var id, name, val;
id = argument0;
name = argument1;
val = argument2;
if (ds_map_exists((id).vars,name) == true)
{
ds_map_replace((id).vars,name,val);
}
else
{
ds_map_add((id).vars,name,val);
}

var_get(id,name);

var id, name;
id = argument0;
name = argument1;
if (ds_map_exists((id).vars,name) == true)
{
return (ds_map_find_value((id).vars,name));
}
else
{
return 0; //éste valor lo puedes cambiar por el valor que tu quieras considerar como nulo
}

donde id es la id de la instancia, name el nombre de la variable y val su valor.

Se que no viene al caso en absoluto, pero más vale prevenir xD
13
Al menos para cada tecla que quieras utilizar dentro del juego, sí. Necesitas guardar el valor de alguna forma y utilizar éstas variables en la interacción jugador-juego en lugar de las constantes predefinidas o referencias directas a los keycodes.

Personalmente me parece mucho más limpio utilizar un array para las teclas direccionales y otro para el resto de las teclas, pero en realidad puedes hacerlo utilizando sólo un array, o una estructura de datos como un mapa o una lista, pero lo cierto es que necesitas guardarlas en algún lado.

Si te interesa cómo hacerlo en una estructura de datos, te puedo hacer un ejemplo :D la gracia de las estructuras de datos es que como existen funciones nativas para convertirlas en un string, guardarlas y cargarlas desde archivos externos no es para nada difícil, haciendo que programar el guardado de la configuración sea sencillo :)
14
Cita de: ferhand en Enero 14, 2013, 11:46:38 PM
  Entiendo que utilizas la estructura "with", pero dentro del código de la estructura no estamos en el objeto desde donde se realiza la llamada, sino en el objeto donde está la variable "my_array". ¿No habrá una forma de acceder a los valores de dicha variable sin "salirse" del objeto que realiza la llamada?
No se exactamente si existirá alguna forma, pero dentro de la función no creo que haya alguna forma de hacerlo a menos que sea ejecutando el código en la instancia que contiene la variable, dentro de la instancia que necesita obtener el dato.

Una pregunta, ¿por qué estás ocupando esa función? ¿Es porque defines dentro del juego una variable en cierta instancia que no todas las instancias del mismo objeto poseen, y necesitas una forma de corroborar que ésta exista en la instancia que estás chequeando para evitar un error? Si es así, creo que se me ocurren un par de formas creativas para solucionar el problema :D

Cita de: ferhand en Enero 14, 2013, 11:46:38 PM
Por cierto, es normal que la variable "bleh" creada antes del "with" tome los valores de "my_array". La variable "bleh" está en el código "padre" que contiene al segmento del codigo del "with", o sea  un segemento de código  abarca al otro.  ;D   
Eso tiene sentido :p aunque sigo sin entender del todo por qué código que se ejecuta en otro objeto es capaz de escribir en una variable local del código padre sin hacer referencia explícita a éste.
Si tuviese una variable llamada "bleh" en el objeto emparentado, ¿Cual de las dos variables escribiría?
Cita de: brunoxzx en Enero 15, 2013, 12:15:32 AM
Pero puedes hacerlo tal como lo dijo calio simplemente así.
[gml]
var a;
with(obj){
     other.a=array[0];
}[/gml]
Si no me equivoco, other sólo devuelve un valor en eventos de colisión.
15
Preguntas y respuestas / Re:Teclado y cambio de room
Enero 15, 2013, 01:16:37 AM
Cita de: Wadk en Enero 13, 2013, 04:07:18 AM
Entonces podrías hacer:
[gml]global.dpad[1] = global.dpad[1] || keyboard_check(vk_right);[/gml]
antes de cambiar de room, y en step en algún lado:
[gml]global.dpad[1] = global.dpad[1] && !keyboard_check_released(vk_right);[/gml]
¿No?

Lamentablemente, eso resulta en el error que provoca que el jugador siga caminando si suelta la tecla justo entre cambio de rooms.
El error lo gatilla la primera línea de código, y sucede porque -oh, error mío el no haber comentado eso xD- antes de pasar a de room el juego activa una variable que se desactiva al llegar a la room siguiente, y la función de esa variable es suspender el control de las teclas a través del script aburrido de keyboard_check_pressed() y keyboard_check_released() para pasar al chequeo de las teclas directamente previo al cambio de room y mantenerlo hasta la siguiente room, donde la variable vuelve a su estado normal.
Dado que el valor de global.dpad[1] no puede ser actualizado durante éste proceso mediante el método habitual de chequeo, el valor de global.dpad[1] no va a cambiar nunca entre rooms hasta que la variable de control vuelva a su estado normal.

De todos modos, voy bien encaminado con el tema de hacerlo todo en una sola room xD hice un mapa de 256 pantallas y me ocupaba 2.5mb, lo cual encontré excesivo y ridículo así que estoy en el proceso de cambiarme de estructura de datos de una grid a un map con llaves numéricas :) el concepto es sencillo: si enumeramos cada espacio dentro de la cuadrícula de 16x16 de una pantalla de 320x240, (o lo que es lo mismo, 20x15) tenemos 300 cuadros, y haciendo un par de expresiones sencillas

x = (key mod 20);
y = ((key div 20)*20);

guardar y recuperar la posición de elementos guardados en una estructura unidimensional no es difícil :D

EDIT: Hace un rato terminé de hacer la mayoría de los cambios para guardar las pantallas en mapas. El peso de un archivo de 256 pantallas vacías bajó de 2.5mb a 9kb :D