I´m trying to initialize a class, based on a concatenation of a string and a number.
All my classes are public.
This is my code:
public function setCurrentPath(pathNumber:String)
{
var pth_class:Class = getDefinitionByName('Pth'+pathNumber) as Class;
var pth:MovieClip = new pth_class();
addChild(pth)
pth.getXY();
}
So I´m getting Error #1065.
Any help?
Yes I have up on my class file import flash.utils.*
Is your pth_class variable null?
If so, there are a couple of reasons this might be the case:
1) You haven't input the correct fully qualified class name of your class. E.g com.myClasses.Pth1
or
2)
If you're instanciating classes dynamically like this and there is no other "regular" reference to the class (such as blah = new Pth1()) then the "Pth1" class won't be included in the compilation process.
To get around this I think you can supply arguments to the compiler to force it to compile those classes OR you can manually include references to them in your existing code:
p1:Pth1;
p2:Pth2;
Related
As you know,you can access properties and methods in two ways:
dot syntax: object.property=value;
&
bracket syntax: object["property"]=value; or object["property"]=["value];
The bracket syntax also works for methods:
this["myMC"]["stop"]();
I tried to do that with constructors and i "Failed" :(
I try to make variables but
This code does NOT work:
this["mySprite"]=new ["Sprite"](); Error:Instantiation attempted on a non-constructor.
or
this["mySprite"]=new ["Sprite()"]; Error:Instantiation attempted on a non-constructor.
or
this["mySprite"]=["new Sprite"](); Error:Value is not a function.
or
this["mySprite"]=["new Sprite()"]; Error:a term is undefined and has no properties
None of them work
Maybe you wonder why i want that:
I want to make new variables at runtime:
this[tf1.text]=new [tf2.text]();
tf1.text is my variable's name and tf2.text is my constructor.
then I set properties and methods of my variable at runtime(you know how).
I appreciate helpful answers.
You can use getDefinitionByName() to get the class from a string, then create a new object from that class.
This is an example for getting the Sprite class from a string.
import flash.utils.getDefinitionByName;
var aClass:Class = getDefinitionByName("flash.display.Sprite") as Class;
var sprite:Sprite = new aClass();
I am trying to target a variable in the main .as file (The one that acts as the stage) from another .as file.
public var stageRef:MovieClip = root as MovieClip;
or
MovieClip(root)variable = 10;
don't seem to want to work for me. Neither of them produce any compile errors but when I try to use them they give me a 1009 error, cannot access a property or a null object reference. Any ideas of how i would go about doing this? Thanks in advance.
Im your Main.as class make the variable public. Here's an example:
package
{
import flash.display.Sprite;
public class Main extends Sprite
{
public var YOUR_VAR_HERE:VARIABLE_TYPE = DEFAULT_VALUE;
public function Main()
{
}
}
}
DEFAULT_VALUE is optional. VARIABLE_TYPE is recommended, if not specified the type will be Object by default.
There are many ways to pass a variable to another class. If the class is created inside the Main class, just pass the variable to that class like this:
var myOtherClass:OtherClass = new OtherClass(YOUR_VAR_HERE);
or
var myOtherClass:OtherClass = new OtherClass();
myOtherClass.varReference = YOUR_VAR_HERE;
In first case make sure the constructor is expecting a variable. In the second, make sure the OtherClass has a public variable varReference that you can access and modify.
Another way loved by newbie programmers are static (singleton) variables: in the Main class specify your variable as such:
public static var YOUR_VAR_HERE:VARIABLE_TYPE = DEFAULT_VALUE;
Then you can access YOUR_VAR_HERE simply by referring to the class Main. Like this:
trace(Main.YOUR_VAR_HERE);
NOTE: it's considered to use all uppercase letters for constants, not variables, in this case I used all caps for readability.
I need a little help understanding how classes work in Actionscript 3. I understand you start with "package" and why and then go to import any necessary libraries, as well as then naming the class and stating if it's public/private and extends anything.
After that is what I don't understand. It seems you write "(public) function class name()
I don't understand why you do this and what goes in the curly brackets.
I've probably missed a bit of earlier reading because I've done a little reading but I can't seem to get it.
Could someone try explain it to me? Thanks.
ActionScript 3 Classes
The package statement.
Okay, so firstly like you mentioned, a class must be wrapped by a package1. This gives us the first block, where you need to define the class.
package
{
// Your class here.
}
The package statement reflects the location of the class relative to the .fla2. For example, if you have a folder "classes" within the same directory as the project .fla, then classes within that folder will need a package statement that reflects that:
package classes
{
// Your class here.
}
Defining the class.
Within a package statement, you may insert one class. Do not confuse this with the package itself, which can contain many classes - each class just needs to have its own file with the same package statement.
A class definition is made up of up to 5 parts:
The namespace. A class can be internal or public. An internal class can only be seen by classes within the same package, whereas public classes can be seen from anywhere in the project.
The class name.
A base class (optional). If a base class is defined, then your new class will act as an extension to that class, inheriting all of the qualities of the base class.
An interface to implement (optional). Interfaces are an advanced topic thus I suggest you forget about these for now until your AS3 and OOP have evolved.
If you wanted to create a class called "Person" within the package classes, then we would end up with:
package classes
{
public class Person
{
// Class qualities here.
}
}
Properties.
Classes can contain properties. Properties are defined using the var keyword. They may belong to one of a number of namespaces (including your own) and are used to hold values that belong to your class. Properties are most commonly found clustered together at the top of your class.
Our Person class may enjoy the properties height and weight:
package classes
{
public class Person
{
// Properties.
public var height:Number = 1.70;
public var weight:Number = 67.5;
}
}
These properties can be accessed via any instance of Person that you create. Each instance will have its own set of these properties.
Class constructors (I believe this is what you're asking about).
Constructors are used to hold logic that should be run as soon as an instance of your class is created. The class constructor has the same name as the class itself. It must be public and it does not return anything. Constructors can accept arguments, which are typically used to pass in references to dependencies for that class or required values.
package classes
{
public class Person
{
// Properties.
public var height:Number = 1.70;
public var weight:Number = 67.5;
// Constructor.
public function Person(height:Number, weight:Number)
{
this.height = height;
this.weight = weight;
}
}
}
Methods.
Methods are used to hold logic that can be run when calling that method. Methods often return values and can accept arguments. Methods can belong to any namespace that you would expect properties to be able to belong to.
We may want to be able to easily determine the BMI of each instance of Person that we create, so we should create a method for that:
package classes
{
public class Person
{
// Properties.
public var height:Number = 170;
public var weight:Number = 65.5;
// Constructor.
public function Person(height:Number, weight:Number)
{
this.height = height;
this.weight = weight;
}
// Determine my BMI and return the result.
public function getBMI():Number
{
return weight / (height * height);
}
}
}
Instances.
Now that we've defined our new class, we can create instances of this class using the new keyword. This can be done from anywhere that can access the Person class, which in this case is anywhere in the project because we've made the class public.
Though the class is public, accessing it from anywhere outside of the package it belongs in will require the use of an import statement. This statement will need to be used within any class that belongs to a different package. The import statement follows the same name used for the package and includes the name of the class you want to include on the end:
import classes.Person;
Once you've imported Person, you can create instances of it and assign them to a variable with different height and weight values:
var marty:Person = new Person(71, 1.76);
var bruce:Person = new Person(96.4, 1.72);
We can then obtain the BMI for each person using their getBMI() method:
trace(marty.getBMI()); // 22.9
trace(bruce.getBMI()); // 32.6
1 You can place classes outside of a package which can be referred to in the same .as file.
2 You can add more source paths, and packages can be relative to that.
The function that have the same name as class is a constructor. In curly brackets is basically part of code that will execute instantly when object will be created. Try to search info about constructors, they exist I think in every object oriented programming language (I may be wrong), so you have a lot of resources.
You can also read about this concept on Wikipedia.
The function that is named the same as the class is the constructor. It's optional, so you can leave it out if you don't need it. A default constructor will be added, which essentially does nothing.
The constructor lets you write code that executes immediately after an instance of the class is created (ie when another bit of code runs new ClassName(). You would typically use it to initialise some variables that are used by the class. Defining a constructor also lets you handle constructor arguments, which other code can pass when they use the new operator.
Can I create an instance of a class from AS3 just knowing it's name? I mean string representation, like FlagFrance
Create instances of classes dynamically by name. To do this following code can be used:
//cc() is called upon creationComplete
private var forCompiler:FlagFrance; //REQUIRED! (but otherwise not used)
private function cc():void
{
var obj:Object = createInstance("flash.display.Sprite");
}
public function createInstance(className:String):Object
{
var myClass:Class = getDefinitionByName(className) as Class;
var instance:Object = new myClass();
return instance;
}
The docs for getDefinitionByName say:
"Returns a reference to the class object of the class specified by the name parameter."
The above code we needed to specify the return value as a Class? This is because getDefinitionByName can also return a Function (e.g. flash.utils.getTimer - a package level function that isn't in any class). As the return type can be either a Function or a Class the Flex team specified the return type to be Object and you are expected to perform a cast as necessary.
The above code closely mimics the example given in the docs, but in one way it is a bad example because everything will work fine for flash.display.Sprite, but try to do the same thing with a custom class and you will probably end up with the following error:
ReferenceError: Error #1065: Variable [name of your class] is not defined.
The reason for the error is that you must have a reference to your class in your code - e.g. you need to create a variable and specify it's type like so:
private var forCompiler:SomeClass;
Without doing this your class will not be compiled in to the .swf at compile time. The compiler only includes classes which are actually used (and not just imported). It does so in order to optimise the size of the .swf. So the need to declare a variable should not really be considered an oversight or bug, although it does feel hackish to declare a variable that you don't directly use.
Yes, use getDefinitionByName:
import flash.utils.getDefinitionByName;
var FlagFranceClass:Class = getDefinitionByName("FlagFrance");
var o:* = new FlagFranceClass();
I've got a string which, in run-time, contains the name of a class that I want to instantiate. How would I do that?
I read suggestions to use flash.utils.getDefinitionByName():
var myClass:Class = getDefinitionByName("package.className") as Class;
var myInstance:* = new myClass();
However, that gives me the following error:
[Fault] exception, information=ReferenceError: Error #1065: Variable className is not defined.
The easiest method I've come up with is to simply write the classnames out, separated by semicolons, anywhere in your project.
e.g. I create an Assets.as file with this in it:
package {
public class Assets {
// To avoid errors from the compiler when calling getDefinitionByName
// just list all of the classes that are not otherwise referenced in code:
Balloon;
Cloud;
FlyingHorse;
FlyingPig;
UFO;
Zeppelin;
}
}
Full code example/tutorial on this is here: http://producerism.com/blog/flashpunk-dame-and-lua-tutorial-part-6/
The other option is to use the mxmlc -includes compiler argument like this:
-includes=com.mydomain.package.MyClass
http://blogs.adobe.com/cantrell/archives/2010/09/loading-classes-dynamically-in-actionscript-3.html