AS3 - Gone over from AS2 to AS3 and it's killing me.
I've recently started using AS3 and I'm sooo disappointed. I can't code anything now. All my old games gives tons of errors with AS3. I can't draw API, do my old way of hitTests, can't get to MCs inside other MCs, can't use onEnterFrame stuff anymore, no code on buttons or MCs, terrible re-design of the Flash GUI, Flash complains about everything I do.... etc etc etc etc
Anyway, I'm slowly trying to learn AS3 and have figured out how to do some API. What I've been stuck on ALL day is working with movie clips. I've read like 1000 rows of text on the internet on this matter with movie clips. People say they have solutions and post code and stuff, I just can't make anything work. I've searched and read so much that I now give up.
It's a part of a game I'm slowly trying to convert over to AS3.... I have no problem doing anything in AS2...
Anyway, as u can see I have MC in root called "container_mc". I create 3 mcs inside that container, but no matter what I do I can't get to them. My first attempt of course was container.andTheMC, but just a bunch of error messages. I've tried bunch of different variations of getChildByName and stuff. No matter what I do I can't get to them.
Well, the first thing is that AS3 is NOT AS2! It's a more programmer-oriented language and if you want to learn it you're going to have to let go of your AS2 "baggage" - this is true of any programming language you want to learn. If you know how to do stuff in AS2 and aren't excited about learning AS3, you could always continue using AS2.
Anyway, sorry for the preachy stuff. There's many ways you can accomplish what you're looking to do. One option if you like the GUI is to create the symbols and add them to the stage manually - then you can give them instance names and refer to them that way.
Another way is to put the variable declarations (var lines_mc:MovieClip = new MovieClip()) at the top of your ActionScript. This puts it in the global scope so then you can always refer to that MovieClip with lines_mc. Another way that is pretty similar is moving to object-oriented code and making this in to a class where lines_mc is a member variables, but that is starting to get a bit more advanced.
As for the getChildByName stuff, I'd just recommend staying away from that. If you really want to, you can iterate over the containers children like this:
Actionscript Code:
for(var i:int = 0; i < container_mc.numChildren; i++){ trace(container_mc.getChildAt(i); }
Well, the first thing is that AS3 is NOT AS2! It's a more programmer-oriented language and if you want to learn it you're going to have to let go of your AS2 "baggage"
And I will, I want to learn AS3 and have been trying so hard, but can't get stuff to work anyway.
[b]There's many ways you can accomplish what you're looking to do. One option if you like the GUI is to create the symbols and add them to the stage manually - then you can give them instance names and refer to them that way.[b/]
Yeah, but I'm drawing API, I can't manually create them on the stage, they have to be drawn inside a container so that I can manipulate the api mcs inside the container mcs, but still can't get to those api mcs I create inside the container mc.
Another way is to put the variable declarations (var lines_mc:MovieClip = new MovieClip()) at the top of your ActionScript. This puts it in the global scope so then you can always refer to that MovieClip with lines_mc.
I don't understand, do you mean moving all those var mc:MovieClip lines to the top? Then they won't be inside the function and they won't be created properly either, or you mean move the var mv:MovieCip and it's content to the top?, well they already are sort of, just inside a function.
Another way that is pretty similar is moving to object-oriented code and making this in to a class where lines_mc is a member variables, but that is starting to get a bit more advanced.
And how is this done?
As for the getChildByName stuff, I'd just recommend staying away from that. If you really want to, you can iterate over the containers children like this:
That code, no matter where I placed it just caused errors:
1084: Syntax error: expecting rightparen before semicolon.
And with moving (var lines_mc:MovieClip = new MovieClip()) to the top I just get more errors.... but guess there should be no ( at the start and ) at the end, still get errors.
Could you please modify the code I posted in my first post so it can find the api mcs inside the container? That way it's easier for me to see what has been done.
Wonder when I will ever learn how to do the stuff I can do in AS2 in AS3.
Aww, no edit button? Can't fix all my errors. Will have to remember to preview post before posting next time then.
Originally Posted by adit_ya_sharma
stop being lazy?
Aww, that hurt ... I'm everything but lazy, I'm working my ass off to learn how to do the stuff I can do in AS2 in AS3 and it's so hard.... been reading so many guides and examples on the internet, but not much help, most stuff I do in AS3 just throws error messages at me
if you want to use dot notation for accessing objects in MovieClips you need to set references to those objects in the MovieClip. Simply adding the child to the MovieClip does not create a direct reference to that object. Here are three ways you could do this:
Code:
var lines_mc:MovieClip = new MovieClip();
//draw line stuff
//add the lines_mc to container_mc and create a pointer to it
container_mc.addChild(lines_mc);
container_mc.lines_mc = lines_mc;
//now you can access it using dot notation
trace(container_mc.lines_mc) //returns MovieClip
the other option is to give lines_mc a name (notice lines_mc is a DisplayObject, because the "getChildByName" returns objects as DisplayObjects. If you wanted to know if "lines_mc" was a MovieClip, you'd need to cast it as one: trace(container_mc.getChildByName("lines_mc") as MovieClip) would return MovieClip ONLY IF its actually a MovieClip. It will return null if the object is something else.
Code:
var lines_mc:MovieClip = new MovieClip();
lines_mc.name = "lines_mc";
//draw line stuff
//add the lines_mc to container_mc
container_mc.addChild(lines_mc);
//now you can access it by its name
trace(container_mc.getChildByName("lines_mc")) //returns DisplayObject
The most complicated but most powerful is by making a class. You could make your container_mc as a Class which extends MovieClip and manage all this stuff internally.
Code:
class ContainerClass extends MovieClip {
private var lines_mc:MovieClip;
public function ContainerClass() {
lines_mc = new MovieClip();
//draw lines
addChild(lines_mc);
}
}
Ok, took a break and now I'm getting back to AS3 again.
Thanks, mr_malee, now I know how to get to mcs inside mcs...
So I went on to the next step, which is masking, which doesn't work. I found out it AS3 it's just "mask" and no longer "setMask" and also with mask I need "=" and no ()
Ok, had some progress, forgot to add a couple of "xxxx_mc.name = "xxxx_mc";" so now stuff happens, but for some reason they just disappear.... not the result I want... the problem could maybe be that wall_mc and ground_mc are mcs I've created insidr the container, not with code. Maybe AS3 doesn't like masking coded mcs with none-coded ones.... but it works perfecly in AS2... hmmm...
Yeah, manually creating mc a and mc b and "a.mask=b" works. But creating mc a with code and manually creating mc b, then it won't work.
So, like I said, seems like AS3 can't mask manually created MCs with coded MCs.
Imo, donno why it shouldn't work.... even though the manually created one (like the container_mc) is not created by code, the code one still should be a close enough real MC. Sounds like it anyway when it's made with: var lines_mc:MovieClip = new MovieClip();
I hope any of you know how to fix this .... maybe convert the coded MC to a REAL mc, somehow?... donno...
More progress, still not the result I want, but at least it's masking now:
I added the 2 MCs to the stage from the library instead with code, like:
Code:
var myMovieClip:MovieClip = new mc();
myMovieClip.name="mc";
container_mc.addChild(myMovieClip);
So yup, AS3 can't mask mcs of not the same type thingy.... the 2 mcs has to be created the same way or they won't mask..... I'm sure I'm wrong, but don't know how to do it besides this way.... I still hope someone can shed some light on a solution without having to link them to stage from library...
edit:
yay, now I've gotten it to look exactly like I have it in AS3....... so, now like 4 different things has been converted from AS2 to AS3, took some time.... now I have tons more to convert.... hope they are easier to do..... I google alot but usually find confusing stuff.... when searching for a simple thing, and u find like 5 sources of explanations, like 1 of them could be super easy and written in very little code... that's the stuff I want.... but most people just spam tons of stuff I don't need, like classes, packages and tons of lines of code... but turns out I only need a fraction... and still they were just showing how this one thing was done..... so, I love FlashKit.... easier to get a more exact reply here
Well, that's not really what I meant. You created both objects/items/thingies with code. What I meant is making one of the MCs manually, like draw a circle, mark it and convert to movie clip and give it an instance name right on the canvas with the mouse.... that's what I mean..... that MC can't be masked with a mc being created with code, like: var mc1:MovieClip = new MovieClip();. I also said I'm probably wrong .... but whenever I tried this, it didn't work... but instantly worked if both were made the same way... ie both were made with script, or both were made manually on the canvas, like drawing 2 circles etc...
Ye, I didn't do enough testing... the problem is that they are created and located inside the container mc, and to access them in there I need to use this weird code you've seen, like container_mc.getChildByName("lines_mc").mask with another item inside doing it the same way, like: container_mc.getChildByName("lines_mc").mask = container_mc.getChildByName("another_mc").
Some stuff works, some doesn't..... if I go with the dot apporach instead, then more stuff works...
But ye, seems if I create the stuff, no matter if both are made the same way or not (one coded mc, one not, or whatever the type is), both can be masked as long as they are on the "root", and not inside a mc.... only solution I found to mask my coded mc inside the container mc with an actual manually created mc inside the container mc was to make the manually created mc linkable in the library and attach it with code... then it worked....
And with the rest, which you tought me, I can use the dot approach instead, which I would like to do for all, not just dot for some and getChildByName for others.
getChildByName returns the object as a DisplayObject, and a DisplayObject does not have graphics. When you're unsure about what a flash method does, check the docs. In order to get the graphics object you need to cast the object as one which has graphics capabilities. These three objects have graphics properties:Shape, Sprite, MovieClip.
Shape is the most lightweight as it can't contain other children, Sprite comes next as it doesn't have a timeline, MovieClip is the most heavy DisplayObject which has a timeline and allows for dynamic properties. You should always avoid using MovieClips unless you need a timeline, and if you don't need to add children to an object, use Shape. Two other key components here are the classes DisplayObject and DisplayObjectContainer, these are core classes which cannot be created but provide the above classes with functionality, you could think of them as blueprints for other objects. Here's MovieClip's inheritance chain:
DisplayObject allows something to be added to a display list.
DisplayObjectContainer allows the object to contain other DisplayObjects (this is where getChildByName() is defined)
Sprite adds extra functionality for interactivity and the ability to draw graphics
MovieClip adds a timeline and ability to add dynamic properties
So finally, to get your graphics object:
Code:
var lines_mc:MovieClip = container_mc.getChildByName("lines_mc") as MovieClip;
lines_mc.graphics.clear();
The reason for this is because DisplayObjectContainer cannot automatically know exactly what types of children it has, if you were to add a Shape, Sprite, Bitmap, MovieClip or some custom display class, how would 1 function return the correct type? It can't, so it must return the objects as their most primitive type, the DisplayObject. It would be nice to have some methods like "getSpriteByName" "getMovieClipByName", "getShapeByName" but you can see that would get ugly and bloat the core class unnecessarily
Originally Posted by TenchyCho
Anyway, how do I apply the dot method on this one?
The exact same way, if container_mc is a MovieClip, it can have any type of property added to it.
Code:
var myMovieClip:MovieClip = new mc();
myMovieClip.name="mc";
container_mc.addChild(myMovieClip);
container_mc.myMovieClip = myMovieClip;
You might start wondering if there's a better way to do all this stuff and the answer is: Classes. I would create a Class for your container_mc and have all this stuff done internally. So you would add "lines_mc" as a property of that class, and then the class can access it with the correct type without every having to call "getChildByName" and cast objects. You can also make properties available to other objects with correct Type as well, by making the property "lines_mc" public or as a getter. I highly recommend reading about Classes in AS3. Its the way AS3 was designed to work, you'll find it hard to start, but slowly you'll learn about Structure and the power you can create.
Many thanks again for helping me, and the stuff works everytime
Some new problems: ()
I've noticed that if I declare a variable outside stuff, it can't be used inside the stuff. Like if I at the first line on the very top of the frame add a variable, I can't touch that variable from inside a function or something like that. If I make a variable inside something I can't use it on the outside. So I looked it up to see if there was a way to make the declared variable usable anywhere (read about adding private before "var variable:blah" so thought maybe there was something like global instead of private, but couldn't find anything on that. So I found a page (link) where this was discussed and they said to make a variable work everywhere, it has to be made into a class, which I'm still confused over how it works. On the same page someone also says a class or package is actually not needed, all you need is something like the code line in this quote (which I tried and it didn't work):
enmity3
If you want to use the timeline and not use a package or class do the following:
var whateverVariable:String = “Whatever u want it to be”;
// you can access it from anywhere on the timeline if you do this:
MovieClip(this.root).whateverVariable;
So, what do you think? Is a class really needed or is there another way?
About hitTesting, of course the old ways of hitTesting is gone, I have AS2 code to hittest anything, even irregular shapes. When I look for code to do it in AS3 I get examples with like a million lines of code and tons of import stuff at the top. I know all this is not necessary. I found after quite some searching the simple way of hitTesting stuff like boxes, pretty much like AS2, except now hiTestObject:
Code:
if (ball.hitTestObject(ground)) {
trace("ball is on the ground")
} else {
ball.y += 10
}
But how do I hitTest with irregular shapes now? I want to hitTest, let's say an irregular shaped red thingy with another irregular shaped blue thingy, but only find a billion code line examples.
I use this for irregular hitTesting in AS2: (and here's the swf: link)
I did try to convert above code to AS3 as good as I could, like replacing all _blah stuff with just blah and hitTest with both hitTestObject and the other hitTest(fogot the other word) etc. I received no errors when trying it, but nothing happend and it won't work.
the AS3 timeline can be nasty and thats why you should avoid coding on it. Can you maybe supply a simple example with it not working? Its hard to know exactly what your problem is.
As with your bitmapTest problem, can you post your converted AS3 code so I/we can help better.