Accediendo al stage antes de tiempo
En AS3 es una práctica habitual asociar eventos al stage para cogerlos globalmente. El caso más utilizado probablemente se dé con los del tipo MouseEvent. Por ejemplo, si tenemos varios objetos en pantalla, en vez de definir un evento click para cada uno de ellos, cogemos sólo el click en el escenario (global) y vemos sobre quién se está interactuando:
-
this.stage.addEventListener(MouseEvent.CLICK, click);
-
private function click(e:MouseEvent):void
-
{
-
trace("Click en", e.target);
-
}
Pero a veces, cuando intentamos añadir un evento al stage obtenemos el siguiente error:
TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.
Vamos a reproducir el error.
Tenemos dos clases: Main, asociada al documentClass, y Circulo, que se encarga de dibujar un pequeño circulo y capta un evento click.
Clase Main
-
package {
-
import flash.display.Sprite;
-
import Circulo;
-
-
public class Main extends Sprite {
-
-
function Main() {
-
var c:Circulo = new Circulo();
-
addChild(c);
-
}
-
}
-
}
Clase Circulo
-
package {
-
import flash.display.Sprite;
-
import flash.events.*;
-
-
public class Circulo extends Sprite {
-
-
function Circulo() {
-
-
// Dibujar Circulo
-
this.graphics.beginFill(0xFF0000);
-
this.graphics.drawCircle(50, 50, 10);
-
this.graphics.endFill();
-
-
// Definir el evento click
-
this.stage.addEventListener(MouseEvent.CLICK, clic);
-
}
-
-
private function clic(e:MouseEvent):void
-
{
-
if (e.target == this) trace("Click sobre circulo")
-
else trace("No es circulo");
-
}
-
}
-
}
Si compilamos obtenemos:
TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.
at Circulo()
at Main()
¿Por qué obtenemos este error?
Stage es el contenedor base de todos los objetos visuales y se encuentra en lo más alto de la displayList. Este contenedor no se puede acceder directamente, sino que se tiene que hacer mediante la propiedad stage, que se encuentra en cualquier objeto que extiende de DisplayObject.
Nuestro objeto Circulo extiende de Sprite y por tanto es un DisplayObject que soporta la propiedad stage, pero cuando intentamos acceder a dicha propiedad el objeto no se encuentra todavÃa en la displayList y por tanto la referencia es nula.
Solución
Para solucionar esto existen dos eventos muy útiles definidos en DisplayObjet: added y addedToStage. El primero se dispacha cuando un objeto se añade a la displayList y el segundo cuando se añade al escenario.
Asà pues, podemos suscribirnos a estos eventos antes de acceder al stage y asà garantizar que está disponible y que no genera error.
Finalmente nuestra clase Circulo quedarÃa:
-
package {
-
import flash.display.Sprite;
-
import flash.events.*;
-
-
public class Circulo extends Sprite {
-
-
function Circulo() {
-
-
// Dibujar Circulo
-
this.graphics.beginFill(0xFF0000);
-
this.graphics.drawCircle(50, 50, 10);
-
this.graphics.endFill();
-
-
// Escuchar el evento ADDED
-
this.addEventListener(Event.ADDED, init);
-
// o en este caso también ADDED_TO_STAGE
-
//this.addEventListener(Event.ADDED_TO_STAGE, init);
-
}
-
-
private function init(e:Event):void
-
{
-
// Definir el evento click
-
this.stage.addEventListener(MouseEvent.CLICK, clic);
-
}
-
-
private function clic(e:MouseEvent):void
-
{
-
if (e.target == this) trace("Click sobre circulo")
-
else trace("No es circulo");
-
}
-
}
-
}
Post publicado el 18 de February de 2008 a las 16:07 por llops
Categorias: Tips
Etiquetas: added, addedToStage, as3, Error #1009, stage
¿Quieres seguir los comentarios de esta entrada? RSS 2.0
19 comentarios
#1 Junio Vitorino
Hummm, i tried create another instance of the circle object and i add it to displaylist. After this the event workn't properly. The output show me both messages. Because?
Feb 18, 2008
#2 LLops
Ummm it's strange, for me this code works properly:
Are you trying with the correct code?
Feb 18, 2008
#3 EgoSum
Gracias por el tip, me ha solucionado ese runtime error que me salia cuando intentaba lanzar un swf hecho en flash que cargaba a partir de un SWFLoader en flex.
Apr 17, 2008
#4 Juan
Hola. Como les va?
Tengo la siguiente clase en un archivo .AS
package {
import mx.core.WindowedApplication;
import flash.events.*;
public class HW extends WindowedApplication
{
private var appWA:WindowedApplication;
public function HW(){
super();
}
}
}
Y cuando la quiero usar de la siguiente manera con el siguiente codigo de un archivo .MXML
public function ingresar():void {
var newWindow:HW = new HW();
newWindow.initialize();
newWindow.setVisible(true);
}
Obtengo el siguiente error:
TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.
at mx.core::Application/initialize()
at HW/initialize()
at ingresar()
Para resolver el problema intente agregar el siguiente codigo:
override public function initialize():void{
super.initialize();
}
public function HW(){
this.addEventListener(Event.ADDED_TO_STAGE, initialize);
super();
}
Pero no he tenido éxito. AgradecerÃa me puedan indicar como lo soluciono.
Gracias.
May 15, 2008
#5 gonzalo geraldo
Muchas gracias Llops, este tema no lo podia resolver y no lo he visto documentado. Tengo el Essential Actionscript 3.0 y tampoco aparece (espero no pecar de no entender lo que leo). En el Help de Actionscript tampoco lo habia visto explicado asi.
Me ha servido mucho
saludos
Jun 2, 2008
#6 David E Sanchez
Hola!
Quisiera Agradecer la ayuda!!!! pues me proporciono informacion ademas de que encontre solucion al mismisimo problema que se presenta aqui; lo unico que puedo decir es gracias LLop!!! estare publicando mis trabajos para que me ayuden a mejorar pues soy Principiente en FLASH y empece con CS3
Salu2 a la comunidad!!!!
Jun 24, 2008
#7 matias
Ok, pero esto solo funciona cuando se utilizan classes, pero si el codigo esta en un keyframe dentro de un movieclip no funciona...
a mi me continua tirando ese error y no tengo forma de solucionarlo...
Oct 8, 2008
#8 LLops
Matias, si el código está en un keyframe, no necesitas utilizar este evento, ya que un objeto en linea de tiempo lleva implÃcito encontrarse en la displayList.
Si quieres, detállame el caso concreto (puedes hacerlo a través de contacto) y le echo un vistazo a ver si te puedo ayudar.
Oct 8, 2008
#9 Pilar
Genial me has ayudado mucho a encontrar la solución a parte de mi problema, estoy pasando del AS2 al AS3 y la verdad el cambio es brutal, sobre todo para alguien que es mas de diseño que de desarrollo.
Como podrÃa cambiar las variables por el ejemplo el color del circulo creado'???? desde el fla por supuesto
Feb 9, 2009
#10 LLops
Hola Pilar, me temo que no te he entendido... como le comentaba a Matias (#8), si quieres contáctame y me detallas lo que quieres hacer.
Saludos!
Feb 12, 2009
#11 Pablo
Hola Llop, he de decirte que llevo tiempo buscando a alguien que me de una respuesta a esto pero aún no lo he encontrado, o bien no supe entender lo que me explicaron, mi problema es parecido, yo no utilizo Adobe CS3, uso KoolMoves un programa de bajo costo pero que en su ultima version incorpora AS3, este programa no tiene al igual que CS3 en el panel de propiedades, el campo Clase de Documento (el del lapicito), por lo que tengo que llamar a las clases desde el timeline con action script en el primer frame, yo utilizo para llamarlas al estage en el fotograma 1:
import Circulo;
var c:Circulo = new Circulo();
addChild(c);
Esto a veces funciona y otras no, por ejemplo con tu clase MainSelector.as:
import com.llops.MainSelector;
var selector:MainSelector = new MainSelector();
addChild(selector);
No funciona. ¿Por que? ¿ Es que todas las clases no se conportan igual? Gracias.
Mar 5, 2009
#12 llops
Buenas Pablo, creo que lo que pasa es lo siguiente:
Con el DocumentClass, el archivo se inicializa y se añade a la displayList, pero cuando tú lo haces "manualmente" en el stage (tanto en el KoolMoves como en Flash), pasa algo como esto:
En el ejemplo final que he puesto para descargar, en la clase Circulo, comenta la linea:
y descomenta esta:
Ahora sà se está esperando a que se añada Circulo a la display List (no al "programa"), y no deberÃa generarte errores.
Y si quieres evitar andar pensando cual va a ser el orden de ejecución del programa, siempre puedes hacer algo asÃ:
En el constructor del Main no pones nada e inicializas en un método público (init), habiéndote asegurado que ya está en displayList y que puedes añadir cualquier hijo.
Saludos!
Mar 9, 2009
#13 Pablo
Gracias, por tu explicación Llops. Practicaré lo que tan gentilmente me has explicado. Muchas Gracias y un Saludo.
Mar 9, 2009
#14 Chefo
Hola LLops, muy bueno el tutorial. Me ha funcionado al pelo!
Sin embargo cuando he querido ampliarlo un poco ve he visto frente a un problema serio. Quiero tener un Main.as que sea el document y que llame a un Controlador.as que sea quie efectivamente llame al cÃrculo. Tengo que pasar el stage hacia los futuros hijos
Para Circulo ahora escucho stageRef en lugar de stage
Hasta aqui todo va bien, pero si quiero editar a mano el objeto Circulo, es decir desde flash y no desde as. No se ve nada en la pantalla! Eso si que me ha dejado planchado. Mi objetivo es desde la clase Controlador.as cargar todos los simbolos de un juego y detectar un fin de partida para avisar a Main y que éste carge a traves de otro controlador otro juego.
De momento estoy haciendo los juegos por separado, pero no puedo ensamblar sus clases principales a traves de un Main comun porque no se ve nada, ademas de que para probar cada juego desde el Main tengo que pasar una instancia de stage hasta los hijos, con lo cual, cuando los edito con flash me fallan por que les sobra un parametro en el constructor (el parametro que les paso el stage).
Le he dado mil vueltas y leido muchos foros, pero no veo cual es el problema, a ver si me puedes orientar un poco Llop
Apr 13, 2009
#15 ELSanto
hola. soy nuevo en este tema, no se mucho pero ahi voy tratando de aprender.
Tengo una serie de botones que me llevan cada uno a una etiqueta, cada boton es una sola etiqueta pero en una de ellas debo ingresar dos botones para darle continuacion a la informacion. Quiero decir que cada boton tiene una sola pagina de información, pero uno de ellos tiene dos paginas y debo poner un boton de "siguiente" eneste pantallazo. cuando hago esto me sale el error #1009: este es el codigo que tengo...me pueden ayudar urgente?
Sep 19, 2009
#16 Ccenta
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
Oct 3, 2009
#17 Nilson
Hola, creo que tengo el mismo problema que Matìas, pues los Movieclips los tengo ya en el escenariom pero al pulsar un botòn dentro de un MC que me dirija al Escenario principal, me arroja el error
aqui el còdigo dentro de un MC
grafico_BTN.addEventListener(MouseEvent.MOUSE_DOWN,grafico);
function grafico(Event:MouseEvent):void {
root.imagen_mc.gotoAndStop(113);
}
Jan 7, 2010
#18 aquiles perez
Hola todos, tengo una dudilla, por que este codigo no me trabaja, cuando creo un objeto en un frame de flash, no me muestra nada, sin embargo cuando agrego addChild(new GrettingApp) si trabaja, alguien me puede decir como puedo mostrar los graficos de esta clase sin poner esa instruccion, ya se que el stage es el tope, pero necesito referirme a el desde mi clase.
saludos
Feb 27, 2010
#19 Kaus
gracias men si no encuentro esto para evitar ese error no se que haria ya me estaba desesperando me fue de gran ayuda, creeme muchas gracias
May 29, 2010
¡Deja un comentario!