AS3: SetChildIndex not working - actionscript-3

I'm working with the QuickBox2D library, and I'm trying to move one object to the bottom of the stage.
But it's not working, QuickBox2D doesn't seem to recognize it.
Call to a possibly undefined method setChildIndex through a reference with static type com.actionsnippet.qbox:QuickBox2D.
Object:
var gameBall:QuickObject;
ChildIndex
sim.setChildIndex(gameBall, 0);

The QuickBox2D class inherits from EventDispatcher, not DisplayObjectContainer where setChildIndex is defined. I don't see a way to handle z-indicies in the QuickBox2D system, which actually makes sense to me because objects shouldn't overlap in a physical system.

Let's have a look at setChildIndex()
It's a method defined by DisplayObjectContainer.
Its first argument must be of type DisplayObject.
Currently, you're trying to:
Call setChildIndex() from an instance of QuickBox2D (not a DisplayObjectContainer).
Pass another instance of QuickBox2D as the first agument (which needs to be a DisplayObject).

Related

Targeting event.target instance name and not object

I have a drag and drop SWF I created and am now trying to implement a new function where I need to pass the instance and x/y coordinates to a different function outside of the startDrag and stopDrag functions. I'm trying to target the instance name by setting up a variable and storing the event.target in in the startDrag function.
However, the issue is that when I run a trace on that variable, it doesn't return the instance name. For example, I have a movieclip with an instance name of myClip1. Yet, when I run a trace on the variable, the console reports it as [object myClip1_1].
How can I instead pass the actual instance to the variable so I can use with the external function?
Update: I figured out why I was getting "object myClip1_1" as the output: somehow AS Linkage in the library got turned on. I've disabled that, but now, when I run a trace on event.target and event.currentTarget, I just get "[output MovieClip]" and not the instance name. What gives?
just add .name to event.target:
event.target.name
EDIT:
You shouldn't need the instance name to connect to the object that is being dragged. just say in the startDrag function:
currentDragObject = event.target.
currentDragObject is defined at the global scope:
var currentDragObject:MovieClip;
In this manner, currentDragObject will always be reset to the object being dragged.

How to add a MovieClip from the library to the stage programmatically?

I am wondering how to add a MovieClip from the library onto the stage programmatically.
How would I go about doing this?
Symbols within Flash may define ActionScript Linkage.
AS Linkage may be set by right-clicking a symbol from the library and selecting Properties...
Check Export for ActionScript and enter a Class name.
If you don't need to explicitly define a base class beyond the symbol type, you can enter AS Linkage directly from the Library:
This creates a class definition no different than if you had written an ActionScript class.
Create instances by instantiating new instances of your AS Linkage type:
var symbolExample:SymbolExample = new SymbolExample();
addChild(symbolExample);
You will essentially be creating a "class" for your movieclip. Do what James suggests above... But when calling it into your program you will have to execute something like this:
//instantiate your object
var movieClip:MovieClip = new MovieClip;
//add it to the stage
addChild(movieClip);
//object will default to x=0 , y=0 so you can define that as well
movieClip.x=100;
movieClip.y=100;
//and so on...
movieClip is whatever you want... but MovieClip is the name you assign the class in the properties dialog. These var/class relationships are typically case sensitive so follow this formula for anything you create in your library.
There are many different ways to call and remove your objects, and it can get simpler or more complicated depending on what you intend to do with your object. For instance, you can tell the object which layer to occupy with:
addChildAt(movieClip, 1);
this adds movieClip to layer 1 or the layer just above the bottom-most layer.
Hope this helps...
You create your movieclip via any method you want, then when it is in the library you right click and select Properties, check the box Export for Actionscript, choose a class name and export in frame 1. Then whenever you want to add it you add it as you would any other object. I'm sure someone else will have a more detailed explanation after me, this is the general idea.

Flash/AS3: How do I access <Instance Name> object from the Document class?

In Flash CS4, I can give an object in my timeline an instance name via the properties pannel. I figured this variable would be available to me in my Document class, but when I try to access it, it's null.
How can I get access to these instance from within my Document class? Also, do the objects have to be in the timeline at frame 1 in order to be available to my Document class's constructor?
The constructor is always the first thing called on an object, it is used to get the memory necessary to store all the properties for that object type. After an object is constructed then (assuming it's a display object) at some point it's added to the stage. If an instance of one of your objects is added to the stage on a frame then the main document class will have to know when that object was added to the stage to appropriately access it. You could create the instance of the object within your document class constructor then when added to stage fires on your main class you could add the instance.
Just attempted this wasn't able to reproduce the OPs initial behavior, I'm able to access the instance that is added on frame 1, posted some examples here:
http://www.shaunhusain.com/TestHandleOnInstance/TestHandleOnInstance.as
http://www.shaunhusain.com/TestHandleOnInstance/TestHandleOnInstance.swf
http://www.shaunhusain.com/TestHandleOnInstance/TestHandleOnInstance.fla

Calling MovieClip(root) from a dynamic MovieClip instance produces error 1034

NINJA EDIT:
For some reason, the same code works now, without any problem at all. I don't know what happened, or why, but I no longer have this problem
Here's the original post:
To put simply, I created a MovieClip, put it with addChild() to stage, and when I tried to call this piece of code:
MovieClip(root).someFunction();
It throws Error #1034: Type Coercion failed: cannot convert flash.display::Stage#4034f71 to flash.display.MovieClip.
I really can't figure out why this piece of code won't work. The object itself works perfectly, as I can call functions within it (that line of code is actually within a function). It's just that piece of code that is problematic
Can someone tell me where I went wrong?
EDIT:
To better illustrate the situation, here's my pieces of code:
in a MovieClip, I have this function:
function bombReset():void
{
bBombIsDropped = false;
tCarpetBombTween.gotoAndStop(0);
this.visible = false;
MovieClip(root).carpetBombAttack(iPosition);
}
And on Scene1(root, the outermost parent) I have this function:
function carpetBombAttack(position:int):void
{
damagePlant(15,vTileOccupant[(position-1)]);
}
If I create a MovieClip instance via addChild and call bombReset in it, Flash will throw an error
If I manually drag the MovieClip onto stage, when I call bombReset, it will work fine
Your error means that the compiler doesn't know how a MovieClip and a Stage can be the same thing. Also, I'm not certain, but I believe the compiler will whine about someFunction not existing on the stage even if you casted the stage (aka root) correctly.
The proper way to solve this is by assigning a document class to your project and make someFunction a public method (class function).
The lay-mans solution (which I sometimes use when I'm being lazy) is the following
Object(this.stage).someFunction();
That works because you are type-casting this.stage in a way that makes the compiler think it's an Object instead of a Stage. Objects can have any number of undocumented properties and functions, thus allowing you to call items on the Object whether they are part of a class definition or not (and even ones that don't exist - which is where you can get yourself into trouble).
The inheritance for Stage is Stage -> DisplayObjectContainer -> InteractiveObject -> ... while MovieClip is MovieClip -> Sprite -> DisplayObjectContainer -> InteractiveObject -> ... (I'd link directly to the docs but the pages keep crashing on me).
While they share common base classes, the Stage and MovieClip classes aren't actually related, so trying to cast one as the other will fail.
As you're doing the MovieClip(root) type cast and not the root as MovieClip cast, that's why you're getting the error you're getting.
Either cast it directly to the object that has the someFunction() defined, use the solution defined by Jackson, or if you absolutely know it's there, you can also do root["someFunction"]()

AS3: Major Slowdown

I'm working on a Flash game, and after running my game for a while there is a huge drop in frame rate. There aren't a lot of MovieClips onscreen at once, but MovieClips are being replaced using removeChild and addChild often.
How can one test for problems such as memory leaks? And what are some good AS3 programming standards on this matter?
It seems like you're not preparing your instances of MovieClip for garbage collection. This thread could be extremely helpful to you.
Some of the basic things you want to cover when discarding a MovieClip (or any other Object) properly are:
Remove the object from the DisplayList (if it's a DisplayObject). This is done via what you're doing already, removeChild()
Remove any event listeners that have been applied to the Object. Best thing to do is keep on top of this right from the beginning; by that I mean, when you call addEventListener(), be sure to somewhere in the very near future add a sister removeEventListener() as well.
Remove reference to your Object. This includes, but is not limited to: reference to the Object via being part of an Array/Vector, reference via being stored in a property of another Object, etc.
A suggestion that I can offer is to have in the base class of your objects a method that handles all of this, eg remove() or deconstruct().
Here's an example:
public function deconstruct():void
{
if(parent)
parent.removeChild(this);
removeEventListener(MouseEvent.CLICK, _onClick);
}
And when you extend this class and need other dereferencing features, just build on your deconstruct() method:
override public function deconstruct():void
{
removeEventListener(MouseEvent.MOUSE_OVER, _mouseOver);
var i:int = someArray.indexOf(this);
someArray.splice(i, 1);
super.deconstruct();
}
http://gskinner.com/talks/resource-management/