Diciembre 08, 2017, 11:39:30 PM Ultima modificación: Diciembre 16, 2017, 05:48:43 PM por Naitsabes0
¿Que les parece esta mecánica?
https://i.gyazo.com/fccff4d89b224448c5eaa2c539f0ae10.gif

El concepto es simple, toca los bloques y desaparecerán, pero la forma en como esta funcionando lo hace especial, desde mi punto de vista analizo las siguientes partes.

1.- Tenemos 2 objetos, el obj_Bloque_Color y el obj_Pincho_Color (la razón del porque se llama color es para que no entre el conflicto con los bloques y pinchos normales)
2.- El jugador debe colisionar con la plataforma cuadra, es decir el  obj_Bloque_Color y no la puntiaguda, la cual vendría siendo el obj_Pincho_Color para que esta se destruya.
3.- Estas comenzaran a parpadear/brillar de forma llamativa antes de desaparecer, por lo que hay un limite de tiempo antes de que se destruyan producto del ejemplo 2.
4.- Las plataformas que tienen el mismo color y que a su vez están en colisión/contacto con sus semejantes, son afectadas por la colisión, por lo tanto las del mismo color que no estén en contacto o que sean de otro color, no son afectadas por lo anterior.
5.- Hay un código en creation_code que se encarga de darles el color a los objetos, por lo que asumo que están de color blanco antes de darles una identidad, ya que esto permite hacer varios colores con solo 2 objetos.

Lo anterior correspondería a mi análisis escrito  :), ahora pasare a mi punto débil y la razón principal por la que publique este post, el código  :-[.

Como dije tendríamos 2 objetos, el obj_Bloque_Color y el obj_Pincho_Color

El obj_Bloque_Color
CREATE
///Variables
destello = false; //no a sido activado
tiempo = 90; // 3 segundos 3*30

Collision_obj_Jugador
destello = true //a sido activado
if destello = true // si esta activo activa la alarma
    {
    alarm[0] = 30 // 1 segundos 1*30
    }

ALARM0
(algo que la aga brillar)
(destruir cuando el tiempo es 0)

El obj_Pincho_Color
STEP
if destello = true // si esta activo activa la alarma
    {
    alarm[0] = 30 // 1 segundos 1*30
    }

ALARM0
(algo que la aga brillar)
(destruir cuando el tiempo es 0)

En el obj_Bloque_Color y el obj_Pincho_Color
Creation_code
color = c_green;

En el obj_Bloque_Color y el obj_Pincho_Color
Creation_code
color = c_yellow;

Bueno admito que hay muchos problemas para que esto funcione como lo que se ve arriba en el GIF, por ejemplo no esta definida la variable color como para que funcione, probablemente deba hacer algo que controle cuando los objetos de mismo color están colisionando, ya que no se como hacer las canciones para que eso se este leyendo en códigos, sin embargo mi código esta muy lejos de poder funcionar de las misma forma que el ejemplo, sin embargo ya estoy armando una base junto con algunas teorías, hasta el momento estaré estudiando para una prueba de matemáticas y ya he gastado sus buenas horas tratando de desentrañar esta interesante mecánica, en caso que pueda o pasamos resolverlo, el código estará aquí para su uso y análisis, que tengan un buen día.

Yo recomendaría tener un objeto Bloque_color y Pincho_color, por color ( ejemplo: objBloque_Azul,objPincho_Azul )
es mucho más fácil de colocar en los cuartos.

Pero de la forma que quieres hacerle se puede hacer un array global y que cuando el personaje pise un bloque de color la coloque en 1(true) y los dos objetos en cuestión tengan un if que compruebe el estado de está variable y transcurra la secuencia de eliminación. Para ello estos objetos en su create code, además de la variable para cambiarlo de color, tendrán una variable que posea el valor del indice del array al cual afectará .

ejemplo:

[gml]
//Variable global
global.OrdenBloques[1] = false;
//Variable bloque
Orden = 1;

//Step
if global.OrdenBloques[Orden]
{
//cositas
}
[/gml]

Cita de: TheWood en Diciembre 09, 2017, 12:28:44 AM
Yo recomendaría tener un objeto Bloque_color y Pincho_color, por color ( ejemplo: objBloque_Azul,objPincho_Azul )
es mucho más fácil de colocar en los cuartos.

Pero de la forma que quieres hacerle se puede hacer un array global y que cuando el personaje pise un bloque de color la coloque en 1(true) y los dos objetos en cuestión tengan un if que compruebe el estado de está variable y transcurra la secuencia de eliminación. Para ello estos objetos en su create code, además de la variable para cambiarlo de color, tendrán una variable que posea el valor del indice del array al cual afectará .

ejemplo:

[gml]
//Variable global
global.OrdenBloques[1] = false;
//Variable bloque
Orden = 1;

//Step
if global.OrdenBloques[Orden]
{
//cositas
}
[/gml]

No es mala idea crear en un principio un objBloque_Azul,objPincho_Azul, pero es muy limitado, en  :GMS: tienes un montón de valores de colores para elegir que van desde c_agua a c_yellow, es decir 19 colores, imagínate que quieras crear un nivel especial que solamente esta físicamente formado por estos, el jugador no solamente deberá saltar con habilidad, también tendrá que armar una estrategia de cual bloque deberá destruir 1°, si combinas esta mecánica con otras, incluso con jefes, puedes hacer un nivel tan divertido y desafiante, que me extraña que no lo haya visto por las grandes posibilidades, pero al parecer ninguno de los 2 sabemos como programar el funcionamiento de los objetos que vemos en pantalla, por lo que solamente formamos códigos y teorías al respecto, pero de ese modo vamos analizando las partes  :).

Xd...Yo ya hice el mecanismo, realmente lo hice con lo que te explique anteriormente.

Y tienes razón con lo que te da el sistema, pero colocar los objetos en la room y a cada uno colocarle un color es muy latero xd, y por eso decía lo de hacer un bloque de color y su pincho de color respectivamente, para evitar trabajar en el editor de cuartos y así ahorrar tiempo.

Cita de: TheWood en Diciembre 09, 2017, 01:47:07 AM
Xd...Yo ya hice el mecanismo, realmente lo hice con lo que te explique anteriormente.

Y tienes razón con lo que te da el sistema, pero colocar los objetos en la room y a cada uno colocarle un color es muy latero xd, y por eso decía lo de hacer un bloque de color y su pincho de color respectivamente, para evitar trabajar en el editor de cuartos y así ahorrar tiempo.
Pues analizándolo.

//Variable global
global.OrdenBloques[1] = false;
//Variable bloque
Orden = 1;

//Step
if global.OrdenBloques[Orden]
{
//cositas
}

El CREATE
tendría desactivada su función, pero no me queda claro porque debe haber un orden, es decir el jugador puede tocar la que sea y cuando lo haga esta comenzara a desaparecer, por lo lo tanto no tiene sentido que el código lleve orden, otro problema es que es global, si los objetos se destruyen cuando el valor de la variable sea "X", entonces este objeto se vuelve inútil cuando el valor sea alcanzado, por lo que se puede colocar una unica vez.

STEP
Cuando global.OrdenBloques alcance su valor ejecutara la acción descrita, pero como se menciona arriba esta esta muy lejos de funcionar.

Otro fallo es que has omitido el evento de COLLISION ¿como se supone que el objeto sabrá que entro en contacto con el jugador?

Aunque se que mi código esta malo, creo que esta mas cerca de hacer la función que aparece en el GIF, al menos desde mi punto de vista parece encajar medianamente bien en la mayoría de los puntos.

El obj_Bloque_Color
CREATE
///Variables
destello = false; //no a sido activado
tiempo = 90; // 3 segundos 3*30

Collision_obj_Jugador
destello = true //a sido activado
if destello = true // si esta activo activa la alarma
    {
    alarm[0] = 30 // 1 segundos 1*30
    }

ALARM0
(algo que la aga brillar)
(destruir cuando el tiempo es 0)

El obj_Pincho_Color
STEP
if destello = true // si esta activo activa la alarma
    {
    alarm[0] = 30 // 1 segundos 1*30
    }

ALARM0
(algo que la aga brillar)
(destruir cuando el tiempo es 0)

En el obj_Bloque_Color y el obj_Pincho_Color
Creation_code
color = c_green;

En el obj_Bloque_Color y el obj_Pincho_Color
Creation_code
color = c_yellow;

No entendiste muy bien o yo no me explique bien xD. El nombre de la variable solo la puse de nombre, no es que haya orden o algo así es solo para que este esa variable global en el videojuego, aunque revisando mi I wanna be me di cuenta que te lo había dado mal, así que perdón por eso.  :-[

[gml]

//Variable global establecida en algún objeto persistente que se inicie al comienzo de todo
global.Ejecutor[99] = 0;
[/gml]

Y ahora el bloque, y también como en el caso anterior la variable orden que yo coloque es solo para darle un nombre.

[gml]

/*ObjBloque_color*/

//Create
Numero = -1; //El valor de esta variable debe colocarse en el evento creation code
Color = -1 //El valor de esta variable debe colocarse en el evento creation code

Activo = false; //Para que no se ejecute infinitamente

[/gml]

Faltan la variables para disminuir el tiempo, eso ya es tarea tuya.Y ahora lo que mencionas con lo del evento colisión es muy sencillo de hacer

[gml]
//Colision
if place_meeting(x,y-1,objPlayer)
{
global.Ejecutor[Numero] = 1;
}
[/gml]

Y ahora solo queda comprobar el estado de la variable global.Ejecutor

[gml]
//Step
if Numero != 0
{
if (!Activo) and global.Ejecutor[Numero] == 1
{
  Activo = true;     
}
}
[/gml]

Ahora te faltaría, solamente que parpadee,una forma de destruirlo y el codigo para los pinchos, lo cual te lo dejo para que lo hagas tú.

pero que no se te olvide que al destruir el objeto se debe colocar la variable global a 0, en los cuartos siguientes los objetos también se verán afectados



Algo así debería de quedarte  ;D

Cita de: TheWood en Diciembre 09, 2017, 06:00:56 PM
No entendiste muy bien o yo no me explique bien xD. El nombre de la variable solo la puse de nombre, no es que haya orden o algo así es solo para que este esa variable global en el videojuego, aunque revisando mi I wanna be me di cuenta que te lo había dado mal, así que perdón por eso.  :-[

[gml]

//Variable global establecida en algún objeto persistente que se inicie al comienzo de todo
global.Ejecutor[99] = 0;
[/gml]

Y ahora el bloque, y también como en el caso anterior la variable orden que yo coloque es solo para darle un nombre.

[gml]

/*ObjBloque_color*/

//Create
Numero = -1; //El valor de esta variable debe colocarse en el evento creation code
Color = -1 //El valor de esta variable debe colocarse en el evento creation code

Activo = false; //Para que no se ejecute infinitamente

[/gml]

Faltan la variables para disminuir el tiempo, eso ya es tarea tuya.Y ahora lo que mencionas con lo del evento colisión es muy sencillo de hacer

[gml]
//Colision
if place_meeting(x,y-1,objPlayer)
{
global.Ejecutor[Numero] = 1;
}
[/gml]

Y ahora solo queda comprobar el estado de la variable global.Ejecutor

[gml]
//Step
if Numero != 0
{
if (!Activo) and global.Ejecutor[Numero] == 1
{
  Activo = true;     
}
}
[/gml]

Ahora te faltaría, solamente que parpadee,una forma de destruirlo y el codigo para los pinchos, lo cual te lo dejo para que lo hagas tú.

pero que no se te olvide que al destruir el objeto se debe colocar la variable global a 0, en los cuartos siguientes los objetos también se verán afectados



Algo así debería de quedarte  ;D

Vale analizando por parte, no había un orden sino que lo definió de esa forma

obj_Control
CREATE
[gml]
global.Ejecutor[99] = 0;
[/gml]

Bueno este obj_Control tiene el valor global.Ejecutor[99] = 0;, por lo que va a comenzar en 0, y es persistente para que vaya guardando este valor.

obj_Bloque_Color
CREATE
[gml]
Activo = false; //Inicialmente esta desactivado.
[/gml]

Aquí lo tendría inicialmente desactivo para que no se vaya a destruir antes que el jugador lo toque.

STEP
[gml]
///Estado actual
if Numero != 0 //Si numero no es igual a 0
{
if (!Activo) and global.Ejecutor[Numero] == 1 //si no activo y global.Ejecutor numero doblemente igual a 1
{
  Activo = true;  //se activa   
}
}
[/gml]

Bueno aquí estaría comprobando si el numero no es igual a 0, y en caso que no sea igual a 0 ara algún procedimiento para que activo sea verdadero, casi nunca suelo usar los !, ya que me confunde al momento de decir "NO", entonces me confundo, no termino de entender bien la sentencia if (!Activo) and global.Ejecutor[Numero] == 1

Collision_obj_jugador
[gml]
///Colisión jugador
if place_meeting(x,y-1,obj_Jugador) //si colisiona con el jugador
{
global.Ejecutor[Numero] = 1; //global.Ejecutor[Numero] es 1
}
[/gml]

Entonces se supone que cuando colisione global.Ejecutor[Numero] sera 1, y al momento de hacer eso step cumplirá la condición para que lo vuelva activo.

El controlador esta en la sala y el objeto tiene en su creation_code los valores.
Numero = -1;
Color = -1;

Vale soy consciente de que tengo que programar el tiempo y lo que ocurre cuando esta activo, pero si todo ese procedimiento esta bien ¿porque tiene error?

#############################################################################
FATAL ERROR in
action number 1
of  Step Event0
for object obj_Bloque_Color:

Push :: Execution Error - Variable Index [0,-1] out of range [1,100] - -5.Ejecutor(100000,-1)
at gml_Object_obj_Bloque_Color_StepNormalEvent_1 (line 4) -  if (!Activo) and global.Ejecutor[Numero] == 1
############################################################################

Las variables "Numero" y "Color" deben ser definidas(a definidas me refiero que tengan cualquier valor,por eso el -1, porque después se cambiaran cuando se ejecute el creation code cuando se pruebe el juego ) en el evento create del objeto.

y en el creation code debes colocar sus valores, asegúrate que "Numero" no sea negativo y que "Color" sea una constante de color. también debes hacer una forma que cambie de color.

Cita de: TheWood en Diciembre 11, 2017, 04:08:57 AM
Las variables "Numero" y "Color" deben ser definidas(a definidas me refiero que tengan cualquier valor,por eso el -1, porque después se cambiaran cuando se ejecute el creation code cuando se pruebe el juego ) en el evento create del objeto.

y en el creation code debes colocar sus valores, asegúrate que "Numero" no sea negativo y que "Color" sea una constante de color. también debes hacer una forma que cambie de color.
Vale lo deje de este modo.
obj_Bloque_Color
///Variables
Activo = false; //Para que no se ejecute infinitamente
Numero = -1;
Color = -1;

///Estado actual
if Numero != 0
{
if (!Activo) and global.Ejecutor[Numero] == 1
{
  Activo = true;     
}
}

///Colision jugador
if place_meeting(x,y-1,obj_Jugador)
{
global.Ejecutor[Numero] = 1;
}

Creation_code
Numero = 1;
Color = 1;

Bueno el objeto no me impide hacer correr el juego, sin embargo la colisión no se hace aunque este programada para ello, por otra parte le propuse un tema en twitter, pero me envió a su block, a pesar de que le haya puesto unas horas a la creación de la mecánica, me he puesto a mejorar los escenarios de mi juego, así que le preguntare ¿quiere hacer algún intercambio? ya sea código, sprite o cualquier elemento que se pueda enviar.

Este es mi actual diseño de escenario, uno de decenas, creo esto cuando me frustro al programar código, así me da la sensación de que avance en algo.
https://i.gyazo.com/fea786278368a4e328240fc389975548.gif

#9 Diciembre 11, 2017, 04:46:22 PM Ultima modificación: Diciembre 11, 2017, 04:54:10 PM por TheWood
mmm...que extraño que no te detecte una colisión, probaría usar el debug para saber que está ocurriendo.

Y sobre el intercambio estoy algo indeciso, pero eso lo podemos conversar en privado para no desviar el hilo.

Cita de: TheWood en Diciembre 11, 2017, 04:46:22 PM
mmm...que extraño que no te detecte una colisión, probaría usar el debug para saber que está ocurriendo.

Y sobre el intercambio estoy algo indeciso, pero eso lo podemos conversar en privado para no desviar el hilo.
¿Así que quieres hablar en privado? tomando en cuenta que me dirigi a tu twitter y que después me envió a su bloc personal https://thewoodg.blogspot.cl/2017/11/i-wanna-flex-en-gamejolt.html#comments, y que ademas deje un comentario que ni siguiera se tomo el tiempo de responder ¿como esperara hablar en privado si ni siguiera revisa sus últimos mensajes? no veo la razón para reservarse tanto secreto, es mas, el intercambio tiene que ver con este hilo, yo busco la forma de hacer el código del GIF o almenos hacer el que tiene usted tiene, pero se que pedirá algo a cambio, es hay donde entra el intercambio.

#11 Diciembre 12, 2017, 07:22:18 AM Ultima modificación: Diciembre 12, 2017, 08:24:48 AM por brunoxzx
¿Intercambio de que hombres? Tranquilo que aquí llegará la respuesta de TheWood en algún momento con paciencia, yo creo que el no te dejo el ejemplo para que te eches la talacha (el trabajo) y aprendas, así que no te apresures.

Mira lo que debes hacer en pocos pasos para ahora que estás conectado y tengo ganas de divertirme:


  • Crear un "obj_muro_color" padre, y le das "color=image_blend" (o el color que quieras)  en el evento create.
  • Crear un hijo de "obj_muro_color" que se llame "obj_bloque_verde" a ese le pones en create "image_blend=c_green; color=image_blend;". Puedes crear cuantos hijos quieras para cuantos colores quieras y así añadirlos fácilmente en el room.
  • Crear un hijo de "obj_muro_color" llamado "obj_pincho", puedes crear cuantos hijos quieras de obj_pincho de diversos colores o solo añadir el objeto pincho en el editor de rooms y cambiar el color desde allí
  • Añadir a obj_muro_color el siguiente código en el "event_user 0":
    [gml]
    if (alarm[0]<0) {
            alarm[0]=30; //o el tiempo que le quieras poner antes que se destruyan
            var ins;
            for(var i=0; i<4; i++){
                ins=collision_point(x+sprite_width/2+lengthdir_x(sprite_width, i*90), y+sprite_width/2+lengthdir_y(sprite_width, i*90), obj_muro_color, false, true);
               if ( instance_exists(ins) ){
                   if (ins.alarm[0]<0 && color==color) {
                       with(ins) event_user(0);
                   }
               }
            }
    }
    [/gml]
  • Añadir al objeto "obj_muro_color" en el evento de colisión con tu personaje lo siguiente: "event_user(0)"
  • Añadir el D&D de instance_destroy() a la alarma 0 de el "objeto_muro_color"
  • Añadir el "with(other) instance_destroy();" al evento de colision del "obj_pincho" con tu personaje
  • Añadir el siguiente código al step de "objeto_muro_color":
    [gml]
    if (alarm[0]>0) image_blend=lerp(color, c_white,  sign(alarm[0] mod 2)); //puedes cambiar el 2 para que parpadee más lento o más rápido
    [/gml]

Listo, siempre puedes añadir el "obj_muro_color" directamente en el room sin necesidad de crear un hijo y darle el color que quieras desde la interfaz.

Edit: Me di cuenta que querías una cosa un poquitín distinta a lo que pensaba y acabo de modificar

Cita de: brunoxzx en Diciembre 12, 2017, 07:22:18 AM
¿Intercambio de que hombres? Tranquilo que aquí llegará la respuesta de TheWood en algún momento con paciencia, yo creo que el no te dejo el ejemplo para que te eches la talacha (el trabajo) y aprendas, así que no te apresures.

Mira lo que debes hacer en pocos pasos para ahora que estás conectado y tengo ganas de divertirme:


  • Crear un "obj_muro_color" padre, y le das "color=image_blend" (o el color que quieras)  en el evento create.
  • Crear un hijo de "obj_muro_color" que se llame "obj_bloque_verde" a ese le pones en create "image_blend=c_green; color=image_blend;". Puedes crear cuantos hijos quieras para cuantos colores quieras y así añadirlos fácilmente en el room.
  • Crear un hijo de "obj_muro_color" llamado "obj_pincho", puedes crear cuantos hijos quieras de obj_pincho de diversos colores o solo añadir el objeto pincho en el editor de rooms y cambiar el color desde allí
  • Añadir a obj_muro_color el siguiente código en el "event_user 0":
    [gml]
    if (alarm[0]<0) {
            alarm[0]=30; //o el tiempo que le quieras poner antes que se destruyan
            var ins;
            for(var i=0; i<4; i++){
                ins=collision_point(x+sprite_width/2+lengthdir_x(sprite_width, i*90), y+sprite_width/2+lengthdir_y(sprite_width, i*90), obj_muro_color, false, true);
               if ( instance_exists(ins) ){
                   if (ins.alarm[0]<0 && color==color) {
                       with(ins) event_user(0);
                   }
               }
            }
    }
    [/gml]
  • Añadir al objeto "obj_muro_color" en el evento de colisión con tu personaje lo siguiente: "event_user(0)"
  • Añadir el D&D de instance_destroy() a la alarma 0 de el "objeto_muro_color"
  • Añadir el "with(other) instance_destroy();" al evento de colision del "obj_pincho" con tu personaje
  • Añadir el siguiente código al step de "objeto_muro_color":
    [gml]
    if (alarm[0]>0) image_blend=lerp(color, c_white,  sign(alarm[0] mod 2)); //puedes cambiar el 2 para que parpadee más lento o más rápido
    [/gml]

Listo, siempre puedes añadir el "obj_muro_color" directamente en el room sin necesidad de crear un hijo y darle el color que quieras desde la interfaz.

Edit: Me di cuenta que querías una cosa un poquitín distinta a lo que pensaba y acabo de modificar

He leído detenidamente cada parte y he armado lo siguiente:

obj_Muro_Color

CREATE
[gml]
///Color
color = image_blend
[/gml]

ALARM 0

Tiene un D&D de "destroy the instance"

STEP
[gml]
if (alarm[0]>0) image_blend=lerp(color, c_white,  sign(alarm[0] mod 2));
[/gml]

COLLISION obj_Jugador
[gml]
///Activar evento
event_user(0)
[/gml]

USER DEFINED 0
[gml]
///Evento
if (alarm[0]<0) {
        alarm[0]=30; //o el tiempo que le quieras poner antes que se destruyan
        var ins;
        for(var i=0; i<4; i++){
            ins=collision_point(x+sprite_width/2+lengthdir_x(sprite_width, i*90), y+sprite_width/2+lengthdir_y(sprite_width, i*90), obj_Muro_Color, false, true);
           if ( instance_exists(ins) ){
               if (ins.alarm[0]<0 && color==color) {
                   with(ins) event_user(0);
               }
           }
        }
}
[/gml]

obj_Bloque_Verde (Hijo obj_Muro_Color)
CREATE
[gml]
///Color
image_blend=c_green;
[/gml]

obj_Pincho (Hijo obj_Muro_Color)
CREATE
[gml]
///Color
image_blend=c_green;
[/gml]

Quiero aclarar que los 2 objetos tienen un sprite a los que llame spr_Bloque y spr_Pincho, los cuales son con tonalidades de blanco, el obj_Muro_Color se encuentra en la room, pero me da error.



FATAL ERROR in
action number 1
of Other Event: User Defined 0
for object obj_Muro_Color:

Variable obj_Bloque_Verde.color(100015, -2147483648) not set before reading it.
at gml_Object_obj_Muro_Color_UserEvent0_1 (line 8) -                if (ins.alarm[0]<0 && color==color) {

Debes de poner "event_inherited()" en el evento create de los objetos que heredan y debe de ir después de poner el código de image_blend. Ese error es solo porque no tienen la variable color, también puedes declararla directamente en el evento create de esos objetos.

Cita de: brunoxzx en Diciembre 12, 2017, 07:58:02 PM
Debes de poner "event_inherited()" en el evento create de los objetos que heredan y debe de ir después de poner el código de image_blend. Ese error es solo porque no tienen la variable color, también puedes declararla directamente en el evento create de esos objetos.



Le he programado lo que me ha dicho, sin embargo considera a los objetos como traspasables, se que podría solucionar esto asiéndolo solido, pero la colisión de estos objetos esta destinada al jugador, se puede apreciar que los pinchos y bloques responden a tu función al colisionar, pero deja caer al jugador antes de desaparecer.

Honestamente este resultado es genial ¿porque digo esto? imagínate que el bloque fuera un botón y los pinchos sus puertas, sin querer queriendo he descubierto que puede ser el típico mecanismo llave/ puerta, aun así me gustaria saber porque esta fallando la colisión con el jugador, al resolver este problema ya puedo dar por terminado este post que se ha extendido por 3-4 días.