Mayo 02, 2018, 02:39:58 PM Ultima modificación: Mayo 17, 2018, 06:17:41 PM por yottaomi
Estoy intentando recrear el movimiento de las naves enemigas de space invaders, pero no consigo que bajen al mismo tiempo.

Hice varios intentos y aquí dejo uno de los más simples y menos engorrosos, con el el cual lo único que consigo es que cada fila vertical baje a un mismo tiempo, pero no todo el conjunto. Es decir, que bajan únicamente las naves que entran en contacto con el extremo de la pantalla, el resto espera a llegar.

(Este es código del objeto <parent>):

Create:
     move = 1;                //Cuando es 1 permite el movimiento lateral
     down_move = 0;      //Cuando es 1 permite el movimiento hacia abajo
     dir = 1;                   //Dirección horizontal: 1=derecha, 0=izquierda

Alarma[1]:
     move = 1;

Alarma[2]:
     down_move = 0;

Step:
//Movimiento Horizontal
     //Movimiento a la Derecha
if move = 1  and  dir = 1{        //Si move está accionado y la dirección es derecha
    move = 0;
    alarm[1] = 15;
    x += 12;
}

     //Movimiento a la Izquierda
if move = 1 and dir = 0{         //Si move está accionado y la dirección es izquierda
    move = 0;
    alarm[1] = 15;
    x -= 12;
}

     //Movimiento Vertical
if x >= room_width-32 and down_move = 0{    //Bajar al llegar al extremo derecho y cambiar dirección a izquierda
    dir = 0;
    down_move=1;
    alarm[2]=30;
    y += 32;
}

if x <= room_width-room_width+32 and down_move = 0{    //Bajar al llegar al extremo izquierdo y cambiar a dirección a derecha
    if dir = 0{dir=1;}
    down_move=1;
    alarm[2]=30;
    y += 32;
}

Espero no haberlo escrito de un modo innecesariamente complejo.

Por si no quedó claro la pregunta es, ¿qué hago para que bajen y se muevan lateralmente a un mismo tiempo?

objeto movementManager

STEP:

switch( movement )
{
case 0: //moviendo hacia abajo

iterar todos los objetos enemigos y mover
for..
   enemigo
  • .y+=2;

    break;
    case 1: //moviendo a la derecha
          iterar todos los objetos enemigos y mover
    for..
       enemigo
  • .x+=2;

    break;
    case 2: //moviendo hacia izquierda

    iterar todos los objetos enemigos y mover
    for..
       enemigo
  • .x-=2;
    break;
    }


    ya tu decides cuando los quieres mover, basicamente asi seria el objeto manager que debiera mover a todos los enemigos.
Es Mejor No Saber Porque Funciona, Que Saber El Porque No Funciona...
Tienes alguna duda con "Game Design" o de videojuegos en general, contactamente mas facil en twitter @pavulzavala

Prueba este codigo:
[gml]
//CREATE
alarm[0]=30
mover=1  ///1=mover derecha ; 0=mover abajo ; -1=mover izquierda

//ALARMA 0
switch(mover)
    {
     case 1 : with(nave)
                {
                 x+=32
                 if x>room_width-64 {other.mover=0}
                }
              break
     case 0 : with(nave)
                {
                 y+=32
                 if x>room_width-64 {other.mover=-1}
                 if x<32 {other.mover=1}
                }
              break
     case -1: with(nave)
                {
                 x-=32
                 if x<32 {other.mover=0}
                }
              break
    }

alarm[0]=30
[/gml]

No logro encontrar un buen resultado con switch y el código que 3dgeminis escribió, me funcionó bien, pero solo en el caso de que hubiera una única instancia. Pero en el momento de que haya más de una el movimiento el movimiento es como si en un momento dado perteneciera a una de las instancias y al llegar al extremo de la room le perteneciera a otro. Y necesito 44 instancias del mismo objeto, lo cual vuelve el movimiento de las instancias del objeto un caos.

¿Qué solución le puedo dar?

Lo mejor es utilizar el ciclo with. Yo tengo una versión diferente. Ejemplo adjunto.
[gml]
/// Mover aliens
// En esta alarma se realiza un movimiento horizontal o vertical

// Primero. Se revisa si colisionan con el borde
borde = false; //suponemos que no colisionan con el borde
with (obAlien) {
   // si la velocidad horizontal el positiva y
   // hay colisión con el borde derecho
   if (other.vx > 0 and x >= room_width - 16) {
      other.borde = true; //activar variable
      other.vx *= -1; //invertir dirección
      break; //salir del ciclo with
   }
   //si la velocidad horizontal es negativa y
   // hay colisión con el borde izquierdo
   else if (other.vx < 0 and x <= 16) {
      other.borde = true; //activar variable
      other.vx *= -1; //invertir dirección
      break; //salir del ciclo with
   }
}

// Segundo. Se realiza el movimiento
if (borde) {//si hay colisión con el borde
   with (obAlien) y += other.vy; // el mov es vertical
}
else {// si no hay colisión con el borde
   with (obAlien) x += other.vx; // el mov es horizontal
}

// Repetir alarma
alarm[0] = 10;
[/gml]

Clamud, ¿en dónde debería situar el código, en Alarm[0]? En cualquier caso no estoy seguro de entenderlo bien porque o me da error o directamente no se ejecuta el movimiento.