I'm about to start building a site entirely in flash (per the client's request), using AS3, and was wondering about best practices for doing so in terms of application architecture. The site isn't too large--think homepage, persistent nav, 8 subsections or so, each with their own content but similar design between subsections. In the past, I would have used multiple swfs (say, one for the nav and one each for the subsections) and loaded them dynamically; now, though, I'm considering taking a different route and using a more object-oriented design, with lots of classes and just one swf (plus a preloader to load it).
Are there any best-practices for determining whether it's better to dynamically load smaller swfs vs building a single large swf? In AS2 I think loading many smaller swfs made more sense, but with AS3's stronger object-oriented capabilities I'm wondering if that's still the case.
I know that one argument against the single-swf design would be the added weight of loading everything upon initial siteload, but I don't think there's enough heavy content that it's of real concern here.
Any thoughts?
In my experience, the common practice these days for (most) small to medium Flash websites/applications is a two SWF architecture, a shell that loads a core. Sometimes you can get by with just one SWF that tracks its own load progress. That said, you want to load content and assets on demand; images, video, animations and large textual content. These typically should not be embedded in the core SWF but loaded on user request. The primary advantage in either case here (one vs two SWFs) is code maintenance. You only need recompile the core SWF when you make updates to the application. In this model, you could still load additional SWFs that contained timeline-based animations, as long as you kept your application code in the core.
Hope that helps!
It depends on what you mean by "smaller."
Don't break it into chunks that are too small or you'll kill yourself with connection overhead. Don't pack the whole site into one mammoth wad that will takes weeks to download.
A good rule of thumb: if you find yourself trying to think up catchy or entertaining things to display while your users are waiting for it to download, restructure instead.
-- MarkusQ
I thinks this heavy depends on the content of the pages and how many assets you already have included in you swf.
We usually just make 2 swfs: one preloader and the real application.
The applications does not have any text or images included. Everything (except fonts) loaded dynamicly from the server as the content is dynamic on most of our cases. The size of the swf does not increase much you add another 10 classes.
The it is hard to give a 100% direct answer to you question, as said it depends on the weight of the content (and whether it is dynamic or very static).
There is never one "SAY ALL" way of doing anything. One project may be small and fine to code up in a procedural fashion, as to where another may be intricate, have many hands involved and upon most certainly be able to accept change, then OOP and design patterns may be the way to go. For a production based site that is surely going to be broken into sections, abstracting each section into its own FLA/SWF/DOCUMENT CLASS allows your code to be maintainable. If something in the about section requires change, we merely open the AboutDocumentClass.as, for instance, and make our changes. Lets be real, you should be using SWFAddress now days to offer deeplinking; enabling favorites, back, and forward buttons for flash sites. With a proper implementation of SWFAddress and a nice preloader, one can achieve a very smooth, low footprint site, that is easy to manage and scale.
That being said, I believe any production level flash developer ought to know about the GAIA Framework. In just minutes you have an entire bone structure of FLA's, document classes, swf's, etc. GAIA not only arranges the outputted files in an intelligent hierarchy, but it also sets up SWFObject, and SWFAddress, as well a preloader.
This is all done by first editing an XML file that is in the bin folder wherever you had GAIA output the new project files. Once your done editing the XML and any other items, you tell GAIA to scaffold, for every section you accounted for in the XML, a FLA is created, a document class with hooks to either a timeline based transition, or a TweenLite/Max implementation depending on your choice before scaffolding. Again this takes about five minutes and you have bones of your site with preloading, SWFAddress deeplinking, and hooks to transitions.
The result is a tidy output of files using a standard set of names and conventions that should be easy to read and cut back on redundancy ten-fold.
one argument against the single-swf design would be the added weight of loading everything upon initial [...]
You will want to keep parts that change frequently from those that don't separate if there is any. There is something called Ordered Creation and creationPolicy to take care of loading time. But apart from that, it really boils down to something you will be comfortable maintaining.
no there is that i know of
("best-practices for determining whether it's better to dynamically load smaller swfs")
but i can think of a good reason to load all the content in the beginning
what i am usually doing
i write all the code in one
place
load swf with graphic dynamically
Your loading time may be an important factor, but an additional factor to consider is whether or not the "look and feel" of your SWF is apt to change while the underlying code remains the same. For several "skinnable" games I worked on, where the gameplay was identical but we wanted to be able to change the imagry to match sponsor clients, we broke the title into two SWFs, one with all the executable code (Application.swf), and another with all the art assets in it (Library.swf). This worked out well as our art team could go and muck with the Library.swf, and as long as they maintained the same movieclip export naming scheme (and frame labels as applicable), they could build new artwork and simply swap out their "skin" swf without needing to recompile or know anything about the source code.
I think we used LoadMovieClip() to handle the library assets, and of course all the library clips needed to be marked for export on frame 1 with appropriate labels. Also, all of our code was in separate AS files, and as we were using AS2.0, we included movie clips as members of classes, as opposed to putting logic in the movie clips themselves. This almost totally segregated the art from the code, with the exception of a few base movie clips in the Application.SWF that were used for initialization and handling the OnEnterFrame() functions, then passing any input or tick based functionality down the chain of child objects.
It's been about a year since I worked on this stuff, so my terminology may be a bit off. Still, I hope this is helpful.
Related
I am planning to create a game with the help of Flash CS3/AS3. This game will feature too many functions and lots of code. A 30-seconds demo alone I've been making here already has 5,000 lines of code, and will only get bigger and bigger as I make progress.
I'm planning on separating snippets of this code into separate as files, so I can embed them on the timeline using the include function, but before I proceed, I need to know: Is this considered a bad practice?
I mean, there will be a point in development where the code will become so huge, it might threaten the game's stability, or am I just paranoid and this is a perfectly normal way to address this issue. Pasting all the important functionality on the timeline and being done with it?
Your ActionScript code isn't going to affect your load time nearly as much as your assets. Any audio assets have to be embedded in your actionscript compile frame, which you can pick from your document properties.
If you're using library assets that are connected to AS Classes, the only place you can really practically defer loading is visual assets that are placed on stage later in the timeline, by not checking "compile on frame X" (whatever frame you selected as your compile frame). Timeline scripts are, as a rule, bad practice, so I assume that you're not using them.
include is also bad practice. I suspect it won't work like you want, but it also breaks compile-time error checking pretty hard.
I can't imagine needing 5000 lines of code for a demo that size, so you may want to revisit your design. Look for places you can reuse code (literally reuse the same code, not copy and paste it).
That's depend a lot if you are using OOP to develop or if you type your whole code in a procedural way. Having some codes drop on separate movieclip/sprite is not a bad thing, I even feel it's good! but that's true if each of them manage themself without depending. For example in a video game if you want to manage with script the animation of a specific monster, that's a great way to write the code inside his movieclip and make sure that his own script doesn't depend on others script.
I am just getting into object oriented programming, and I was wondering, is it okay to put some code on the timeline, like stop(); and mouseclick events for moving frames, or should all this be on separate files also? If they do belong in other files, how would I go about doing that?
MPO is that you should learn the tool as the tool. I think that the timeline is the very best part of Flash, and if you throw that away, you are making your life harder for no good reason. I think all tools have a "code way" and "some other" way to accomplish what they do, and the default of most developers is to assume that the code way demonstrates your skillz and that "the other way" is so obviously easy that it's not worth your time to learn it.
IME, nothing could be further from the truth. I have learned these "other ways" in several tools/language, and you pretty much always get more power and productivity out of knowing both, at the risk of having a significant fraction of your fellow developers looking down their noses at you because they assume that if you're really good at "the other way" that you are doing it because you can't code. For this reason, there are very few developers who truly understand the full depth and subtlety of the timeline, and there are almost none who will talk about how to do this well.
I actually develop scalable enterprise-level Flash applications using the timeline for clients whose stores you've almost certainly been in within the past couple of days, so I do have a fair amount of experience in this area. My rule of thumb is that stop() is ok if it is unimportant to the overall functioning of the program (it's a visual thing only). However, it gets tedious after a while to keep adding it, so when you get to where you're not under deadline pressure, you'll probably replace that at some point with a Class that uses addFrameScript to do the stop().
The best use for timeline code is when you need to synchronize things (for example, with a streaming sound, which has absolutely zero Actionscript handles to get hold of it). Generate a bubbling event at the precise point where the narrator is saying "click the thingamajig" and you've animated the cursor over the thingamajig. Then, in the AS code that controls the parent of the timeline with the streaming sound (or grandparent, or whatever--somewhere positioned to catch the event), you'd put the thingamjig into the toggled state (for example by changing the data model the thingamajig is responsible for displaying).
Very, very occasionally, I will use timeline code to do something more significant. One example is that a swf compiled by Flash Builder knows what color its stage is, but one compiled by Flash Pro does not, without reading the bytes of the swf. I have a Class that fades a graphic in that can only get the real stage color sometimes, depending on how it was compiled (I'm not goint through the mess of reading the bytes--that's frankly ridiculous). So, I just assume we're fading in from white or something close to it (which we are most of the time). For the rare case where it's not, I've noted in the ASDOCs for the Class that it's ok to just populate the color variable from the timeline rather than worry about how to get it in there through dependency injection. I view this as kind of a poor man's version of the Flash Components properties panel.
Hope that points you in the right direction :).
I think it depends on what you mean by is it okay. (no I am not Bill Clinton)
You'll be hard pressed to get a positive response on this as most of the community on SO are developers and generally are not huge fans of using the Flash IDE/Timeline coding.
That being said, I try to always remain open minded and do realize there's a place for the Flash IDE in creating motion graphics quickly, etc. There's nothing that says you should not code in the timeline, if you absolutely shouldn't do it, they wouldn't have made it possible.
The problem I think arises when you start working with other developers and have to figure out where they buried some code on the timeline within some movieclip that is affecting things. For small projects this isn't really an issue, getting into larger teams (3-5 devs at a time, maybe more) then being able to work independently and collaboratively becomes a challenge.
One last point since you say you're just learning OOP. AS3 is a great language, tons of fun, lots of features provided by the run-time so you can just jump past some of the nitty gritty in C/C++ etc. But the concept of the Timeline is unique to AS3. So if you learn to do everything based on the Timeline, then moving to say C++ or Java or C# or any other OOP will likely be that much more difficult. For now I wouldn't stress about this since you're just getting rolling, but just something to keep in your mind as you move forward.
Edit (response to Ms. Blankenship's good answer and comments from Mr. Mear)
I think there is some arrogance on the side of developers. I can speak for myself in saying I've generally not been a fan of WYSIWYG editors (except when I try to build them, then they're okay :).
A couple of reasons:
They have in my past experience been terrible (take Word or DreamWeaver's code output as examples, try to work on a site some mom and pop threw together in one of those apps and you'll start to hate it too).
If someone was able to get this completely right it would invalidate a lot of knowledge I've built up (so it gets me into a defensive stance, not an objectively valid reason, I know).
Working with bigger teams finding code is key + the code editor is bad (compared with any of the alternatives, Flash Builder [my tool of choice], FDT, FlashDevelop, IntelliJ [my friends' tool of choice]).
Coming from a OOP background that doesn't include anything similar to the Timeline and potentially moving back to those technologies. You have the choice to be great at 1 thing or good at 5 things what do you choose? (I'm vastly over simplifying but hopefully you get the gist). I learned to use Eclipse writing Java, I can use the same tool to write C++, C, PHP, etc. This isn't to say I actually always use Eclipse for everything (lately been using SublimeText a fair amount), but I like that it's always an option. As an aside I'm not an Eclipse "Pure Blood", I started off early on playing with Flash IDE and HTML/JS in Notepad, used Visual Studio for a bit, eventually got pushed into Eclipse but have taken a liking to it for the all in oneness.
Ultimately there are too many factors in this open ended situation to say that one solution is the end all be all. To explain with an analogy, if you were to build a birdhouse a hammer, some nails, and some wood are probably all you need. If instead you want to build your own human house you're going to need some different tools (probably including a hammer, some nails and wood).
Also a related SO post (re-hashes many of the same points):
Why not use Interface Builder
My Flex app allows people to enter text. There's a broad selection of fonts to choose from. Because it is a multi-lingual app, some of those fonts (e.g. Chinese) are very large indeed - too big to embed all fonts.
I know that I can load fonts at runtime via stylesheets - I plan to do this as people select a font (a small wait while the font loads is not a problem). What I want to be able to do is to unload those fonts again, so that the app doesn't consume huge amount of memory if people select one font and then another.
I can't see a way to do it, though. I can load fonts at runtime, but not unload them. Any ideas?
I did see this question on SO that mentions loading fonts as part of a module - with one font per module, I guess. The advantage being that modules can be unloaded. But then, the font isn't accessible outside the module, as the questioner points out. So that seems like a dead end.
If it's not possible, I will - sadly - accept an answer that shows me that it's impossible, but much more useful would be an alternative strategy! This must be a pretty common scenario that people have run into before...
As your intuition suggests, this is a relatively common scenario for flex developers - there's got to be a solution!
As you have suggested, I would compile the stylesheets as modules with the fonts embedded in each (for Chinese, I suggest you look at specifying unicode ranges if possible to save on font size: http://renaun.com/blog/2011/10/flash-embed-font-unicode-range-generator/).
There are 3 application domains you can load modules into a parent app. Take a look at this: http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e07.html. I believe 2 out of the 3 ways allows you to use resources from the module. The easiest is to load it with the same application domain - meaning you assume the classes in the module are the same as the parent's.
Make sure your build system is compiling the modules with the same version of the sdk as the parent application. Otherwise, you will run into actionscript runtime errors with marshalling classes.
Finally, how are you profiling your application for garbage collection? Are you using the flash builder's built-in profiler? Forcing garbage collection on a flex app is annoying (from what I remember, you must call System.gc() twice or some weird voodoo magic like that).
Here are some useful links:
http://livedocs.adobe.com/flex/3/html/help.html?content=fonts_04.html (esp. see the section beginning "Embedding fonts in ActionScript")
http://divillysausages.com/blog/as3_font_embedding_masterclass
http://bryanlangdon.com/blog/2007/03/22/loading-fonts-dynamically-in-actionscript-2-and-3/
You can embed the fonts externally in SWF files (one per font), load them up as needed, and use the same value as SWF Embed's "fontName" for CSS's "fontFamily".
When the user is done, and you've cleared all references to the font, you can unload the SWF (Loader.unloadAndStop()) and set it to null. I would think this would prompt it for garbage collection and free up the memory.
I think this is your best bet, because for a font to be used it must be registered, no matter how you got it to that point. And there is no Font.unregisterFont() method. This solution at least lets you free up everything up to that point.
Though I'm curious if Font.enumerateFonts() would still list the font and if it is really freed for garbage collection...
I haven't got too deep into it, but I too think it's not possible to unload a registered font.
I can only think of two probably unfeasible workarounds:
Come up with an elaborate and reliable way to use device fonts. I
guess it would imply quite an extensive investigation about fonts
available/required in different systems and countries, but if you're
not using the font for very graphical things, I think it could be
pulled off.
Reload the whole movie when you change the font. This
obviously depends heavily in what's your application like, but maybe
you could save the app state and reload it through javascript, or
maybe even have a separate overlaid swf that you load on demand
(maybe the latter could work loading the swf in a separate
application/security domain, but I'm not sure the registered fonts
would be sandboxed correctly).
Anyway, I guess it being a Flex app would complicate things quite a bit and render anything outside the box useless...
I just checked out chromium's source, but I desperately need to learn how to navigate around this monster.
How would I search for parts of the code that implement behavior/features I'm interested in?
Let's say I want to see what happens after a URL is entered into the address bar. How do I find that piece of code?
Or, that I want to see what happens when, while parsing HTML, a certain tag is reached.
I have before me a huge amount of source code, and no skill of navigating around it. How do I learn that skill?
My recommendation for sort of diving in is to take a look at the source for http://code.google.com/p/chromiumembedded/.
It's sort of the condensed version of Chrome and if you look at the files it specifically uses, either ones included in its source tree, or files included therein from the Chromium repo at large. The Chromium code base is a huge amount of stuff, most of which isn't actually in the browser. There's a ton of pulled in code from third party repos which are then boiled down in the build process or Chromium's implementation is located somewhere else in the tree, there's a lot of side projects that (while interesting and an awesome resource for a wide breadth of stuff) will prevent you from achieving your goal of specifically honing in on the browser implementation and how that fits together.
CEF is great because you can see someone who's already done the process of pulling all that stuff together to build a project very specifically scoped at the browser view and nothing else. You can see which parts are primarily derived from webkit easily, you can see where the crossover comes in with Google's implementations, and you can see pretty easily how V8 gets tossed into the mix.
I do say "easily" in relative terms because we're still talking a huge amount of code overall. CEF will put you smack in the center of the requirements, but that stuff is still pulling in the massive amount of various things from the rest of the tree. Compiling it takes me about an hour on a really good computer with 12 gigs of ram and 8 cores, and the generated files take up like 6-10 gigs depending.
At the very least, there's not going to be any sort of quick jump into the shallow end to pick something here or there piecemeal. Browsers are incredibly complex pieces of engineering necessarily, because they have to subsume such a huge amount of individual pieces of functionality and then combine them into a shared context. You may find the one thing you're looking for, but you'll find that it's part of a class library that likely is composed of dozens or hundreds of files, which in turn relies on a hundred more of these libraries to handle each task, so to really take something away you'll have to commit time to taking in a lot more than any given piece of information.
Edit: oh also as your specific example.
src is root http://src.chromium.org/viewvc/chrome/trunk/src
/chrome http://src.chromium.org/viewvc/chrome/trunk/src/chrome
The "chrome" tree largely contains the direct implementations (a lot of stuff isn't in there though, most of it even, but that's the starting point). This has overlap with chromeos (chromeos is kind of chromium browser taken to a crazy extreme)
/chrome/browser http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/
Is getting you to close to where you want to be. You start to see specific references to things that you can match to the browser, like the tabs and whatnot (ignoring the giant elephant of the actual browser implementation itself which is what takes up the majority of the mindspace in all this stuff)
/chrome/browser/ui http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/ui/
Brings you to where most of the ui code is for the browser. It can be confusing when there's crossover or when stuff migrates, like there's a "ui" in the root src directory which has some crossover.
And finally http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/ui/omnibox/
Which has a surprisingly small amount of code in it. But this is what you find a lot. The code here is an implementation of a number of classes that are built up elsewhere. For non-webview gui component you'll find them mostly pointing back to the root "ui" and the native widgets stuff there, which is where the bulk of the actual event handling code is if I remember correctly.
You can try this... it may actually lead somewhere too :-)
http://aaronboodman-com-v1.blogspot.com/2010/10/wherein-i-help-you-get-good-job.html
Reading through the dev forums may help too...
http://groups.google.com/a/chromium.org/group/chromium-dev/topics
Also, this section has a lot of useful documents, such as style guides, etc.
http://dev.chromium.org/developers/contributing-code
Last, but not least, IRC is your friend...
http://dev.chromium.org/developers/irc
I was just wondering what are the pros and cons of using embedded images instead of dynamic loading? Because when making games on pure AS3 (without Flash IDE), its a pain to manually embed all the assets needed... That makes your code sloppy, besides you don't have control to automatically change the hud, for example, by only changing the external file.
But I heard that some sites only let you upload a single swf, so you can't have external images. Also I heard that some are worried about users downloading their art... But as far as I know, and please correct if I'm wrong, they can also download them if they hack the swf with a decompiler. Having it external, you can encrypt the image, and unencrypt it on the code, so if they try to download they will only get encrypted code.
So... What do you think about embedding images? Please share all your thoughts to me.
I believe dynamic loading of images is a better approach. I agree with you about the game problem you stated, but when you are talking of flash/as3 as a whole, games are just one of the things among the many, you do. Also there are a few which also accept multiple files & maybe more will allow later. As of now hosting sites are just being on the safe side by not allowing multiple files & formats. So if you really have additional files you could just host them elsewhere & call them from your main swf.
I however cant agree about the point of making the code sloppy by managing images dynamically. When you do it through an IDE the IDE is writing the code for you, but as you might realize letting an IDE decide what to write doesn't always make the best. Manually handling things let's you understand all entry & exit points of an app. Moreover, would you want to open a flash IDE every time you wish to add an image, make an update, etc.
I usually like to use IDE cause of the awesome tools it provides to make things more efficient & prefer letting the code do all management/control stuff.And yes, if you have many small images (as in online flash games), embedding is better approach.
As far as the security is concerned even externally loaded files can be accessed if the encryption algorithm you use, can be found by decompiling the swf. So your best bet in case of security is usually using a third party software to encrypt the swf, which let's say increases your chance to prevent theft of your material. So if you really encrypt the swf using a 3rd party tool, both the ways would be acceptable.
I believe both approaches are valid, it mainly depends on your assets.
As you know embedding assets, will increase the size of your swf, I would only consider doing this for icon type images where size is hardly an issue.
For bigger images, I would definitely go for dynamic loading which I also find more flexible.
If I have lots of small icons, I'm embedding them. Imagine that number of requests in runtime, any of which may timeout. Pain of embedding, where? A single Embed tag in source or CSS for an asset. "Constant" assets must be embedded, "variable" ones - loaded.
Edit: OK, I got it. Pain of embedding lots of assets. Here is one idea come to my mind... Even if you loading something dynamically, you need some list with all filenames? You may take list of files and generate class full of public static const members with [Embed] attributes, that's fairly trivial. Then you use that class in project and voila, all is in the place. Maybe this helps.