How do I apply different classes to different frames in flash CS5? - actionscript-3

I am coding in actionscript 3 and need some help with classes. I want the first frame to have its own class/package and I want the other frames to share another class/package. How do I do this?

Don't. It is neither a clean nor a recommendable way to organize ActionScript code in your project. Use classes and packages the way they were intended: for object-oriented programming. In fact, you should use frame actions only if you have minor tasks to do, especially controlling the timeline (stop(); and such), or to create or remove objects at a point in time.
If you want your frames to spawn new behavior, create and/or remove class instances on the stage instead - they can be transparent or fill the entire stage, so they will not be noticed by users, but your program will have proper encapsulation. You can attach a Class to each MovieClip in your library, so you can put one in each frame of your timeline, and you can even edit the timeline of that MovieClip, if you want to.
Whichever you decide, you should read up on object-oriented programming in ActionScript here.

The timeline is, at the end of the day, a sub-class of a MovieClip. Each frame is a frame of that MovieClip, so you cannot associated a class with each frame. You could use a single class and use the "undocumented" addFrameScript to associate a method with each frame. Better yet, I'd probably just add a new MovieClip to each frame with its own unique subclass. So frame1's BaseClass would be Frame1MovieClip.as and frame2's BaseClass would be Frame2MovieClip.as. If you want the frames to share a class, just extend that frame across the number of frames you want.
1 2 3 4 5
layer2 [o]
layer1 [o ]
So "layer2" would contain a MovieClip with Frame1MovieClip.as as the BaseClass and layer 1 would have a different BaseClass.

Related

Flash / pure AS3 preloader is seen after game is 100% loaded

first of all I want to tell that I know there are hundreds of similar questions, but most of them are for projects/games which are built for "on stage development".
I'm using pure as3 approach to develop games. I don't use*main timeline and my project has only 1 frame*.
On my main class's constructor, I only add preloader to the stage.
But still my preloader is seen only when the game is completely loaded.
My question is simple: "Why?" and "How can I fix this?"
-When I try to "uncheck" export as3 on frame 1, flash gives error.(because some of my classes are imported on the main class.)
-Even if I create second frame and put every contents of the game except preloader, the problem is still unsolved.
Thank you very much for spending your time to read this and help me.
-Ozan
To make the preloader, you either need two SWFs or at least two frames. Even FlashDevelop has an ability to use two frames, for this the directive [frame factoryClass="ClassName"] is used in main AS file before public class Main. This is the core limitation of Flash player, that is, it first loads the first frame, and only then it can display that frame. Since you've said you have only one frame, then your game has to be loaded 100% (1/1 frames) before you will see a thing.
There's more - if you are referencing a certain class on frame 1 via its class name, the class with all its dependencies is embedded in the same frame (the first), so you're screwed again. To bypass this, execute stepos 10 through 14 from this instruction to set the frame for classes to be 2 (replace 10 for 2 while executing the instruction), clear "export in the first frame" for all classes except your preloader, and add an instance of game's main class to keyframe 2. Then in preloader code perform proper cleanup and do gotoAndStop(2).

as3 how can i prevent that a new instance is created by entering a frame?

i am working with several nested movieclip objects in a project. but i get into trouble with the buttons i created and implemented in the nested movieclips:
to describe it in a simple way:
I have a main movieclip with five frames, including two buttons with listeners to browse between the frames. Then inside of one Frame I have another movieclip with its own buttons. i instanciated it by hand not through code and gave it a specific name like "nestedMc".
Now I dont want to build the Listeners for those buttons inside the class of the nested movieclip class but in its parent class, which works fine until i then goto another frame in the main movieclips timeline and come back.
obviously every time flash enters a frame its contents get created anew (and therefore get new instance names). I could now try solve this through filling the frames via code.
But maybe there is another way to make sure the frame contains the same instance everytime i enter?
Timeline scripting is a dirty business, and really, a carry-over compatibility layer for Actionscript 2 projects. Whenever possible, I highly recommend not doing it, and simply keeping all of your code in your document class. As you're experiencing, timeline code causes headaches.
Consider instead just creating both states of your Stage (it sounds like that's what your two buttons are jumping between) and simply hiding them offstage or setting their alpha to zero and their mouseEnabled state to false. Furthermore, if the purpose of your frames is to play animation (a tween), consider instead switching to a much more powerful suite such as TweenLite. Moving an object over a hundred pixels (smoothly) can be as easy as:
TweenLite.to(redBall, 3, {x:100});
Now, if you're manually adding these items to the stage, as long as the object is a dynamic one, you can assign an instance name to it which will be saved between frame loads. Be aware the object name is not the same as the instanced name. For example:
var redBall:Ball = new Ball();
redBall.name = "bubbles";
The object's name is Ball, but it's represented as a variable called redBall. Its actual DisplayList name will likely be ambiguous (such as "Instance71"), and I can manually define it as "bubbles". 3 different names for the same object, all very different and necessary.
Even if you give the object a displayList name, you may not be able to reference it through code unless you enable Automatically declare stage instances, which basically creates on each object a pointer to the displayList object.
That said, you can always fetch the object by other means. Obviously, your buttons are always appearing, but you're trying to find a very specific object on the stage. At this point, we can use getChildByName() or getChildAt().
Hope that helps.
-Cheers

AS3 How to communicate between frames

I have been writing a game in timeline code. I want the different frames (rooms) in the game to be able to share information between each other. Of course, timeline code is limited to the frame it is written in.
After doing quite a bit of reading ("Foundation Game Design with Flash" and a number of articles, tutorials, forums etc) I decided to employ a document class. This did not work either. It seems it only works for frame one but not the rest of the frames (I have four).
How can I have frame four respond to something that happpened in frame one? For example, if the player achieves something in frame one, I want a movie clip in frame four to be visible.
If You are writing your code on the timeline, My suggestion would be to create two layers in the timeline, one for 'frame-actions' - in this layer you insert the code specific to a single frame (will work when the movieclip is stopped on that particular frame).. And also create one more layer called global-actions (for the entire timeline). Only the first frame will be a key frame and there should be empty frames till the end of the timeline.
In this layer actions write the code that you want to access from any keyframe in the same timeline.
If you define a variable in the actions which are written for the whole timeline (global-actions) then that will be available on all the frames.
Now if you want to go to a different frame based on some action, just write some functions in the layer which contains global actions and call that particular function through the frame actions. To go to a different frame use the 'gotoAndStop(frameNumber)' function of flash.
I want to tell you that while it will work, I would not recommend using it in this way.
HTH.
You can use static variables - these are variables which are linked to a class, rather than an instance of it.
Suppose your document class was called Document.as, and you wanted a variable, playerLives, to be visible from any part of the program.
Declare it inside Document.as:
public static var playerLives:int = 3;
You can then reference this directly from anywhere else in your code with:
Document.playerLives
(note that the variable is a member of the class itself, not an instance of it).
You could use a dedicated Statics class to hold these variables if you want to keep your document neat, or attach them to the relevant classes (eg Player.lives)
I've not used timeline/frames for some years but I believe this is how I used to do it!
NB Statics will be fine for your purposes but they are, in some ways, an equivalent to the _global variable in AS2 (at least, they can be used in the same manner) - many would not approve of their use, or over-use, as they are freely accessible from anywhere in your program (thus anathema to the OO concept of encapsulation), but personally I try not to worry about it in small cases - the most important thing to know about the rules of any design pattern is when they can be broken!
They are also slightly slower to access than instance members, but you won't notice this unless you are constantly accessing/changing them (making things like player velocity, which will need to be referenced/changed every frame, static, is not a good idea).
Hope this helps.
You may find the simplest way to link everything with the document class is to move your four frames into a movieclip together and have that on the first frame, then interact with that movieclip.
E.g. in the document class, where the movieclip instance on the timeline is called 'game'.
game.gotoAndStop(4);
game.objectToDisplay.visible = true;
If you encounter reference errors in the IDE then you can avoid these by using [] notation to refer to the properties of game, e.g. game["objectToDisplay"].visible = true;
Note that it's not really best practice to do this, but it will at least help you to finish that first game which is really more important at this stage in your learning. Afterwards, if you want to learn more then I'd recommend "The Essential Guide to Flash Games" by Jeff Fulton from 8bitrocket.com - it will teach you how to use the document class effectively.

Instantiate MovieClip with its layers?

I have searched a lot lately, I found that I can load an external swf file to my haxe project at compile time, and use the movieClips via their IDs as Classes types ..
That's cool& nice, but how it would work when I instantiate a MovieClip that has layers?
What I have is MovieClips with layers, layer of image, and a layer of text over the image layer.
So, is this achievable? will I be seeing instances of movieClips (images& texts over them) ?
Let's first dissect the flash terms in terms of code,
Layers :
Consider the layers as grouped z indexes. A single layer with multiple objects will also assign sub z indexes to each clip (see the send to back option in context menu)
The flash IDE provides you a nice interface to group & lock a few instances of objects, while working on the other. Each such group is a layer.
At runtime, every layer (with it's objects) will be concatenated into one single list (the display list) and the objects placed onto the stage in order of their position in the list.
Frames :
Frames are slices of time controlled by the fps property of the flash player. So if you have 12 fps, it means that whatever code you put in that frame of time will receive attention for 1/12th of a second.
Of course there is code being written for anything you do inside a frame or layer. The code, for example that you put in manually in IDE is added in by calling the addframescript internally.
MovieClip
The MovieClip class itself is actually an IDE related thing. The split being Sprite Class plus a timeline (collection of frames) plus associated properties & methods.
The Movieclip class thus provides you with properties like currentFrame, totalFrames, etc & methods like gotoAndPlay(), stop(), etc to interact with the flash controlled class.
Considering all of the above together, you should expect to see different images/text/objects at different intervals of time as defined in the frames when you access the movieclip.
I haven't spent a lot of time in flash, but the answer to your question comes from having a better understanding of how Flash/AS3 works, and not so much to do with Haxe.
Quoting this answer:
Layers only exist in the Flash IDE. They are not part of Flash Player's display list system. So you can't specify what layer a child goes into. Use addChild() or addChildAt() to add children to containers.
So that means Haxe will not have any concept which object is in which layer, nor would AS3 for that matter. The correct approach seems to be to use containers with IDs, which are recognised by AS3 or Haxe, and then add children to the containers.
TLDR: use containers movie clips, not layers.

Flash memory management and Actionscript

There was many discussions about this problem, but I want to pay attention on the situations that IMHO seems not so clear:
Yes the general rules are:
Remove chachedAsBitmap
Stop movieClip if playing
Remove events
Delete references
etc.
But let's look:
First Example:
I have nested sprite (ex: mainSprite), it contains other sprites with dynamic textFields in it (and are chached as bitmaps), just textFileds and MovieClips with event listeners on it (with weak reference).
When I need to remove this sprite I need first to remove all it's nested content via loops or just
removeChild(mainSprite);
mainSprite=null;
is just enough?
Second Example:
I have some sprite in which I'm loading bitmap and manipulating with bitmapData, later I'm just replacing content of this sprite with another bitmap, is allocated memory for older bitmap automatically erases and is overwritten or it still exists?
Third example:
I have some "graphics template" MovieClip (in library with Export for Actionscript property set on it) which I'm adding on the stage and filling with dynamic data (and adding event listeners), let's say that it's one scene of the app, on another scene I need same MovieClip with other dynamic data, but inbetween need to clear my stage (need something like transition animation which is also library MovieClip), what's the best way: to set this MovieClip visible property to false (while transition animation is plays) and then reuse it, or just remove it with removeChild and then add when add with addChild once more?
All I wrote is more about Air Mobile, cause in most cases for the desktop these situations aren't so problematic, but in case of mobile development they are.
You can visually monitor memory usage along with fps etc using this lib: http://code.google.com/p/flash-console/
hope that helps.
P.S. gc in flash is always a weird thing :)
First example: removing mainSprite from display list is enough if there are only weak listeners on its children.
Second example: I'd advice reusing the same object with visible = false. Recreating the same object is more resource expensive plus you get another instance of the same thing being in memory before it gets gc'ed.