Comunidad de diseño web y desarrollo en internet online

cargar SWF+Class externo error #1009

Citar            
MensajeEscrito el 25 Mar 2010 04:01 pm
Buenas,
sé que es un topic más que repetido en este foro pero he sido incapaz de encontrar solución a mi caso.

Explico:
En el movie principal de la web, quiero cargar un SWF externo que hace las funciones de un lector de noticias, cargadas desde un XML y formateadas con un CSS. Este news.swf (que se encuentra en la carpeta news) llama a una clase Main que se encuentra en la misma carpeta que él. Este Main.as llama a su vez a otras dos clases XMLLoader y CSS que se encuentran en una carpeta "sources" que se encuentra dentro de la carpeta del SWF externo.

Este news.swf se cargará al dar al botón INDEX del movie principal y se cargará en la posición x150-y60 tal y como se indica en los archivos adjuntos (todo en el mismo fotograma, en su respectiva capa, de momento únicamente trabajo en un fotograma de tiempo)

Resumiendo:
news.swf en carpeta news
main.as en carpeta news
XMLLoader en carpeta news/sources
CSS en carpeta news/sources

El problema viene al cargar el news.swf en la película principal (ya sea mediante el clic sobre el botón INDEX o directamente nadamás cargar la pelicula principal). El error es el susodicho #1009 que tantos quebraderos de cabeza está dando a todo el mundo.

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at news_fla::MainTimeline/frame1()

Necesito vuestra ayuda! He probado de todo, entiendo el hecho de tener que cargarse primero antes de ejecutar la clase y como veréis en los adjuntos hago lo que decís en otros posts pero continua fallando.

Adjunto los archivos aquí: http://www.silviafotografia.com/CRISTALAB/FLASH.zip

Por avizcaino.87

5 de clabLevel



 

Ulldecona

firefox
Citar            
MensajeEscrito el 25 Mar 2010 04:59 pm
Lo siento, no tengo Flash a mano, Le he echado un vistazo al Main.as que genera el news.swf y tienes confundida alguna cosa.
1.-NO declares una función dentro de otra. Vamos, tienes

Código ActionScript :

//MAL HECHO
public function Main():void{
     //<---esta función NO debería estar aquí---->
   public function Test():void{
          addEventListener( Event.ADDED, onAdded );
   }
   public function onAdded( event:Event ):void{
          removeListener( Event.ADDED, onAdded );
          stage.scaleMode = StageScaleMode.NO_SCALE;
          stage.align = StageAlign.TOP_LEFT;
   }
   Test();
    .....
}

Saca las funciones onAdded y Test FUERA del constructor (fuera de la función Main)

Código ActionScript :

//AHORA SÍ
//MAL HECHO
public function Main():void{
   Test();
    .....
}
public function Test():void{
     addEventListener( Event.ADDED, onAdded );
}
public function onAdded( event:Event ):void{
     removeListener( Event.ADDED, onAdded );
     stage.scaleMode = StageScaleMode.NO_SCALE;
     stage.align = StageAlign.TOP_LEFT;
}

TODA REFERENCIA a stage se debe hacer DENTRO de la función onAdded. Eso incluye tus declaración de variables al principio

Código ActionScript :

//TENÍAS PUESTO
public class Main extends Sprite {
      private var xml:XMLLoader;
                .....
      private var stgW:Number = stage.stageWidth;
      private var stgH:Number = stage.stageHeight;
                ......

Declara las variables, pero dalas valor en la función onAdded

Código ActionScript :

//TENÍAS PUESTO
public class Main extends Sprite {
      private var xml:XMLLoader;
                .....
      private var stgW:Number; //Las declaramos, pero sin ningún valor
      private var stgH:Number; //Las declaramos, pero sin ningún valor
                ......

Luego, en la función onAdded

Código ActionScript :

public function onAdded( event:Event ):void{
     removeListener( Event.ADDED, onAdded );
     stgW=stage.stageWidth;
     stgH=stage.stage.Height;
     .....
}

Vale, ahora me dirás, con razón, que el borde no lo puedes crear si no sabes el valor de stgW y stgH. Bueno, pues pasa la parte de dibujar el borde a la función onAdded.

Puff. Ya sé que me vas a preguntar que ¿por qué funciona? Pues porque es una Clase de documento, pero es mejor que hagas esos cambios para poder usarla como Clase normal. Vamos, que si no haces esos cambios no podrás hacer nunca algo como

Código ActionScript :

var new:Main=new Main()
addChild(new)


Vale, repito que no tengo el Flash a mano, así que me toca preguntar
¿cómo cargas el news.swf? en la película principal
El motivo, supongo es que tienes una instancia de
stage.align = StageAlign.TOP_LEFT;

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 25 Mar 2010 05:09 pm
gracias por responder,

he hecho lo que me has comentado y el news.swf continua funcionando por si solo como hacia antes. Pero el problema persiste.

Adjunto el código del botón INDEX que tiene que cargar el movie news.swf en el principal.

Código ActionScript :

include "as/menubutton.as"
this.addEventListener(MouseEvent.ROLL_OVER, rollover); //incluidas en el menubutton.as
this.addEventListener(MouseEvent.ROLL_OUT, rollout);    //incluidas en el menubutton.as
this.addEventListener(MouseEvent.CLICK, obrir);
 
function obrir(e:MouseEvent):void{
   var loader:Loader = new Loader();
   loader.load(new URLRequest("news/news.swf"));
   loader.contentLoaderInfo.addEventListener(Event.COMPLETE, insertMovie);
   function insertMovie(evt:Event):void{ 
      addChild(loader);
      loader.x=150;
      loader.y=60;
   }
}

Por avizcaino.87

5 de clabLevel



 

Ulldecona

firefox
Citar            
MensajeEscrito el 26 Mar 2010 07:32 am
NO metas una función dentro de otra función. En general es una mala práctica.

Código ActionScript :

//La voy a sacar pero todavía NO funciona  
function obrir(e:MouseEvent):void{ 
   var loader:Loader = new Loader(); 
   loader.load(new URLRequest("news/news.swf")); 
   loader.contentLoaderInfo.addEventListener(Event.COMPLETE, insertMovie); 
}
function insertMovie(evt:Event):void{  
      addChild(loader); 
      loader.x=150; 
      loader.y=60; 
} 

Vale, no funciona porque al poner la función insertMovie FUERA ya no tiene valor "loader" dentro de insertMovie. Aún así, repito, NO DEBEMOS definir una función DENTRO de otra función.
¿cómo se soluciona, pues, el problema? pues usando el argumento "evt" DENTRO de la función insertMovie.
evt.target será a quien le hemos añadido el listener -realmente es evt.currentTarget-.
En el caso de un event ENTER_FRAME o MOUSE_CLICK es el propio MC, en el caso de un Loader es el "contentLoaderInfo", así que, para aceder al "loader" -que es el que queremos añadir- lo haremos basándonos en la propiedad "loader"

Código ActionScript :

//Ahora sí
function insertMovie(evt:Event):void{ 
      var loader:Loader = Loader(event.target.loader);
      addChild(loader); 
      loader.x=150; 
      loader.y=60; 
} 

Observemos que la variable "loader" de dentro de la función es una variable independiente de la anterior. Usamos el mismo nombre, pero podríamos haberla llamado "porompompero"

Código ActionScript :

function insertMovie(evt:Event):void{ 
      var porompompero:Loader = Loader(event.target.loader);
      addChild(porompompero); 
      porompompero.x=150; 
      porompompero.y=60; 
} 

Bueno, ya puestos una aclaración. Si lo único que vamos a hacer es añadir el loader o cambiarle la posición, NO necesitamos añadir el listener ni nada. Nos valdría

Código ActionScript :

function obrir(e:MouseEvent):void{ 
   var loader:Loader = new Loader(); 
   //Aquí ya lo añadimos y le damos la posición
   addChild(loader); 
   loader.x=150; 
   loader.y=60; 
   //Simplemente lo cargamos
   loader.load(new URLRequest("news/news.swf")); 
   //NO necesitamos añadir ningún listener de cuando acaba
   //Cuando acabe ya mostrará el contenido
}

Mira si es eso, sino, el problema debe estar en otro lado -y lo miro con más tranquilidad-

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Mar 2010 09:26 am
Perfecto!
impresionante explicación, muchas gracias.
Ahora solamente tengo un problema que el movie no me aparece del tamaño que toca pero ahora miraré. Por lo demás ningún problema.

Gracias!!

Por avizcaino.87

5 de clabLevel



 

Ulldecona

firefox
Citar            
MensajeEscrito el 26 Mar 2010 02:29 pm
aquí vuelvo a estar.

He conseguido que al hacer clic sobre el botón INDEX me cargue el movie en la posición especificada. Copio aquí el código del botón:

Código ActionScript :

include "as/menubutton.as"
this.addEventListener(MouseEvent.ROLL_OVER, rollover);
this.addEventListener(MouseEvent.ROLL_OUT, rollout);
this.addEventListener(MouseEvent.CLICK, obririndex);


Y el código del "menubutton.as":

Código ActionScript :

this.stop();
this.buttonMode = true;
//ACCIONS BOTONS
function rollover(e:MouseEvent):void { 
   e.currentTarget.gotoAndStop(2);
} 
function rollout(e:MouseEvent):void { 
    e.currentTarget.gotoAndStop(1);
} 
//obrir index
function obririndex(e:MouseEvent):void{  
      var loader:Loader = new Loader();  
   var news:MovieClip = new MovieClip(); //crea instancia de mc news
   addChild(news);
   news.x=150;
   news.y=0;
      news.addChild(loader);  
      loader.load(new URLRequest("news/news.swf"));
   removeEventListener(MouseEvent.CLICK, obririndex);
}


El problema viene que al cargar el movie news.swf, al pasar por encima del movie cargado, me lo considera como parte del botón INDEX y cada vez que clico encima se me vuelve a cargar, además de que el botón INDEX se ilumina en blanco con la acción rollover - rollout.

Pienso que es problema del Listener pero eliminándolo continua pasando.

Alguna idea?

Por avizcaino.87

5 de clabLevel



 

Ulldecona

firefox
Citar            
MensajeEscrito el 27 Mar 2010 02:17 pm
solucionado,

el problema era que lo habia situado en el mismo movieclip del botón INDEX.
Arreglado con un:

Código ActionScript :

stage.addChild(news);
stage.addChild(ofertes);

Por avizcaino.87

5 de clabLevel



 

Ulldecona

firefox

 

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