2
votes

and i am having problem, switching from Timeline code to OOP/Document Class. I managed to build the Fla with AS3 on timeline with no problem. But totally clueless when on OOP.

I had been told that Scenes are no good and i should stick to saving my scenes as Movieclips.

My situation is as such: I have 8 pages of PSD files, and i imported each PSD into Flash Pro, and each PSD has a few buttons and textinput. First page is Login page, second page is register page etc.

My questions are:

1.) How should i save the PSD? Do i save them as nested Animation,(Giving each item on PSD a symbol? Buttons and textinput?) Then saving that PSD as 1 movieclip(Nested Animation?) I already tried importing the PSD with Flash Layers onto Stage,then giving each buttons and Textinput their Properties then savin them as Nested Animation, but do i call that Movieclip from the Class document? Or do i link All Movieclips in the Document Class(Main.as)?

2.) How do i access the Movieclip from Class file, I tried var login:Login = New Login, then addChild(login). That adds the movieclip but none of the functionality works, and errors saying Access of Undefined Properties for every single button's Name.

3.) And if 1 button is clicked and that links to another page(PSD) do i do the Below?

h.addEventListener(MouseEvent.CLICK, fl_ClickToGohome);

 function fl_ClickToGohome(event:MouseEvent):void
{
    gotoAndStop("register.as");

Thanks for your time

1

1 Answers

1
votes

Programming in .as files apart from the timeline isn't too different. If you're using the document class (found in Actionscript Settings panel), you may be feeling the abrupt change in class specific programming a bit too daunting. For a smoother transition, you can simply dump your current timeline code into a new code.as file (as-is), and simply drop the following line in your timeline:

include "code.as";

This effectively just copy/pastes the code and runs it, except now you can use a proper code editor (such as Sublime Text). Furthermore, as it's not a new class, the code you write there has the same scope as your timeline.

2). Functions only have access to the namespace their created in (this is probably why your document class was throwing "Access of Undefined Properties" errors). You can always pass a reference to an object (and by extension, its namespace) through function arguments.

1). To answer your first question, you can create your movieclips, and nest them as deeply as your want, in any order you want. The important thing is to be aware of how to navigate to that object. Take for example the following stage heiarchy:

root:MainTimeline ¬
    0: PSD_one:MovieClip ¬
        0: backgroundImage:Bitmap
        1: button:Sprite
        2: txt:TextField
    1: PSD_two:MovieClip
    2: PSD_three:MovieClip

The timeline has 3 objects, each with a zero-based index. The first PSD is a MovieClip DisplayObjectContainer with 3 child elements, each with name properties that we can use to address the objects. In Flash IDE we label these "instances", and they automatically become properties on the parent object due to internal magic the IDE has enabled in the Actionscript Settings panel labeled "Automatically declare stage instances".

magic sauce

This means, to change the text on txt, we can write PSD_one.txt.text = "foo". Without this setting, you'll need to use container methods like root.getChildByName("PSD_one").getChildAt(2). Outright calling txt.text = "foo" will never work because there is no property on the current scope called that (ie., this.txt is implied).

3). gotoAndStop is a MovieClip method that controls timeline frames. If you're really going to make a clean break from the old way of doing things, you should drop your use of frames.

There are two ways you could approach displaying these PSDs.

Method 1: You instance your PSDs on the stage with the Flash IDE and give each one a unique name that you can then reference in your code. Assuming the layout above, you may simply move each PSD offscreen (such as with PSD_two.x = this.loaderInfo.width), and swap them to the center of the screen when you want to "go" to the next "frame".

Method 2: You've imported your PSDs into your library as you're accustomed to, but do not instance them. Instead, you jump straight into your code and when someone clicks on button h to go to fl_ClickToGohome, your function picks the library object and manually instances it, and parents it to the stage with addChild().

function fl_ClickToGohome(e:MouseEvent):void {
    var psd:PSD_one = new PSD_one();
    addChild(psd);
}

This sort of approach would be preferable if you're going to start getting into dynamic loading of assets. Of course, rather than having an already created PSD_one class in your library, you'll simply use URLLoader() or Loader(), and you'll want to save out compressed images, not full-blown PSDs.

I hope this helps. I know I haven't answered your questions directly, but sometimes the issue stems from manner of implementation, not specific code.

-Cheers


To answer your questions...

1: Pathing to Objects

If you're not sure what the path is to your objects, try this function. It's a trimmed down version of the one I use in my own work.

function listLayers(obj = null, indent:String = ""):void {
    // If no object was provided, start with the MainTimeline
    if (obj == null) { obj = root; }

    for (var i:int = 0; i < obj.numChildren; i++) {
        // Make a pointer to the object at this index
        var item = obj.getChildAt(i);

        // Get the item type
        var type:String = flash.utils.getQualifiedClassName(item);
        if (type.lastIndexOf("::") != -1) {type = type.split("::")[1];}

        var msg:String = indent + i + ": " + item.name + ":" + type;
        if (type != "TLFTextField" && item.hasOwnProperty("numChildren") && item.numChildren > 0) {
            trace(msg + " ¬");
            listLayers(item, indent + "  ");
        } else {
            trace(msg);
        }
    }   
}

This will print out the structure of your stage in much the same format as you saw above (with the PSDs). You can then use getChildByName from the root to the child (the full path must be provided, much like navigating folders on your hard drive).

2: Public/Private Namespaces

These are only to be used in dedicated classes. If you're using the include method I mentioned, you omit these as you would in your timeline code. They denote whether a property/method is accessible from "the outside" of the class. If you're just starting out, leave everything Public. You can worry about memory optimizations later when you're ready to tackle it.

3: How does the class access the buttons?

The easiest way to think of the DisplayList is as a folder structure.

enter image description here

You might write

C:/Users/Me

Which in the DisplayList would look more like

C.Users.Me

Of course, we don't have a root location called C, and your objects are probably called PSD_one and myButton, so we can rewrite it as follows...

root.PSD_one.myButton

This is assuming you actually have those properties pre-defined on the objects, which does not happen when dynamically creating objects. In those cases, you'd string together your commands, as follows:

root.getChildByName("PSD_one").getChildByName("myButton")

When you write a Class, it's like creating a new computer on your network. There is no direct relationship between that Class and your MainTimeline. You need to connect them.

If you instance a DisplayListObject (such as a Sprite) and add it to the stage, the object automatically gains a few properties like stage, root, and parent which until it was parented were in fact null. These are properties that the class can reference from inside itself to connect to the MainTimeline and access objects on it.

Conversely, if you wanted to you could pass a reference to the stage to the class from the constructor arguments, as follows:

var foo:MySprite = new MySprite(stage);