Actionscript 3.0 - Get variable from superclass to new object - actionscript-3

How do I do this?
public class SuperClass extends MovieClip {
public static var test:String = 'Hello world';
}
public class SubClass extends SuperClass {
public function SubClass() {
var unit = new Unit();
addChild(Unit);
}
}
public class Unit extends MovieClip {
public function Unit() {
//Get variable:test from SuperClass??
trace(SubClass.test); //Error
}
}
Hope you understand what I want to do?
Want to get the variable 'test' from the SuperClass in my new Unit added in SubClass.
Thanks!

In this case your class named SubClass uses the Unit class through composition, not inheritance. As such the Unit class knows nothing about SubClass or SuperClass or any of their properties like the test property.
You can, however, pass a value into the Unit class through it's constructor (or just set a value directly onto a property of the Unit class):
(showing the last two classes only)
public class SubClass extends SuperClass {
public function SubClass() {
var unit = new Unit(test);
addChild(Unit);
}
}
public class Unit extends MovieClip {
private var test:String;
public function Unit(test:String) {
this.test = test;
}
}
[Edit]
Since your Unit class needs to access many properties of SubClass (and/or SuperClass), you might want to just pass an instance of SubClass to Unit:
public class SubClass extends SuperClass {
public function SubClass() {
var unit = new Unit(this);
addChild(Unit);
}
}
public class Unit extends MovieClip {
private var subClass:SubClass;
public function Unit(subClass:SubClass) {
this.subClass = subClass;
trace(subClass.text);
}
}
How you actually solve this depends on your use case. But there is no fundamental shortcut to do what you are asking.

Related

ActionScript 3.0 class extends

SCENARIO:
I have the class characterObject and n class that extends (cat, dog, bird, n...)
public class characterObject
{
public static var totalCounter:int;
}
public class cat extends characterObject
public class dog extends characterObject
public class bird extends characterObject
Is it possible for the extended classes to listen to changes to static variables (eg totalCounter) in the main class with or without events?
This is possible using a combination of getter/setter functions and events.
Getters and Setters, in actionscript, are functions that can be accessed like variables, giving you the ability to execute functions on variable changes.
public class characterObject
{
private static var _totalCounter:int;
protected static var internalDispatcher:EventDispatcher = new EventDispatcher();
public static function get totalCounter():int
{
return _totalCounter;
}
public static function set totalCounter(value:int):void
{
_totalCounter = value;
var event:Event = new Event("totalCounterChanged");
internalDispatcher.dispatchEvent(event);
}
}
As you can see we have a protected static event dispatcher called internalDispatcher, we can listen to events from this object only if we have extended the characterObject class. By hiding the true totalCounter behind the getter/setter we can dispatch an event whenever something changes it's value.
We can then listen for this event in our extended classes:
public class cat extends characterObject
{
public function cat()
{
super();
internalDispatcher.addEventListener("totalCounterChanged",totalChangedHandler);
}
public function totalChangedHandler(event:Event):void
{
//Your code here;
}
}
Depending on your requirements it maybe better to have your Event Handlers be static also to reduce the same code being executed multiple times without a change in output.

AS3: Call function from one class to another

So i have two Class's Class A and Class B.
I have a function that i wish to use on Class A but my flash fla file is linked to Class B
So I have done the following:
Class A - the function
public function Fb_Checks()
{
// constructor code
load_top_bar();
}
Class B - import
import ClassA;
then if i try to call the function in Class A from Class B:
Fb_Checks();
I get the following error:
Call to a possibly undefined method Fb_Checks.
Is there something more i should be doing to get this to work?
You need to get more info about the OOP. How it is working then it will be easier to understand concepts.
For now simple explanation: We have ClassA, ClassB and ClassC:
ClassA
{
var value:ClassB;
public function ClassA ()
{
// each variable needs to initialize unless it is the ClassC, see below
// Only after that you will be able to reach the public properties
// of the class.
value = new ClassB();
value.calculate();
}
}
ClassB
{
var value:Number;
public function ClassB ()
{
}
public function calculate():void
{
// these must be statis
ClassC.sum(150, 450);
}
}
ClassC
{
// if the function is static, then you can call it without initializing
// the class
static public function sum(value1:Number, value2:Number):Number
{
return value1 + value2;
}
}
You'll have to make an instance of ClassA before you can call its public functions.
package
{
import ClassA;
public class ClassB
{
public function ClassB()
{
var instanceOfA:ClassA = new ClassA();
instanceOfA.Fb_Checks();
}
}
}
If you want to make it work like your example you should extend your ClassB with the ClassA. In that case it's public and protected functions are available in ClassB as well.
package
{
import ClassA;
public class ClassB extends ClassA
{
public function ClassB()
{
Fb_Checks();
}
}
}

Interface that is also a Display Object

I have some classes that implement an interface, but also extend the Sprite class:
package {
public interface IState {
function addMonster():void;
}
}
package {
public class Fuzzy extends Sprite implements IState {
public function addMonster():void {
}
}
}
package {
public class LizardSkin extends Sprite implements IState {
public function addMonster():void {
}
}
}
// Document class
package {
public class Main extends MovieClip {
private var state:IState;
public function Main():void {
state = new Fuzzy();
addChild(state);
}
}
}
When I try to addChild(state) I keep getting an error message 1067: Implicit coercion of a value of type IState to an unrelated type flash.display:DisplayObject.
Now I know I've seen examples where a class extends MovieClip / Sprite and implements an interface...what can I do to make it so I can add "state" to the stage but also implement the methods I want??
A simple cast should do it most of the time:
addChild(state as DisplayObject);
The compiler raises that error otherwise because it doesn't assume IState is always implemented by something that is a DisplayObject, but if you can guarantee that condition you can always cast.
What I do in situations like this is use an IDisplayable interface, that looks like this:
public interface IDisplayable
{
function get displayObject():DisplayObject;
}
and its implementation in a Sprite or MovieClip simply looks like this:
public function get displayObject():DisplayObject
{
return this;
}
Your IState objects could then be added to the stage using addChild(state.displayObject);, when your IState interface extends IDisplayable.

AS3 override public function both are called?

I am a little confused by this concept.
If I override a public function in a base class, I would have thought that this override function is called and the original is ignored? though this doesn't seem to be the case...
public class AbstractScreen extends Sprite
{
public function AbstractScreen()
{
}
public function updateLanguage():void
{
trace("WARNING: need to override public function updateLanguage()");
}
}
public class Start extends AbstractScreen
{
override public function updateLanguage():void
{
title.text = _model.language.start
title.setTextFormat(titleFormat);
}
}
public class ViewManager extends Sprite
{
private var _model:Model;
private var _screens:Array;
public function ViewManager(model:Model)
{
_model = model;
_model.addEventListener(AppEvent.INIT_VIEW, initViews);
_model.addEventListener(AppEvent.UPDATE_VIEW, updateView);
_model.addEventListener(AppEvent.CHANGED_LANGUAGE, changeLanguage);
}
private function initViews(e:AppEvent):void
{
trace("View Manager: initViews");
_screens = new Array(new Start(_model), new TakePhoto(_model));
dispatchEvent(new ViewEvent(ViewEvent.VIEW_READY));
}
private function changeLanguage(e:AppEvent):void
{
for each (var screen:AbstractScreen in _screens)
{
screen.updateLanguage();
}
}
}
If my model dispatches a CHANGED_LANGUAGE event, the text in the views gets updated, But I also get a trace of "WARNING: need to override public function updateLanguage()" What could I be doing wrong?
You are right, this should not call the base class function. Are you sure there is no call to
super.initLanguage()
within your override?
Most IDE's add this call in the function body automatically, if they create an override for you.
EDIT
From your edit I see your are iterating over two objects of the types Start and TakePhoto. I assume TakePhoto is also derived from AbstractScreen and the trace may be comming from this one.
Also I suggest to use the abstract base class in your iteration.
for each (var screen:AbstractScreen in _screens)
{
screen.updateLanguage();
}

Can Objects not on display-list access root or any object that is added on displaylist?

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).