AS3 Accessing Variables of Parent Class From Child - actionscript-3

i'm trying to assign a parent's variable from the parent's child
//Parent
public class Main extends Sprite
{
public var selectedSquare:Sprite;
public function Main()
{
//inits and adds new Square child class to display list
}
...
-------
//Child
public function dragSquare(evt:MouseEvent):void
{
Sprite(parent).selectedSquare = this; //evil doesn't work!
parent.addChild(this);
this.startDrag();
}
i'm receiving this error, but i'm casting parent from displayObjectContainer to a Sprite so i have no idea why it's not working.
1119: Access of possibly undefined
property selectedSquare through a
reference with static type
flash.display:Sprite.

You should cast parent as a Main rather than a Sprite, since a Sprite won't have any references to a "selectedSquare". If Main were to extend MovieClip, this wouldn't be a problem, since MovieClips can have dynamically created references.
Proposed modification to child function:
public function dragSquare(evt:MouseEvent):void
{
(parent as Main).selectedSquare = this;
parent.addChild(this);
this.startDrag();
}

Another reason that this may not work is that you're attempting to use the parent property right before adding the child to the parent's display list.
Sprite(parent).selectedSquare = this;
parent.addChild(this);
That second line is what worries me. In this code, the current object (this) must already be added as a child to the parent object (Main) for the first line to work properly. So, either the current object is not yet a child of the parent object, in which case you need to revise your code.
Or, the second line is unnecessary (because this is already a child of Main, that's why this.parent, or just parent, works as expected).
I believe, though, that your code is probably set up well. You just don't need that second line, as it's completely redundant.
I hope that helps! Let me know if you want me to clarify anything.
(This is, of course, assuming you didn't already know all of this and aren't doing some sort of insane, arcane, weird magic with the redundant addChild call. You never can tell with magicians!)

Related

Is ES6 class extend fully equivalent to Object.assign based extending of an object?

In other words are these two different blocks of code fully equivalent?
ES6 class extend based
class Child extends Parent {
// Define my subclass
}
var myInstance = new Child();
Object.assign based
var myInstance = Object.assign(new Parent(), {
// Define my subclass
}
In my particular use case I am trying to extend (Facebook's) Flux Dispatcher. In their examples they use Object.assign. I would like to ES6 class extend, but I am worried that there are subtle differences between the two so I should stick with Object.assign.
No, these code blocks are not equivalent
In the class inheritance example you will get a new constructor which makes objects having features from parent class.
Extending objects via Object.assign is a example of mixins.
You just add some properties to one instance but not change all future children.
Unlike child classes, an instance after extension will still have the constructor property pointing to the Parent. It means that you can't recognize extended child among non-extended, because they all have the same constructor and operator instanceof will give the same result. Also you can't get access to overridden methods in child, because you will lose the link to it.
As for flux's dispatcher in this example, you can't extend it via class inheritance, because there is no constructor which you can provide as a parent.

Disable mouse event for a specific child of a movieclip

I've a MovieClip that contains lot of children.
One of them is a big (and useless) shadow the graphic designer put there to make my life harder (and also the user's one, probably)
:)
Now I'm facing a little issue: the shadow is catching the MouseEvents attached to the main MovieClip (its parent), and this is very bad because it's very distant from the rest of the graphic. I'm now trying to avoid it.
Obviously I've already tried to set the shadow mc's properties mouseEnabled and mouseChildren to false, but it doesn't work.
I've found a previous thread (here), facing the same situation. But the solution accepted looks like it's not working for me.
What I am missing?
If mouseEnabled and mouseChildren is not working for you then use e.target.name property.
But first you will have to give a name to that shadow MovieClip (say shadowMC).
If you added it dynamically then use,
yourDynamicMC.name = "shadowMC"
If added manually on the stage then give instance name as "shadowMC",
Then, inside your code where you have MouseEvent function for parent MovieClip add the following lines
if(e.target.name != "shadowMC")
{
//Then proceed
}
Reading your question, I am assuming you already tried to set the parent MovieClip's mouseChildren to true with mouseEnabled to false and then set the children's mouseEnabled to true (except for the shadow). This solution should work in my opinion so I am guessing the event might be caught by one parent of your movieclip (you do not give much information about this).
Try to add a listener to the stage to see which object is receiving your MouseEvents:
import flash.utils.getQualifiedClassName;
stage.addEventListener(MouseEvent.CLICK, onClick);
private function onClick(event:MouseEvent):void
{
trace(event.target.name, getQualifiedClassName(event.target));
}
Try changing the hit area of your MovieClip. see the MovieClip doc here, this will override you MovieClip zone.

addChild(Button) in AS3

I am writing a class that extends mx.core.UIComponent. In the constructor of this class, I would like to add a Button (spark.components.Button). However, creating a new Button object (such as var b:Button = new Button();) and then doing this.addChild(b) doesn't work -- no button is appearing. Is there any reason why a Button object can't be added as a child?
Edit: Just to add, when I print out the children, it says that the Button object is a child, but the Button doesn't show up.
You need to add the button in the createChildren method not in the constructor.
protected var button:Button;
override protected function createChildren():void {
super.createChildren();
button = new Button();
addChild(button);
}
Depending on what you are trying to do you may also need to implement the measure and updateDisplayList methods.
Using UIComponent directly, you aren't getting the layout of the child handled for you; you would need to set the position and size of your child components manually (see docs).
Consider using a Group (or Canvas, if you're still on MX components) to handle child layout. You can still add rendering in updateDisplayList, just make sure you call super.updateDisplayList() as well.
You need to read up on the differences between ActionScript components and Flex components. When using a Flex component, you must use container.addElement( element ), not container.addChild( child ). As far as I am aware, the only classes with this functionality descend from Group (at least in the Spark framework, the one I am most familiar with). So extending UIComponent will not allow you to add a Button, although a UIComponent can be added to a Flex container (which I do not believe a normal Sprite can do)

Children of Children of MovieClip not showing up when MovieClip is added to stage?

This problem seems very simple to me, but I've been unable to fix it, or find an answer anywhere.
This is in a class constructor for a class called block, block_maker is the object that called the constructor, an instance of level.
this.bitmap = new Bitmap(this.bitmap_data);
this.addChild(this.bitmap);
this.block_maker.stage_foreground.addChild(this);
In level, stage_foreground is added to the stage, but nothing appears. trace(stage_foreground.numChildren); shows the correct count of children, and var temp = (this.stage_foreground.getChildAt(0)); trace(temp.numChildren); correctly but the children OF the children don't actually show up, the stage just stays blank.
When I change the above code to
this.bitmap = new Bitmap(this.bitmap_data);
this.block_maker.stage_foreground.addChild(this.bitmap);
the blocks appear on the stage, as children of level_instance.stage_foreground, but with this method, the bitmaps aren't appropriately positioned, as they have no position data. I can simply give this.bitmap x and y positions, and it works, but I am curious as to why it won't work when just adding the bitmap as a child to the block and then adding that as a child to stage_foreground.
I've tried replacing this.bitmap with a number of other object classes, such as a temporary MovieClip I made, or a Shape, but nothing shows up, so I know it has nothing to do with it being a Bitmap.
As you stated
This is in a class constructor for a class called block, block_maker
is the object that called the constructor, an instance of level.
this.bitmap = new Bitmap(this.bitmap_data);
this.addChild(this.bitmap);
this.block_maker.stage_foreground.addChild(this);
The level class needs to to extend a display object for it to show up.
In other words
"this"
has to be a display object or extend it in some form.
The reason this doesn't work.
this.block_maker.stage_foreground.addChild(this);
and this does
this.block_maker.stage_foreground.addChild(this.bitmap);
Is because "this" is not a display object but "this.bitmap" is.
The DisplayObject class is the base class for all objects that can be placed on the display list.
First of all, even though it's not neccesary, I'd suggest to make a classname start with a capital letter, and vars always start with a lower-case letter. It's a common 'rule' in AS3 that's mainly to avoid confusion.
The problem most likely lies within you use of this; what you're doing is adding this into this. It seems to me it's not a proper way of coding.
Also, since all of the other attempts didn't work; have you tried to make the var you want ot add a public static var?

Movieclip stacking in Actionscript

I'm building a game of which the interface is one of the first items to load on screen. Sound button, pause and all the bits -
During the game - all manor of things are dynamically added and removed to the stage. Therefore my interface goes behind my game scene.
How do I ensure the movieclip always stays on top?
Can I override the addChild of my Document Class and every time a new child is added, I restack the interface to the top?
You can use setChildIndex to rearrange objects that are already contained within a MovieClip or Sprite. For example, if you have an object called container, which contains a redBall, blueBall and many other ball objects, you can use the following to make sure redBall is behind everything else:
container.setChildIndex(redBall, 0);
Equally you can make sure that blueBall will be displayed infront of everything else using:
container.setChildIndex(blueBall, container.numChildren-1);
addChildAt will sort you out for adding children straight into their correct position, and setChildIndex will allow you to re-position objects already placed. Hope that helps.
debu
Look into addChildAt, it allows you to specify the index that the new object should be added too.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObjectContainer.html#addChildAt%28%29
A good strategy is to keep all interface elements in one parent Sprite/MovieClip, and all game assets in another. (With the interface one on top)
With your guys suggestion I made this, apparently, if you addChild an object already on the screen, it's simply reindex'd to the top. Does this look ok?
private var topLevelChildrenArray:Array = [];
public function addTopLevelChild(child:DisplayObject):DisplayObject
{
topLevelChildrenArray.push(child)
return this.addChildAt( child, this.numChildren - 1 );
}
override public function addChild(child:DisplayObject):DisplayObject
{
this.addChildAt(child, this.numChildren);
for each(var topChild:DisplayObject in topLevelChildrenArray)
{
super.addChild(topChild);
}
return child
}