I have a vector in my Main class file that store objects. I will like to be able to add more objects to that SAME vector from a different class. I gave the vector in my main class the "public" modifier. I now need the syntax to reference it in my other class file
public var badChar:Vector.;
You have options. How you approach it is dependent on your project setup, and the needs of the property. Is it an instantiated object, or should there ever only be one (even if the class is instantiated multiple times)? Do you need direct access to it regardless of any relationship to the stage? Each solution below has pros and cons.
Class-to-Class via Stage
Assuming the following main foo.as class:
package {
public class Foo {
public var bool:Boolean = true;
}
}
Bar class:
package {
public class Bar extends Sprite {
import flash.events.Event;
public function Bar() {
addEventListener(Event.ADDED_TO_STAGE, accessFoo);
}
private function accessFoo(e:Event):void {
trace(this.parent["f"].bool); // traces "true"
}
}
}
Document Code:
var f:Foo = new Foo();
var b:Bar = new Bar();
addChild(b);
Inheritance
Foo Class:
package {
public class Foo {
public var bool:Boolean = true;
}
}
Bar Class
package {
public class Bar extends Foo {
public function Bar() {
trace(bool); // traces "true"
}
}
}
Class-to-Class via Static
Some disclaimers should be in order for Static properties, but I'll leave you to read up on those.
Foo Class:
package {
public class Foo {
public static var bool:Boolean = true;
}
}
Bar Class
package {
public class Bar {
public function Bar() {
trace(Foo.bool); // traces "true"
}
}
}
Direct Access via New Declaration
Foo Class:
package {
public class Foo {
public var bool:Boolean = true;
}
}
Bar Class
package {
public class Bar {
import Foo;
public function Bar() {
trace(new Foo().bool); // traces "true"
}
}
}
Access via Sharing
Foo Class:
package {
public class Foo {
public var bool:Boolean = true;
}
}
Bar Class
package {
public class Bar {
import Foo;
public var fluffy:Foo;
public function Bar() {
trace(fluffy.bool);
}
}
}
Document Code:
var f:Foo = new Foo();
var b:Bar = new Bar();
b.fluffy = f;
Note that after the third line in the document code, fluffy is no longer an undeclared variable and will now point to the f object, where the properties updated in it (such as bool) will reflect inside of Bar.
Related
I'm trying to instantiate a class based on a function type parameter.
Although the documentation says it is possible, I can't make it work.
Consider the following code:
// Dialog base class
// Every dialog in my application will derive from this
class Dialog
{
public function new()
{
// do some stuff here
}
}
// One of the possible dialogs in the application
// Extends Dialog
class TestDialog extends Dialog
{
public function new()
{
super();
// do some more stuff
}
}
// A simple class that tries to instantiate a specialized dialog, like TestDialog
class SomeAppClass
{
public function new()
{
var instance = create(TestDialog);
}
#:generic
function create<T:Dialog>(type:Class<T>):T
{
return new T();
}
}
This doesn't work with the following error:
create.T does not have a constructor
Clearly, I'm doing something wrong, but what?
SpecialDialog could have a different constructor than Dialog.
So you have to constraint it and then also constraint to Dialog.
Code # Try Haxe
package;
typedef Constructible = {
public function new():Void;
}
// Dialog base class
// Every dialog in my application will derive from this
class Dialog
{
public function new()
{
trace("dialog");
}
}
class SuperDialog extends Dialog
{
public function new()
{
super();
trace("super dialog");
}
}
// A simple class that tries to instantiate a specialized dialog, like TestDialog
class SomeAppClass
{
public function new()
{
var dialog = create(Dialog);
var superDialog = create(SuperDialog);
}
#:generic
public static function create<T:(Constructible,Dialog)>(type:Class<T>):T
{
return new T();
}
}
class Test {
static public function main() {
new SomeAppClass();
}
}
hi there i am trying to call a root class function (back)? from a sub class but i am getting an error, i have tried a few things without luck. please help! cheers
Main class
package {
import flash.display.MovieClip;
import foo;
public class Main extends MovieClip {
public function Main(){
var foo:* = new foo();
addChild(foo)
foo.call();
}
public function back(){
trace("back");
}
}
}
Sub foo class
package {
public class foo {
public function foo() {
trace("foo int");
}
public function call(){
trace("foo, Main call");
(parent as Main).back();
}
}
}
My work around..
main class;
package {
import flash.display.*;
import foo;
public class Main extends MovieClip {
private static var main: Main;
private var Foo: foo;
public function Main(){
Foo = new foo();
Foo.call();
}
public static function get back(): Main {
trace("foo!");
return main;
}
}
}
foo class:
package {
public class foo {
public function foo() {
trace("foo int");
}
public function call(){
trace("foo, Main call");
Main.back;
}
}
}
parent is a property of the DislpayObject class: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#parent
This means that you should first extend it and second (very important) - you must add the child to any display list in order to use parent (as the ref says: parent -> Indicates the DisplayObjectContainer object that contains this display object)
thanks for your help guys appreciated but unfortunately that didn't work for me.. i found a work around, here's what i did. this is exacting what i needed (i didn't have an option to change the document class structure needed to stay the same).
package {
import flash.display.*;
import foo;
public class Main extends MovieClip {
private static var main: Main;
private var Foo: foo;
public function Main(){
Foo = new foo();
Foo.call();
}
public static function get back(): Main {
trace("foo!");
return main;
}
}
}
foo class;
package {
public class foo {
public function foo() {
trace("foo int");
}
public function call(){
trace("foo, Main call");
Main.back;
}
}
}
I'm having an issue with a little app I'm trying to create at the moment, it's my first try and dealing with classes but for some reason I can't create any instances of the class even if it's imported into the document. Here's the code for the class (named "Players"):
package
{
public class Player
{
public function Player(name_:String)
{
}
public var name_:String;
private var alignment:int;
public var healed:Boolean = false;
public var revealed:Boolean = false;
public var attacked:Boolean = false;
public var dead:Boolean = false;
public function action(target:Player)
{
}
public function describe():String
{
}
}
public class Citizen extends Player
{
public function Citizen(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
}
override public function describe():String
{
return "Citizen";
}
}
public class Investigator extends Player
{
public function Investigator(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.revealed = true;
}
override public function describe():String
{
return "Cop";
}
}
public class Doctor extends Player
{
public function Doctor(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.healed = true;
}
override public function describe():String
{
return "Doctor";
}
}
public class Mafioso extends Player
{
public function Mafioso(name_:String)
{
alignment = -1;
}
override public function action(target:Player)
{
target.attacked = true;
}
override public function describe():String
{
return "Mafia";
}
}
}
And the code which creates the instance:
import Players;
stop();
var totalplayers:Number;
var playerArray:Array = new Array();
var playerType:Array = ["Citizen","Cop","Doctor","Mafia"];
var test:Citizen = new Citizen("James");
Both are in the same folder. I get the error code 1046 described in the title but I honestly have no idea why, flash picks it up in the code hints yet it comes up with that! Any help would be appreciated.
Also secondary question, I'll never initiate the Player class (except through inheritance with the other classes), so can I make it private?
Thanks
I'm assuming all that code is in a file called Players.as.
This is wrong. Each file should contain one class and the class should be the same name as the .as file.
You currently have two classes (Player and Citizen) within one file.
What you need to do is take the Player class you've defined and place it in its own .as. file with the same name (Player). Do the same for Citizen.
Then you can use:
import Player;
import Citizen;
Though this won't be necessary because you don't need to import classes that are in the same directory that you're trying to access it from.
As for the error, you're getting that because Flash is trying to find the class Players and you don't have a class with that name (just a file with that name).
Per your secondary question regarding whether ActionScript supports private classes, if you have a class that would not otherwise be accessed except internally by a public class you may define it as internal.
Internal classes are visible to references inside the current package.
If you do not want a class to be publicly visible outside a package, place the class inside a package and mark the class with the internal attribute. Alternatively, you can omit both the internal and public attributes, and the compiler automatically adds the internal attribute for you. You can also define a class to only be visible inside the source file in which it is defined. Place the class at the bottom of your source file, below the closing curly bracket of the package definition.
In the following example, both X and Y classes are defined in a single file (X.as). X may be referenced and instantiated as normal; however, Y is internal to X and only visible from from the scope of X.
package
{
import flash.display.Sprite;
public class X extends Sprite
{
public function X()
{
super();
var y:Y = new Y();
}
}
}
internal class Y
{
public function Y()
{
trace("internal Y ctor.");
}
}
This pattern is helpful when a class requires small data models that would not otherwise be accessed outside of a class.
Agree with others here should be as shown below (note filenames match class names, file names are denoted in brackets above code blocks). Also you wrote import Players instead of import Player, regardless as the other poster wrote if all classes are currently in the default package the import is unnecessary.
[Player.as]
package
{
public class Player
{
public function Player(name_:String)
{
}
public var name_:String;
private var alignment:int;
public var healed:Boolean = false;
public var revealed:Boolean = false;
public var attacked:Boolean = false;
public var dead:Boolean = false;
public function action(target:Player)
{
}
public function describe():String
{
}
}
}
[Citizen.as]
package
{
public class Citizen extends Player
{
public function Citizen(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
}
override public function describe():String
{
return "Citizen";
}
}
}
[Investigator.as]
package
{
public class Investigator extends Player
{
public function Investigator(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.revealed = true;
}
override public function describe():String
{
return "Cop";
}
}
}
[Doctor.as]
package
{
public class Doctor extends Player
{
public function Doctor(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.healed = true;
}
override public function describe():String
{
return "Doctor";
}
}
}
[Mafioso.as]
package
{
public class Mafioso extends Player
{
public function Mafioso(name_:String)
{
alignment = -1;
}
override public function action(target:Player)
{
target.attacked = true;
}
override public function describe():String
{
return "Mafia";
}
}
}
It's unfortunate there's no abstract classes as this would be an ideal situation for an abstract class and abstract methods.
Suppose in document class
public class Test extends MovieClip
{
public function Test()
{
var object1:ClassA = new ClassA();
//addChild(object1);
object1.accessRoot();
}
}
public class A extends MovieClip
{
public function accessRoot()
{
var mc : MovieClip = root as MovieClip;
mc.box.visible = false;
}
}
Now box is placed at stage. but when Class A is added to Test Class, it works and when object of Class A is not added in Test constructor, root becomes in-accessible. Is there any way that objects not on display-list can access root or display-list objects??
I would not recommend having your classes fiddle around with root or stage, it's way better to dispatch events and have the proper encapsulation.
Hacky way:
public class A extends MovieClip
{
private var _root:MovieClip;
public function A(root:MovieClip)
{
_root = root;
}
public function accessRoot()
{
_root.box.visible = false;
}
}
Proper way:
public class A extends MovieClip
{
public static const ACCESS_ROOT:String = "access_root";
public function accessRoot()
{
dispatchEvent(new Event(ACCESS_ROOT));
}
}
// in your document class
var myA:A = new A();
myA.addEventListener(A.ACCESS_ROOT, handleAccessRoot);
public function handleAccessRoot(e:Event):void{
box.visible = false;
}
I normally create a sort of base class that holds a reference to the document class - or "main" class. Anything that I create from here that should need reference to anything defined in Main would extend Element. Example:
The Main class (or document class):
public class Main extends MovieClip
{
/**
* Constructor
*/
public function Main()
{
var obj:MyElement = new MyElement();
obj.main = this;
// stage will be outputted
}
}
Element - which stores reference to the main class.
It also contains an init() function which I generally use in place of a constructor by overriding it.
public class Element extends MovieClip
{
private var _main:Test;
public function set main(m:Main):void
{
_main = m;
init();
}
/**
* Called when _main is defined
*/
protected function init():void
{
// override me
}
public function get main():Main{ return _main; }
}
And here's how you would use Element as a base class for your classes:
public class ClassA extends Element
{
/**
* Override init rather than using a constructor
*/
override protected function init():void
{
trace(main.stage);
}
}
The only thing really to note is that you of course have to set the _main property whenever you create an object. (as shown on line 9 of Main).
I need to increment an integer variable in a function within the document class upon transpiring event in another class. I can't seem to figure out how to call the function and reference the variable.
as3 newbie, please help!
The proper scope needs to be in place and the proper packaging.
Declare a static variable to handle your access to the Main Document Class
private static var _instance:Main;
public static function get instance():Main { return _instance; }
public function Main() { // constructor
_instance = this;
}
Declare some getters and setters in the Main Document Class
private var _foo:int = 0;
public function get foo():int{
return _foo;
}
public function set foo(value:int):void {
_foo= value;
}
And then in any class you need you can change to something as follows,
public class O {
public function O() {
Main.instance.set(Main.instance.get() + 1);
}
}
simple example, defining a variable 'test' in the document class:
package {
public class DocumentClass extends Sprite {
public static var test:Number = 3;
public function DocumentClass() {
test = 4;
}
}
}
now access the 'test' variable in another class:
package {
public class OtherClass extends Sprite {
public function OtherClass() {
DocumentClass.test = 5;
}
}
}
does this apply to your code?