Septiembre 16, 2017, 11:15:31 AM Ultima modificación: Septiembre 17, 2017, 09:15:52 AM por Naitsabes0
Con este GIF muestro lo que busco.

En algunos juegos, el jugador debe tocar ciertos objetos en un orden para que pase "X" acción, en este ejemplo de Mario 64 el jugador debe tocar los cofres en el orden correcto, de no seguir la secuencia correcta sufrirá daño, ademas los cofres volverán a su estado original, de esta forma el jugador deberá tener algo de memoria hasta encontrar el patrón correcto por descarte.

¿Hay algún tutorial de  :GMS: para hacer esta mecánica en particular? la verdad no se como se puede llamar a esta mecánica de puzzle de patrones, puede verse común y simple, pero la he visto pocas veces en juegos, y con el diseño de escenario adecuado mas otros puzzles que tengo en el "proyecto texteo" que siempre muestro para dar informacion visual, podria hacer combinaciones que logren captar la atencion.

Si no hay un tutorial, pues no importa, poco a poco analizare los elementos involucrados, por el momento sigo experimentando con el "puzzle de colisiones", gracias por leer  :).

El puzzle de bloques deberia servirte para esto, aplicandole una variable con un numero de orden para saber cual es el que estas abriendo.

Pero la logica es mas o menos la misma.

#2 Septiembre 16, 2017, 07:47:46 PM Ultima modificación: Septiembre 16, 2017, 07:50:24 PM por NiuWeb
Se me ocurre que podrías, como dice [user]bochaPastore[/user], definir una identificación a cada bloque, en el orden en el que deban activarse. Además, contar con dos arreglos en un controlador: El patrón original y correcto, y un arreglo vacío donde se meterán los ids en el orden en el que se activan.
[gml]
///Evento create del controlador
globalvar base, hecho;
base = ds_list_create(); //Lista para meter los identificadores en el orden correcto.
ds_list_add(base, 1, 2, 3, 4); //Se añaden los valores en ese orden.

hecho = ds_list_create(); //Lista para meter los identificadores de los bloques que se van activando
[/gml]
[gml]
///Evento create de cada bloque
orden = 1;
[/gml]
Para este objeto (bloque) deberás modificar el valor de orden en el creation code de cada instancia.

[gml]
///Evento step del jugador
//El código completo sería el mismo del adjunto de puzzles con colisiones
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //Y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
[/gml]
La idea es, cuando se completen todos los bloques, se compruebe si la lista hecho es igual a la lista base: Si es así, entonces el puzzle se completó correctamente; si no, pues no.

De nuevo, asumo que aún usas el código que de dejé en el adjunto de puzzles con colisiones, la forma de comprobar si el orden es correcto sería algo así:
[gml]
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
    /*A partir de aquí asumimos (como debería ser) que todos
      los bloques ya han sido activados, por lo que el tamaño
      de las listas `orden` y `hecho` tiene que ser el mismo.
    */
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var or = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(or <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlock)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
[/gml]
Estos código no los he probado, pero en teoría deberían funcionar. En todo caso, reporta si hay algún error.

Espero que si tienes problemas no digas que las listas son inútiles XD.
alaberga regué el café.

BA:STFW&RTFM

#3 Septiembre 17, 2017, 01:31:45 AM Ultima modificación: Septiembre 20, 2017, 12:04:02 AM por Johann
Cita de: NiuWeb en Septiembre 16, 2017, 07:47:46 PM
Se me ocurre que podrías, como dice [user]bochaPastore[/user], definir una identificación a cada bloque, en el orden en el que deban activarse. Además, contar con dos arreglos en un controlador: El patrón original y correcto, y un arreglo vacío donde se meterán los ids en el orden en el que se activan.
[gml]
///Evento create del controlador
globalvar base, hecho;
base = ds_list_create(); //Lista para meter los identificadores en el orden correcto.
ds_list_add(base, 1, 2, 3, 4); //Se añaden los valores en ese orden.

hecho = ds_list_create(); //Lista para meter los identificadores de los bloques que se van activando
[/gml]
[gml]
///Evento create de cada bloque
orden = 1;
[/gml]
Para este objeto (bloque) deberás modificar el valor de orden en el creation code de cada instancia.

[gml]
///Evento step del jugador
//El código completo sería el mismo del adjunto de puzzles con colisiones
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //Y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
[/gml]
La idea es, cuando se completen todos los bloques, se compruebe si la lista hecho es igual a la lista base: Si es así, entonces el puzzle se completó correctamente; si no, pues no.

De nuevo, asumo que aún usas el código que de dejé en el adjunto de puzzles con colisiones, la forma de comprobar si el orden es correcto sería algo así:
[gml]
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
    /*A partir de aquí asumimos (como debería ser) que todos
      los bloques ya han sido activados, por lo que el tamaño
      de las listas `orden` y `hecho` tiene que ser el mismo.
    */
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var or = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(or <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlock)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
[/gml]
Estos código no los he probado, pero en teoría deberían funcionar. En todo caso, reporta si hay algún error.

Espero que si tienes problemas no digas que las listas son inútiles XD.
Descuida no muerdo la mano que me ayuda a programar elementos poco comunes en los juegos, le he dado esta forma al código, pero hay un error simbólico de lógica en la parte inferior del código que evita la ejecución del juego, como el código es una copia muy similar, seria menos engorroso leer el problema adjunto en la imagen de abajo antes de tener que leer todo esto.

[gml]
//Movimiento
var vel = 5;
var hor = keyboard_check(ord("D")) - keyboard_check(ord("A"));
var ver = keyboard_check(ord("S")) - keyboard_check(ord("W"));
repeat(vel)
{
    if(place_free(x + hor, y))
        x += hor;
    else break;
}
repeat(vel)
{
    if(place_free(x, y + ver))
        y += ver;
    else break;
}
//Codigo encargado de los patrones alarma
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //Y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
/*A partir de aquí asumimos (como debería ser) que todos
     los bloques ya han sido activados, por lo que el tamaño
     de las listas `orden` y `hecho` tiene que ser el mismo.
   */
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var or = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(or <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlock)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
[/gml]

Los demás elementos los he creado siguiendo tus instrucciones, no presentan errores evidentes, por lo que solo debería ver este pequeño detalle para probar si todos los elementos funcionan como deben, un saludo  :).

Cita de: bochaPastore en Septiembre 16, 2017, 02:55:39 PM
El puzzle de bloques deberia servirte para esto, aplicandole una variable con un numero de orden para saber cual es el que estas abriendo.

Pero la logica es mas o menos la misma.
Pues gracias al código que mando "NiuWeb", tengo armada la siguiente estructura en el "STEP" del jugador, pero hay un pequeño error de la clase lógica que evita la ejecución.



Esta ordenado siguiendo la lógica "puzzle de colisiones" del post anterior, por lo que se encuentra en la mitad inferior bajo el mismo nombre de variables, si es como el 1° tienen pinta de funcionar bien, al menos después de ver el error lógico anteriormente mencionado.

#5 Septiembre 17, 2017, 01:43:36 AM Ultima modificación: Septiembre 17, 2017, 01:48:21 AM por NiuWeb
Lol, XD.
Lo siento, es el nombre de la variable or, ése es un operador booleano, no sé como se me pasó xDxD.
Sólo cambia el nombre de la variable, algo así:
[gml]         var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
[/gml]
Por cierto, sólo por si acaso, el último bloque de código que escribí en mi mensaje anterior iría en el lugar del evento step del controlador.
alaberga regué el café.

BA:STFW&RTFM

Cita de: NiuWeb en Septiembre 17, 2017, 01:43:36 AM
Lol, XD.
Lo siento, es el nombre de la variable or, ése es un operador booleano, no sé como se me pasó xDxD.
Sólo cambia el nombre de la variable, algo así:
[gml]         var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
[/gml]
Por cierto, sólo por si acaso, el último bloque de código que escribí en mi mensaje anterior iría en el lugar del evento step del controlador.
Creo que fue mala idea utilizar elementos del post anterior, en vez de crear códigos nuevos que no dependan de los anteriores, la razón es que se han mezclado códigos de objetos con otros asiendo que los eventos no tengan los códigos donde corresponden, por darte un ejemplo de armo este desorden por mezclar patrones del puzzle colisiones con cogidos del puzzle patrones.

//////////////////////////////////////////////////oPlayer
STEP
//Movimiento
var vel = 5;
var hor = keyboard_check(ord("D")) - keyboard_check(ord("A"));
var ver = keyboard_check(ord("S")) - keyboard_check(ord("W"));
repeat(vel)
{
    if(place_free(x + hor, y))
        x += hor;
    else break;
}
repeat(vel)
{
    if(place_free(x, y + ver))
        y += ver;
    else break;
}
//Codigo encargado de los patrones alarma
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //Y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}

///////////////////////////////////////////////oBlock
CREATE
image_speed = 0;
colliding = false;

STEP
if(!place_meeting(x, y, oPlayer)) //Si no está colisionando con el jugador
    colliding = false; //Permitir colisión de nuevo

//////////////////////////////////////////////control
STEP
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
/*A partir de aquí asumimos (como debería ser) que todos
     los bloques ya han sido activados, por lo que el tamaño
     de las listas `orden` y `hecho` tiene que ser el mismo.
   */
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlock)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}

/////////////////////////////////////////////////////obj_Control_Patron
///Variables del controlador
globalvar base, hecho;
base = ds_list_create(); //Lista para meter los identificadores en el orden correcto.
ds_list_add(base, 1, 2, 3, 4); //Se añaden los valores en ese orden.

/////////////////////////////////////////////obj_Patron_1
CREATE
///Debe activarse en "X" lugar
image_speed = 0;
orden = 1;
hecho = ds_list_create(); //Lista para meter los identificadores de los bloques que se van activando
/////////////////////////////////////////////obj_Patron_2
/////////////////////////////////////////////obj_Patron_3
/////////////////////////////////////////////obj_Patron_4
Siguen la misma mecánica

Ese es el contenido que tiene  :GMS: en este proyecto, al tener los mismos sprite y las mismas variables, la cosa se ha quedado patas arriba, hasta el punto que el jugador ya no puede colisionar con ningún objeto sin que salgan errores, tal vez por que hay elementos con nombres iguales y valores que confunden el estado de algún objeto al momento de ejecutar su acción, el ultimo error que tuve fue el que menciono abajo, pero surgió mas de 1 por hacer esta mezcla.

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

Variable oBlock.orden(100003, -2147483648) not set before reading it.
at gml_Object_oPlayer_StepNormalEvent_1 (line 28) -                 ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.

NOTA: Estos ejemplos están en el  :GMS: que me envió por el post anterior, no lo he metido en el "proyecto texteo" porque podría perjudicar a los códigos que actualmente tiene, digamos que este proyecto se encuentra en cuarentena hasta encontrar la cura por decirlo de otro modo   :-[, aunque si resulta ser muy complicado añadir este elemento, no hay problema, creo poder hacer grandes cosas con lo que ya tengo, estas ultimas cosas que he estado preguntando serian aplicadas en "Red Heart 2", ya que el uno fue una prueba de novato, tampoco esperaba que me saliera una obra maestra a mi primer proyecto  :).

Hiciste algo muy distinto a lo que deberías haber hecho.

La variable orden debes declararla en el objeto oBlock, y debes modificar su valor bloque por bloque en el creation code de cada instancia para hacer la secuencia. Con creation code me refiero en el editor de rooms, pon varias instancias del bloque, dales clic derecho y selecciona creation code; ahí modifica la variable.

Además, lee bien en dónde deben ir los códigos, no necesitas de los llamados "obj_patron", todo funciona con los mismos objetos del ejemplo original.

[gml]
///Evento create del controlador
globalvar base, hecho;
base = ds_list_create(); //Lista para meter los identificadores en el orden correcto.
ds_list_add(base, 1, 2, 3, 4); //Se añaden los valores en ese orden.

hecho = ds_list_create(); //Lista para meter los identificadores de los bloques que se van activando
[/gml]
TODO este código va en un solo objeto, un controlador que se ejecuta primero. Si algún código debe ponerse en un evento u objeto distinto, suelo separarlos en bloques distintos.

PD: Qué feos mensajes, encierra los códigos dentro de las etiquetas [gml]código[/gml] para que se vean bien.
alaberga regué el café.

BA:STFW&RTFM

Cita de: NiuWeb en Septiembre 17, 2017, 05:02:07 AM
Hiciste algo muy distinto a lo que deberías haber hecho.

La variable orden debes declararla en el objeto oBlock, y debes modificar su valor bloque por bloque en el creation code de cada instancia para hacer la secuencia. Con creation code me refiero en el editor de rooms, pon varias instancias del bloque, dales clic derecho y selecciona creation code; ahí modifica la variable.

Además, lee bien en dónde deben ir los códigos, no necesitas de los llamados "obj_patron", todo funciona con los mismos objetos del ejemplo original.

[gml]
///Evento create del controlador
globalvar base, hecho;
base = ds_list_create(); //Lista para meter los identificadores en el orden correcto.
ds_list_add(base, 1, 2, 3, 4); //Se añaden los valores en ese orden.

hecho = ds_list_create(); //Lista para meter los identificadores de los bloques que se van activando
[/gml]
TODO este código va en un solo objeto, un controlador que se ejecuta primero. Si algún código debe ponerse en un evento u objeto distinto, suelo separarlos en bloques distintos.

PD: Qué feos mensajes, encierra los códigos dentro de las etiquetas [gml]código[/gml] para que se vean bien.
Vale probare eso de colocar [gml]código[/gml] para ayudarle en ayudarme (que raro suena), pues tengo ahora 3 objetos.

oPlayer, oBlock y control.

oPlayer
STEP
[gml]
//Movimiento
var vel = 5;
var hor = keyboard_check(ord("D")) - keyboard_check(ord("A"));
var ver = keyboard_check(ord("S")) - keyboard_check(ord("W"));
repeat(vel)
{
    if(place_free(x + hor, y))
        x += hor;
    else break;
}
repeat(vel)
{
    if(place_free(x, y + ver))
        y += ver;
    else break;
}
//Codigo encargado de los patrones alarma
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //Y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
[/gml]

oBlock
CREATE
[gml]
image_speed = 0;
orden = 0;
colliding = false;
[/gml]

STEP
[gml]
if(!place_meeting(x, y, oPlayer)) //Si no está colisionando con el jugador
    colliding = false; //Permitir colisión de nuevo
[/gml]

control
CREATE
[gml]
///Variables del controlador
globalvar base, hecho;
base = ds_list_create(); //Lista para meter los identificadores en el orden correcto.
ds_list_add(base, 1, 2, 3, 4); //Se añaden los valores en ese orden.

hecho = ds_list_create(); //Lista para meter los identificadores de los bloques que se van activando
[/gml]

STEP
[gml]
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
/*A partir de aquí asumimos (como debería ser) que todos
     los bloques ya han sido activados, por lo que el tamaño
     de las listas `orden` y `hecho` tiene que ser el mismo.
   */
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlock)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
[/gml]

los 4 bloques que están lejos de los demás tienen en su creación de código o como se dice"creation code", lo siguiente.
orden = 1;
orden = 2;
orden = 3;
orden = 4;

Pues no hay errores que eviten el normal funcionamiento del juego, pero estos 4 objetos se comportan como si fueran puzzles de alarma del post anterior, tendría sentido de cierta forma,por que tienen su mismo sprite, solo que tienen creación de código a diferencia de los que están juntos en linea.



El chiste es que ahora todos se vuelven azules cuando esta completado, independiente si pertenecen al puzzle patrón de números o al puzzle alarma de colisión, ya que al hacerlo deparados tampoco funcionan cada uno por su lado, es como el chiste de que abres una ventana, pero se cierra la otra, por decirlo de un punto de vista mas cómico  :).

Si tienes la secuencia  {1, 2, 3, 4} con los bloques separados, se supone que los cinco (creo que son cinco) que están juntos tienen todos orden 0, por lo que el patrón original debe cambiar. Sería algo así:
[gml]
ds_list_add(base, 0, 0, 0, 0, 0, 1, 2, 3, 4); //Se añaden los valores en ese orden.
[/gml]
De esa manera, no importa el orden en el que se activen los cinco primeros, mientras se activen antes que cualquiera de los cuatro separados, y al activarse éstos últimos se haga en el orden correcto ( {1, 2, 3, 4} ), se completará el puzzle.

Por cierto, en el evento step del jugador sobra este código:
[gml]
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
[/gml]
Déjalo sólo en el controlador, no en el jugador.
alaberga regué el café.

BA:STFW&RTFM

Cita de: NiuWeb en Septiembre 17, 2017, 06:13:30 AM
Si tienes la secuencia  {1, 2, 3, 4} con los bloques separados, se supone que los cinco (creo que son cinco) que están juntos tienen todos orden 0, por lo que el patrón original debe cambiar. Sería algo así:
[gml]
ds_list_add(base, 0, 0, 0, 0, 0, 1, 2, 3, 4); //Se añaden los valores en ese orden.
[/gml]
De esa manera, no importa el orden en el que se activen los cinco primeros, mientras se activen antes que cualquiera de los cuatro separados, y al activarse éstos últimos se haga en el orden correcto ( {1, 2, 3, 4} ), se completará el puzzle.

Por cierto, en el evento step del jugador sobra este código:
[gml]
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
[/gml]
Déjalo sólo en el controlador, no en el jugador.
No voy a negar el buen funcionamiento de ese cambio



Pero en vez de crear 2 puzzles independientes como argumente en el inicio, se han fusionado ambos puzzles, por dar un ejemplo en GIF

El puzzle patron numerico es independiente al puzzle patron de colision.


Mientras que a su vez el puzzle patron de colision es independiente del puzzle patron numerico.


Pero tu lo has dicho: "mientras se activen antes que cualquiera de los cuatro separados"

Los puzzles se fusionaron, ahora ninguno se puede ejecutar si el otro no esta presente en la misma habitacion.

En el "proyecto texteo", el puzzle patron de colision activa su acción "X" que en este caso es destruir a la puerta "X" en su habitación, gracias a tu preciso codigo del post anterior no tuve problemas en crear esa mecánica que puedes ver en este GIF.


El puzzle patron numerico también va a destruir o activar su mecanismo, una vez que los patrones fueron logrados en el orden correcto claramente, pero como se muestra en los 2 primeros GIF, mas la información respaldada suya, los puzzles están ligados y se limitan entre ellos mismos, ademas que ya no puedo colocar una cantidad indefinida de objetos puzzle de colision, por estar sujeto al nuevo código, que en este caso son 5, al igual que el anterior podria colocar 1000 de ellos en toda la habitacion y estaria obligado a escribir unos 1000 ",0,", por lo que volvimos a la respuesta del post anterior.

Para ser honesto nunca he visto en un juego un puzzle de colision y patron complementados  :), pero están ligados como carne y hueso en vez de ser cuerpos independientes, por dar una comparativa  :D.

Ah vale, que son dos puzzles distintos. En ese caso, lo más fácil sería dividir cada puzzle en un objeto separado: Uno que funcione hasta el punto de colisionar, y otro que compruebe el orden, algo como oBlock y oBlockPattern, con quienes ejecutarías sólo partes del código completo.
alaberga regué el café.

BA:STFW&RTFM

#12 Septiembre 17, 2017, 08:30:05 AM Ultima modificación: Septiembre 17, 2017, 08:32:38 AM por Naitsabes0
Cita de: NiuWeb en Septiembre 17, 2017, 07:47:51 AM
Ah vale, que son dos puzzles distintos. En ese caso, lo más fácil sería dividir cada puzzle en un objeto separado: Uno que funcione hasta el punto de colisionar, y otro que compruebe el orden, algo como oBlock y oBlockPattern, con quienes ejecutarías sólo partes del código completo.
Logre hacer una solución, medianamente satisfactoria.

Con este nuevo codigo
oPlayer
STEP
[gml]
//Movimiento
var vel = 5;
var hor = keyboard_check(ord("D")) - keyboard_check(ord("A"));
var ver = keyboard_check(ord("S")) - keyboard_check(ord("W"));
repeat(vel)
{
    if(place_free(x + hor, y))
        x += hor;
    else break;
}
repeat(vel)
{
    if(place_free(x, y + ver))
        y += ver;
    else break;
}
//Codigo encargado de los patrones alarma
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //Y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
var wall = instance_place(x, y, oBlockPattern); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //Y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
/*
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
[/gml]

oBlock y oBlockPattern
[gml]
CREATE
image_speed = 0;
orden = 0;
colliding = false;
[/gml]

STEP
[gml]
if(!place_meeting(x, y, oPlayer)) //Si no está colisionando con el jugador
    colliding = false; //Permitir colisión de nuevo
[/gml]

control
CREATE
[gml]
///Variables del controlador
globalvar base, hecho;
base = ds_list_create(); //Lista para meter los identificadores en el orden correcto.
//ds_list_add(base, 0, 0, 0, 0, 0, 1, 2, 3, 4); //Se añaden los valores en ese orden.
ds_list_add(base, 1, 2, 3, 4); //Se añaden los valores en ese orden.

hecho = ds_list_create(); //Lista para meter los identificadores de los bloques que se van activando
[/gml]

STEP
[gml]
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }
/*A partir de aquí asumimos (como debería ser) que todos
     los bloques ya han sido activados, por lo que el tamaño
     de las listas `orden` y `hecho` tiene que ser el mismo.
   */
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlock)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
//Otro puzzle
var completed = true; //Comenzamos pensando que todos están completos
with(oBlockPattern)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
    with(oBlockPattern)
    {
        image_index = 2; //Ponerles la imagen verde
    }
//Codigos encargados del funcionamiento de los patrones
var completed = true; //Comenzamos pensando que todos están completos
with(oBlockPattern)
{
    if(image_index == 0) //Si se encuentra uno incompleto
    {
        completed = false; //No se ha completado el puzzle
        break; //Ya con eso no tenemos que recorrer los bloques
    }
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlockPattern)
    {
        image_index = 2; //Ponerles la imagen verde
    }
/*A partir de aquí asumimos (como debería ser) que todos
     los bloques ya han sido activados, por lo que el tamaño
     de las listas `orden` y `hecho` tiene que ser el mismo.
   */
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlockPattern)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
[/gml]

EL resultado son los siguentes

Funciona de forma independiente el puzzle de patron numerico



Pero el otro no, ademas todavía esta enlazado de alguna forma.



¿Que debo quitarle y sumarle a los nuevo códigos para que ambas partes sean independientes?  :-\, ya estoy muy cerca, puedo sentirlo  :).

Inténtalo así:
[GML]
///Toooodo este código va en el step del jugador; ni más ni menos. Elimina el código antíguo y pega éste.
var vel = 5;
var hor = keyboard_check(ord("D")) - keyboard_check(ord("A"));
var ver = keyboard_check(ord("S")) - keyboard_check(ord("W"));
repeat(vel)
{
    if(place_free(x + hor, y))
        x += hor;
    else break;
}
repeat(vel)
{
    if(place_free(x, y + ver))
        y += ver;
    else break;
}
//Codigo encargado de los patrones alarma
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
                image_index = 1; //Activarlo
            else if(image_index == 1) //y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
wall = instance_place(x, y, oBlockPattern); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
[/GML]
[gml]
///Y tooodo éste en el step del controlador; ni más ni menos. Borra el código antíguo y pega éste.
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }


//Otro puzzle
var completed = true; //Comenzamos pensando que todos están completos
with(oBlockPattern)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlockPattern)
    {
        image_index = 2; //Ponerles la imagen verde
    }
   
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlockPattern)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
[/gml]
alaberga regué el café.

BA:STFW&RTFM

#14 Septiembre 17, 2017, 09:11:54 AM Ultima modificación: Septiembre 17, 2017, 09:15:13 AM por Naitsabes0
Cita de: NiuWeb en Septiembre 17, 2017, 08:46:39 AM
Inténtalo así:
[GML]
///Toooodo este código va en el step del jugador; ni más ni menos. Elimina el código antíguo y pega éste.
var vel = 5;
var hor = keyboard_check(ord("D")) - keyboard_check(ord("A"));
var ver = keyboard_check(ord("S")) - keyboard_check(ord("W"));
repeat(vel)
{
    if(place_free(x + hor, y))
        x += hor;
    else break;
}
repeat(vel)
{
    if(place_free(x, y + ver))
        y += ver;
    else break;
}
//Codigo encargado de los patrones alarma
var wall = instance_place(x, y, oBlock); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
                image_index = 1; //Activarlo
            else if(image_index == 1) //y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
wall = instance_place(x, y, oBlockPattern); //Encontrar el bloque con quien colisiona
if(instance_exists(wall)) //Si hay colisión
{
    with(wall)
    {
        if(!colliding) //Si no ha cambiado antes (para evitar parpadeo)
        {
            if(image_index == 0) //Si no está activo
            {
                image_index = 1; //Activarlo
                ds_list_add(hecho, orden); //Meter el identificador en la lista, en orden de llegada.
            }
            else if(image_index == 1) //y viceversa
                image_index = 0;
               
            colliding = true; //Evitar nueva colisión
        }
    }
}
[/GML]
[gml]
///Y tooodo éste en el step del controlador; ni más ni menos. Borra el código antíguo y pega éste.
var completed = true; //Comenzamos pensando que todos están completos
with(oBlock)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
    with(oBlock)
    {
        image_index = 2; //Ponerles la imagen verde
    }


//Otro puzzle
var completed = true; //Comenzamos pensando que todos están completos
with(oBlockPattern)
{
    if(image_index == 0) //Si se encuentra uno incompleto
        completed = false; //No se ha completado el puzzle
}
if(completed) //Si se ha completado el puzzle
{
    with(oBlockPattern)
    {
        image_index = 2; //Ponerles la imagen verde
    }
   
    var correcto = true; //Comenzamos pensando que se hizo correctamente
    for(var i = 0; i < ds_list_size(base); i++) //Recorremos toda la lista
    {
        var bs = base[| i]; //Obtenemos el valor i de la lista original
        var he = hecho[| i]; //Obtenemos el valor i en el orden de activación
        if(bs <> he) //Si los valores son diferentes (si se activaron en un orden incorrecto)
        {
            correcto = false; //No se ha completado;
            break; //Ya con eso no tenemos que recorrer más la lista
        }
    }
    if(correcto)
    {
        //Algo si el puzzle es correcto
    }
    else
    {
        //Supongo que se reiniciará el puzzle
        with(oBlockPattern)
        {
            image_index = 0; //Ponemos su estado a 'desactivado'
        }
        ds_list_clear(hecho); //Vaciamos la variable `hecho`
    }
}
[/gml]
Vaya si que fue un largo camino, pero

Valio la pena, como siempre agradecido y te puedo mandar cualquier código de algún elemento que haya creado  , gracias :).