Comunidad de diseño web y desarrollo en internet online

Manipular MovieClips usando clases AS3

Citar            
MensajeEscrito el 13 Feb 2009 08:40 pm
Holas sorry seguramente es una pregunta muy novata pero ya le he dado muchas vueltas y no entiedo por que no sale un simple ejemplo de manipulación de las propiedades de un MovieClip en AS3.
Lo que necesito es simple, tengo un objeto dibujado directamente en la pelícual de flash y puesto su respectivo nombre de instancia, y en una clase aparte a la cual la estoy llamando mediante un "import" le quiero decir que mueva al objeto o en todo caso manipular las propiedades de este. si lo hago de esta forma lo único que obtengo son mensajes como:

1120: Access of undefined property bola. ----- esto si no le exporto para Action Script en la libreria
1046: Type was not found or was not a compile-time constant: bola. ----- esto si le exporto para action script o le especifico a la clase que a lo que quiero modificar las propiedades es un MovieClip.

Este ejemplo solo me funciona si a la peli principal en las opciones de publicación le especifico el "Document Class" pero lo que necesito es hacerlo por medio de importación de la clase ... hay como?

les dejo mis tristes y miserables códigos:

la importada y declarada

import MoverBola;
var posBola:MoverBola=new MoverBola();

la clase

package {
import flash.display.*;

public class MoverBola extends MovieClip{

function MoverBola(){
Mover();
}
public function Mover(){

bola.x=30;

}
}

}

Por m3g4m4n

4 de clabLevel



 

opera
Citar            
MensajeEscrito el 13 Feb 2009 08:45 pm
favor no me refieran a otro post que ya los he leido todos y no me explican de manera eficiente, es posiblemente un problema de conceptos y la idea es enteder de lleno como manipular los objetos dibujados directamente en la película de flash y no creados con código thnx.

Por m3g4m4n

4 de clabLevel



 

opera
Citar            
MensajeEscrito el 13 Feb 2009 10:23 pm

Por esedeerre

132 de clabLevel



 

MadRid

opera
Citar            
MensajeEscrito el 16 Feb 2009 08:47 pm
:D gracias, ese tutorial me aclaró algunas dudas sin embargo me ha generado unas nuevas no si si tu sepas la respuesta pues ya entiendo cuando asociar una clase a un MovieClip, pero que sucede cuando quieres hacer que una clase cambie las propiedades de varios objetos inculido propiedades del stage. como manipulo varios objetos con una clase... algo que si lo conseguí pero solo incluyendo directamente la clase en la película con "Document Class"
^^
thnx

Por m3g4m4n

4 de clabLevel



 

opera
Citar            
MensajeEscrito el 17 Feb 2009 08:48 am
En general, la idea es que una Clase (aquí incluo también la Clase de documento) sólo cambie o acceda a propiedades de la propia clase o de objetos que pertenezcan a dicha clase. vaaaaaaale. A ver si lo explico mejor con un ejemplo.
Ejemplo 1: Tienes tu Clase Bola y NADA en el frame de la película principal

Código ActionScript :

/**Esta es la película principal***/
var bola:Bola=new Bola();  //<--creamos un objeto de la clase Bola y lo asignamos a una variable "bola"
addChild(bola);  //<--lo añadimos al stage
bola.x=200;  //<--cambiamos el valor de una propiedad del Objeto a través de la variable que hace referncia a él

Ejemplo 2:Tienes un Mc con nombre de instancia bola en el frame de la película principal

Código ActionScript :

/**Esta es la película principal***/
bola.x=200

Sí, cuando tenemos un MC en la película principal con nombre de instancia, Para Flash es como si hubiésemos declarado una variable que hace referencia a ese MC -digamos que las dos primeras líneas del primer ejemplo nos las añade automáticamente.
Ejemplo 4: Tienes tu Clase Bola y NADA en el frame de la película principal. Tu Clase de documento es Main

Código ActionScript :

/**Esta es main.as***/
package{
  public Class Main extends MovieClip{
  //declaramos la variable bola AQUÍ
  private var bola:Bola;
  public function Main(){
        bola=new Bola();  //<--creamos un objeto de la clase Bola
        addChild(bola);  //<--lo añadimos al stage
        bola.x=200;  //<--cambiamos el valor de una propiedad del Objeto
  }
}

Observa dos cosas:
1.-Hemos declarado la variable "bola" al principio del todo. Eso es para que sea accesible desde cualquier función de la Clase. Si sólo la necesitáramos en la función Main, la podríamos haber declarado dentro de la función Main.
2.-Creamos una función del mismo nombre de la Clase de Documento que es lo primero que se ejecutará. en el ejemplo hemos aprovechado esta función para crear el objeto bola y añadirlo al stage (también la hemos posicionado en x=200)
Ejemplo 4:Tienes un Mc con nombre de instancia bola en el frame de la película principal y nuestra Clase de documento en Main

Código ActionScript :

/**Esta es main.as***/
package{
  public Class Main extends MovieClip{
  public function Main(){
        bola.x=200;  //<--cambiamos el valor de una propiedad del Objeto
  }
}

Vemos que no tenemos que declarar "bola" ni añadirlo al stage (Flash ya lo hace por nosotros)

Vale, vemos que para cambiar las propiedades o acceder a métodos de "objetos" que estén dentro de una Clase, creamos una variable que haga referencia al objeto y la usamos a modo de "nombre de instancia".

El siguiente paso es algo más complicado que es, desde un objeto acceder a propiedades o variables de la clase que le contiene. Tenemos varias posibilidades, no voy a comentar todas sino las más frecuentes
1.-Se trata de una Clase que extiende de DisplayObject y queremos acceder a propiedades del stage.
Se realiza a través de "parent" o de stage, pero sólo una vez se haya añadido al stage
Imaginemos que en nuestra película principal tenemos algo como

Código ActionScript :

public var velx:Number=100
var bola:Bola=new Bola()
addChild(bola);

Y nuestra Clase Bola es algo del estilo

Código ActionScript :

package{
   public Class Bola extends MovieClip{
      public function Bola(){
             this.addEvent(Events.ADD_TO_STAGE,onAddToStage);
      }
      private function onAddToStage(e:Event):void{
            this.addEvent(Event.ENTER_FRAME,onEnterFrame);
            this.removeEvent(Event.ADD_TO_STAGE,onAddToStage);
      }
      private function onEnterFrame(e:Event):void{
            var vel:Number=MovieClip(parent).velx;
            this.x+=vel;
      }
}

Varias cosas en este código. Empezemos por la función onEnterFrame. Para hallar el valor de la variable velx de "parent" hacemos una "conversion de Cast". Esto es, de decimos que "parent" es de la Clase MovieClip (o de una clase que extienda de ella). Ello nos permite preguntar por la variable "velx". Esto es debido a que todas las Clases en AS.3 son "sealed" (selladas") salvo la Clase MovieClip. Por "clase sellada" entendemos que no podemos acceder a propiedades de dichas clases directamente.
Lo siguiente extraño es que, en lugar de en la función Bola (se llama función constructora porque tiene el mismo nombre que la Clase y es la que se ejecuta cuando se crea un objeto de la clase, vamos cuando escribimos un "new") añadir directamente al "listener" el evento ENTERFRAME lo que añadimos es el evento ADD_TO_STAGE. Ello es así, porque hasta que no se haya añadido al stage, no está definido el "parent", Y no podríamos acceder a la variable "velx". El removeEvent es porque ya no lo vamos a necesitar más.
NOTA:He puesto "this" y realmente no se suele poner porque ya se entiene que se trata de las propiedades y métodos del propio objeto.
2.-Nuestra Clase no va a acceder a "parent", sino que va a "dispachar" un evento, para que sea controlado por la película principal. Hagamos un MC "dragueable", cuando se suelte "dispacharemos" un evento que controlará la película principal.

Código ActionScript :

package{
   public Class Bola extends MovieClip{
      public function Bola(){
             this.addEvent(MouseEvent.MOUSE_DOWN,onMouseDown);
             this.addEvent(MouseEvent.MOUSE_UP,onMouseUp);
      }
      private function onMouseDown(e:Event):void{
            startDrag();
      }
      private function onMouseUp(e:Event):void{
           stopDrag();
           dispatchEvent(new Event("MOUSEUP"));
      }
}

Nuestra película principal sería e la forma

Código ActionScript :

var bola:Bola=new Bola();
bola.addEventListener("MOUSEUP",onEventoBola);
addChild(bola);
private function onEventoBola(e:Event){
   trace("Se ha soltado la bola "+e.target)
}

NOTA al margen
Podríamos tener una película igualmente funcional si nuestro MC fuera un MC simple y hubiéramos esrito en nuetra película principal

Código ActionScript :

var bola:Bola=new Bola();
bola.addEvent(MouseEvent.MOUSE_DOWN,onMouseDown);
bola.addEvent(MouseEvent.MOUSE_UP,onMouseUp);

private function onMouseDown(e:Event):void{
      e.target.startDrag();
}
private function onMouseUp(e:Event):void{
      e.target.stopDrag();
      trace("Se ha soltado la bola "+e.target)
}

Vamos, añadir los eventos a nuestro Objeto "bola" en la clase principal y controlarlo sólo desde allí, sólo quería mostrar un ejemplo. Según lo compleja que sea nuetra película, en ocasiones tomaremos una u otra opción. La ventaja de meter los eventos en nuestra Clase Bola es que todas las bolas creadas con un new serán "dragables". No tendremos nada más que hacer que añadir el objeto con addChild o arrastrar numerosas instancia desde la biblioteca a la película principal.

Vemos que hemos creado un evento en nuestra Clase Bola. Crear Eventos personalizados es algo que sale "naturalmente" enm el sentido de que vemos que el modo de controlar los eventos es muy parecido a lo que hacemos con cualquier Clase ya definida en Flash
3.-Nuestra Clase va a tener una variables propias que tendrán el mismo valor (o serán una referncia) de variables de nuestra película principal. Volvemos a nuestra "bola Móvil"

Código ActionScript :

package{
   public Class Bola extends MovieClip{
      private var velx:Number;  //<--declaramos una variable dentro de la Clase
      public function Bola(){
      }
      public function moverBola(velx:Number):void{
            this.velx=velx;
            this.addEvent(Event.ENTER_FRAME,onEnterFrame);
      }
      private function onEnterFrame(e:Event):void{
            this.x+=this.velx;
      }
}

Y nuestra película principal sería

Código ActionScript :

public var velx:Number=100
var bola:Bola=new Bola()
addChild(bola);
bola.moverBola(velx);

Vemos que, en este caso, el onEnterFrame usa una variable propia de la Clase. Variable a la que le damos valor cuando llamamos al método "moveBola" dentro de la película principal. Advierto que salvo el "this de la instrucción

Código ActionScript :

this.velx=velx;

NO se suele poner el "this" porque ya se sobreentiende

puff, ha quedado largo (no sé si demasiado claro). Y No conviene olvidar que existen otras "técnicas" que no pretendo cubrir en este post

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 18 Feb 2009 08:00 pm
^^ expectacular! sabía que era un problema de conceptos, me ha servido muchisimo tu explicación gracias full!

Por m3g4m4n

4 de clabLevel



 

opera
Citar            
MensajeEscrito el 03 Oct 2009 06:11 pm
Hola y gracias por el post, pero la misma dura me persiste a mi, por favor podria darme un pequeña ayuda.

Soy novato en todo esto. Resulta q estoy haciendo una pequeña aplicacion en actionscript 3.0 que desde una clase as3 todo ese pequeño trozo de codigo, intento llamarlo desde el mismo reproductor fla, la clase as3, dentro de esa clase tengo un parametro de MovieClip y desde el reproductor aplicando su parametro movieclip me vota cierto error

1120: Acceso a una propiedad stage no definida
1120: Acceso a una propiedad stage no definida

package
{
import flash.display.MovieClip;
public class Centrar
{
public var miclip:MovieClip = new MovieClip();
public function Centrar (clip):void
{
miclip = clip;
miclip.x = (stage.stageWidth - miclip.width) / 2;
miclip.y = (stage.stageHeight - miclip.height) / 2;

}
}
}

y lo llamo asi

import Centrar;
var movi:Centrar = new Centrar(cuadro_mc);

press control + enter y me vota este error

1120: Acceso a una propiedad stage no definida
1120: Acceso a una propiedad stage no definida

lo q intento es querer llamar por via codigo import, no por el mismo documento principal donde nada mas se pone el nombre de la clase, por favor ayuden

Por ccenta

4 de clabLevel



 

firefox
Citar            
MensajeEscrito el 03 Oct 2009 10:12 pm
Hola, para acceder al Stage debes crear una referencia a este , para que puedas trabajar con la display list para ello debes pasarle al constructor el scope como dice Solisarg; asi que el code seria :

Código ActionScript :

package 
{
   import flash.display.*;

   public class AlignCenterObject
   {

      public function AlignCenterObject(dispObj:DisplayObject,obj:MovieClip)
      {
         //referncia al Stage.
         var stageObj:Stage = dispObj as Stage;
         //referencia al TimeLine
         //var timeLineObj:DisplayObjectContainer = stageObj.getChildAt(0) as DisplayObjectContainer;

         //alinear el MovieClip
         obj.x = (stageObj.stageWidth - obj.width)/2;
         obj.y = (stageObj.stageHeight - obj.height)/2;
      }
   }
}

y su uso

Código ActionScript :

var alignCenter:AlignCenterObject = new AlignCenterObject(stage,movieClip);


eso es todo espero te sirva, saludos.

Jonathan

Por maneuver

243 de clabLevel



Genero:Masculino  

Mexico City

firefox
Citar            
MensajeEscrito el 04 Oct 2009 02:25 am
mil gracias Jonathan por la respuesta, pero una consulta mas, si por ejm quisiera q el stage no se pasase ninguna referencia dentro de los parametros del constructor y q me trabajara el stage dentro de la clase asignando como referencia DisplayObject, independientemente sin el parametro del constructor, mas o menos como seria el codigo amigo, desde ya muchisimas gracias por la respuesta anterior.

haber si me dejo entender:

package
{
import flash.display.*;

public class AlignCenterObject
{
public dispObj:Stage = new Stage()
public function AlignCenterObject(obj:MovieClip)
{
//referncia al Stage.
var stageObj:Stage = dispObj as Stage;
//referencia al TimeLine
//var timeLineObj:DisplayObjectContainer = stageObj.getChildAt(0) as DisplayObjectContainer;

//alinear el MovieClip
obj.x = (stageObj.stageWidth - obj.width)/2;
obj.y = (stageObj.stageHeight - obj.height)/2;
}
}
}


para llamarlo:

var alignCenter:AlignCenterObject = new AlignCenterObject(movieClip);

Por ccenta

4 de clabLevel



 

firefox
Citar            
MensajeEscrito el 04 Oct 2009 05:29 am
un poco rebuscado lo que dices :? , pero si lo que quieres es crear una isntancia de la clase Stage la resuesta es no , todas las clases son selladadas y aparte de eso no todas se puden crear instancias de ellas, pero si quieres acceder al stage en cualquier momento en tu clase , puedes usar la propiedad stage de los DisplayObject y crear la referencia a fuerza usando el constructor pero esta ves nada mas le pasas el displayObject el code seria asi :

Código ActionScript :

package 
{
   import flash.display.*;

   public class AlignCenterObject
   {
      private var stageObj:Stage;
      
      public function AlignCenterObject(dispObj:DisplayObject)
      {
         stageObj = dispObj.stage;
         trace(stageObj, stageObj.stageWidth, stageObj.stageHeight);
         trace(dispObj, dispObj.width, dispObj.height);
         dispObj.x = (stageObj.stageWidth - dispObj.width)*0.5;
         dispObj.y = (stageObj.stageHeight - dispObj.height)*0.5;
      }
   }
}


tambien usa el buscador de CL hay un tip sobre " Como acceder al Stage desde cualquier clase".

Jonathan

Por maneuver

243 de clabLevel



Genero:Masculino  

Mexico City

firefox
Citar            
MensajeEscrito el 04 Oct 2009 06:16 pm
Una vez mas mil gracias amigos, sinceramente esto se estaba haciendo un lio para mi, sin embargo con la solucion q me acabastes de dar, se me acabo de solucionar todo este lio q me tenia horas doliendo la cabeza, un saludo muy grande y espero poder seguir disponiendo de este grandioso foro cristalab.

Por ccenta

4 de clabLevel



 

firefox

 

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