View Full Version : Trying to load external .swf
Navy_Spitfire
12-21-2010, 01:51 AM
import flash.media.Sound;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.net.URLRequest;
import flash.display.Loader;
var sound:Sound = new songmp3();
sound.play();
var loader:Loader = new Loader();
addChild(loader);
var url:URLRequest = new URLRequest("Main.swf");
stage.addEventListener(KeyboardEvent.KEY_DOWN, playGame);
function playGame(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.ENTER)
{
loader.load(url);
}
}
I'm getting this error when I hit enter:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
I can't figure out why. All the files are in the same folder.
Mazoonist
12-21-2010, 03:12 AM
If it's not working at all, you are probably just experiencing the flash authoring tool capturing the ENTER keypress itself. On the running swf's menu bar (not flash's) pull down the View menu and choose "disable keyboard shortcuts."
Certain keys have meaning to flash itself. Like if you press the "b" key it means the brush tool. So to capture the b key yourself, you have to disable flash's own keyboard shortcuts, and that's what that menu choice is for. This all only makes a difference in the testing environment. Your published swf in a different environment will capture the key reliably.
After you get that part working, you will probably find that your loading is working, but now the stuff is being placed on top of what is already there. The thing is, there is no such thing as "taking away the current swf and loading another one." The current swf is playing host to the one being loaded, so there is no taking away the first one.
Instead, you have to just remove all the items on the stage somehow with removeChild. You can do this manually yourself by just issuing that command on all the stuff you know is there. Or you might do it in a loop like this:
while(this.numChildren > 0) {
this.removeChildAt(0);
}
If you use this loop, be sure to run it before you add the loader to the display list. So do something like this:
import flash.media.Sound;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.net.URLRequest;
import flash.display.Loader;
var sound:Sound = new songmp3();
sound.play();
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("Main.swf");
stage.addEventListener(KeyboardEvent.KEY_DOWN, playGame);
function playGame(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.ENTER)
{
loader.load(url);
while(this.numChildren > 0) {
this.removeChildAt(0);
}
addChild(loader);
}
}
Mazoonist
12-21-2010, 03:18 AM
If the external swf makes any reference to the stage at all in its code, you will get the null reference error. To fix it, use some code like this in the external swf:
import flash.events.Event;
if(stage != null) {
init(null);
} else {
addEventListener(Event.ADDED_TO_STAGE, init);
}
function init(event:Event):void {
//put all your code here that refers to the stage in any way:
}
Then re-compile the external swf. Then test the loading swf again.
Navy_Spitfire
12-21-2010, 03:19 AM
The disable keyboard shortcuts has been disabled and I keep getting the error: TypeError: Error #1009: Cannot access a property or method of a null object reference.at Main()
While I'm really not looking to remove everything from the stage, my main goal is to actually load the Main.swf and that isnt' working.
If it helps I have three files: titlePage, Main, and Main.as. titlePage has all the code on the timeline and is the code below, while all of Main's code is in the .as file.
Mazoonist
12-21-2010, 03:25 AM
Navy_Spitfire,
Well, without seeing your files, I just made my best guess as to what your problem is. Null reference errors when loading an external swf are almost always caused by stage references.
If all else fails, maybe upload your files here.
Navy_Spitfire
12-21-2010, 03:32 AM
titlePage main timeline
import flash.media.Sound;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.net.URLRequest;
import flash.display.Loader;
var music:Sound = new songmp3();
music.play();
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("Main.swf");
stage.addEventListener(KeyboardEvent.KEY_DOWN, playGame);
function playGame(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.ENTER)
{
loader.load(url);
while(this.numChildren > 0) {
this.removeChildAt(0);
}
addChild(loader);
}
}
Main.swf .as file
package
{
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.display.Loader;
public class Main extends MovieClip
{
public var ground:MovieClip;
public var splitGround:MovieClip;
public var brokenGround:MovieClip;
public var brokenGround2:MovieClip;
public var brokenGround3:MovieClip;
public var brokenGround4:MovieClip;
public var brokenGround5:MovieClip;
public var brokenGround6:MovieClip;
public var brokenGround7:MovieClip;
public var player:MovieClip;
public var split:MovieClip;
public var keyPressed:uint;
public var a:uint;
public var sound:Sound;
public var sound2:Sound;
public var sound3:Sound;
public var speed:Number = 10;
public var yVel:Number = 3;
public var yAcc:Number = 0.25;
public var currentPos:Number = 0;
public var origin:Point;
public var rightKeyIsDown:Boolean;
public var leftKeyIsDown:Boolean;
public var wr11:Boolean = false;
public var wr22:Boolean = false;
public var breakTimer:Timer = new Timer(1000);
public var breakTimer2:Timer = new Timer(1000);
public var breakTimer3:Timer = new Timer(1000);
public var breakTimer4:Timer = new Timer(1000);
public var breakTimer5:Timer = new Timer(1000);
public var breakTimer6:Timer = new Timer(1000);
public var breakTimer7:Timer = new Timer(1000);
public var removeIceTimer:Timer = new Timer(2000);
public var removeIceTimer2:Timer = new Timer(2000);
public var removeIceTimer3:Timer = new Timer(2000);
public var removeIceTimer4:Timer = new Timer(2000);
public var removeIceTimer5:Timer = new Timer(2000);
public var removeIceTimer6:Timer = new Timer(2000);
public var removeIceTimer7:Timer = new Timer(2000);
public function Main()
{
splitGround = new iceSplitComplete_mc();
splitGround.name = "splitGround";
addChild(splitGround)
splitGround.x = -2.50;
splitGround.y = 359.4;
ground = new beginGround_mc();
addChild(ground);
ground.x = -2.50;
ground.y = 359.4;
player = new player_mc();
addChild(player);
player.y = 200;
rightKeyIsDown = false;
leftKeyIsDown = false;
sound = new iceCrackmp3();
sound2 = new iceBreakmp3();
sound3 = new hardEight();
sound3.play();
stage.addEventListener(KeyboardEvent.KEY_DOWN, pressKey);
stage.addEventListener(KeyboardEvent.KEY_UP, releaseKey);
stage.addEventListener(Event.ENTER_FRAME, gravity);
stage.addEventListener(Event.ENTER_FRAME, hitting);
}
Etc...
Those eventListeners are the only things added to the stage. I really appreciate your help, btw, I don't mean to come off as rude or unappreciative.
Mazoonist
12-21-2010, 03:49 AM
In the case of a class, yeah, you work the add event listener part into the constructor, and write the other part (the handler) as a private function:
package
{
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.display.Loader;
public class Main extends MovieClip
{
public var ground:MovieClip;
public var splitGround:MovieClip;
public var brokenGround:MovieClip;
public var brokenGround2:MovieClip;
public var brokenGround3:MovieClip;
public var brokenGround4:MovieClip;
public var brokenGround5:MovieClip;
public var brokenGround6:MovieClip;
public var brokenGround7:MovieClip;
public var player:MovieClip;
public var split:MovieClip;
public var keyPressed:uint;
public var a:uint;
public var sound:Sound;
public var sound2:Sound;
public var sound3:Sound;
public var speed:Number = 10;
public var yVel:Number = 3;
public var yAcc:Number = 0.25;
public var currentPos:Number = 0;
public var origin:Point;
public var rightKeyIsDown:Boolean;
public var leftKeyIsDown:Boolean;
public var wr11:Boolean = false;
public var wr22:Boolean = false;
public var breakTimer:Timer = new Timer(1000);
public var breakTimer2:Timer = new Timer(1000);
public var breakTimer3:Timer = new Timer(1000);
public var breakTimer4:Timer = new Timer(1000);
public var breakTimer5:Timer = new Timer(1000);
public var breakTimer6:Timer = new Timer(1000);
public var breakTimer7:Timer = new Timer(1000);
public var removeIceTimer:Timer = new Timer(2000);
public var removeIceTimer2:Timer = new Timer(2000);
public var removeIceTimer3:Timer = new Timer(2000);
public var removeIceTimer4:Timer = new Timer(2000);
public var removeIceTimer5:Timer = new Timer(2000);
public var removeIceTimer6:Timer = new Timer(2000);
public var removeIceTimer7:Timer = new Timer(2000);
public function Main()
{
splitGround = new iceSplitComplete_mc();
splitGround.name = "splitGround";
addChild(splitGround)
splitGround.x = -2.50;
splitGround.y = 359.4;
ground = new beginGround_mc();
addChild(ground);
ground.x = -2.50;
ground.y = 359.4;
player = new player_mc();
addChild(player);
player.y = 200;
rightKeyIsDown = false;
leftKeyIsDown = false;
sound = new iceCrackmp3();
sound2 = new iceBreakmp3();
sound3 = new hardEight();
sound3.play();
if(stage != null) {
init(null);
} else {
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
private function init(event:Event):void {
stage.addEventListener(KeyboardEvent.KEY_DOWN, pressKey);
stage.addEventListener(KeyboardEvent.KEY_UP, releaseKey);
stage.addEventListener(Event.ENTER_FRAME, gravity);
stage.addEventListener(Event.ENTER_FRAME, hitting);
}
...etc
That was a pretty long class listing, but I left it intact anyway. The crucial part is at the end, though. Put that in, recompile, and it should work.
Nah, I don't suspect anyone seeking help of being unappreciative when they get some :)
Mazoonist
12-21-2010, 03:58 AM
By the way, the way that works is this:
If the file is being run standalone, the stage will not be null. In that case, the init function will run right away. init() is called with null in the parentheses because it is an event handler function and requires an argument (this is also how you might run an event handler manually, as long as the function body doesn't rely on the event object in any way).
But if the stage is null, then this file must be being loaded externally, and the add event listener part in the else runs. This will make the file wait until it's added to the stage with an external addChild() command. At that point, its stage reference is valid.
Navy_Spitfire
12-22-2010, 01:58 PM
Okay, I think that makes sense to me. And it works, thanks!
One last question, though: After the player hits enter I want the title page to fade a little, and and the end of the fade for the new map to begin and for the title page (with its music) to go away.
main timeline
function playGame(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.ENTER)
{
gotoAndPlay(120);
//loader.load(url);
if(currentFrame >= 121)
{
loader.load(url);
addChild(loader);
trace("working");
}
}
}
At 120, a fade begins for 20 frames. If I do (currentFrame >= 120) it works, but any number higher then that doesn't load. Why is that, and how would i fix it?
Navy_Spitfire
12-23-2010, 12:45 AM
Also, since I begin on the title page swf and I load another swf, how would I unload the title page once its not needed?
Mazoonist
12-23-2010, 12:52 AM
Navy_Spitfire,
I wonder if you have thought of a scenario like this: your main swf would be nothing but a host for all your other swfs. It would contain nothing but a loader and perhaps a progress bar.
Your "title page" animation would also be loaded as an external swf. The only thing you would need to worry about hiding would be the preloader, and rather than using removeChild on it, you could just set its visible property to false.
When you tell your loader to load a new swf, it automatically replaces what was already in it.
You might dispatch an event at the end of your title page swf to let the main application know that the animation is done playing. You would dispatch this event from the final frame of the animation.
Navy_Spitfire
12-23-2010, 01:36 AM
Thank you Mazoonist for helping my visualize it. I figured it out. I didn't think about it the way you described and now see how simple it can be.
Navy_Spitfire
12-23-2010, 02:06 AM
Do you know much about embedding multiple files into an HTML page? I'm trying to embed these files so that there is continuous play between them. I have all the files in the same folder and embed'd the first .swf, but as it stands right only that .swf plays and they don't access each other.
|
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.