A Flash Developer Resource Site

Results 1 to 20 of 20

Thread: AS3 - Gone over from AS2 to AS3 and it's killing me.

  1. #1
    Member
    Join Date
    May 2011
    Posts
    55

    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.

    How do I reach mcs inside other mcs?

    Here's a bit of code I'm working on:

    Code:
    function restart() {
    	var wallMask_mc:MovieClip = new MovieClip();
    	wallMask_mc.graphics.beginFill(0x00ff00);
    	// MODIFY
    	wallMask_mc.graphics.moveTo(800, 400);
    	wallMask_mc.graphics.lineTo(800-266, 240);
    	wallMask_mc.graphics.lineTo(800-532, 320);
    	wallMask_mc.graphics.lineTo(0, 200);
    	// MODIFY
    	wallMask_mc.graphics.lineTo(0, 480);
    	wallMask_mc.graphics.lineTo(800, 480);
    	container_mc.addChild(wallMask_mc)
    	//--------------------------
    	var groundMask_mc:MovieClip = new MovieClip();
    	groundMask_mc.graphics.beginFill(0xff0000);
    	// MODIFY
    	groundMask_mc.graphics.moveTo(800, 400+15);
    	groundMask_mc.graphics.lineTo(800-266, 240+15);
    	groundMask_mc.graphics.lineTo(800-532, 320+15);
    	groundMask_mc.graphics.lineTo(0, 200+15);
    	// MODIFY
    	groundMask_mc.graphics.lineTo(0, 480);
    	groundMask_mc.graphics.lineTo(800, 480);
    	groundMask_mc.graphics.endFill();
    	container_mc.addChild(groundMask_mc);
    	//--------------------------
    	var lines_mc:MovieClip = new MovieClip();
    	lines_mc.graphics.lineStyle(2, 0xffffff, 100);
    	// MODIFY
    	lines_mc.graphics.moveTo(800, 400);
    	lines_mc.graphics.lineTo(800-266, 240);
    	lines_mc.graphics.lineTo(800-532, 320);
    	lines_mc.graphics.lineTo(0, 200);
    	//--------------------------
    	lines_mc.graphics.moveTo(800, 400+15);
    	lines_mc.graphics.lineTo(800-266, 240+15);
    	lines_mc.graphics.lineTo(800-532, 320+15);
    	lines_mc.graphics.lineTo(0, 200+15);
    	container_mc.addChild(lines_mc);
    	// MODIFY
    	//--------------------------
    restart();
    }
    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.

    PLEASE HELP!

  2. #2
    Senior Member
    Join Date
    May 2009
    Posts
    138
    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);
    }

  3. #3
    doItLikeThis
    Join Date
    Jan 2004
    Location
    :noitacoL
    Posts
    1,080
    stop being lazy?
    -Aditya

  4. #4
    Member
    Join Date
    May 2011
    Posts
    55
    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.

  5. #5
    Member
    Join Date
    May 2011
    Posts
    55
    Aww, no edit button? Can't fix all my errors. Will have to remember to preview post before posting next time then.

    Quote Originally Posted by adit_ya_sharma View Post
    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

  6. #6
    M.D. mr_malee's Avatar
    Join Date
    Dec 2002
    Location
    Shelter
    Posts
    4,139
    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);
    	}
    }
    Last edited by mr_malee; 05-09-2011 at 02:31 AM.
    lather yourself up with soap - soap arcade

  7. #7
    Member
    Join Date
    May 2011
    Posts
    55
    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 ()

    I use this for masking in AS2:

    Code:
    container.wall_mc.setMask(container.wallMask_mc);
    container.ground_mc.setMask(container.groundMask_mc);
    And that works perfectly in AS2, so now when I can communicate with mcs inside another mc I tried this:

    Code:
    container_mc.getChildByName("wall_mc").mask = container_mc.getChildByName("wallMask_mc")
    container_mc.getChildByName("ground_mc").mask = container_mc.getChildByName("groundMask_mc")
    And that doesn't work, nothing happens. Any idea on this one?

    When checking masking in AS3 in the Adobe Community Help thingy it has some examples I don't understand, they have:

    Implementation
    public function get mask()isplayObject
    public function set mask(valueisplayObject):void

    and

    import flash.text.TextField;
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    in them, I've seen alot of code using these things. When do I know if I need to "import" something?

    I'm hoping for more working answers so I can continue with what I do

  8. #8
    Member
    Join Date
    May 2011
    Posts
    55
    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...

  9. #9
    Member
    Join Date
    May 2011
    Posts
    55
    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...

  10. #10
    Member
    Join Date
    May 2011
    Posts
    55
    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
    Last edited by TenchyCho; 05-10-2011 at 06:45 PM.

  11. #11
    M.D. mr_malee's Avatar
    Join Date
    Dec 2002
    Location
    Shelter
    Posts
    4,139
    Quote Originally Posted by TenchyCho
    So, like I said, seems like AS3 can't mask manually created MCs with coded MCs.
    Quote Originally Posted by TenchyCho
    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.
    This isn't true. Copy paste the code below in flash:

    Code:
    var mc1:MovieClip = new MovieClip();
    
    mc1.graphics.beginFill(0xFF0000);
    mc1.graphics.drawRect(0, 0, 200, 200);
    mc1.graphics.endFill();
    
    var mc2:Sprite = new Sprite();
    
    mc2.graphics.beginFill(0x000000);
    mc2.graphics.drawRect(100, 100, 100, 100);
    mc2.graphics.endFill();
    
    addChild(mc1);
    addChild(mc2);
    
    mc1.mask = mc2;
    uncomment the mask line and you'll see the red box can be masked/unmasked by the dynamically created sprite.
    lather yourself up with soap - soap arcade

  12. #12
    Member
    Join Date
    May 2011
    Posts
    55
    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...

  13. #13
    M.D. mr_malee's Avatar
    Join Date
    Dec 2002
    Location
    Shelter
    Posts
    4,139
    that is also not true. Check the attachment (CS4)

    either mc1 or mc2 can be the mask.
    Attached Files Attached Files
    lather yourself up with soap - soap arcade

  14. #14
    Member
    Join Date
    May 2011
    Posts
    55
    Ok, masking would work with one of the examples you made me, but not graphics.clear(). So I had to use the dot approach instead.

    This doesn't work for clearing the API for lines_mc:

    Code:
    container_mc.getChildByName("lines_mc").graphics.clear()
    So I tried your dot syntax thingy instead, and now I can clear the lines_mc:

    Code:
    container_mc.lines_mc.graphics.clear();
    How come the first line doesn't work? Because I can actually access that API's MC, move it around, mask stuff with it, but not clear it.

  15. #15
    Member
    Join Date
    May 2011
    Posts
    55
    Quote Originally Posted by mr_malee View Post
    that is also not true. Check the attachment (CS4)

    either mc1 or mc2 can be the mask.
    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....

  16. #16
    Member
    Join Date
    May 2011
    Posts
    55
    Anyway, how do I apply the dot method on this one?

    Code:
    var myMovieClip:MovieClip = new mc();
    myMovieClip.name="mc";
    container_mc.addChild(myMovieClip);
    I can't use the same approach as I did with my other stuff, as they were not made as "new mc", they were "new MovieClip".

    So, for this "new mc" which is the one I add to the stage from the library, I have to use this code:

    Code:
    container_mc.getChildByName("mc").mask=container_mc.getChildByName("wallMask_mc");
    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.

  17. #17
    M.D. mr_malee's Avatar
    Join Date
    Dec 2002
    Location
    Shelter
    Posts
    4,139
    Quote Originally Posted by TenchyCho
    container_mc.getChildByName("lines_mc").graphics.c lear()
    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:

    MovieClip extends Sprite extends DisplayObjectContainer extends DisplayObject

    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

    Quote 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.
    Last edited by mr_malee; 05-11-2011 at 10:02 AM.
    lather yourself up with soap - soap arcade

  18. #18
    Member
    Join Date
    May 2011
    Posts
    55
    Works great now

    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)

    Code:
    import flash.geom.Point;
    import flash.display.BitmapData;
    this.onEnterFrame = function():Void  {
    	if (red.pixelHitTest(blue)) {
    		this.red._alpha = this.blue._alpha=50;
    	} else {
    		this.red._alpha = this.blue._alpha=100;
    	}
    };
    this.red.onPress = this.blue.onPress=startDrag;
    this.red.onRelease = this.blue.onRelease=stopDrag;
    MovieClip.prototype.pixelHitTest = function(mc:MovieClip, threshold:Number):Boolean  {
    	threshold = threshold ? treshold : 1;
    	var thisBitmap:BitmapData = new BitmapData(this._width, this._height, true, 0);
    	thisBitmap.draw(this);
    	var mcBitmap:BitmapData = new BitmapData(mc._width, mc._height, true, 0);
    	mcBitmap.draw(mc);
    	if (thisBitmap.hitTest(new Point(this._x, this._y), threshold, mcBitmap, new Point(mc._x, mc._y), threshold)) {
    		return true;
    	}
    	return false;
    };
    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.
    Last edited by TenchyCho; 05-12-2011 at 06:22 PM.

  19. #19
    M.D. mr_malee's Avatar
    Join Date
    Dec 2002
    Location
    Shelter
    Posts
    4,139
    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.

    also, use the "trace" command a lot. A LOT.
    lather yourself up with soap - soap arcade

  20. #20
    Senior Member Ray Beez's Avatar
    Join Date
    Jun 2000
    Posts
    2,793
    Sometimes, a good book as reference will explain all this stuff.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center