I have an an class a fla called draw.fla . The document class associated with draw is Draw.as The code inside Draw.as is as follows
package
{
import flash.display.MovieClip;
import flash.display.Graphics;
public class Draw extends MovieClip
{
public function drawCircle1(color:Number):void
{
graphics.beginFill(color);
graphics.drawCircle(100,100,40);
graphics.endFill();
}
}
}
The resulting swf is called draw.swf.
I have another fla called test.fla.
The following is the code on the first frame on the main time line.
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.display.Loader;
var swfLoader = new Loader();
var color:Number;
color = Math.round(Math.random()*0xFFFFFF);
var urlReq:URLRequest = new URLRequest("draw.swf");
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoadComplete);
swfLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, swfLoadError);
swfLoader.load(urlReq);
function swfLoadComplete(evt:Event):void
{
var loader:Loader = Loader(evt.target.loader);
addChild(loader.content);
swfLoader.removeEventListener(Event.COMPLETE, swfLoadComplete);
}
function swfLoadError(evt:IOErrorEvent):void
{
trace("Unable to load swf ");
swfLoader.removeEventListener(IOErrorEvent.IO_ERROR, swfLoadError);
}
I have loaded dwaw.swf into test.swf as you can see. Is there anyway I can access the drawCircle1 function of Draw from the test.fla. Actually I need to pass the value color as an argument while accessing this function.
If I'm not wrong, once the loader is complete you could simply make MovieClip(loader.content).drawCircle1(0xFF0000);.
Loader.content should be that class, and function can be called by name with square bracket syntax:
function swfLoadComplete(evt:Event):void
{
var loader:Loader = Loader(evt.target.loader);
addChild(loader.content);
//trying to call function drawCircle1
loader.content["drawCircle1"](0xFF0000);
swfLoader.removeEventListener(Event.COMPLETE, swfLoadComplete);
}
Related
I have many movieclips that i add or remove with "addChild / removeChild" as player navigate through the game views. I want to save these movie clips (propably using shared objects) so load function show the last status of view. I have to say that always are more than one movie clip in each view. I have no a specific code for this yet.
I do not advise you to store objects entirely in SO. Save only object config data. Adobe Flash Professional CS6 (v. 12).
Main - SharedObjectSaver.as
package {
import flash.display.MovieClip;
import flash.net.SharedObject;
import flash.utils.ByteArray;
import flash.net.registerClassAlias;
public class SharedObjectSaver extends MovieClip
{
public function SharedObjectSaver()
{
//Step 1. Check object
//this.addChild(new SomeObject(20,100));
//Step 2. Save object to SharedObject file.
registerClassAlias("SomeObject", SomeObject);
var mySo2:SharedObject = SharedObject.getLocal("SaveData");
mySo2.data.someObject = new ByteArray();
mySo2.data.someObject.writeObject( new SomeObject() );
mySo2.flush();
//Step 3. Try to read object from SharedObject file.
registerClassAlias("SomeObject", SomeObject);
var mySo3:SharedObject = SharedObject.getLocal("SaveData");
mySo3.data.someObject.position = 0;
var someObjectFromSO:* = mySo3.data.someObject.readObject() as SomeObject;
trace(someObjectFromSO is SomeObject); // true
this.addChild(someObjectFromSO);
trace(someObjectFromSO.s);
}
}
}
Being serialized SomeObject class - SomeObject.as
package {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.Loader;
import flash.net.URLRequest;
public class SomeObject extends Sprite
{
public var s:String;
// You can not require passing arguments to the constructor
// because ByteArray in readObject() method tries to read class and
// create an instance of serialized object.
public function SomeObject()
{
var loader:Loader = new Loader();
loader.load(new URLRequest('https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png'));
s = "Hi";
trace("I'm called");
var rectangle:Shape = new Shape;
rectangle.graphics.beginFill(0xFF0000);
rectangle.graphics.drawRect(0, 0, 10,20);
rectangle.graphics.endFill();
this.addChild(rectangle);
this.addChild(loader);
}
}
}
I have a "score1.as" class in which it will access a data from an swf and display it into
my "finalscore.fla"...I was able to pass and trace the data successfully into my "finalscore.fla"..But my problem is this: Though I was able to access the data by tracing it, I can't display it to my dynamic text...I thought by simply typing "txtScore.text = ("Score: " + lol1.go() );" would solve the problem but it didn't...Please help..Here's my code..bY the way, I'm using actionscript 3.0..
score1.as:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
public class score1 extends Sprite
{
private var loader:Loader;
public function Parent()
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("savescore.swf"));//This is the swf where in the data came from
}
public function onLoaded(e:Event):void
{
trace(loader.content['currentScore']);
}
public function go():int{
return loader.content['currentScore'];//This is the data being accessed
}
}
}
finalscore.fla:
var lol1:score1 = new score1();
txtScore.text = ("Score: " + lol1.go() ); // This is where I can't display the data
lol1.Parent();//I successfully traced the data
Check your embedded fonts. You are likely only embedding the characters from the font that were present at compile time. For example, if you have a textfield with "Hello World!", and you wanted to do textfield.text = "Jiggly Jello Lord!" would display as "l ello ord", because only those characters were present in the textfield during compile.
Edit:
I took a closer look at your code. You need to call Parent() before you can get your content. In fact, rename it to be the constructor, and you should be good.
package {
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
public class score1 extends Sprite {
public var loader:Loader;
public function score1() {
// You need to run this code as your constructor.
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("savescore.swf"));
}
public function onLoaded(e:Event):void {
trace(loader.content['currentScore']);
}
public function go():int {
return loader.content['currentScore'];
}
}
}
You'd also want to wait for your content to be loaded before accessing the data. For this, you'd need to wait for your onLoaded to fire before trying txtScore.text = ("Score: " + lol1.go() );
Edit 2
onLoaded is how you know if it runs. It gets called when Event.COMPLETE fires. By the same extension, just register for that event from outside your class, or fire an event, or any other solution that completes after the data is loaded.
finalscore.fla:
var lol1:score1 = new score1();
lol1.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, scoreReady);
function scoreReady(e:Event):void {
txtScore.text = "Score:" + lol1.go();
}
I loaded a test swf into a class. The swf has its own code that loads a link when clicked. This works fine but I want to UNLOAD the class when the swf is clicked.
How can I unload a class when clicking on the loaded content?
I called the function "meow", a simply random name, as I am testing anyway. :)
Here is what I have that does not work:
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Loader;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import flash.events.MouseEvent;
public class theAd extends MovieClip
{
public function theAd()
{
var my_loader:Loader = new Loader();
my_loader.load(new URLRequest("http://www.massmediamail.com/testing/Manga.swf"));
my_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, startListener);
function startListener(e:Event):void
{
addChild(my_loader.content);
trace("Content Loaded");
my_loader.content.addEventListener(MouseEvent.CLICK, meow);
}
function meow(e:Event):void
{
//this.parent.parent.removeChild(this);
trace(this.name);
}
}
}
}
Are you having troubles with correct removal of loader.content? You should employ event.target property to get the correct instance.
function meow(e:MouseEvent):void {
var mc:DisplayObject=e.target;
if (!mc) return;
mc.parent.removeChild(mc);
}
So, my menu for my game is in a separate .fla file and I have used a loader like so to load the menu into my game:
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.ui.Mouse;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.system.LoaderContext;
import flash.display.Sprite;
import flash.net.Socket;
import caurina.transitions.Tweener;
public class Main extends MovieClip {
public static var gameLayer:Sprite = new Sprite;
public static var endGameLayer:Sprite = new Sprite;
public static var menuLayer:Sprite = new Sprite;
public var gameTime:int;
public var levelDuration:int;
public function Main()
{
addChild(gameLayer);
addChild(endGameLayer);
addChild(menuLayer);
var myMenu:Loader = new Loader();
var url:URLRequest = new URLRequest("Menu.swf");
myMenu.load(url);
myMenu.contentLoaderInfo.addEventListener(Event.COMPLETE, menuLoaded);
function menuLoaded(event:Event):void
{
menuLayer.addChild(myMenu.content);
}
playBtn.addEventListener(MouseEvent.CLICK, startGame);
}
public function startGame(e:Event)
{
// Code to remove the menu (menuLayer.removeChild?)
// Code here to start timers etc
}
I set instance names for my buttons but when I try to do something like menuLayer.playBtn.addEventListener(MouseEvent.CLICK, startGame);, I get messages saying Access of undefined property playBtn.
Now, I double checked on my Menu.fla and I definitely gave the button an instance name of playBtn but it's not working. Any help please? Might be something really obvious I've missed but I'm not sure what.
EDIT: Trying it another way (Converting the menu to a movieclip) but not 100% sure how to do it exactly. The code I have is:
public class Main extends MovieClip {
var mainMenu:menuMain = new menuMain;
// Other variables
public function Main()
{
addChild(gameLayer);
addChild(endGameLayer);
addChild(menuLayer);
menuLayer.addChild(mainMenu);
mainMenu.addEventListener(Event.COMPLETE, menuLoaded);
}
function menuLoaded(event:Event):void
{
//var mainMenu:LoaderInfo = event.currentTarget as LoaderInfo;
//var menuInstance:MovieClip = menuLayer.getChildAt(0) as MovieClip;
// now you can actually add the listener, because the content is actually loaded
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
}
public function startGame(e:Event)
{
// Code to execute timers etc.
}
My guess is that you think that when you go menuLayer.addChild(myMenu.content) that menuLayer suddenly becomes an instance of menu.swf That is not the case. It becomes a child of menuLayer.
Try this :
menuLayer.addChild(myMenu.content);
var menuInstance:MovieClip = menuLayer.getChildAt(0) as MovieClip;
trace (menuInstance.playBtn);
This code assumes that you have nothing else added to menuLayer and in that case your menu.swf content would be the only child on the display list of menuLayer.
I am also assuming that menu.swf's contents are a MovieClip.
If my assumptions are wrong, this may not work.
I also noticed that you have your menuLoaded method inside your constructor. Not a good idea. Especially since the next line is expecting playBtn to exist and the menu hasn't even been loaded.
Try something like this :
public function Main()
{
addChild(gameLayer);
addChild(endGameLayer);
addChild(menuLayer);
var myMenu:Loader = new Loader();
var url:URLRequest = new URLRequest("Menu.swf");
myMenu.load(url);
myMenu.contentLoaderInfo.addEventListener(Event.COMPLETE, menuLoaded);
}
function menuLoaded(event:Event):void
{
var myMenu:LoaderInfo = event.currentTarget as LoaderInfo;
menuLayer.addChild(myMenu.content);
var menuInstance:MovieClip = menuLayer.getChildAt(0) as MovieClip;
// now you can actually add the listener, because the content is actually loaded
menuInstance.playBtn.addEventListener(MouseEvent.CLICK, startGame);
}
public function startGame(e:Event)
{
// Code to remove the menu (menuLayer.removeChild?)
// Code here to start timers etc
}
I've generated a class to load and unload SWFs, however, it does not seem to load to swf visually, but it doesn't return any errors either.
Parent code:
//specify the path for the child SWF
var PageURL:URLRequest = new URLRequest("home/home_index.swf");
//include the SWF loading class
import MM_swfloader;
var mainPage:MM_swfloader = new MM_swfloader();
//evoke the load
mainPage.LoadSWF(PageURL);
MM_swfloader class:
package {
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
/**
* author: Me
* email: lala#lala.com
**/
public class MM_swfloader extends Sprite {
public var loader:Loader = new Loader();
public function MM_swfloader():void
{
// constructor code
}
public function LoadSWF(val:URLRequest):void{
var loader:Loader = new Loader();
loader.load(val);
addChild(loader);
trace("loaded"); //returns true
}
public function UnLoadSWF():void {
loader.unload();
}
}
}
I don't understand where the loaded SWF is being loaded to. Any ideas?
You need to add the instance of your SWF loading class to the stage in the parent class:
//specify the path for the child SWF
var PageURL:URLRequest = new URLRequest("home/home_index.swf");
//include the SWF loading class
import MM_swfloader;
var mainPage:MM_swfloader = new MM_swfloader();
// add the instance to the stage
this.addChild(mainPage);
//evoke the load
mainPage.LoadSWF(PageURL);
There are also a couple of problems with the code in your loader class which I have fixed below (see the comments for an explanation):
// Poor practice to use the default namespace, stick it in com.lala
package {
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
/**
* author: Me
* email: lala#lala.com
**/
public class MM_swfloader extends Sprite {
public var loader:Loader = new Loader();
public function MM_swfloader():void
{
// constructor code
// listen for loader complete on the loader instance
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
// add loader to stage
this.addChild(loader);
}
// Note that by convention loadSWF would be a better name for this method
public function LoadSWF(val:URLRequest):void {
// commented out to avoid creating a new locally-scoped
// loader each time the method is called
//var loader:Loader = new Loader();
loader.load(val);
// commented out to avoid adding child each time
// method is called, added in constructor instead
//addChild(loader);
// loading is asynchronous, this needs to be in a handler
// for the loader.complete event
//trace("loaded"); //returns true
}
// call this unloadSWF
public function UnLoadSWF():void {
loader.unload();
}
// handler for loader.complete event
private function loaderCompleteHandler(event:Event):void {
trace("loaded");
}
}
}
You need to add the loader content to the stage on complete, like so:
import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.Event;
import flash.events.ProgressEvent;
function startLoad()
{
var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest("someswf.swf");
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
mLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
mLoader.load(mRequest);
}
function onCompleteHandler(loadEvent:Event)
{
addChild(loadEvent.currentTarget.content);
}
function onProgressHandler(mProgress:ProgressEvent)
{
var percent:Number = mProgress.bytesLoaded/mProgress.bytesTotal;
trace(percent);
}
startLoad();