Reuse Instance Names for Different Objects - actionscript-3

Simple question: how can I reuse instance names for different objects (obviously on different frames)? I really want to be able to use the same instance name for all my scenes, "ground", even though these ground instances are of different classes. I really don't want to have to go about naming them "ground0", "ground1", etc.I realize that there are ways around this, but I would hate to fool around with all that extra work. So that being said, how do I reuse the instance name "ground" without having this warning thrown at me?:
Menu, Layer 'ground', Frame 1 Warning: The instance name 'ground' is declared on an object of type Ground but there is a conflicting use of the instance name 'ground' on an object of type Ground2.
And by the way, I realize that an instance is supposed to be an occurrence of a specific object, but to be honest I don't quite see the point in not being allowed to reuse instance names when appropriate. Any help would be much appreciated.

If I recall how finicky Flash was, it may have something to do with how you created the "ground" instance on those frames.
By that, I mean:
Did you create one instance first, and then created new keyframes afterwards (meaning: the same instance would be used in all keyframes), or...
Did you begin by creating your empty keyframes first, and then drag-dropping / pasting one "ground" instance in each frames? (meaning: in this case, it would likely be treated as 3 separate instances).
I'm not sure if this assumption is correct, but Flash doesn't necessarily tie instances to layers, as in "Oh, ground is on Layer 1, therefore every frames should reuse the same instance...". In a perfect world, I agree this would make sense. But from the early versions of Flash when it was mostly targeted to animators, where anything goes (from having multiple shapes and instances on the same frame, from re-arranging the depth of groups / instances on one frame/layer), it's still making the assumption that if you drag / copy an item from the library to the stage, it doesn't necessarily mean they are the same instance. Instead, you have to babysit Flash by creating more keyframes (or tween keyframes depending on your need) after the frame with the existing asset instance you want to reuse.
Again, the above is an assumption based on my experience - but if you did enter the "ground" instance-name manually for each instances found on each frames, chances are you previously copy/pasted or dragged new instances to those frames.
Does it sound like something you may have done?
EDIT:
If you have "ground" assets across a few frames, which are instances of different Symbols, then that definitely would trigger those Warnings you've been getting. I'm not sure where you can turn those off (Preferences? Project Publish settings? Advanced AS3 settings maybe?).. but regardless, here's a way that may work for you, programmatically.
Since each frames have a unique instance, with each instances named "ground", you could create a helper function to work like the .getChildByName("ground") method (and to be honest, I'm not sure if that method would work right-off the bat, you could try). You would need to for-loop through the given MovieClip's children (In your Menu's children, in your case I believe?), and check if(child.name==theNameInQuestion) return child;.
That being said, I can't guarantee this is THE proper solution (didn't test), as I don't know how you're navigating the frames at runtime (play/stop/gotoAndPlay/gotoAndStop/etc), and that may affect which "ground" instance is available at a given time. Internally, Flash does addChild/removeChild to swap out those various "ground" instances as it cycles through the frames, it's not a simple visible=true/false toggle (AFAIK).
EDIT 2:
This could be what you need?

If any programming language if you want to reuse instance name variables you simply type them with the top most superclass type. In your case that would be:
var ground:DisplayObject;
ground = new Ground!();
ground = new Ground2();
//etc ....
Edit: If using property panel you can't use the same name for 2 objects as there will be no way to differentiate between them. So an error will be correctly thrown.
Now if you want to use in code only one name same principle as shown above applies:
var ground:DisplayObject;
ground = ground0;
ground = ground1;
//etc ....
Then you can safely use in code the variable ground.

Related

What's the reason for interface to exist in Actionscript-3 and other languages

what is the meaning of this interfaces? even if we implement an interface on a class, we have to declare it's functionality again and again each time we implement it on a different class, so what is the reason of interfaces exist on as3 or any other languages which has interface.
Thank you
I basically agree with the answers posted so far, just had a bit to add.
First to answer the easy part, yes other languages have interfaces. Java comes to mind immediately but I'm pretty sure all OOP languages (C++, C#, etc.) include some mechanism for creating interfaces.
As stated by Jake, you can write interfaces as "contracts" for what will be fulfilled in order to separate work. To take a hypothetical say I'm working on A and you're working on C, and bob is working on B. If we define B' as an interface for B, we can quickly and relatively easily define B' (relative to defining B, the implementation), and all go on our way. I can assume that from A I can code to B', you can assume from C you can code to B', and when bob gets done with B we can just plug it in.
This comes to Jugg1es point. The ability to swap out a whole functional piece is made easier by "dependency injection" (if you don't know this phrase, please google it). This is the exact thing described, you create an interface that defines generally what something will do, say a database connector. For all database connectors, you want it to be able to connect to database, and run queries, so you might define an interface that says the classes must have a "connect()" method and a "doQuery(stringQuery)." Now lets say Bob writes the implementation for MySQL databases, now your client says well we just paid 200,000 for new servers and they'll run Microsoft SQL so to take advantage of that with your software all you'd need to do is swap out the database connector.
In real life, I have a friend who runs a meat packing/distribution company in Chicago. The company that makes their software/hardware setup for scanning packages and weighing things as they come in and out (inventory) is telling them they have to upgrade to a newer OS/Server and newer hardware to keep with the software. The software is not written in a modular way that allows them to maintain backwards compatibility. I've been in this boat before plenty of times, telling someone xyz needs to be upgraded to get abc functionality that will make doing my job 90% easier. Anyhow guess point being in the real world people don't always make use of these things and it can bite you in the ass.
Interfaces are vital to OOP, particularly when developing large applications. One example is if you needed a data layer that returns data on, say, Users. What if you eventually change how the data is obtained, say you started with XML web services data, but then switched to a flat file or something. If you created an interface for your data layer, you could create another class that implements it and make all the changes to the data layer without ever having to change the code in your application layer. I don't know if you're using Flex or Flash, but when using Flex, interfaces are very useful.
Interfaces are a way of defining functionality of a class. it might not make a whole lot of sense when you are working alone (especially starting out), but when you start working in a team it helps people understand how your code works and how to use the classes you wrote (while keeping your code encapsulated). That's the best way to think of them at an intermediate level in my opinion.
While the existing answers are pretty good, I think they miss the chief advantage of using Interfaces in ActionScript, which is that you can avoid compiling the implementation of that Interface into the Main Document Class.
For example, if you have an ISpaceShip Interface, you now have a choice to do several things to populate a variable typed to that Interface. You could load an external swf whose main Document Class implements ISpaceShip. Once the Loader's contentLoaderInfo's COMPLETE event fires, you cast the contentto ISpaceShip, and the implementation of that (whatever it is) is never compiled into your loading swf. This allows you to put real content in front of your users while the load process happens.
By the same token, you could have a timeline instance declared in the parent AS Class of type ISpaceShip with "Export for Actionscript in Frame N *un*checked. This will compile on the frame where it is first used, so you no longer need to account for this in your preloading time. Do this with enough things and suddenly you don't even need a preloader.
Another advantage of coding to Interfaces is if you're doing unit tests on your code, which you should unless your code is completely trivial. This enables you to make sure that the code is succeeding or failing on its own merits, not based on the merits of the collaborator, or where the collaborator isn't appropriate for a test. For example, if you have a controller that is designed to control a specific type of View, you're not going to want to instantiate the full view for the test, but only the functionality that makes a difference for the test.
If you don't have support in your work situation for writing tests, coding to interfaces helps make sure that your code will be testable once you get to the point where you can write tests.
The above answers are all very good, the only thing I'd add - and it might not be immediately clear in a language like AS3, where there are several untyped collection classes (Array, Object and Dictionary) and Object/dynamic classes - is that it's a means of grouping otherwise disparate objects by type.
A quick example:
Image you had a space shooter, where the player has missiles which lock-on to various targets. Suppose, for this purpose, you wanted any type of object which could be locked onto to have internal functions for registering this (aka an interface):
function lockOn():void;//Tells the object something's locked onto it
function getLockData():Object;//Returns information, position, heat, whatever etc
These targets could be anything, a series of totally unrelated classes - enemy, friend, powerup, health.
One solution would be to have them all to inherit from a base class which contained these methods - but Enemies and Health Pickups wouldn't logically share a common ancestor (and if you find yourself making bizarre inheritance chains to accomodate your needs then you should rethink your design!), and your missile will also need a reference to the object its locked onto:
var myTarget:Enemy;//This isn't going to work for the Powerup class!
or
var myTarget:Powerup;//This isn't going to work for the Enemy class!
...but if all lockable classes implement the ILockable interface, you can set this as the type reference:
var myTarget:ILockable;//This can be set as Enemy, Powerup, any class which implements ILockable!
..and have the functions above as the interface itself.
They're also handy when using the Vector class (the name may mislead you, it's just a typed array) - they run much faster than arrays, but only allow a single type of element - and again, an interface can be specified as type:
var lockTargets:Vector.<Enemy> = new Vector.<Enemy>();//New array of lockable objects
lockTargets[0] = new HealthPickup();//Compiler won't like this!
but this...
var lockTargets:Vector.<ILockable> = new Vector.<ILockable>();
lockTargets[0] = new HealthPickup();
lockTargets[1] = new Enemy();
Will, provided Enemy and HealthPickup implement ILockable, work just fine!

Where should these AS3 variables go?

I am trying to build the foundations for a platformer game in Actionscript 3. I'm still fairly novice at AS3, but I'm hoping this will help build my knowledge.
Anyway,
I understand that I can create Actionscript files that are associated with something such as a Sprite or a MovieClip by extending the Sprite/Movieclip class. I also know about Actionscript files that work as the 'Document class'.
Each level in my game will have different properties that vary such as gravity. Where should I store these variables? Obviously not in the player... Not sure if they're supposed to go in the timeline or the document class, or if they have a separate AS file of their own. I've been told that having global variables is generally bad, so I'm not sure what to do.
You can make levels as separate files that are even not Actionscript, but XML or JSON, since your levels are basically data structures with different starting values. And you can make a Level class that can take such a file, parse it and initialize an in-game level structure based on what's read. Yes, such data should not go to timeline, because should you need to change one piece of that data, it could implicitly affect other game processes. Also, one simple right click can ruin such a game :) I myself use JSON files as my level data holders, and I parse them at the initialization time, you can do like this or say when your level is being loaded.
In short, if something is different by initial data, but common in methods, it should reside separately from main code, or entire code, and be included as data.
I think this similar question and answers will help you somewhat:
As3 OOP game structure (class architecture)
Basically, "What you want to do is to separate what changes in your game from the game itself". So definitely do not include the code in the timeline.

Flash CS3 - how to clean memory

I have a question how can I clear/free memory in flash? For example I am finishing game and I want to start from beginning and if I will just jump to the first frame all the objects there are still in this memory, is any possibility to force cleaning memory?
Can I free memory for an object? for example I removeChild(something) - and I want to free memory for an object as I will reuse it?
Can anybody explain me how the engine works?
Thanks
I would encourage you to read Chapter 14, Garbage Collection in the "Moock Book" (Essential ActionScript 3.0 by O'Reilly Publishing).
The short answer to your question is that you're not in control of de-allocation, the garbage collector is. In a garbage-collected language like AS3 or Java, you don't have manual control over allocation and de-allocation of memory like you do in lower level languages; there are no AS3 equivalents to things like delete in C++ or free in C. Your goal should not be controlling when you destroy things, but rather not forgetting to remove references to things you no longer need around and making sure you disable things that you intend for garbage collection.
Memory leaks in AS3 typically come from a mixture of newbie misunderstanding (like thinking removeChild or setting a reference to null destroys objects), and from not keeping good track of references to objects--especially where strong listeners are involved.
A previous respondent posted this:
myObject = null;
What this does is remove a reference to the object that the variable myObject was holding. Nothing more. You need to know a lot more about the situation in order to be able to say whether this assignment even makes the object in question eligible for garbage collection, especially how many other variable are holding references to the object. And the object might already be eligible for garbage collection even if you didn't set the reference to null (i.e. if myObject has no connection to a GC root).
Suffice to say, the entire GC mechanism is more complex than can be satisfactorily explained in a StackOverflow post. That's why it has a whole chapter in the Moock Book, and even that book does not go into implemenation detail or great detail about when exactly the Flash Player does its ref counting deletions or mark and sweep passes.
The most important things to remember are, IMHO:
When you intend to "kill" an object, give it a cleanUp() or destroy() function where you do things like stop all its timers, sounds, remove listeners, etc. An object will continue to exist and execute code until it gets GC'd. And the Flash Player defers GC as long as it can--it's usually triggered when the Player needs to allocate more RAM from your system, because allocating memory is about the only thing that's more time consuming than doing the mark and sweep GC pass.
Read about weak vs strong listeners. Basically, when you have a weak listener, the listener reference is one that is ignored by mark-and-sweep GC, so it alone will not prevent an object from getting collected. But don't listen to anyone who tells you "always use weak" or "always use strong listeners and manually remove them" because there are times where each is appropriate, and that's why the choice is yours.
removeChild() will remove object from stage, but will still keep it in memory. You will have to null the object like this myObject = null if you wish to get rid of it entirely. You might not need to do that thought. Just removing it from stage and removing all associated events will be sufficient in most cases.
Clearing memory is a tricky thing with Flash, the proper way ow implementing it setting up objects properly in the first play for easy clearing, rather than forcing deletion. When you want to remove an object from memory, you do it by removing any reference to it, and then flash marks it for garbage collection. Then Flash at a later point removes the object from memory.
In order for the object to be ready for data collection it cannot have any connection to another object.
so if you have an object that has a single connection to a MovieClip and the movie clip has no other relation, then if you set it to null, you will remove it.
if you, however, have two objects that point to it, if you remove one link by setting it to null, the MovieClip will not be removed.
furhtermore, if you have a 2 or more movie clips that have a network of connections, removing those objects requires these connections be broken as-well. For example if you have a level with many characters and listeners set up, removing the lavel movieClip will not clear it.
one way of breaking these connections is adding onRemovedFromStage Events, that remove further children, listeners and objects. I've started using the casaLib extension of movieclip - CasaMovieClip, that has a function called removeChildrenAndDestroy. this makes it a bit easier, but would take a while to implement on an older project.
Anyhow, you'll find there are many sites discussing this, a good place to start is grant skinner's blog

How should I substitute an image in a larger animation using AS3?

We're making a Flash browser game with a few reasonably complex animations. Our designer is making the animations in Flash Professional while I'm wiring everything up and adding some logic through AS3 (using FlashDevelop).
In one of our more complex animations a "bonus item" moves around the screen. It tweens hither and tither, there special effects and as such, it disappears for a few frames and then reappears later.
From AS3 we want to be able to dynamically decide which bonus item (say a mushroom or a star) to include in the animation. We don't want to have to ask our designer to replicate the entire animation for each of our bonus items.
This is what we've tried:
Created a two frame (1 mushroom frame, 1 star frame) "BonusItem" movieclip in FlashPro and Exported for ActionScript.
Created the complex animation movieclip in FlashPro and added the BonusItem movieclip to the relevant frames. Gave the BonusItem instance an instance name on all necessary KeyFrames. Exported entire movieclip for ActionScript (exported as "ComplexAnimation").
Intention:
The intention was to be able to do this:
var complexAnimation:ComplexAnimation = new ComplexAnimation();
complexAnimation.bonusItem.gotoAndStop("star"); // Frame labels have been added in FlashPRo.
this.addChild(complexAnimation);
This would play the complex animation with the star and we could easily call gotoAndStop("mushroom") to play the same animation with the mushroom.
Problems:
The first problem was that complexAnimation.bonusItem was null on line 02 above. I solved this by handling ADDED_TO_STAGE for complexAnimation and putting line 02 above in the handler.
The next problem was that each time the bonusItem movieclip started tweening, or if it was not present in some frames and was subsequently re-added the complexAnimation.bonusItem attribute/reference was reassigned to a new bonusItem instance. I then had to find a way to know when this was happening and call gotoAndStop("star") on the new instance.
I've found two ways to do this:
1) Listen for ADDED events on complexAnimation with a target.name of "bonusItem". It's a bit crap in a strongly typed language to have to resort to matching strings, but this works. Btw, when the ADDED event is fired new frame object references are still null.
2) Listen for FRAME_CREATED events. This happens later than ADDED at a point where new frame references have been initialized. As such I can check if complexAnimation.bonusItem is non-null at then call gotoAndStop("star") on it. One problem with this is that calling gotoAndStop actually triggers another FRAME_CREATED event to fire, so I need to guard against infinite looping. Again, it works but I don't have a great feeling about it.
Conclusion:
Well I don't really have a conclusion other than I feel like I'm working really hard to do something relatively simple. I'm hoping there's an easier & more robust approach. I have a strong feeling that I'm going crazy. Anyone know a better way to do this?
If you have an object that exists on a timeline and it has an instance name, and you need to be able to maintain a reference to it through the duration of the timeline, then it must exist on every frame (and in the same layer!) of the movieclip. I grant you, your workarounds get the job done but you have already experienced the pain involved in doing so.
The path of least resistance is to just have the object exist at all times. If the user shouldn't "see" it, just hide it offscreen somewhere. Just make sure it always exists, contiguously, on that timeline layer from frame 1 all the way to the final frame.
The other thing I'd suggest is to stop deeply nesting movieclips in the hopes of using those nested clips as state representations. This is one of the things that sadly was very easy to do in the AS2 days, but has been rendered impractical to the point of madness in AS3. Anything deeper than 1 layer is getting into some dicey territory. 3 layers deep and you need to rethink your strategy. Perhaps instantiating different movieclip instances from the library and adding/removing dynamically instead of relying on frames.
I thought I'd update this post with our current (and hopefully long-term) solution.
First of all, I made an error in the above post:
The next problem was that each time the bonusItem movieclip started tweening ... the complexAnimation.bonusItem attribute/reference was reassigned to a new bonusItem instance.
This was incorrect. Flash was indeed assigning a new instance of BonusItem, but it was caused by a Mask layer keyframe rather than the tween.
I had been keen to try to avoid having any logic which relied on string comparisons, but in the end I swallowed my pride to make life easier.
Our designer gives all relevant objects (stuff that we'll need to access from AS3) instance names on each keyframe in the timeline. If the object is nested within other objects our designer must assign those parent objects instance names too. We must coordinate those instance names so that dev know what the accessors are called - we would've had to do all this anyway. Our designer also still has to "Export For Actionscript" a class for each relevant movieclip (e.g. BonusItem).
In AS3 we're using Robotlegs for dependency injection and as the basis of our MVC framework. Robotlegs suggests that application-specific logic should be separated from view-specific logic. It allows us to specify a logic class (called a Mediator) to be associated with each and any of our views. As such we can do the following mapping:
BonusItem -> BonusItemMediator
This means that every time Flash creates a BonusItem on the timeline Robotlegs somehow knows about it and creates a new instance of BonusItemMediator (which we write ourselves and have full control over). In addition, Robotlegs can easily give us a reference from our BonusItemMediator to its associated view instance (the BonusItem instance). So inside my BonusItemMediator I can ask the view reference what its instance name is. I also walk up its parents to the stage and record each of their names to generate a resultant string of instance names that uniquely specified this instance of the BonusItem.
e.g.
"game.complexAnimation.bonusItem"
Once I know this I can ensure that the bonusItem is showing the correct image (star or mushroom) with the following code:
var frameLabelName:String myGameModel.whatTheHellShouldThisBeShowing("game.complexAnimation.bonusItem");
this.view.gotoAndStop(frameLabelName); // where view is the BonusItem instance
So now regardless of how or when Flash seemingly randomly decides to destroy and recreate my bonusItem I'll hear about it and can ensure that that new BonusItem instance is displaying on the correct frame.
The main weakness with this solution is that we're relying on string comparisons. Our designer could easily mistype an instance name and we wouldn't hear about it until that code was hit at runtime. Of course tests mitigate that risk, but I still feel that it's a shame that I'm using a strongly typed language, but then not making use of the compile time type checking.

AS3: Faster to use EventListeners or ArrayLoops?

I am writing a game in AS3 and have, as an example, around 40 objects on screen. Let's say they are clouds. I'm wondering which of the two paths would be less a strain on system resources:
a) Put an eventListener on each object and have it update itself, or
b) Loop through the array and manually update each object
Or is the performance difference negligable? Does either solution scale better than the others?
I would expect the performance to be fairly negligable either way. Once you get a lot of objects you might see a difference (with the loop being the winner). From my experience Adobe put a lot of work into optimizing the actionscript event listener path.
This is a tricky one, purists would say to to go with the array looping method, as with this method it would be possible to cut out the 'view' out of the MVC and still have the system working (which is a good test of any system). However, if you are working with the events you can cut some corners with event bubbling and strict typing.
For example if we assume you make a custom event called CloudEvent that has a property called cloud that contains a reference to the dispatching CloudSprite, then as long as the event bubbles by default, you don't need to add an event listener to each one, just to the DisplayObjectContainer which holds them (which I am imaginatively calling CloudContainer). This way the event bubbles up and you only have to add one listener, and don't have to worry about managing listeners on child items.
public function CloudContainer()
{
super();
addEventListener(CloudEvent.CHANGE, cloudChangeHandler);
}
private function cloudChangeHandler(evt:CloudEvent):void
{
var cloud:CloudSprite = evt.cloud;
cloud.update();
}
Hope this helps
I am under the impression that event listeners require more resources so it is better to use an array when performance is required. It would also scale better for that reason. If you are using Flash 10 then use a Vector, I believe it offers better performance than an array (and type saftey).
Use EventListeners! Just make sure you manage them properly ie. remove them when you done, use weak references.
You wont really find much performance from doing things like this. Usually better performance comes from the bigger ticked items, like not using filters, lowering the frame-rate etc. So punishing your code clarity and OO for the sake of a half a millisecond is not worth it in my book.
There are a few really great guides out there that will teach you all about optimizing in AS3. The best one I have found is Grant Skinner's; AS3 Resource Management. And I just found a quicker seven step version. I would definitely recommend everyone doing AS3 should read the Grant Skinner slides though.
Of course don't just take my word (or anyone else answering your question), you can do you own tests and actually see whats up using a profiler. See Lee Brimlow's latest video tutorial for how to do this. It is worth the watch! Check it out here: GotoAndLearn - ActionScript 3 Performance Testing.