Comunidad de diseño web y desarrollo en internet online

Detener código flash durante animación de un movieClip

Citar            
MensajeEscrito el 02 Ene 2010 08:44 pm
Muy buenas,

Paralelamente al problema que me ha surgido durante el diseño de mi juego de combate por turnos (podéis leer de qué va en este enlace, me han surgido varias necesidades relacionadas con la ejecución secuencial de código en flash.

Os pongo un ejemplo parecido al que tengo: primero tengo un movieClip llamado "Anim_nave_1" al cual he definido varios keyframes con sus correspondientes nombres y animaciones, por ejemplo "parado", "aparecer","disparar", "explosion" y "desaparecer"; por otro lado en cierto fotograma del código raíz tengo algo como esto:

Código ActionScript :

(...)
//Hay lucha entre dos naves, y aparecen ambas por pantalla
//NaveJ1 es la del player
//NaveCPU es la de la CPU

_root.Anim_nave_1.gotoAndPlay("aparecer");
//Determinamos el tipo de nave a la que atacamos para decidir
//qué animación ejecutar
if(NaveCPU.tipo == NAVE_1){
   //Cargamos la animación de entrada de la nave 1
   _root.Anim_nave_1_CPU.gotoAndPlay("aparecer");
   //LO QUE NECESITO: que flash se pare aquí hasta que la animación
   //anterior haya terminado
} else if(NaveCPU.tipo == NAVE_2){
   //Cargamos la animación de entrada de la nave 2
   _root.Anim_nave_2_CPU.gotoAndPlay("aparecer");
   //LO QUE NECESITO: que flash se pare aquí hasta que la animación
   //anterior haya terminado
}

//Cargamos la animación de la nave atacando a la CPU:
_root.Anim_nave_1.gotoAndPlay("disparar");
//DE NUEVO NECESITO QUE EL CÓDIGO SE PARE AQUÍ HASTA QUE LA
//ANIMACIÓN ANTERIOR HAYA TERMINADO!
NaveCPU.vidas -= NaveJ1.power;

if (NaveCPU.vidas<=0){
   _root.Anim_nave_1_CPU.gotoAndPlay("explosion");
   //NUEVAMENTE NECESITO UNA PAUSA
   NaveCPU.removeMovieClip();
} else {
   //Contraataque de la nave enemiga
   _root.Anim_nave_1_CPU.gotoAndPlay("disparar");
   //DE NUEVO NECESITO QUE EL CÓDIGO SE PARE AQUÍ HASTA QUE LA
   //ANIMACIÓN ANTERIOR HAYA TERMINADO!
   
   NaveJ1.vidas -= NaveCPU.power;
   if (NaveCPU.vidas<=0){
      _root.Anim_nave_1.gotoAndPlay("explosion");
      //NUEVAMENTE NECESITO UNA PAUSA
      NaveJ1.removeMovieClip();
   }
}


Como veis, necesito hacer una pausa en el código hasta que la animación de las naves termine. He probado con stop(), mediante bucles de while pero nada funciona (sobretodo porque los de while me saturan la CPU y termino cerrando el flash porque ya no responde).

¿Alguna sugerencia? Gracias de antemano!

Por Protoss

5 de clabLevel



 

firefox
Citar            
MensajeEscrito el 02 Ene 2010 09:47 pm
El tema es que tendrás que programar una pausa, para hacerlo... Piensa en la definición de una pausa para lo que quieres. Lo que estas buscando es dejar de funcionar cierta pieza de código mientras algo más sucede. Eso lo puedes lograr agregando un if que sea capaz de si esta en true seguir el código y en false cortarlo. Así ya habrás evaluado tu "propio pause".

Saludos, Hernán . -

Por Hernán

BOFH

6148 de clabLevel

19 tutoriales
23 articulos

Genero:Masculino   REC Desarrollador de GAIA

Marketing & IT

firefox
Citar            
MensajeEscrito el 02 Ene 2010 10:59 pm

Hernán escribió:

El tema es que tendrás que programar una pausa, para hacerlo... Piensa en la definición de una pausa para lo que quieres. Lo que estas buscando es dejar de funcionar cierta pieza de código mientras algo más sucede. Eso lo puedes lograr agregando un if que sea capaz de si esta en true seguir el código y en false cortarlo. Así ya habrás evaluado tu "propio pause".

Saludos, Hernán . -


Hola Hernán,

Entiendo que debo programar una pausa, pero cada vez que lo he intentado Flash ha dejado de responderme, seguramente por un fallo mío.

Te pongo un ejemplo de lo que he estado probando hasta ahora:

Código ActionScript :

(...) 
//Hay lucha entre dos naves, y aparecen ambas por pantalla 
//NaveJ1 es la del player 
//NaveCPU es la de la CPU 
 
_root.Anim_nave_1.gotoAndPlay("aparecer"); 
//Determinamos el tipo de nave a la que atacamos para decidir 
//qué animación ejecutar 
if(NaveCPU.tipo == NAVE_1){ 
   //Cargamos la animación de entrada de la nave 1 
   _root.Anim_nave_1_CPU.gotoAndPlay("aparecer"); 
   //Posible pausa:
   esperaFinalAnimacion();
} else if(NaveCPU.tipo == NAVE_2){ 
   //Cargamos la animación de entrada de la nave 2 
   _root.Anim_nave_2_CPU.gotoAndPlay("aparecer"); 
   //Posible pausa: 
   esperaFinalAnimacion(); 
} 
 
//Cargamos la animación de la nave atacando a la CPU: 
_root.Anim_nave_1.gotoAndPlay("disparar"); 
//Posible pausa: 
esperaFinalAnimacion(); 
NaveCPU.vidas -= NaveJ1.power; 
 
if (NaveCPU.vidas<=0){ 
   _root.Anim_nave_1_CPU.gotoAndPlay("explosion"); 
   //Posible pausa: 
   esperaFinalAnimacion(); 
} else { 
   //Contraataque de la nave enemiga 
   _root.Anim_nave_1_CPU.gotoAndPlay("disparar"); 
   //Posible pausa: 
   esperaFinalAnimacion(); 
    
   NaveJ1.vidas -= NaveCPU.power; 
   if (NaveCPU.vidas<=0){ 
      _root.Anim_nave_1.gotoAndPlay("explosion"); 
      //Posible pausa: 
      esperaFinalAnimacion(); 
      NaveJ1.removeMovieClip(); 
   } 
}


Donde:

Código ActionScript :

var fin:Boolean=false;
function esperaFinalAnimacion() = {
     while (true){
            if(_root.fin){
                   _root.fin = false;
                   break;
            }
     }
}


Siendo _root.fin una variable tipo Boolean que cambia a true al final de cada animación. El problema es que si implemento esto flash se cuelga por saturación de la CPU! ¿Qué puedo hacer?

Por Protoss

5 de clabLevel



 

firefox
Citar            
MensajeEscrito el 04 Ene 2010 12:46 am
While es un bucle , y en este caso infinito. No deberías programarlo así sino así:

1. Crear la función de chequeo
2. Una vez se cumple el parametro pones en true la variable
3. Para chequear constantemente lo pones en un setInterval

Sino más fácil metelo directo el if en el código principal, si la variable no es correcta no funcionará nada y ya hasta que sea false de nuevo.

Saludos, Hernán . -

Por Hernán

BOFH

6148 de clabLevel

19 tutoriales
23 articulos

Genero:Masculino   REC Desarrollador de GAIA

Marketing & IT

firefox
Citar            
MensajeEscrito el 05 Ene 2010 05:51 pm
Gracias por la respuesta Hernán,

Al final he prescindido del setInterval puesto que llama a la función paralelamente a la ejecución del código, y esto no me lo solucionaba.

He cambiado todo el código puesto que no conseguía definir esta función de chequeo sin usar elementos que funcionasen en timelines diferentes. Ahora mismo es algo complejo de explicar y no tengo tiempo, pero os pongo un esquema de como se van llamando las funciones entre sí. La idea ha sido hacerlo todo lo más secuencial posible y crear los bucles mediante llamadas a las propias funciones!

Puesto que puedo llamar a una función dentro de sí misma:

Código ActionScript :

function mueveNave(inicioTile, tileProximo) {
   if (_root.tileEncontrado) {
      //Hemos encontrado un tile para ir
      //Localizamos nuestra naveCPU a mover:
      for (var i = 0; i<nausCPU.length; i++) {
         if (nausCPU[i].xtile == xtile_i && nausCPU[i].ytile == ytile_i) {
            break;

         }
      }
      
                //SOLUCIÓN PARCHE AL PROBLEMA
                //Después de esta función ya no hay más código en el frame,
                //por lo tanto no ejecutará nada más
      nausCPU[i].onEnterFrame = function() {
                        //Código para desplazar la nave hasta el tile
                               (...)
                 //Si este es el último tile al que se puede desplazar...
            if (_root.prou) {
               _root.prou = false;
               var nomTile = "t_"+this.xtile+"_"+this.ytile;

               //Miramos si el suelo es peligroso
               if (_root.joc.clip[nomTile].defensaJ1 == 0) {
                  //Calculamos la lógica de la siguiente nave
                  _root.indexCPU++;
                  trace("Passem a la nau següent: "+_root.indexCPU);
                                                //Borramos el onEnterFrame
                  this.onEnterFrame = function() {
                  };
                                                //Ejecutamos de nuevo la función logicaCPU()
                  logicaCPU();
               } else {
                  //Código de defensa de la J1
                  (...)
                  }
               }
            } else {
               //Si aún no hemos llegado al máximo alcance de movimiento
               iniciTile = tileProper;
               this.onEnterFrame = function() {
               };
                                        //Volvemos a ejecutar el pathfinding y el moverNave
               pathFinding(iniciTile,_root.finalTile,_root.pas,_root.max_passos);

               moverNave(inicioTile,_root.tileProximo);
            }
         }
      };
   } else {
      //No hay tile próximo al que desplazarse
      trace("No movem la nau");
   }
}


Gracias por el interés Hernán, si tuviera más tiempo buscaría una solución mejor pero ahora mismo voy a contrarreloj. El tema de la interrupción mediante la función de chequeo es la clave, espero conseguir hacerla para otra ocasión!

Y en el root el código que se ejecuta es éste:

Código ActionScript :

function desplaza(nau, objectiu) {
   var nomTile = "t_"+nau.xtile+"_"+nau.ytile;
   var iniciTile = joc.clip[nomTile];
   var nomTile = "t_"+objectiu.xtile+"_"+objectiu.ytile;
   _root.finalTile = joc.clip[nomTile];
   _root.pas = 1;
   _root.max_passos = nau.moviment;
   pathFinding(iniciTile,finalTile,_root.pas,max_passos);
   mueveNave(iniciTile,tileProper);
}

Por Protoss

5 de clabLevel



 

firefox
Citar            
MensajeEscrito el 07 Ene 2010 03:17 am
Tranquilo, siempre pasa igual, una vez este todo entenderás era simple el problema, pero mientras uno esta contra reloj realmente todo parece más jodido. jaja

Saludos, Hernán . -

Por Hernán

BOFH

6148 de clabLevel

19 tutoriales
23 articulos

Genero:Masculino   REC Desarrollador de GAIA

Marketing & IT

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.