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