View Full Version: Actionscript 3

lassie >>Discussions >>Actionscript 3


<< Prev | Next >>

fatbuoy1- 09-11-2008

Ok, iv tried to work out a structure for my Playing Cards model... I thought about the process of actually creating a pack of cards in real life. First you have the card manufacturing company, with their CardMakers making the 52 cards and putting them into a pack. Then you have the CardDealer who places the cards on the table, and finally the uh.. Referee who makes sure that the games rules are followed (ok so there arn't actually referees in real life as such, but you know what I mean :D). So to create a game of cards, I need those 3 classes: DeckMaker (to create the deck of cards), CardDealer (to place the cards on the table in a certain structure) and Referee (to apply the game rules... different Referee classes could be plugged in for different games); So, stage 1, the DeckMaker class. This needs to run through the arrays containing the 4 suits of cards, and call the CardMaker class to create a card for each one. The CardMaker class creates the rectangle and places the right graphic on it, calls various classes to determine how the card should look and act (CardShadow, CardPhysics, etc). I think iv got my head around how to basically structure this, my main problem is the syntax.. how to make the various classes talk to each other in the right way. I'll post an example.

fatbuoy1- 09-11-2008

In the interests of making this as scalable and adaptable as possible, I'm wanting to split EVERYTHING into classes, so I can plug in or out various features easily. So in my CardMaker class (basically an adapted version of the 'draggable rectangle creator' example class you posted back on page 9), im wanting to call the CardShadow class to apply a shadow to the card. import com.carmstrong.playingCards.CardShadow; private var _cardShadow:CardShadow = new CardShadow(); private function drawFrame():void { graphics.lineStyle(3, 0xCCCCCC, 1, true); graphics.beginFill(0xFFFFFF, 1); graphics.drawRoundRect(-(CARD_WIDTH/2), -(CARD_HEIGHT/2), CARD_WIDTH, CARD_HEIGHT, (2/8)*INCH); graphics.endFill(); filters = [_cardShadow]; } My CardShadow class is the following package com.carmstrong.playingCards{ import flash.filters.DropShadowFilter; public class CardShadow extends DropShadowFilter { // -------------------------------------------------- // Private members // -------------------------------------------------- private var _distance:Number = (1/32)*100; private var _angle:Number = 25; private var _blur:Number = (1/8)*100; private var _alpha:Number = 0.25; // -------------------------------------------------- // Constructor // -------------------------------------------------- public function CardShadow():void { super(); drawShadow(); } // -------------------------------------------------- // Private methods // -------------------------------------------------- private function drawShadow():void { distance = _distance; angle = _angle; blurX = blurY = _blur; alpha = _alpha; } } } I'm getting the following error: 1016 Base class is final. Public class CardShadow extends DropShadowFilter{ I'm guessing theres something inherently wrong with the way I've set up that class (my logic is quite probably skewed). but iv no idea how to fix it. Any ideas would be muchly appreciated should you get the chance!

bigmac- 09-18-2008

I'll do this in two posts. The first will be the basic answer to your above problem (sorry for the delay, BTW. I've been swamped at work...). So, the reason you're getting a #1016 error is because you're trying to extend a final class. What does that mean? Well, AS3 added in massive amounts of OOP structure control, which is REALLY nice. However, it creates lots of little nuances that you need to learn. Here, we run into the case of the "final" class attribute. A "final" class means that you've extended a class as far as it should be allowed to go, so no more extensions are allowed on top of it. Adobe has provided a lot of class structures that are intended for extension, like the Sprite and MovieClip. However, there are some things that they do not want you as the end developer to tinker with. Case of point: the DropShadowFilter. That's an intrinsic component within their filter engine, so they don't want developers futsing with the Filter object and then having it break the system. So, they've locked you out from extending the class by making it "final". All you are allowed to do is implement the class, not extend it. You can add these structural rules within your own OOP, and I highly recommend it! While these may seem like trivial details (allowed inheritance models, etc), all these little things lock your application structure into a pretty solid parcel, and prevent you from messing up while using your own code.

bigmac- 09-18-2008

Part 2: Since you're going down this road anyway, it sounds like you're ready to be introduced to that which is real "grown-up" OOP... two words: Design Patterns. Google that as a search term. I'm guessing you'll get back more techno-babble about programming than you could ever want. Design patterns can be a scary thing to read about since people are so die-hard technical about them, but the fact that you have some background and foundation understanding of them automatically knocks you up three-fold in your experience (and value) as a programmer... even if you can just barely wrap your head around them. So first, what the heck are design patterns? Basically, think of this along the lines of painting: any tom-fool can hold a brush and swirl colored pigments around on a canvas. However, the true artists can take those colored swirls and really craft them into masterful works with style, grace, elegance, and beauty. They create something that works (ie: is visually pleasing), using a carefully constructed technique that people admire and hail as efficient and effective. So to that end, do we say that there are varying degrees of talent among painters? There most certainly are! While I think of myself as a decent painter, I'm no master! So, this exact same premise is true about programmers. Any tom-fool can copy lines of code out of tutorials. Noobs can write their own code, but do so with the precision of a surgeon operating with a shovel. The Michelangelos of the programming world on the other hand, can conceptualize brilliant programming models that are clean, simple, efficient, expandable, etc... And at the core, they "design" code patterns to do this. This is where creativity comes into programming. Only folks to don't understand design patterns say that programming is not an art form. So, I guess where I'm going with this is that design patterns are where programming stops being about lines of code, and more about conceptual models that just happen to utilize lines of code to implement them. These very frequently boil down to using a real-world metaphor to implement a system. This is why I say that, for as bad as the later Matrix movies were, the premise of the Matrix is spot-on with OO theory... The matrix just happens to use the entire world that we know as a programming metaphor. So,let's look at a very common and basic design pattern known as "The Factory". The factory pattern is very common for instantiating object types. Basically, we have a factory who's job is to build products. A factory may have a single product, or multiple products. What the factory builds and returns to the customer who places an order depends on the order spec. But there's the rub: instead of writing build specification logic into your main program, you just move it all off into a Factory. Your main program tells the factory what it needs and how many, and that factory figures out how to fulfill the order. You might even break a factory down into divisions that build multiple types of products, or you may just have multiple factories to do this. In the end, there's no single way to do this. There are just good ways and better ways. Nothing says that you even NEED a design pattern to make your application work; in fact, most new programmers have never heard of the concept of design patterns and write plenty of functional code without them. Design patterns really aren't a different type of code, they are just a different type of thought process... and for the most part, they tend to help you build much more robust OO applications. In conclusion, look them up: design patterns. While there is no finite count as to the number of patterns that you can create with code, the experts in the field have narrowed it down to (as I recall) 14 foundation patterns that pretty much everything else is derived from. Of those, only about half are structural patterns... the rest are utility. The two most ungodly useful structural patterns (in my own experience) are The Singleton and The Factory. As you get better and more experienced, you'll also start to come on board with the MVC pattern, which is one of the largest conceptual patterns that generally performs at the application level. I'm also a huge fan of the Adaptor model. Look then up, they rock. The Singleton is probably the single best way to get your feet wet, because it's simple and unbelievably handy; even in larger and more advanced models.

fatbuoy1- 09-18-2008

Thanks, ill look up those design patterns. In the meantime, I actually bit the bullet and bought Colin Moocke's Essential Actioncript book, as well as one about creating dynamic animation - "Foundation ActionScript 3 Animation: Making Things Move!"... and between them and your past posts, I think I understand OOP a good bit better... still not wonderful like, but a lot better than I did! At this stage my card simulation has 3 classes; Paper, Card and Dealer. Paper deals with the material properties of the card, the physics, etc (making it throwable, bouncable, etc). Card extends the Paper class, so it inherits all the Paper properties, but deals with whats actually ON the card... card indices, etc. Finally, Dealer goes through the deck, creates the required Cards and places them on the stage. Iv set it up with lots of variables so when I call the dealer class I can choose how many cards I want, how many suits, how loosely they should be positioned, etc... it feels pretty cool to just call a Dealer class, input a few variables and have it dynamically create whatever I want! Its actually working quite well, and I'm trying to structure it in a way that will make it as expandable as possible, so now might be the perfect time to look at those design patterns. Iv tried to keep my code as clean and streamlined as possible, but theres a few things here and there that I need to do better... im loving how OOP makes it so easy to improve things section by section though! If you'd like I could post my class scripts here for you to take a glance at, or email you the files so you can see it working?

fatbuoy1- 09-18-2008

By the way, dunno if i've asked you this before, but you keep mentioning interactive election maps... what all does that entail?

fatbuoy1- 09-23-2008

Having a problem with something, would really appreciate help if you get the chance. I'm making a small flash slideshow, using XML to contain the image path, title and link data. My problem is I need to wait until the XML is loaded into my array before I try using it... so I need an event listener, but I cant work out what to attach it to! var imgList:Array = new Array(); loadXML(); function loadXML() { //Load the XML file var uldr = new URLLoader(); //create loader container uldr.addEventListener(Event.COMPLETE, xmlCompleteHandler); //check if loading is complete (start checking BEFORE loading starts) uldr.load(new URLRequest("/images.xml")); //load request into loader function xmlCompleteHandler(evt:Event) { var xmlData = new XML(evt.target.data); var imagesList:XMLList = xmlData.image; // Iterate through the list of image nodes for each (var image:XML in imagesList) { // extract each node's data var path:String = image.path; var linkTitle:String = image.linkTitle; var link:String = image.link; var imgItems:Array = new Array; imgItems.push(path); imgItems.push(linkTitle); imgItems.push(link); imgList.push(imgItems); } } } function startSlideshow(event:Event) { trace (imgList.length + imgList); } Any thoughts?

bigmac- 09-27-2008

Hey, sorry for the prolonged delay. I've been overseas in Germany and the Czech Republic visiting Matt Kempke. Back now, and trying to get settled back in. In quick reply... I haven't read all the way through your code, but I did see that you're using nested methods. For what it's worth, I find those to be incredibly cumbersome and more trouble than they're worth, especially because you don't ever NEED to use them, and they don't belong to a compile-time object that can be validated. So, as soon as you implement one of those crazy nested methods, you're basically handing your house keys to a person a random person on the street and kindly asking them not to rob the house at your street address. Maybe they're honest and they'll leave your place alone, but why take the risk? So, I'd write all methods and event handlers into the main object scope where the compiler can look them over. As for loading XML and waiting for an event to fire off, you need to use a URLLoader object to load in the XML file, and that loader will fire off a COMPLETE event when it has finished the load. So, that's the event to use. However, an alternate solution that I do is to break XML loading off into a separate service object. While we need to wait for XML to load, chances are that we also need to wait for it to parse into application data before we can use it. Therefor, I have an XMLService object that I composed which is just an extended EventDispatcher. You tell the XMLService object what file to load, and it takes care of setting up and monitoring the load operation, and then parsing the XML data once the file has finished loading. Then, my XMLService object dispatches its own COMPLETE event when it has taken care of all XML loading and parsing, and has complete, ready, and usable data wait for the application to consume. So, when utilizing that in my app, I just set up the XMLService object, then listed to it for a COMPLETE event to know when all XML related activity has been resolved and my main application can safely proceed. Does that make sense?

bigmac- 09-27-2008

By the way, dunno if i've asked you this before, but you keep mentioning interactive election maps... what all does that entail? Hehe... it involves a lot, and the scope of the data presentation has been growing exponentially as we get closer to election night. The tricky part is the overwhelming volume of data coming from all different sources, so I'm loading XML from the Associated Press as well as a raw data XML file from NPR (our client), as well as a separate XML document that contains all the different winner calls. Then there's an assortment of about a dozen other miscellaneous XML feeds that come in to populate various data displays. While you'd think it would be simpler to load in a single data file, that's not possible when you have a team of different data providers that all want their respective assets to be controlled separately, etc... So, you humor them and load in all their different data sets. Now we get to the tricky part. Everyone has a slightly different chunk of data that all needs to be displayed in a common presentation screen, so the data models all need to be merged into one central structure intelligently. This gets complicated when you have 50 states with variable numbers of political races, and each race with varying numbers of candidates competing for the position. And then there's the case of winners... no one wants to get caught with their pants down these days after the hairline margins of the past two elections and the explosive reactions to press agencies making premature winner calls. So, there becomes a huge logic chain for assessing a winner... as in: use my data unless this other guy has made a call, but still give me the option to override his call in the event that I don't agree with him. ...and it goes on and on. I ended up crafting an ultra rigid OO structure that merges data models and can be queried for specific data elements on request. Thankfully, it's proving robust enough to handle the amount of data (intelligently) that we're throwing it. Now we just need to get them to decide on and stick with a method of visually displaying all that data, and then all those graphics need to be programmed into the data model. It's a challenge, but it it fun it its own, really tedious sort of way.

fatbuoy1- 09-29-2008

Thanks for the advice, I'll restructure the nested methods. :) you need to use a URLLoader object to load in the XML file, and that loader will fire off a COMPLETE event when it has finished the load. So, that's the event to use. I do have an event complete listener on the XML Loader, which calls the function xmlCompleteHandler which puts the XML into an array for me. What I need is a way of knowing when the xmlCompleteHandler is finished so I can start the slideshow. But I can't seem to attach a COMPLETE listener to it for some reason, it just doesnt work? Does that make sense? I think so.. the principle does anyway. So your XML service object is basically a class that loads in the XML, then puts it into an array that isnt contained within the class? By the way, I've been enjoying your blog! Finding it really helpful, and even stuff that goes over my head now will probably be a big help in the future, so the blog's a great idea. Oh and interactive election maps sound... er... fun... :D

bigmac- 09-30-2008

What I need is a way of knowing when the xmlCompleteHandler is finished so I can start the slideshow. Your complete handler should probably call the operation of starting the slide show its self; otherwise, you're probably not leveraging the best OO model. OO aims to have major processes happen in the location that they aim to influence, but breaks them off into a separate chunks that process and then return their outcome. Erm... so what does that mean? It means: build a pipeline that runs your application. A pipeline is the concept that we have a very narrow path that your application moves along. It has a start point (start up) and an end point (launch), and in the path between the two is very confined with no forks in it. So it's a straight shot from startup to launch... however, we may pause along the way to wait for external actions to happen. Ultimately though, your central pipeline should be configured to listen for those external events to resolve so that it can advance its self to the next step in the pipeline. From your description, it sounds like you're outsourcing your processes to China, who is in turn farming them out to Japan. While Japan might be reporting back to China, it sounds like China is not reporting back to you. So, cut out the middle man... talk directly to Japan.

fatbuoy1- 11-05-2008

Heya, I STILL havn't managed to get that XML loading thing sorted out in my head, still working on it! However, I've come across a bit of a puzzler, for me anyway. I've basically got 10 instances of my class 'Card' in a pile on the stage. The card class has a method called "FLIPTO" which, when called, basically plays a tween that makes the card flip over. I want to be able to click through the pile... so when I click on it once, it flips the first card, if I click again it flips the second card, etc etc. However I'm having trouble referencing the right card. If I use the line pile.getChildAt(currentCard).scaleX = 2; then it works fine, and one by one the cards get wider when I click. However, when I change this to pile.getChildAt(currentCard).FLIPTO(leftX, leftY, leftRotation, leftScale, flipSpeed); it throws up a runtime error... 1061: Call to a possibly undefined method FLIPTO through a reference with static type flash.display:DisplayObject. Im guessing this has something to do with scope, but I dont understand why the first example references the right Sprite, but the second one cant? I think basically Im asking how come I can reference the right object using getChildAt if i'm wanting to change its scale, but not if I'm trying to call a method of the child? Nice job on the electoral map btw, shame I didnt get to watch it in action, but I had a play about with it anyway, theres something cool about data isnt there?

bigmac- 11-10-2008

Hey, sorry for the delay... Okay, this one isn't a scope issue, it's actually a silly transcending issue. This is one of the really annoying but awesome things about AS3: this stuff is annoying because it is nitpicky and confusing for new programmers (and has probably alienated a few folks who used to program Flash), however it kicks butt once you understand it because the compiler is being so specific and identifying potential problems and errors. So, I hated this stuff when I got into AS3, now I love it. You just have to learn it. So, remember your own ancestry that we've discussed before? If you were an Object, you'd be a Human > European > NorthernIrish > Chris. Right? Okay, now here's the weird thing: You have specific properties, but that doesn't mean your ancestors also do. For example, you're a male. BUT, just because you descend from NorthernIrish, does that mean that ALL NorthernIrish objects are male? Certainly not! No one would want to live there if that was the case :D So, you are a specific Object, Chris, who descends from NorthernIrish. You are male. NorthernIrish as a whole has no gender, so to refer to you as any old NorthernIrisher --and then ask if you're a male-- doesn't work. Specific attributes apply only to specific objects. That said, the problem in this case is that all of the "getChild" flash methods return a generic reference to a DisplayObject, which is an ancestor to Sprite, MovieClip, and any extensions that you make of them. So, you can't call a specific method on a generic object. Thankfully, there are two ways that you can down-cast an object reference down to a specific type. 1) decoration: var obj:MySpecificObject = MySpecificObject(getChildAt(0)); 2) using the transcending operator "as" var obj:MySpecificObject = getChildAt(0) as MySpecificObject;

fatbuoy1- 11-11-2008

Blimey Greg, you never cease to amaze me with how clearly you can explain this stuff! Thanks a lot, that makes sense... I actually posted a similar question on the adobe forum and they suggested using ClassName(getChildAt(0)) which I assume is doing a similar sort of thing, but your way seems clearer. So would I have a variable called currentCard, which is an object equal to getChildAt(i)... so I could update which object the currentCard variable points to and just call that variable when I need to reference it? If you're interested in seeing what I'm up to, you can take a look here www.pigstylearts.co.uk/cards/Testing.html Its for our company's new site, as a quick, coverflow-like way of scanning through our portfolio. However, I'm kind of doing things in a way that will be reusable when the time comes to look at that portfolio website of mine again... I'm loving OOP! :D Got a few things to fix still, like the fact that it goes UNDER the pile on the left hand side instead of on top, and still need to make it look prettier with shadows etc. Oh and I'm currently downloading the Flash CS4 trial... rather excited!

bigmac- 11-11-2008

That snippit that you got off of the Adobe forums is actually the exact same concept that I posted as method #1: decoration. The decorator pattern is basically the concept of dressing, or "wrapping", a Class object in a SpecificClass costume. The full capabilities of the decorator pattern actually go quite a bit deeper than just being able to transcend class ancestry, however, I find the pattern rather confusing and cumbersome so generally only use it for simple transcendence. If you want more information though, every AS3 design pattern book out there that I've seen includes a full chapter on class decoration.

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