Comunidad de diseño web y desarrollo en internet online

Colisiones entre infinitos MovieClip para Juego de Disparos

Citar            
MensajeEscrito el 06 Ene 2007 02:59 am
Hola

Este es mi primer mensaje :D Mi profesor me dijo que esta comunidad es super wahoo y que preguntara aca.
Estoy haciendo un experimento de un Juego, espero que lo puedan ver. Lo estoy haciendo para aprender AS 2.
Lo que quiero hacer, es que los disparos, colisionen con las rocas que caen. Pero no tengo ni idea :lol:
Los disparos y las rocas las traigo con un attachMovie desde la biblioteca. Los disparos y las rocas también heredan las propiedades de unas Clases que cree. Una Clase para los disparos, y una para las Rocas. Estas dos Clases hacen que se muevan y se destruyen cuando terminan de moverse. Haaa... y también estas Clases heredan las propiedades de la Clase MovieClip. El Muñequito es de adorno :lol:

El problema que tengo, es que no se como afrontar las colisiones. :crap: No se como hacer que colisionen con hitTest. Osea, no quiero que sea por el nombre, puesto que los nombres siempre están cambiando. Estuve pensando que se podría colocar en la Clase del disparo un un hitTest que colisione con cualquier MovieClip o cualquier MovieClip que tenga la Clase Roca. Algo como...

Código :

      miDisparo.onMotionChanged = function():Void  {
         if (this.hitTest(Roca)) {
            this.removeMovieClip();
         }
      };

Pero no se si esto se puede hacer. Algo como una comunicación entre clases o algo así. Necesito que me den pistas, sobre que contenidos debo investigar o que método debo aplicar para lograr que los laser destruyan las rocas :lol:

Acá coloco el código de la Clase del Disparo si la quieren ver

Código :

import mx.transitions.Tween;
class Laser extends MovieClip {
   function Laser() {
      this._y = 115;
      var miDisparo:Tween = new Tween(this, "_x", mx.transitions.easing.None.easeNone, 70, 520, 15, false);
      var scope = this;
      miDisparo.onMotionFinished = function():Void  {
         scope.removeMovieClip();
      };
      miDisparo.onMotionChanged = function():Void  {
         if (MovieClip.Laser.hitTest(MovieClip.Muro)) {
            scope.removeMovieClip();
         }
      };
   }
}

Gracias de Antebrazo

Por AXM

Claber

705 de clabLevel

8 tutoriales

Genero:Masculino  



Ultima edición por AXM el 12 Ene 2007 03:22 am, editado 1 vez

Bogotá

firefox
Citar            
MensajeEscrito el 06 Ene 2007 12:21 pm
Usa un Array. Cuando una roca se crea, que se añada al Array y cuando desaparezca, que se borre. Y los disparos, que comprueben si chocan con cada uno de los clips del array, usando un bucle.

Por Zah

BOFH

4290 de clabLevel

27 tutoriales
5 articulos

  Bastard Operators From Hell Editores

Zaragoza, España

firefox
Citar            
MensajeEscrito el 06 Ene 2007 02:28 pm
Si, eso o un for in y un instanceOf

Por HernanRivas

Claber

3416 de clabLevel

26 tutoriales

 

Argentina

msie
Citar            
MensajeEscrito el 10 Ene 2007 02:15 am
Gracias zah y Hernan... ya entendí el método, y si, creo que ese es el único método.

Ya hice tal cual. Cuando se crea una roca, con un push agrega al nombre a la Array, y luego cuando termina el recorrido, con un shift elimino de la array el nombre de la roca.

Pero tengo un problema mortal. Cuando coloco en un bucle

Código :

if (this.hitTest(_root.MiArray[i]))

o directamente

Código :

if (this.hitTest(_root.MiArray[0]))

No me detecta ni me reacciona a nada. En cambio cuando coloco

Código :

if (this.hitTest(_root.muro1))

Si reacciona. Y el problema, por lo que veo no es de referencia, puesto que si pongo un trace de la array, muestra todos los datos correctamente.

Creo que no se puede poner el nombre de una Array hay, por que no reacciona. tiene que ser directamente el nombre de un MovieClip. Al menos eso me me dio la impresión despues de 6 horas de pruebas :shock: :shock:

Y por eso les quiero preguntar, que puedo hacer en este caso. Si se entendió la pregunta?. Debo colocar la referencia a la Array de esa forma? Quieren ver todo el Codigo?

Aclaracion: donde dice this es realmente scope

Por AXM

Claber

705 de clabLevel

8 tutoriales

Genero:Masculino  

Bogotá

firefox
Citar            
MensajeEscrito el 10 Ene 2007 02:40 am

Código :

if (this.hitTest (_root.MiArray[i]))


Código :

if (this.hitTest (_root[MiArray[i]]))


Tadá!

Por HernanRivas

Claber

3416 de clabLevel

26 tutoriales

 

Argentina

msie
Citar            
MensajeEscrito el 10 Ene 2007 03:54 am
Gracias Hernan... probé lo que me dijiste, pero ni asi hace que la Array sea valida para dar nombre a un MovieClip :cry: :cry: :cry:

Si quieres Hernan o quien quiera, puede bajar el archivo para que me ayude a mirar que es lo que tengo mal :oops:
Acá esta el archivo en zip con el .fla con las dos clases Laser.as y Muro.as ^^ . Lo comente bien para que se entienda.
No quiero que piensen que les estoy pidiendo que me hagan todo, Solo es si lo quieren bajar y hecharle una revisada.

De todas formas voy a colocar aca el código:
.Fla

Código :

// Crea la Array que va a guardar los nombres de todas las rocas que caen
var MiArray:Array = new Array();

////////// Inicio Muros
var contaMuros:Number = 0;
function crearMuros() {
   contaMuros++;
   // El MovieClip id_muro, hereda las propiedades de la clase Muro en la vinculacion de la biblioteca.
   _root.attachMovie("id_muro", "muro"+contaMuros, getNextHighestDepth());
   // Agrega el nombre del MovieClip recien creado a la ultima posicion de la Array MiArray
   _root.MiArray.push("muro"+contaMuros);
}
   // Intervalo que hace que una roca caiga cada 800 milisegundos
var miInterval:Number = setInterval(crearMuros, 800);
////////// Fin Muros

////////// Inicio Laser
var contaLaser:Number = 0;
this.boton.onPress = function() {
   contaLaser++;
       // El MC que sirve de base (id_laser) hereda las propiedades de la clase Laser.as desde la biblioteca
   _root.attachMovie("id_laser", "laser"+contaLaser, getNextHighestDepth());
};
////////// Fin Laser


Clase Laser.as

Código :

// Importa la clase Tween que nos va a servir para darle movimiento  a la bala
import mx.transitions.Tween;
// La Clase Laser hereda las propiedades del objeto MovieClip, para que pueda hacer todas las cosas que
// hace un MovieClip y no de error. Esta Clase la hereda un MovieClip en la película principal desde la biblioteca
class Laser extends MovieClip {
   // Funcion Constructora. Se ejecuta cuando el MovieClip que hereda esta clase se crea con un attachMovie
   function Laser() {
        // Posicion vertical
      this._y = 115;
      // Este codigo hace que el disparo se mueva. 
      var miDisparo:Tween = new Tween(this, "_x", mx.transitions.easing.None.easeNone, 70, 500, 15, false);
      // variable que ayuda a que no se pierda la referencia de this en las siguientes funciones.
      var scope = this;
      // un evento de la clase Tween que ejecuta un codigo cuando el movimiento termina el recorrido.
      // Parecido a enterFrame
      miDisparo.onMotionFinished = function():Void  {
      // Cuando termina el recorrido el Movieclip, este es eliminado
         scope.removeMovieClip();
      };
      // un evento de la clase Tween que ejecuta un codigo cuando el movimiento se esta produciendo. Parecido a enterFrame
      miDisparo.onMotionChanged = function():Void  {
      // EL PROBLEMA! - Deberia servir para la primera roca. Si se cambia MiArray[0] por muro[1] funciona.
      // Lo coloco sin bucle, por que si no me funciona asi, menos con un bucle. 
      // Mientras se mueve, esta evaluando constantemente si colisiona contra un MovieClip que tenga un nombre guardado en la Array de la pelicula principal llamada MiArray. 
         if (scope.hitTest (_root["MiArray"+[0]])) {
      // Si colisiona, el MovieClip se elimina
            scope.removeMovieClip();
         }
      };
   }
}


Clase Muro.as

Código :

// Lo mismo que la Clase Laser :)
import mx.transitions.Tween;
class Muro extends MovieClip {
   public function Muro() {
      this._x = 342;
      var miDisparo:Tween = new Tween(this, "_y", mx.transitions.easing.None.easeNone, -35, 200, 40, false);
      var scope = this;
      miDisparo.onMotionFinished = function() {
         scope.removeMovieClip();
// Cuando una roca termina su recorrido, elimina el primer elemento de la array, Osea, el nombre del MovieClip que heredo esta clase
         _root.MiArray.shift();
      };
   }
}



Ojala nos les parezca muy largo y que soy muy canson y les de pereza responder :crap:

Por AXM

Claber

705 de clabLevel

8 tutoriales

Genero:Masculino  

Bogotá

firefox
Citar            
MensajeEscrito el 10 Ene 2007 09:14 am
Ya vemos que te lo estás currando de verdad...

Prueba así:
En lugar de :

Código :

_root.attachMovie("id_muro", "muro"+contaMuros, getNextHighestDepth());
_root.MiArray.push("muro"+contaMuros);

usa:

Código :

_root.MiArray.push(_root.attachMovie 
                  ("id_muro", "muro"+contaMuros, getNextHighestDepth()));

Y Ahora el array si será de movieclips. Del otro modo tendrías que usar la función eval para recuperar el nombre como MC.

Y después en un bucle de i:
......

Código :

for(i = 0; i < MiArray.length-1; i++){
        !scope.hitTest (_root.MiArray[i]) || scope.removeMovieClip();
}
.....

hecho de hacer echo de echar echarle un vistazo ^^

Por Teseo

SWAT Team

1780 de clabLevel

14 tutoriales

Genero:Masculino   SWAT

msie
Citar            
MensajeEscrito el 10 Ene 2007 06:46 pm
Oye Teseo... Exelente Gracias ^^ ... ya me funciona perfecto. No sabia que se podia hacer eso en la array. Aunque al comienzo no entendí tu segundo codigo, logre entenderlo y lo adapte. quedo asi.
Laser.as

Código :

      miDisparo.onMotionChanged = function():Void  {
         for (var i:Number = 0; i<_root.MiArray.length; i++) {
               trace(_root.MiArray.length);
            if (scope.hitTest(_root.MiArray[i])) {
               scope.removeMovieClip();
            }
         }
      }; 

Ahora voy a hacer que las rocas se destruyan cuando colisionen con el laser. Creo que un listeners se podría. De nuevo gracias ^^

Por AXM

Claber

705 de clabLevel

8 tutoriales

Genero:Masculino  

Bogotá

firefox
Citar            
MensajeEscrito el 10 Ene 2007 07:06 pm
AXM, no olvides postear el codigo cuando lo termines, podias hacer hasta un tutorial y todo, nos vendria bien a los zoquetes como yo q lo llevamos cn mas lentitud! :P ;)

Por dani9del9

46 de clabLevel



 

firefox
Citar            
MensajeEscrito el 10 Ene 2007 09:45 pm
Si quieres "destruir" las rocas con una animación, la mejor manera es ponerla como los siguientes frames del mismo MC muro:
En el primer frame el muro (o mejor vacio). En el segundo el muro. En los siguientes (del 3 en adelante) la animación de rotura.
Al declarar e iniciar dile también :

Código :

scope.gotoAndStop(2);

y en en lugar de eliminarlo con scope.removeMovieClip():

Código :

   if (scope.hitTest(_root.MiArray[i])) { 
       scope.removeMovieClip();
 }

coloca en su lugar:

Código :

  if (scope.hitTest(_root.MiArray[i])) { 
    scope.gotoAndPlay(3);
  }
  if (_scope.currentframe ==1 ){
    scope.removeMovieClip();
  }

Eso animará la rotura del muro......y cayendo por el movimiento del Tween.
Después de terminar la animación, se eliminará el MC del muro.
Y ya tienes la animación de rotura lista. :)

Por Teseo

SWAT Team

1780 de clabLevel

14 tutoriales

Genero:Masculino   SWAT

msie
Citar            
MensajeEscrito el 12 Ene 2007 03:17 am
Ya esta. A ver quien hace mas de 400 a la primera

Gracias zah HernanRivas y Teseo :cry: :cry: :cry:
dani9del9 hay te pongo el codigo, y lo dejo redundantemente comentado para que se entienda. Tal vez me anime a un tutorial. Aunque con los comentarios mas o menos se entiende. como lo mando?
dani9del9 no cojas el código como referencia para programar con objetos, porque esta muy chapusero, chambon o desprolijo. Era solo un experimento para hacer colisiones con infinitos clips.

Película principal

Código :

////////// Inicio Muros
// Crea la Array que va a guardar los nombres de todas las rocas que caen
var MiArray:Array = new Array();
// Variable que nos sirve de contador para que cada nuevo clip tenga nombre nuevo
var contaMuros:Number = 0;
// Funcion que hace que apareca un nuevo Muro en la pelicula
function crearMuros() {
   // Cada vez que se ejecuta la funcion crearMuros se aumenta en 1 el contador
   contaMuros++;
   // Agrega en la ultima posicion de la array un attachMovie y queda como valor el nombre de el mouro.
   // El movieClip id_muro sirve de padre de todas las rocas. Hereda las propiedades de la Clase Muro.as
   _root.MiArray.push(_root.attachMovie("id_muro", "muro"+contaMuros, getNextHighestDepth()));
}
// Intervalo que hace que se ejecute la funcion crearMuros
var miInterval:Number = setInterval(crearMuros, 500);
////////// Fin Muros

////////// Inicio Laser
// Variable que nos sirve de contador para que cada nuevo clip tenga nombre nuevo
var contaLaser:Number = 0;
this.boton.onPress = function() {
   // Cada vez que se pulsa el boton se aumenta en 1 contaLaser
   contaLaser++;
   // Agrega un laser en la pelicula. Este larser hereda todas las propiedades de la Clase Laser.as
   _root.attachMovie("id_laser", "laser"+contaLaser, getNextHighestDepth());
};
////////// Fin Laser

////////// Inicio Explosion y Puntaje
// Funcion que hace que aparesca la explosion. Se activa cuando hay una colisión.
// Cada vez que explota  cambia el puntaje
_global.contaExplosion = 0;
function Explosion() {
   // Variable que nos sirve de contador para que cada nuevo clip tenga nombre nuevo
   contaExplosion++;
   _root.attachMovie("id_explosion", "explosion"+contaExplosion, getNextHighestDepth(), {_y:115, _x:350});
   // Hay un texto dinamico con variable llamada Puntaje. 
   Puntaje = "Puntos: "+(contaExplosion*20);
}
////////// Fin Explosion y Puntaje

////////// Inicio Cronometro
// Esto hace que el juego dure 15 segundos. 
var Cronometro:Number = 15;
// Funcion que se repetira cada 1000 milisegundos osea 1 segundo 
function cuentaAtras() {
//   Cada vez que se ejectua esta funcion se le resta 1 a el Cronometro
   Cronometro--;
   // cuando la variable cronometro llega a 0 para los muros y va al frame 3
   if (Cronometro<0) {
      _root.gotoAndStop(3);
      clearInterval(miInterval);
   }
   // Esto hace que aparesca el tiempo en un texto dinamico
   tiempo = "Tiempo: "+Cronometro;
}
var Reloj:Number = setInterval(cuentaAtras, 1000);
////////// Fin Cronometro
Clase laser Laser.as

Código :

// Importa la clase Tween que nos va a servir para darle movimiento  a la bala
import mx.transitions.Tween;
// La Clase Laser hereda las propiedades del objeto MovieClip, para que pueda hacer todas las cosas que
// hace un MovieClip y no de error. Esta Clase la hereda el MovieClip id_laser en la película principal desde la biblioteca
class Laser extends MovieClip {
    // Funcion Constructora. Se ejecuta cuando el MovieClip que hereda esta clase se crea con un attachMovie
   function Laser() {
      // Posicion vertical 
      this._y = 115;
      // Este codigo hace que el disparo se mueva. 
      var miDisparo:Tween = new Tween(this, "_x", mx.transitions.easing.None.easeNone, 70, 500, 15, false);
      // variable que ayuda a que no se pierda la referencia de this en las siguientes funciones.
       var scope = this;
      // un evento de la clase Tween que ejecuta un codigo cuando el movimiento termina el recorrido.
      // Parecido a enterFrame
      miDisparo.onMotionFinished = function():Void  {
         // Cuando termina el recorrido el Movieclip, este es eliminado
         scope.removeMovieClip();
      };
      // un evento de la clase Tween que ejecuta un codigo cuando el movimiento se esta produciendo. Parecido a enterFrame
      miDisparo.onMotionChanged = function():Void  {
         // Este pedazo es la razon de este post y la parte mas dificil. Asi que veneradlo. Si lees el post entenderas este pedazo
         // Cada vez que nace un muro, este deja el registro de su nombre en la array MiArray.
         // Y cada vez que un muro es eliminado o termina su recorrido, su nombre tambien es eliminado de la array. 
         // Cada vez que nace un laser, este revisa todos los muros que hay en la pelicula,
         // revisando todos los datos que hay en la array MiArray. 
         for (var i:Number = 0; i<_root.MiArray.length; i++) {
            if (scope.hitTest(_root.MiArray[i])) {
               // Si choca contra algun movieClip que tenga el nombre archivado en la Array MiArray
               // de la pelicula principal, el movieClip que herede esta clase se elimina
               scope.removeMovieClip();
               // elimina tambien la roca con la que choco
               _root.MiArray[i].removeMovieClip();
               // ejecuta la funcion Explosion de la pelicula principal. Esta funcion hace que salga la explosion
               _root.Explosion();
            }
         }
      };
   }
}
Clase Muro Muro.as

Código :

// Lo mismo que la Clase Laser :)
import mx.transitions.Tween;
class Muro extends MovieClip {
   public function Muro() {
      this._x = 342;
      var miDisparo:Tween = new Tween(this, "_y", mx.transitions.easing.None.easeNone, -35, 200, 25, false);
      var scope = this;
      miDisparo.onMotionFinished = function() {
         scope.removeMovieClip();
// Cuando una roca termina su recorrido, elimina el primer elemento de la array, Osea, el nombre del MovieClip que heredo esta clase
         _root.MiArray.shift();
      };
   }
}

Saludos

Por AXM

Claber

705 de clabLevel

8 tutoriales

Genero:Masculino  

Bogotá

firefox
Citar            
MensajeEscrito el 12 Ene 2007 11:36 am
AXM eres un crack!

Por dani9del9

46 de clabLevel



 

firefox
Citar            
MensajeEscrito el 29 May 2007 08:59 pm
descubri la media trampa puedo hacer el puntaje q quiera xd!!!!!!


oe tengo 1 pregunta: Quiero hacer un juego de pistolas ( 1 de plataforma y 1 FPS (First Person Shootes = Tirador de Primera Persona) bueno y la cosa es que si alguien sabe como hacerlo que me agrege al msn o que me mande un mail =D

Doy las gracias de antemano :D

casi se me olvida mi mail es : [email protected]

bye

Por inferno222

2 de clabLevel



 

firefox
Citar            
MensajeEscrito el 30 May 2007 02:47 am
Bien, este es un ejemplo que creé no hace mucho. Es un fps visto desde arriba.

De todos modos, el foco era la compleja inteligencia artificial, por lo que todo lo demás está incompleto (los enemigos no se mueren, por ejemplo). Claro que esto no significa que sea difícil de adaptar, en realidad, terminar el juego es bastante fácil.

Si usás todo o parte del código no te olvides de mencionar la fuente en tu trabajo e incluir el logo del cerebro (como explico en el otro post).

Por HernanRivas

Claber

3416 de clabLevel

26 tutoriales

 

Argentina

firefox

 

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