FlashDevelop is putting entire class path on new instance declaration - actionscript-3

This is more of a nuisance than anything, but when I use FlashDevelop and declare a new instance it puts the whole class path instead of just the class name.
For example I have a class called "FrameText" for a game I'm working on, it's located in the path "display.text.gameText.test.FrameText". I have an instance of type FrameText called "currentTask", and when I put currentTask = new the auto-prediction grabs the class FrameText since that's the instance type. I hit enter to accept that class and it puts
currentTask = new display.text.gameText.test.FrameText
instead of just currentTask = new FrameText. I've tried to look through the program settings to get it to stop putting the whole class path but I can't find anything.

My brother figured it out (thanks homie), turns out I had two FrameText classes since I'm testing a text overhaul for my game. I renamed the test class to FrameTextTest and it worked perfectly.

Related

removeChild added in an other class

I've got a little problem.
I'm trying to remove a child called in an other class.
I've called "viseur" in my Engine class like that :
private var viseur:Viseur;
viseur = new Viseur(stage);
stage.addChild(viseur);
Now, in my Puzzle.as class I'd like to removeChild(viseur) when my puzzle is complete.
How do I do to do that ?
I've tried :
Engine.viseur.stage.removeChild(viseur);
But it is not working... (and either Engine.viseur.removeChild(viseur) )
Anyone know how could I do that ?
Thank you very much,
There are two issues at play here:
The call Engine.viseur.stage.removeChild(viseur); does not work because the variableviseur is private to the Engine class. If you wish for it to be accessible to other classes, you need to make it public.
However, the other issue with this is that the viseur variable is not a static variable either. So accessing it like this, Engine.viseur.stage.removeChild(viseur); is still incorrect even if you fix the variable to be public. if you wish to access it via another class, you can either 1) pass a reference of the instance of the Engine class to your other class so that it can access the viseur variable or 2) make the viseur variable a static variable, but remember if you do this, that means you can only ever have one Viseur object named viseur.

getDefinitionByName not finding a variable that exists

I am using flash.utils.getDefinitionByName in an attempt to grab an art asset. I use this function quite a bit and haven't had trouble until now. Check it:
assetName = Assets.MegaBerry; // works
assetName = getDefinitionByName("Assets.MegaBerry") as Class; // doesn't work
What the heck?? Error response for the second line is "Variable not found."
If it matters: Assets is a file in my root source directory (it has no package; Assets is the fully qualified name) and I've tried putting:
import Assets;
at the top with no luck.
For reference, in Assets.as I have:
[Embed(source = "../art/Inventory/MegaBerry.png")]
public static var MegaBerry:Class;
Your problem is that embedding the resource into the Assets class will create a static variable of type Class that belongs to that class - which is what you are referencing when you use Assets.MegaBerry: A variable(!) of type Class.
It does not, however, register the MegaBerry class to a fully qualified class name. To do this, you have to use - who would have guessed it - registerClassAlias at some point in your application:
registerClassAlias("Assets.MegaBerry", Assets.MegaBerry);
After that, it will be available everywhere else when calling getDefinitionByName.
** EDIT **
Well that's some unexpected behavior... It turns out, the class that was embedded is in fact automatically registered, but under {className}_{variableName}, instead of the notation you would expect. So using:
getDefinitionByName("Assets_MegaBerry") as Class;
should to the trick.
registerClassAlias also works, but then you need to call getClassByAliasinstead of getDefinitionByName. Sorry for the mix-up.
** END EDIT **
You can also use the Embed tag to inject the resource into a separate class file, which you can then reference as expected by using getDefinitionByName, or simply using an import:
package assets {
[Embed(source="../art/Inventory/MegaBerry.png"]
public class MegaBerry extends BitmapData {
}
}
Instead of calling
assetName = getDefinitionByName("Assets.MegaBerry") as Class;
, instead just use:
assetName = Assets["MegaBerry"];
try:
[Embed(source = "../art/Inventory/MegaBerry.png" , symbol="MegaBerry")]
public static var MegaBerry:Class;
In actionscript, objects actually have a name property that is different from the actual variable name as it shows in code.
For example, if you create a variable as follows,
var myBerry = new MegaBerry();
Then getDefinitionByName("myBerry") will return null.
Only when you set the name of the variable by writing myBerry.name = "myBerry", will getDefinitionByName("myBerry") return what you want it to. The name of the object doesn't necessarily have to be equal to the variable name in code.
In your specific case, I don't think you need to use any of that anyways. Have you tried assetName = new MegaBerry() ?
If you want to find out what the fully qualified name of you class really is, you may do the following:
trace(getQualifiedClassName(Assets.MegaBerry));
You may do that from inside Assets.as, for instance.
You can feed that string back to getDefinitionByName() and get a reference to the class.
trace(getDefinitionByName(getQualifiedClassName(SomeClass)));
// output [class SomeClass]
And remember, getDefinitionByName() only gets you references for classes that are in the same scope as the getDefinitionByName call itself. So, if you are loading external SWFs, getting class references will depend on the application domain you are using and the place, where this code executes.

this[String] can't be added into a MovieClip

Lets say I have a MovieClip called "Box", and "String" is actually 'box' just that its not a MovieClip
The problem I'm facing now is I can't use something like circle.addChild(this[String])
I've tried tracing this[Strin]==Box and the result returns true.
And when I remove circle.addChild(this[String]), it does not add the Box into it.
BUT, when I traced is there any new object added to circle, the amount still remains the same.
Any idea what seems to be the problem here?
If I understood you, you are trying to add a MovieClip called (has a instance name of) String inside another MovieClip called Box, right?
Well, you can't give the name String to an object, because String is a class name in ActionScript 3.0
You can't name any object with any class name or protected keyword, such if, for, class, Boolean...
Those are words that ActionsScript uses globally (they are Top Level keywords).
Also, note that although you can name an object (give it an instance name of) MovieClip, Sprite, Loader, Stage and such, all theses names are used by ActionScript as class names, inside packages, that can be imported into your animation/application, and Flash will automatically import almost every one of them for you.
If you name your objects with those words you run some risks, like codes that don't work properly or don't compile at all...
As pointed by #Bosworth99 and #merv, you may note, as well, the naming conventions used by ActionScript, the UpperCamelCase and lowerCamelCase.
Classes are (by convention) written with UpperCamelCase (with the first letter capitalized), which indicates that name is a class name.
Objects are, generally, written with lowerCamelCase (with lower first letter and every new composed word with upper case), indicating that word is a object name (or another keyword, which may be reserved already).
Your syntax is a little odd - you say you have a MC called 'Box'. Are you creating this in the flash ide - or programatically? either way - you appear to be referencing Classes, and not instances of a class (an object). Try:
var _circle:MovieClip;
var _box:Sprite;
private function createDisplayObjects():void
{
_circle = new MovieClip();
this.addChild(_circle);
_box = new Sprite();
_circle.addChild(_box);
}
And - just as a generally agreed upon practice, class names are capitalized, and instance name are lowerCamelCase. I like underscores prefixing private vars, as well.
NemoStein is absolutely correct - reserved keywords will bork your code everytime...
good luck

How do I change subclass' variable from superclass?

For some time now I have been making a very easy game for iPhone in flash using as3.
Recently I came in contact with a small problem, which is why I am posting this!
The problem:
I have a superclass from which everything derives. In the superclass I initiate and place an Object on stage.
1. var myObject:typeA = new typeA();
2. stage.addChild(myObject);
As you can see this object follows the class 'typeA' which, ocf, has its own actionscript file. Inside of this file I have declared a global variable of type string.
What I want to do is change the varbiable on the new object from the superclass. Therefor I tried as following:
1. myObject.myVariable = 'someSortOfString';
Unfortunatly it didn't work and so I wonder how to do this; change a subclass' variable from the superclass.
You need to declare the variable that is being accessed from the subclass as protected (Or public), by default the variable is private so only accesible by the superclass.
e.g. protected var myObject:typeA = new typeA();
BTW did you mean change the superclass variable from the subclass instead of "change the subclass variable from the superclass"?

AS3 - Parametrized Factory method using actual class name

Rather than use a hard-coded switch statement where you pass it the string name of a class and it then instantiates the appropriate class, I'd like to pass the actual name of the class to my factory method and have it dynamically create an instance of that class. I thought it would be trivial and am surprised it is not working. I must be missing something quite basic:
sample code:
createProduct(50, "Product1Class");
createProduct(5, "Product2Class");
private function createProduct(amount:uint, productClassName:String):void {
var productReference:Class;
try {
productReference = getDefinitionByName(productClassName) as Class;
for (var i:uint = 0; i < amount; i++) {
var product = new productReference() as ProductBaseClass; // throws reference error!
}
} catch (error:ReferenceError) {
throw new ReferenceError(error.message + " Have you linked a library item to this class?");
}
}
The only thing that may be a little odd (not sure) is that these "products" are actually linked Library items (ie: I have a movieClip in the Library that has a linkage to Product1Class and another to Product2Class both of which extend ProductBaseClass, which in turn extends MovieClip.
Why the ReferenceError?
If you have a runtime loaded library then the Class's are not compiled into the main swf, so you get the runtime reference error when you try to create them.
To work around this you can declare "dummy" vars of the classes you want to compile, or if using the flex compiler there are options to include the classes you are missing.
e.g. declare these anywhere in your project
private var p1:Product1Class;
private var p2:Product2Class;
Its a frustrating problem, if your classes extend MovieClip which is a dynamic class you might be able to access the properties etc by doing something like this:
var product:MovieClip = new productReference() as MovieClip;
p1["someCustomProperty"]; //Dot notation might work here as it is a dynamic class
Chris is absolutely right, the ReferenceError is actually being thrown during the call to getDefinitionByName, meaning that the reflection method cannot find Product1Class or Product2Class in your application domain. You can always check if a definition is available by checking the application domain directly, like:
// inside your createProduct method, yields 'false'.
ApplicationDomain.currentDomain.hasDefinition( productClassName );
Are these library assets loaded in at runtime? If so, you can either make sure that the library swf is loaded into the current application domain by adding an appropriately configured LoaderContext to your Loader, or you can replace the call to getDefinitionByName with the loaded swf's application domain's getDefinition method.
getDefinitionByName() and ApplicationDomain.currentDomain.hasDefinition() require full qualified class names. The example code in the original post works when Product1Class and Product2Class are in the default package. However, if you move the product classes to another package, you have to make sure that you are supplying the fully qualified class name to getDefinitionByName().
So if we put our product classes in com.example.products, then the call becomes:
productReference = getDefinitionByName("com.example.products.Product1Class") as Class;
I'm not really sure what the best practice is with this kind of dynamic factory class, but what I ended up doing (since all products were in the same package) was to create a constant within my factory class that defines the package for my products:
private const PRODUCT_PACKAGE:String = "com.example.products."; // note the trailing period
So that way your client code doesn't need to know (nor define) the product package. You just prepend this constant to your product class name when using getDefinitionByName().