How to get swf's url on swc library - actionscript-3

I'am a beginner of ActionScript3
I wanna get swf's url.
but I develop swc lib.
swf(Main) develop other developer.
I have to get from Main loaderinfo, I / F is already fixed.
Do you have a good idea?
public function doSomething( arg1:String,arg2:String ):String
{
/* some thing */
return result;
}

Get the other developer to pass in the Main class or the Stage (in fact any DisplayObject) and return the loaderInfo.loaderURL from that. Something like:
public function getSWFURL( dObj:Sprite ):String
{
return dObj.root.loaderInfo.loaderURL;
}
the .root will return the root DisplayObject, so any DisplayObject that's attached to the stage will return this.

Related

method (function) in subClass not being called on mouse event

My goal is:
define a subClass of Sprite called Ship
use an event at runtime to call a function within this new class
It seems that I've figured out how to create my Ship class using a package in a linked .as file. But I can't seem to access the function within that class. Can anyone see what I'm doing wrong?
var ShipMc:Ship = new Ship();
addChild(ShipMc);// This successfully adds an instance, so I know the class is working.
addEventListener(MouseEvent.CLICK, ShipMc.addShip);//But this doesn't seem to run the function
This code works fine for instantiating a Sprite, but the code in the Ship.as file, specifically the function, is not working. No runtime errors, but nothing traced to the output window, either.
package
{
import flash.display.Sprite
public class Ship extends Sprite
{
public function addShip():void
{
trace("running addShip function")
}
}
}
The last time a coded anything in flash it was AS2!
I'll just mention that I've tried using addShip():void and just addShip(). Same response with both. It should be with :void, right? Anyway, the fact that neither one throws, tells me that this section of code isn't even getting read, I think.
Any help is much appreciated! Pulling my hair out.
Your code is not working because it contains some problems, so let's see that.
You should know that you are attaching the MouseEvent.CLICK event listener to the main timeline which didn't contain any clickable object yet now (it's empty), so let's start by adding something to your Ship class to avoid that :
public class Ship extends Sprite
{
// the constructor of your class, called when you instantiate this class
public function Ship()
{
// this code will draw an orange square 100*100px at (0, 0)
graphics.beginFill(0xff9900);
graphics.drawRect(0, 0, 100, 100);
graphics.endFill();
}
public function addShip():void
{
trace("addShip function run");
}
}
N.B: You can attach the MouseEvent.CLICK event listener to the stage, which will work even if you have nothing in the stage.
Now, if you test your app, you'll get an clickable orange square at the top left corner of your stage, but the compiler will fire an error (ArgumentError) because it's waiting for a listener function (the Ship.addShip() function here) which accept an MouseEvent object.
So to avoid that error, your Ship.addShip() function can be like this for example :
public function addShip(e:MouseEvent):void
{
trace("addShip function run");
}
Then your code should work.
You can also simplify things by using another listener function in your main code which can call the Ship.addShip() function, like this for example :
var ShipMc:Ship = new Ship();
addChild(ShipMc);
addEventListener(MouseEvent.CLICK, onMouseClick);
function onMouseClick(e:MouseEvent): void
{
ShipMc.addShip();
}
For more about all that, you can take a look on AS3 fundamentals where you can find all what you need to know about AS3.
Hope that can help.

Error in my removeAllChildren function

I thought i should be smart and made/copy a removeAllChildren function which worked nice. But now I get "Error #2069: The Loader class does not implement this method" If i understanded it correctly so is it because I have a loaded picture in a Sprite. (But I'm almost sure it worked with the same type of pictures when I build the function as now.) I cant figure out how to go around it. Think catch error should work somehow, but havn't succeded with it. Or is something else I doing wrong?
This is the picture in R class
public static var picture:Class;
[Embed(source="picture.png")]
The child:
private var bg:Sprite=new R.picture;
canvas.addchild(bg);
My removechildrenfunction:
public static function removeAllChildren(doc:*):void {
while(doc.numChildren){
if (doc.getChildAt(0) is DisplayObjectContainer)
removeAllChildren(doc.getChildAt(0));
doc.removeChildAt(0);
}
}
you are sending removeAllChildren function parameter typed as Loader
from Loader Reference
The Loader class overrides the following methods that it inherits,
because a Loader object can only have one child display object—the
display object that it loads. Calling the following methods throws an
exception: addChild(), addChildAt(), removeChild(), removeChildAt(),
and setChildIndex(). To remove a loaded display object, you must
remove the Loader object from its parent DisplayObjectContainer child
array.
public static function removeAllChildren(doc:*):void {
if(doc is Loader && doc.parent != null)
{
doc.parent.removeChild(doc);
return;
}
while(doc.numChildren){
if (doc.getChildAt(0) is DisplayObjectContainer){
removeAllChildren(doc.getChildAt(0));
}
doc.removeChildAt(0);
}
}

Use FLVplayback in FlashDevelop, add Sprite Class to a World in AS3

Hi (excuse me if there are grammar mistakes, I'm french),
I'm a beginner in AS3 but I know a bit better Flashpunk; whatever, I have really some difficulties to code in AS3 and can't get how to insert a video in an AS3 project using FlashDevelop.
Well I found some code for what I'm looking for, insert a flv video, here : http://www.flashdevelop.org/community/viewtopic.php?f=9&t=6407
But I have some issues to get this code working... As I said before I know better Flashpunk so it's hard for me to link basic AS3 with my knowledges in Flashpunk.
I tried to organize it in classes but I know these are wrong, but please, can anyone tell me how I should do to get the code working ? I think the "addChild" is only a Sprite or Movieclip function so my FLVplayback and PlayerGfx extend Sprite, but I don't know how to add them and display them... Here is my code :
public class testMyWorld extends World
{
public var player:PlayerGfx;
public var _FLV:testFLV;
public function testMyWorld()
{
_FLV = new testFLV;
player = new PlayerGfx();
}
}
public class testFLV extends Sprite
{
public var flvPlayback:FLVPlayback;
public var player:PlayerGfx;
public function testFLV()
{
flvPlayback = new FLVPlayback();
flvPlayback.skin = "none"
flvPlayback.autoPlay = false;
flvPlayback.source = "FLVSkyrim.flv"
player.addChild(flvPlayback);
}
}
and well I didn't know what to put in it but in the link before there is a "player class" so...
public class PlayerGfx extends Sprite
{
public function PlayerGfx()
{
}
}
I'm desperately looking for help, I can't find anyone that can explain me what I should do :/ I just need to display a video in as AS3 project for school and I don't want to use FlashProfessional... But I don't understand many things, such as addChild, display a Sprite Class, etc... But if you know an other code better that I could use and that you could explain to me, I would be very grateful.
Thanks in advance !
EDIT : gosh I'm sorry idk if I saw your answers at the time I asked this. The thing is, one of my coworkers at school wrote me a pretty nice bit of code that answered exactly what I needed to do because it was a bit tricky. I can give it to anyone who may need it, but I'm not sure it would suit any "usual" situation because it was pretty personalized and explained irl. Anyway, thanks for your answers.
Why is your base class a World? In a pure AS3 project it should be a Sprite.
Then, once your player (FLVPlayback) is created, you just have to add it to the display list:
import fl.video.FLVPlayback;
public class Main extends Sprite
{
private var flvPlayback:FLVPlayback;
public function testMyWorld()
{
flvPlayback = new FLVPlayback();
flvPlayback.skin = "none"
flvPlayback.autoPlay = false;
flvPlayback.source = "FLVSkyrim.flv"
addChild(flvPlayback);
}
}
Be simple, you don't need all those classes ;)
This is tricky, because FlashPunk replaces the display list by a custom Bitmap-based renderer.
Your World object is not a regular display object and it can't hold a FLVPlayback component.
Your best option is to attach the video player to the stage. Your Main class (extending Engine) is a display object so it has a reference to the stage.
First you need a global reference to your Main instance so you can find the stage:
public class Main extends Engine
{
static public instance:Main; // global static reference
public function Main():void
{
instance = this;
...
}
}
Now you can attach display objects on the stage (over the FlashPunk stage):
public class testMyWorld extends World
{
private var player:MyPlayer; // your FLV player class extending Sprite
public function testMyWorld()
{
player = new MyPlayer();
}
// when the world is shown
override public function begin():void
{
Main.instance.stage.addChild(player);
}
// when the world is hidden
override public function end():void
{
if (player.parent) Main.instance.stage.removeChild(player);
}
}
PS: I didn't actually run this code

Managing Singletons in external swfs

I'm dealing with the scenario whereby my code might be included in other Flash content either included via import .as commands and then referenced as a Singleton, e.g.
import com.as3.Singleton;
...
...
Singleton.birth();
Singleton.getInstance().test();
...but also imported as a runtime library; with the Singleton class exported as a .swf beforehand (instead of pre-baking the class).
How should I reference the Singleton once Event.COMPLETE has fired off from the Loader that brings in the swf? Normally I'd code something like:
public function singletonCompleteHandler(event:Event):void {
var mySing:Singleton = _loader.contentLoaderInfo.content as Singleton;
}
...but I know I don't want to be referencing the singleton via a "var" reference. I'm not explaining very well, but basically once the singleton.swf has loaded in I need to use the code within it within a singleton model (i.e. ensure there's only one instance of it throughout my application).
Copy of the Singleton class included below (thanks for any thoughts on this by the way).
package
{
public class Singleton extends Sprite
{
private static var instance:Singleton;
public function Singleton() {
if (instance) {
throw new Error("Singleton can only be accessed through Singleton.getInstance()");
}
}
public static function birth() {
if (instance == null) {
instance = new Singleton();
}
}
public static function getInstance():Singleton {
return instance;
}
public function test():void {
trace("Testing our singleton.");
}
}
}
First of all, if you're loading it dynamically, then you don't want to have a reference to it in your loading SWF (otherwise it would defeat the point).
So I'm guessing you're looking to do something like this:
function completeHandler(event:Event):void
{
var singleton:Object = loader.contentLoaderInfo.content;
var instance:IMyObject = singleton.getInstance();
instance.test();
}
IMyObject is of course optional here. If you do it like this, your singleton instance will have to implement IMyObject.
interface IMyObject
{
function test():void;
}
This is all to avoid having to reference the actual class in your loading SWF. Like I said, the interface is optional: you can just use Object instead.
... and now on to the main point: load the singleton SWF into the loading SWF's own "application domain".
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/LoaderContext.html#applicationDomain
var lc:LoaderContext = new LoaderContext();
lc.applicationDomain = ApplicationDomain.currentDomain;
loader.load(new URLRequest("Singleton.swf"), lc);
You see, normally when you load a SWF, it gets loaded into its own application domain. But this makes it impossible to enforce the singleton pattern on the loaded SWF, because each instance of the class can live in its own application domain (hence you can end up with multiple instances). So if you want to enforce this across multiple SWF loads then you want to load it into the loading SWF's application domain.
If your question is "How should I reference the Singleton once Event.COMPLETE has fired off from the Loader that brings in the swf?", then you can do it with:
var Singleton:Object = _loader.contentLoaderInfo.applicationDomain.getDefinition('Singleton');
But, I'm not sure what you mean about not wanting to use a "var" reference.
On a side-note, there's a good chance a global variable would be a better option than a Singleton class for an API.
package myPackage
{
public var myGlobal:MyGlobal = new MyGlobal();
}
Which you can access with myPackage.myGlobal

AS3: Accessing custom class public functions from a MovieClip on a timeline

I've got a AS3 program with a Main.as custom class.
In this class I load an instance of a 'menu' movieclip which has simpleButton instances inside... How do I access the Main class public functions by the menu movieclip buttons?
I.e. Menu button -> gotoPage(5); (which is a Main public function)
If I try to access the Main function with the above statement, it gives
"1180: Call to a possibly undefined method gotoPage.
Create a static method called GetMain() on the Main class that would return the instance of Main (Main should be a singleton).
package whatever
{
public class Main
{
private static var _instance:Main = null;
public static function getMain():Main
{
return _instance;
}
// Main constructor
function Main(..):void
{
_instance = this;
}
}
}
To refer to the instance of Main() from your Menu class, you could use:
Main.getMain().gotoPage(5);
You want to do this with events. If your menu movieclip is a child of Main.as as you say, name the instance buttons inside of the menu movieclip, and set up the listeners in Main.as:
1) Put the below code in the constructor: public function Main(){...
menu.button_a.addEventListener(MouseEvent.CLICK, onButtonClick);
menu.button_b.addEventListener(MouseEvent.CLICK, onButtonClick);
2) and then write the onButtonClick function in Main.as
private function onButtonClick(e:MouseEvent):void{
switch(e.currentTarget.name){
case "button_a":
//call the Main.as function you want here
break;
case "button_b":
//call a different Main.as function
break;
}
ruedaminute's answer on dispatching events from the buttons and having main process those events is by far the best way to handle this, but there are many ways to do this in as3 - but try to use the aforementioned technique. Some of the other techniques.
Make a function in Main such as public function GotoPage(iPageNum:int):void{}
from a button - try this._parent.GotoPage(1);
but this._parent might not be main, do a trace(this._parent), and keep trying
it might end up being
this._parent._parent._parent.GotoPage(1) depending on your display tree hierachry.
Again, this is REALLY bad OOP practices, but well, it will work.
Another tecnique - use a singleton for main- looks like u already are - add that same public method, then from the button click, you could do Main.getMain().GotoPage(1);
That is a bit better, in that you can change the display tree and not have to figure out where the heck Main is in the display tree, but singletons also are discouraged for a variety of reasons, but in this case I would say it makes since.
Good Luck!
~ JT