define('DISALLOW_FILE_EDIT', true);
History Keeper does not provide any state management features beyond the information you store on the actual deep link (URL hash). However, you should be able to use the deep link information to grab the data you need out of a standard JS object (using it like a hash table):
[cc lang=”javascript”]
var storage = {
“/”: {
key: “home value”
},
“/about”: {
key: “about value”
}
};
[/cc]
Once you have your values stored like that you can use the storage object to lookup your chunk of data by the deep link string:
[cc lang=”javascript”]
function onHistoryChange(hash) {
alert(storage[hash].key);
}
unFocus.History.addEventListener(‘historyChange’, onHistoryChange);
[/cc]
You can make the “value” as deep as you want ( key: {more: “complex”} ), I only used a simple string for demonstration purposes.
This example is JavaScript, but the concepts are the same for Actionscript as well.
I hope that helps!
]]>I wanted to see how far I could push that exploding Actionscript 3.0 code – see if Flash could handle updating each animating pixel every frame, while playing a video, then blurring it. Sure enough, it can! It did take further optimization from the version I posted the other day – including swapping copyPixels with getPixel/setPixel, and removing an anonymous function call (wow that was expensive!). Here it is:
Note: This WILL run like slush on the debug player. I don’t know why. If anyone knows why, please let me know!
]]>Well I guess technically the pixels don’t explode as much as the DisplayObject explodes into pixels! I recently needed an effect that would make a bitmap image look sparkley, so I did some goggling, and game across a Firefly particle effect on a blog post belonging to Erik Hallander (at least I think so, the blog has been down for months, so I can’t double check). This pretty impressive effect looks like the following example (I hope reposting it here is not a problem).
Note: This is a modified version of the original adding the Stats.as box, and autolooping – and removes the actual firefly affect (I didn’t need that part for my purposes).
Very nice start! I don’t get an FPS problem – on my computer the example above rocks 62/60 fps (25% CPU on my Core 2 Duo)! So FPS was not the big problem. This example uses over ~19-23MB of RAM (with a lot of fluctuation)! And that is with 2×2 pixels, it goes up higher with 1×1 pixels. Additionally, this example already has an optimization in it to skip over empty (black) pixels in the DisplayObject it works on – which leads to a significant RAM savings.
Using the display list this way – and two filters per DisplayObject – it began causing the player to kick up a lot of invalid BitmapData/null reference errors (which I’m guessing is what happens when you run out of memory, since many many checks confirmed that the BitmapData was not invalid) – especially when I tried to make it work on 1×1 pixels to animate every pixel.
So the first thing I did was to clean up some of the obvious stuff, to bring down the memory usage – in the original blog post, Erik noted that this was unoptimized code, so I knew what I was getting into. I did things like remove the extra nested DisplayObjects (each pixel was a subclasses Sprite instance, with a BitmapData added to it), and cleaned up extra variables that were laying around, moved a lot of things inline, reused as many variables as I could, cutting down on object instantiation – and followed a lot of the other tips in a conveniently timed ByteArray post. Doing that really helped – I cut the memory use about in half – and on the initial animation (a black and white logo) the affect seemed worked quite well. But it didn’t scale well – larger images simply wouldn’t work.
I still wanted to use this affect, and I’ve seen many thousands of pixels being animated before – so I knew it was possible. So a radical departure. I’ve been reading about drawing directly to Bitmaps for quite a while, and that was going to be my path. So more optimizations – removed the display list code completely, changed the Pixel class to a simply property class (where are the enums?!), and used that to store information about where in the original source to look for the pixel data as well as other relevant animation data (most of which was already done for me – thanks!) for each pixel block. I also removed dependence on TweenMax – which is what the original uses for all the animations – and used the easing equations directly, within an ENTER_FRAME event.
The result is a RAM reduction by 25% and a steadier memory usage, coming in at ~5MB with 4x as many pixels (and roughly the same amount of CPU). The changes utilize copyPixels and a linked list, with an accumulation buffer like effect – for a total of 3 bitmaps (the original, which is rendered from the DisplayObject and stored, the scattered one the pixels get copied into, and the copy of that that gets blurred by the BlurFilter – a hidden memory cost illuminated by Thibault Imbert).
There are further optimizations that can be used as well (and should really be used for full image per pixel animations) – such as writing to an opaque BitmapData, rather than one with Alpha, and reducing the BlurFilter quality – getting a better handle on type marshaling, etc. It might also be faster to store the RGB value of each pixel, and draw those directly instead of using copyPixels, but I haven’t tried that yet.
I got so much help from the Flash community on this, that it would be irresponsible not to share this back, so feel free to check out the source.
Some Notes:
The memory usage applies to both swfs on this page – so you can’t see the memory usage difference in these examples. I quoted the standalone Flash Player in this post.
Also, I’m getting some kind of performance problem in plugin browsers (everything except IE) on Windows, and on every browser on mac but Firefox which is limiting both of these to around 30FPS. I have no idea what’s causing it.
On the code quality – the code isn’t all that messy IMHO, but it is not well documented, and a lot of the configuration hooks I left in are not really being utilized in a decent API – I may refactor at some point to clean that up. There is also a limitation of the skip pixel check that will keep it from working well for greater than 1×1 pixel size (since it only checks the top left corner of the size rect).
Enjoy!
]]>Flash Content Debugger and “Allow Debugging”
While it’s not essential for tracing, the first thing you should do, is make sure you are running a content debugger version of the Flash Player. You need both the Active X version for IE, and the Plugin version for everyone else (Firefox, Chrome, Opera, Safari, etc.). Both plugin types have their quirks with regards to JavaScript (and other platform differences), and really require specific testing in each, so make sure you grab both versions. Once you have those, you’ll be able to see uncaught exceptions in AS3 swfs right in the browser. You can even use the Flash Content Debugger from the browser, though I haven’t found a smooth way to do that yet. For many thing, a simple trace is all you need.
A quick tip that took me a while to notice – the “Allow Debugging” checkbox in Flash’s Publishing Settings dialog, actually causes the Flash compiler to add debugging symbols to the compiled swf, symbols that give you useful information like the actual line number of an error, in addition to the stack trace. The “Allow Debugging” verbiage, is most definately not enough to communicate that difference – I thought it was more of a locking mechanism. Hopefully you haven’t stumbled around for too long with that, like I did when I first switched to AS3..
Tracing
The easiest way to trace from Flash is to use Firefox with the FlashTracer extension from sephiroth.it. With FlashTracer, you can use the regular old built in trace method without any extra work on your part. Make sure you download the one from sephiroth.it (2.3.1), since the one from addons.mozilla.org (2.2.0) doesn’t work in Firefox 3.5. For many things that’ll be all you need. But sometimes, you’ll need information in other browsers, and will want to trace to the browsers JavaScript console. In addition to simple trace messages, you can also call a number of other methods that will out put your messages in different formats and colors, making it easier to spot what you might be looking for.
Check out the Firebug Console API for more information.
Enabling the JavaScript console
If you are already familiar with the various JavaScript consoles, please feel free to skip to this part.
Each of the major browser vendors has a JavaScript console implementation, and thankfully, the API is mostly compatible with one another. The GUI is a bit different in each (except Safari and Chrome – both are based on WebKit), so here’s a quick rundown on how to access the JavaScript console for each:
You should get to know and love Firebug. It is currently the best developer tool available on any platform – so good the others all copied it, even if they won’t admit it (*cough*Microsoft*cough*). Firefox is oddly enough, the only browser that doesn’t ship with a JavaScript console, and requires you to install an extension. While running Firefox, you can find and install that extension at www.getfirebug.com.
Once Firebug is installed, you will notice a little bug (insect) icon in the bottom right hand corner of the browser window, on the status bar. Click that to open and enable Firebug for the page you are currently viewing. Firebug will only turn itself on, on a site by site basis, and only after you click on that bug icon. Once it has popped open, you will see some tabs, with many goodies like the fabulous “Net” tab (very useful to make sure swfs are being loaded in the browser), and the “HTML” tab, which contains a live, nested version of your html code, which can be edited in real time – it’s hard to describe how much better life is in the Web Development since Firebug. Anyway, the tab we are interested in, is the “Console” tab – click that. On the actual tab, there will be a little down arrow – click that to open a menu, then click “Enabled” to turn the console on (the onscreen instructions are a little odd, their picture is of the “Script” tab – the arrow you want is on the “Console” tab, not the “Script” tab).
You’ll need to upgrade to IE8. If you are stuck on IE6, I’m sorry for you. You will not be able to easily debug Flash apps – that browser is simply difficult to work with, and you’ll probably need to output to either a text field within flash, or to a div element using JavaScript. Go and download IE8 now, if you don’t already have it. Once you have IE8 installed, you can find the “Developer Tools” under “Tools” menu. You can also press F12 to bring them up. The dev tools in IE8 are docked to the main window, along the bottom of the screen, very much like Firebug. You will notice 4 tabs in a blue bar, below a row of link buttons – click the “Script” tab to open the script tools. You will have two panes at that point – in the left is a debugger, and in the right pane, you should see a button for the Console.
You’ll need to enable the developer tool first, before you can turn on the JavaScript console. Click on the gears icon on the main toolbar, and choose “Preferences”, then click the “Advanced” tab (the one with the gear icon). On that page, there is a checkbox labeled “Show develop menu in menu bar”. Check that, and close the window. Now under the Page icon menu, you’ll see a sub menu called “Develop”. In that sub-menu, choose “Show Error Console”. This will open the “Web Inspector” window. You can dock the window along the bottom of the main window by clicking the dock button in the bottom left of the Web Inspector window. To the right of that button, there is another button with a greater than sign, and three lines. That button will toggle the JavaScript console.
Click the page drop down icon on the right of the main toolbar to open the main menu, then go to Developer, then JavaScript console. This will open the “Developer Tools” window, which contains the many things, including the JavaScript console. You can dock window inside of the main window by pressing the dock button on the bottom left of the popup window. To the right of that button, there is another button with a greater than sign, and three lines. That button will toggle the JavaScript console for Chrome.
Under the Tools menu, choose the “Advanced” submenu, then choose “Developer Tools”. This will open a panel along the bottom of the main window (sensing a trend here?). In that panel, click on the “Error Console” tab. If you’d like to only see JavaScript errors, you can click the bottom JavaScirpt tab (under the white output area of the Error Console). Note: Their is an alternative “Error Console” under Tools -> Advanced -> Error Console. Try them both, and use the one you prefer.
Tracing to the Console
Once you have familiarized yourself with the JavaScript console, you can start to trace to it. The JavaScript command is simple enough:
[cc lang=’javascript’ ]
window.console.log(“your message”).
[/cc]
From Actionscript you’ll need something like this:
[cc lang=’actionscript’ ]
import flash.external.ExternalInterface;
ExternalInterface.call(“console.log”, “your message”);
[/cc]
Since we are using ExternalInterface, you’ll need to make sure you have the allowScriptAccess object param, or embed attribute set to an appropriate value – either “always” or “sameDomain” (sameDomain is the default, so as long as you have your html/javascript/swf all on the same domain, you should be good to go).
You should now be able to trace (or something like it) in the browser. Next time I’ll cover some more advanced uses, as well as some more specific snafus with deep linking and browser back button functionality.
]]>Sloppy change log:
– Fixed Flash Player 10 PlugIn detection.
– Changed license to MIT
– Quick and dirty temp IE8 support (makes IE8 use the timer method).
– removed ObjectPatentMagic
– added Packed library files for Beta 4 (says RC1 in SVN, but I changed my mind, there’s more I’d like to add).
– Added svn:keywords to most files.
– Updated tests for EventManager, FlashPlayerInfo, HistoryKeeper, SwfHTML and SwfShim.
– removed WebTV code, since the entire FlashPlayerInfo script doesn’t work in WebTV anyway.
– Fixed Issue 5. Added methods for major, minor and bugfix versions, to reflect changes to the convention in Flash Player 10 – Also cleaned up issues releated to the changes in IE.
– Added getUpdateVersion for the special case Flash Player 9 updates.
– Quick fix for shimMode on SwfShim.
– Fixes IE support.
– Adds shimMode property (it’s off by default).
– Fixed typo in call to get initial hash value (deep link), which broke it.
– Updates to the HistoryKeeper Actionscript 3.0 files. These changes are generally significant.
– Added asdocs comments (to AS3 files).
– Added support for Opera’s history.navigationMode.
– Made IE8 Hack detection more robust, and IE detectin simpler.
– Initial commit of Actionscript HistoryKeeper and AS3->JS communication framework (really just an easier replacement for fscommand). All of this is pretty rough – vomit draft material.
– Some smaller code comment and formatting cleanups.
– removed problematic _createAnchor functionality. (Issue 6)
– updated IE version detect to be compatible with multi-digit versions.
– Reworked Error messages so that they make sense in FireBug and other Javascript consoles. Fixes Issue #3
– Added direct and gpu WMode values.
– Made value checking case insensitive.
– Added SVN keywords Revision and Date, and added text/javascript mime-type.
– Fixed SwfShim.
Enjoy!
]]>The Tetris game has an event driven engine under the graphics. I wanted it to feel close to the old NES and GameBoy version of the game I remember as a kid, and didn’t want the animation stuff to get in the way of that. The text version of the game in the demo I posted is almost a raw dump of the engine data. The field is a 2D array of 1s and 0s (looking to learn bit shifting and similar concepts at some point, by converting that to a ByteArray of ints). I also did the pieces (tetrads) as 2D array representations of bitmaps at one point, but didn’t feel like working out the rotation math, so I ported a pre-calculated coordinate version of the tetrads from an old Actionscript 1.0 version of a basic tetris game I once wrote.
Quick note about the code – I used TweenLite to do some of the quick animations, but I did not include that in the repository. You’ll need to grab a copy of that yourself, and add it to your class path to compile the source code as it is. At some point I plan to remove that either entirely or replace it with Tweener (because of the licensing).
In regards to game architecture, I don’t know if it follows any particular pattern (MVC seems to be quite popular these days – can’t talk about software design without hearing of that). Anyway, the code is probably far from efficient, as that hasn’t necessarily been a goal as I wrote it, and it’s far from finished, but there are some fun bits in there. Feel free to take a look, and share any thoughts.
]]>There is also a small resurrected Actionscript to Javascript communicator (eh, it’s totally new actually, but I got to use old knowledge!). The theory is that if you use fscommand to send simple strings to Javascript, you save on Flash setting up a lock to wait for a Javascript call to return a value or finish executing, which should conceivably avoid a short hiccup in the Flash Player. I’m not sure if there’s a real world benefit or not yet – one day I might get around to testing to make sure. At the very least, this framework will make it easier to setup fscommand, since it takes care of creating the javascript snippet for you. After that, it will simply eval whatever you put in the command argument (unless it’s a simple function on window, then it’ll just execute that).
Any comments are welcome. Please note, these classes may change quite a bit, they’re not to be considered stable (though the API probably is, there’s not much there really).
]]>The script did require some modification to get it to work with SwfHTML, since it was designed to work with SwfObject. It took very little modification to the JavaScript to make it work with any flash embedding script. The script has a register method that takes an id, and uses SwfObject’s getObjectById method to get the swf ref – I just changed the register method to take a swf reference instead of an id string, and viola! It works with anything now. While I was at it, I also took care of some errors you might get on non-mac browsers. Here’s how to use it:
[cc lang=’javascript’ ]
// with SwfHTML
swfmacmousewheel.registerObject(
unFocus.SwfUtilities.getSwfReference(“swfId”)
);
// with SwfObject
swfmacmousewheel.registerObject(
SwfObject.getObjectById(“swfId”)
);
[/cc]
You can really use any method you want to get a reference to the swf object, and pass that in.
Here is the updated swfmacmousewheel javascript file. Note, you will still need to grab the source and follow the instructions from Pixel Breaker.
]]>Update: Moved to a separate page.
Click to give flash focus – arrows move, up arrow rotates.
There’s no start button, or end to the game – and no levels or scores either. But it’s a start.
]]>There have been a couple of fixes and changes that have gone into HistoryKeeper, SwfHTML and SwfShim that are now in the SVN trunk, as well as a few other issues that have been nailed down, and put into the issue tracker.
Among the fixes are finally a fix for the incorrect use of Javascript Errors in SwfHTML, as well as fixing the previously unfinished SwfShim.
Despite the fact that I can’t figure out how to pass flashvars from SwfShim to loaded AS3 based swfs, I’m still going to include it anyway, with a note about that caveat. It does solve some other issues, and adds an easy way to utilize ExpressInstall even if you are using html to embed the swf (rather than javascript). More on that in a future post.
I’ll also be cleaning house around the site, here and on google code. I’ve already removed some old lingering (and useless) ad stuff.
Also, since Microsoft removed the “click to activate” silliness, I went ahead and deprecated PatentMagic. It was buggy anyway.
Check back for more updates, and hopefully, an actual release!
]]>I’ll see about getting a release out soon. If anyone needs any help updating anything, feel free to leave a comment, or email me.
]]>Feel free to download, test and use the new beta. Here’s what’s new and fixed:
Check out the updated project page for more info, or just skip straight to the download.
]]>