View Full Version: Actionscript 3

lassie >>Discussions >>Actionscript 3


<< Prev | Next >>

fatbuoy1- 02-04-2008

Yeah that makes sense thanks a lot :D So... does that mean I can't get... continuing your analogy... the bathroom sink to see what colour the bedroom door is? i.e. can the bathroom() function be told to look at a variable contained in the bedroom() function?

bigmac- 02-04-2008

That is correct... in fact, its impossible for functions to reference each other because the scope of a function only exists in the space of time while the function is running. Once the function finishes processing, all of its variables are purged. So, in order to retain data that results from a function, you'd need to set it as a property of the Object (that is: make it a property of the house). So, to utilize data between functions, you'd do something like this: var _storeData:String; function setData():void { _storeData = "Hello World"; } function getData():void { trace(_storeData); } setData(); getData(); In that example, the data is being set by the first function, then being accessed and output by the second function. Also, I might as well set you onto another really cool and ungodly handy trick... Functions CAN talk to each other at run-time. Ever wonder what the thing after the colon is when a function is written as "function():void"? That's its return. You can call a function to have it process and return a value in another operation... we'll start simple: function addUpToEight():Number { return 4 + addUpToFour(); } function addUpToFour():Number { return 2 + 2; } trace(addUpToEight()); If you ran that script, the result that gets traced into the Flash output window would be "8". Again, this is an overly complicated example for demonstrating a simple Math operation, but its the concept that counts. Both of those functions return a number, so the number 8 is generated by calling a function that ultimately processes 4 + 2 + 2. In more useful context, lets look at your grid builder scenario... var _cellWidth:Number = 125; var _cellHeight:Number = 100; /** * Method to return the upper-left corner point of a grid cell * @params: Column number, Row number */ function getCellPosition(col:Number, row:Number):Point { var x:Number = _cellWidth*col; var y:Number = _cellHeight*row; return new Point(x, y); } var cellPosition:Point = getCellPosition(1, 3); good stuff.

fatbuoy1- 02-04-2008

Cool! :D Thanks a lot, again! My problem then is this... Im now able to import the images and create thumbnails in a grid (which is amazing to me!), and now I want to be able to click on a thumbnail and display it's picture in a bigger loader frame. I've tried this... imgThumb.addEventListener(MouseEvent.CLICK, displayImage()); with the displayImage() being a function that creates a larger loader and loads imgThumb into it. However, imgThumb is a display object variable contained within my createThumbnails() function... so this won't work. Am I missing something obvious? Btw, hows that adventure-game-esque site going? Im looking forward to seeing it!

bigmac- 02-04-2008

The adventure-game-esque site is kicking ass, thanks, though I must admit that I'm getting a little burned-out on it. It's getting down to the -*test*-('")ing time and people are getting ancy for final features. And of course, this is the point where you start seeing what features need to get cut and such, and people start needing to compromise. The writers are irate about not making script changes to accommodate weird circumstantial scenarios beyond the standard engine capacity; though truth be told it's much easier to tailor the script to the engine than the engine to the script. And remember, the developer is always the bad guy: we're the idiots who only provide 97% scenario coverage in an all-encompassing engine build, so we are directly responsible when people have to compromise their script on the 3% of scenario exceptions that the engine alone doesn't hit. We all know it's true, just read these forums :) Thankfully, I don't have to take you guys' crap! (though unfortunately, I'm paid to take my coworkers' :P ) Anyway, sorry if that was a rant. I'm smiling as I type is, so I have a very good sense of humor about it all! Concerning your question... You're executing the function with your event listener, not referencing it... that's what "()" means. It's the call method; and you don't want to call it. Just reference it. So, remove the "()" as in: addEventListener(MouseEvent.MOUSE_CLICK, handleMyEvent); Once you do that it looks quite a bit like a variable, doesn't it? Loe and behold, there IS a reason for that: function are just properties (ie:variables) of the Object. Back in our house scenario, the kitchen function is just a property of the house like the "_ventilation" was; the kitchen just happens to be a property of the type Function that can be called with the "()" operator. Congrats on the grid builder, rock on man! I look forward to seeing this thing! I'll post a link to the game I'm building as soon as I can. Probably early March. I'd love to post a link to our dev site, but it is bad professional form to publicize a client's work in any capacity before they launch it with guns and glory a' blazin.

bigmac- 02-04-2008

OOPS. I deleted your last post. But, this was my reply: Okay, I'm going home for the night! But first... You still haven't taken out the call method... Code: // this is WRONG imgThumb.addEventListener(MouseEvent.CLICK, displayImage()); // this is RIGHT imgThumb.addEventListener(MouseEvent.CLICK, displayImage); that will take care of the error... or at least it should assuming you are properly referencing the target than you're applying the event listener to. Also, just as a reminder, the event handler (displayImage) MUST receive an event as the sole input parameter in order for it to work properly. So the method signature of your event handler should look like this: Code: function displayImage(evt:MouseEvent):void { }; if the function does not receive an event, it will fail. And finally concerning this... Quote: for (percent=0; percent<100;) { var fileSize:Number = root.loaderInfo.bytesTotal; var amountLoaded:Number = root.loaderInfo.bytesLoaded; var percent:Number = amountLoaded / fileSize * 100; preloader_mc.percentLoaded.text = percent+"%"; } Out of curiosity, what example were you following here? Because I'm sorry, but you're not even close. :P The first things that I notice are A) You're written your "for" loop incorrectly, B) You can't use a "for" loop to track load status, and C) the root has no loaderInfo that will work here. Look at my earlier example... It uses an ENTER_FRAME event and pulls byte totals from the loader objects, not the document.

fatbuoy1- 02-04-2008

the event handler (displayImage) MUST receive an event as the sole input parameter in order for it to work properly Don't quite understand the whole input parameter thing... but thats what the problem was, put the (evt:MouseEvent) bit in and it works now, thanks! Out of curiosity, what example were you following here? Um... I have no idea, I couldn't find any examples or tutorials for preloaders in AS3 so think I just looked for things that looked right and tried to throw them together! This preloader is for the start of the whole website, so my fuzzy logic told me to put root. in there... :P I'll take another look at it tomorrow. I'm going home for the night! And im away to bed! Thanks again for your help :D

bigmac- 02-05-2008

No prob on the help... you're asking good questions and seem to be learning on your own, so I'm happy to share what I would have found helpful back in the day. Input parameters. Also known as just "parameters" or "arguments". They are pieces of data that are fed into a function to customize how the function operates. They are the comma separated values that go between a function's call parenthesis (ie: myFunction(arg1, arg2, arg3):void;). A function can take anything in as parameters (numbers, MovieClips, colors, etc.) So, quick example. Let's build a positioning function that will place a MovieClip at X% each of the stage's width and height. To do this, we'll feed the function a MovieClip and a percentage value (decimal between 0 and 1) for each axis... Also, this script will assume that the movieClip's registration point is in its upper-left corner. Try this out in Flash, it work! /** * Position a movieClip X% of the way across the stage (horizontally) * @param: mc = target MovieClip * @param: percX = percent (decimal 0-1) of X-axis. * @param: percY = percent (decimal 0-1) of Y-axis. * @returns: nothing (void) */ function placeClip(mc:MovieClip, percX:Number, percY:Number):void { var spanW:Number = stage.stageWidth - mc.width; var spanH:Number = stage.stageHeight - mc.height; mc.x = spanW * percX; mc.y = spanH * percY; } So, what could that script do? Here's some recipes: // position in upper left corner of stage placeClip(myClip, 0, 0); // position in lower right corner of stage placeClip(myClip, 1, 1); // position to right of mid-center placeClip(myClip, 0.75, 0.5); // randomly position on screen placeClip(myClip, Math.random(), Math.random()); So, that handy little function could be reused all over the place. It has a job to do, but it performs that job with variable input. Instead of it operating on a concrete target with concrete values, we pass in references to the object and values that we want it to work with. Okay, I need to go to bed; however just to clear things up for future discussion... We've now talked about inputs and return values, which sums up a method's "signature". So, that word in now common vocabulary: "signature". A method's signature represents its function name, inputs, return value, and each element's "data type" (the type of data: Number, String, MovieClip, etc). So, the above example's signature is this: function placeClip(mc:MovieClip, percX:Number, percY:Number):void; AS3 is extremely picky about signature errors (ie: elements not lining up correctly), so inspecting your function signatures closely is generally a good place to start when looking for the source of errors.

fatbuoy1- 02-05-2008

ok, heres my la-*test*-('") attempt at a preloader script... addEventListener(Event.ENTER_FRAME, checkProgress); function checkProgress(evt:Event):void { var fileSize:Number = loaderInfo.bytesTotal; var amountLoaded:Number = loaderInfo.bytesLoaded; var percent:int = amountLoaded / fileSize * 100; preloader_mc.percentLoaded_txt.text = percent+"%"; trace(percent+"%"); if (percent == 100) { gotoAndStop(2); } } First of all, this is supposed to give me the percent loaded of the WHOLE movie, do i need to put anything in front of loaderInfo.bytesTotal; or loaderInfo.bytesLoaded; for this to happen? Second of all, the if(percent == 100) bit works... but also traces an error so im doing something wrong, any ideas? Im guessing I havn't done something as tightly as I should have? Also, the numbers this script returns are to something like 10 decimal places, how do I make it round up? Thanks :)

fatbuoy1- 02-05-2008

Also, the numbers this script returns are to something like 10 decimal places, how do I make it round up? Ah, never mind, iv just remembered what an integer is.

bigmac- 02-05-2008

Also, the numbers this script returns are to something like 10 decimal places, how do I make it round up? Ah, never mind, iv just remembered what an integer is. Also note the ungodly useful rounding functions of Flash: Math.round() // nearest whole number Math.floor() // round down Math.ceil() // round up

bigmac- 02-05-2008

I just got it working in a -*test*-('") flash movie... here it is: // stop timeline on load frame stop(); function checkProgress(evt:Event):void { // get percent loaded var percent:Number = loaderInfo.bytesLoaded / loaderInfo.bytesTotal; // display percent as a factor of 100 percentDisplay.text = Math.round(percent * 100) + "%"; // if percentage has reached capacity if (percent >= 1) { // remove enterframe handler removeEventListener(Event.ENTER_FRAME, checkProgress); // advance to target content frame gotoAndStop(2); } } // add enterframe to moniter load addEventListener(Event.ENTER_FRAME, checkProgress); You were missing a couple things, the most important of which was probably the remove of the enterframe handler. If your timeline proceeded to a new frame on which that function does not exist, the enterframe handler will fail. You'll notice that I'm tracking the percent as a decimal... It helps in the long run becasue you can use the decimal to generate any numeric range that you need. For example, you can display text quoting the numbers 1-100 (as seen in the example), and use that same percentage to advance a 27 frame movieclip between frames 1 and 27 proportinally. Last note... I avoid using the equivelancy operator ("==") when -*test*-('")ing for complete. I've gotten weird scenarios where an extra byte or two of unexpected meta data trickles in with the file giving it more bytes than expected. So, making it greater-than-or-equal-to accomodates this.

bigmac- 02-06-2008

Good grief... E4X parsing for XML data is unbelievably cool. I just got heavily into it for the first time today. This will almost certianly be the deployment vehicle for Lassie data in the future. It's WAY simpler and more straight forward than the archaic (and sloooow) XML parser in AS2. So, when you're ready to get into captions and stuff to go with your photos, it'll be time to plunge into XML.

fatbuoy1- 02-06-2008

Thanks! note the ungodly useful rounding functions of Flash Ah, i'd wondered what that Math.ceil was! You were missing a couple things, the most important of which was probably the remove of the enterframe handler. Yeah that was it, flash was still looking for the enterFrame handler in the second frame... it worked ok, but was messy. Adjusted it accordingly and it now works perfect... it also briefly displays 100% at the end (because of the 'greater than or equal to' thingy I guess), which just seems... reassuring.. in some way! E4X parsing for XML data is unbelievably cool Wow I was just about to ask you about that! What is it? From what I gathered in Flash help,I figured instead of listing all my URL requests in Actionscript, I could do it in an external (and easier edited) XML file... and also bundle a title and a caption in with each photo while Im at it... though I wouldnt have a baldy notion how!

bigmac- 02-07-2008

yup... this is where you get into simple data structures and external data; which is a staple in Flash. Have you worked with XML before? If not, fear not. XML is identical to writing HTML, you just get to specify your own node names rather than be restricted to standard HTML nodes. This is also a really good starter project for this kind of stuff... there's only so many ways you can build a slide show, so the data structures and implementation methods are pretty standard. Just looking at the XML, you'll probably want something like this: <?xml version="1.0" encoding="UTF-8"?> <portfolio> <image> <url>http://www.mysite.com/images/image.gif</url> <title>My Awesome Image</title> <caption>Caption about image</caption> </image> <image> <url>http://www.mysite.com/images/otherimage.gif</url> <title>Another Awesome Image</title> <caption>Caption about other image</caption> </image> </portfolio> So, then you'd just add in as many image nodes as you have slides. That's the easy part: writing the data. The tricky part will be loading it in and working with it. That's a subject for later if you want to pursue this route.

fatbuoy1- 02-07-2008

Yeah thats exactly the sort of thing was looking at. Iv never used XML but it looks simple enough (this bit does anyway), but like you say loading it in and using its another matter! However yeah i'd definately like to know how to do this. Out of interest, when u said E4X parsing for XML data is unbelievably cool im guessing you meant for more than just dynamic image galleries... whats so cool about it? What all can it do?

Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.