Comunidad de diseño web y desarrollo en internet online

Un problema MUY sencillo al trabajar con subclases

Citar            
MensajeEscrito el 25 Sep 2012 10:43 pm
Buenas, estoy aprendiendo a trabajar con subclases y sinceramente estoy muy liado. En la práctica que estoy haciendo intento hacer que un MC "dispare" a otro y que le baje la "vida", cuando esa vida llegue a 0 entonces se le resta una vida de 3 que tiene, cuando esas 3 lleguen a 0 el MC debería desaparecer.

Ahora mi problema es que hice dos Clases, una llamada "heroe" que es el que dispara y otra llamada Enemigo que es la que recibe los disparos y es donde se almacena el comportamiento de bajar vida, desaparecer, etc. Por último a esta le extiendo una subclase llama "e1" la cual contiene los valores de "vida", etc que se declaran en esa clase padre, y se supone que si coloco "extends Enemigo" debería de tomar esos variables y utilizarlos como si fueran propias nada más agregarles el valor pero cuando le doy DEBUG me sale error de "Acceso a una propiedad no definida "vida"" y así con las otras dos variables, no sé si es que no entendí bien lo de trabajar con subclases, pero quisiera que ustedes me ayudaran a entenderlo puesto que no consigo documentación en español entendible :(

Acá el código aunque pueden descargar el archivo .fla y las clases .as desde[url=http://www.4shared.com/rar/Wnytd1sZ/Herencia.html][/url]

Clase "heroe":

Código ActionScript :

package 
{
   import flash.display.MovieClip;
   import flash.events.MouseEvent;
   import flash.events.Event;   

   public class heroe extends MovieClip
   {

      public function heroe()
      {
         this.addEventListener(MouseEvent.CLICK, disparo);
         function disparo(e:MouseEvent)
         {
            gotoAndPlay(2);
         }
      }
   }
}


Clase "Enemigo":

Código ActionScript :

package 
{

   import flash.events.Event;
   import flash.events.MouseEvent;
   import flash.display.MovieClip;

   public class Enemigo extends MovieClip
   {
      private var vida:int;
      private var numeroVidas:int;
      private var daño:int;
      private var vivoMuerto:Boolean = true;

      public function Enemigo()
      {
         addEventListener(Event.ADDED_TO_STAGE,asdasd);
         function asdasd(e:Event)
         {

            addEventListener(Event.ENTER_FRAME, quitarVida);
            function quitarVida(e:Event)
            {

               if (this.bala.hitTestObject(Enemigo))
               {
                  this.vida -=  1;
               }

            }
         }

         if (vida <= 0)
         {
            vivoMuerto = false;
         }
         else if (vida >= 1)
         {
            vivoMuerto = true;
         }
         else if (vivoMuerto == false)
         {
            numeroVidas -=  1;
         }
         else if (numeroVidas <= 0)
         {
            addEventListener(Event.ADDED_TO_STAGE,asdd);
            function asdd(e:Event)
            {
               removeChild(this);
            }
         }


      }

   }

}


Clase "e1":

Código ActionScript :

package 
{
   import flash.display.MovieClip;

   public class e1 extends Enemigo
   {
      vida = 5;
      numeroVidas = 3;
      daño = 1;

      public function e1()
      {
      }

   }

}


Desde ya muchas gracias.

Por DaveyDsign

6 de clabLevel



Genero:Masculino  

Diseño Gráfico

chrome
Citar            
MensajeEscrito el 25 Sep 2012 11:03 pm
Muestranos cual es el código que está generando el error, es decir donde quieres setear las vidas

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 25 Sep 2012 11:16 pm
Clase "e1":

Código ActionScript :

package 
{
   import flash.display.MovieClip;

   public class e1 extends Enemigo
   {

*/Estos de abajo son los códigos que dice que no se declararon, pero los declare en la clase padre ("Enemigo"), además cuando le coloco estos valores a la clase padre y vinculo el MC a ella (es decir ya no la vinculo a "e1" sino a "Enemigo") no salen esos errores, pero tampoco me funciona, ni se baja vida ni nada, la verdad no le termino de entender muy bien a las subclases pero las veo MUY útiles por eso deseo aprenderlas bien*/

      vida = 5; //ERROR
      numeroVidas = 3; //ERROR
      daño = 1; //ERROR

      public function e1()
      {
      }

   }

Por DaveyDsign

6 de clabLevel



Genero:Masculino  

Diseño Gráfico

chrome
Citar            
MensajeEscrito el 26 Sep 2012 09:24 am
BuenAS:

Para que una subclase acceda a las propiedades de su superclase, define las propiedades como 'protected' Y NO como 'private', en la superclase.

En este caso, define en la clase Enemigo las propiedades vida, numeroVidas y daño como protected y no como private.

Otra cosa que es buena hacer es llamar al constructor de la superclase en el constructor de la subclase: para ello añade al principio del constructor, super(). Esto hace que antes de 'construir' la subclase se haya 'construido' la superclase.

Por otro lado, es buena práctica seguir la norma y llamar a las clases con mayúsculas; o sea E1 y Heroe. Pero esto es eso, una buena practica y no afecta al código :)

Un salud.

Por Lukánicos

Claber

468 de clabLevel



Genero:Masculino  

chrome
Citar            
MensajeEscrito el 26 Sep 2012 12:17 pm
Excelente respuesta de Lukánicos. Solo agregar que protected permite que accedan a la propiedad las subclases y las que pertenezcan al mismo paquete, mientras que private impide que nadie que no sea la propia clase acceda las propiedades.

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 26 Sep 2012 07:17 pm
Ok, entiendo, muchísimas gracias, lo que no entendí es donde tengo que agregar lo de super(), una última cosita, si las coloco como public debería acceder a la variable las subclase tmb? Porque en un principio estaba como PUBLIC pero lo cambié a private a ver qué pasaba, muchas gracias por sus respuestas :)

Por DaveyDsign

6 de clabLevel



Genero:Masculino  

Diseño Gráfico

chrome
Citar            
MensajeEscrito el 26 Sep 2012 07:20 pm
super() tiene que ser el primer comando en el constructor, para que corra el constructor del padre antes que el hijo.
Si la variable es publica es accesible por el hijo y por cualquiera que quiera modificarla, con lo cual se rompe la encapsulación

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 27 Sep 2012 04:35 am
Ok, sí me sirvió ya lee las variables etc :D Ahora tengo otro problema, ya cambié lo que iba a hacer, ahora es más sencillo, es para probar que las condicionales etc funcionan, hice unos cambios para hacerlo más sencillo sólo agrego movimiento a la clase "heroe" con las flechas y que cuando toque a MC de la clase Enemigo(con la subclase e1) se le reste el valor de -1 a la variable vida, es sencillo ya lo he hecho trabajando directamente en el archivo principal, pero me sale este error trabajando desde una clase externa y no he sabido cómo solucionarlo y por lo general simplemente pienso en otra forma de hacerlo igual o de plano me rindo, es que no entiendo por qué me sale esto:

1061: Call to a possibly undefined method hitTestObject through a reference with static type Class.

Hasta donde tengo entendido una clase estática es cuando se agrega directamente en el plano de Flash y una clase dinámica es cuando se llama desde addChild (si no es así me corrigen).

En el archivo .fla estoy llamando a las clases desde un addChild y sin embargo me sale ese error, al principio me salía algo parecido diciendo que no es una función hasta que cambié el objeto

este es el código del .fla:

Código ActionScript :

var hero:heroe = new heroe();
var e1_1:e1 = new e1();

addChild(hero);
addChild(e1_1)

hero.x = 20;
hero.y = 10;

e1_1.x = 200;
e1_1.y = 10;


y este es el código que me genera conflicto y no sé por qué:

Código ActionScript :

package 
{

   import flash.events.Event;
   import flash.events.MouseEvent;
   import flash.display.MovieClip;

   public class Enemigo extends MovieClip
   {
      protected var vida:int;
      protected var numeroVidas:int;
      protected var daño:int;
      protected var vivoMuerto:Boolean = true;

      public function Enemigo()
      {
         addEventListener(Event.ENTER_FRAME, quitarVida);
         function quitarVida(e:Event)
         {
            if (heroe.hitTestObject(this))
            {
               vida -=  0;
            }
         }


         if (vida <= 0)
         {
            vivoMuerto = false;
         }
         else if (vida >= 1)
         {
            vivoMuerto = true;
         }
         else if (vivoMuerto == false)
         {
            numeroVidas -=  1;
         }
         else if (numeroVidas <= 0)
         {
            removeChild(this);
         }
      }
   }
}


Sólo por si acaso este es el código modificado de la clase "heroe" a la que le agregué movimiento con teclas:

Código ActionScript :

package 
{
   import flash.display.MovieClip;
   import flash.events.MouseEvent;
   import flash.events.Event;   
   import flash.ui.Keyboard;
import flash.events.KeyboardEvent;

   public class heroe extends MovieClip
   {

      public function heroe()
      {
         this.addEventListener(MouseEvent.CLICK, disparo);
         function disparo(e:MouseEvent)
         {
            gotoAndPlay(2);
         }
         
      }
      private function movimiento()
      {
         this.addEventListener(KeyboardEvent.KEY_DOWN, mover)
         function mover(e:KeyboardEvent){
            
            if(e.keyCode == 38){
               this.y -= 10
            }else if(e.keyCode == 40){
               this.y += 10
            }else if(e.keyCode == 39){
               this.x += 10
            }else if(e.keyCode == 37){
               this.x += -10
            }
         }
      }
      
   }
   
}


Son cosas sencillas y disculpen la molestia es que apenas estoy iniciando en esto de la programación y sobretodo de la programación orientada a objetos (ya manejo CSS y HTML pero eso no cuenta xD)

Por DaveyDsign

6 de clabLevel



Genero:Masculino  

Diseño Gráfico

chrome
Citar            
MensajeEscrito el 27 Sep 2012 09:35 am
BuenAS:

Así, a vote pronto, en la clase Enemigo accedes a

Código ActionScript :

if (heroe.hitTestObject(this))
    {
        vida -=  0;
     }

y no veo por ningún lado que la crees e instancies.

En algún lado de esta clase deberías hacer

Código ActionScript :

var _heroe = new heroe();
addChild(_heroe);


Por eso, comentaba que es bueno empezar el nombre de las clases con mayúsculas, quedaría mejor algo así:

Código ActionScript :

var heroe = new Heroe();
addChild(heroe);


Haciendolo así, la instancia puedes nombrarla como la clase pero en minúscula.

Y ya concreatamente al error que te da, la clase heroe amplia (extiende) a MovieClip, una de las pocas clases dinámicas de AS3, se pueden añadir propiedades en tiempo de ejecución, El compilador cree que 'heroe' es una propiedad añadida a MovieClip.

Un saludo.

Por Lukánicos

Claber

468 de clabLevel



Genero:Masculino  

chrome
Citar            
MensajeEscrito el 27 Sep 2012 09:36 am
...perdón, en el último párrafo me quería referir a la clase Enemigo y no heroe

Por Lukánicos

Claber

468 de clabLevel



Genero:Masculino  

chrome
Citar            
MensajeEscrito el 29 Sep 2012 07:17 am
Una sugerencia, la gestión de los puntos y vidas de tu heroe y tu enemigo, debería estar en la clase del documentos principal, de esta manera, te será mas transparente la lógica.

Me explico:
Tienes una clase juego, que en su "enterframe" verifica si "heroe" hace "hittest" con "enemigo", en caso de ser verdadero le resta un punto a traves de una funcion publica, tipo: enemigo.quitaVida().

Lo mismo te funcionaria para los disparos.

Suerte.

Por blashstar

4 de clabLevel



Genero:Masculino  

chrome

 

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