I’ve been toying with an entry into the 4k game competition held at gamepoetry. The game I’m making uses the keyboard for controls which is a bit rare for me.
AS2 had a very useful method called Key.isDown() whose functionality is pretty self explanatory. This isn’t available in the much more event driven AS3, but when doing something as tiny as 4k it’s a pretty useful thing to have. So I wrote my own tiny little version of it. A bare bones swf with nothing but this code weighs in at about 750bytes, but it’s not that big of an addition to your filesize since the swf has some basic stuff that adds to the size. The demo code adds another 200 bytes, but that’s meant to be stripped out.
Note that the trick is to add this into your main class, not to put is as a class of it’s own. That adds too much to your filesize.
I also recently discovered wonderfl which is a crazy cool online actionscript editor thingie. You can try the code live there! or the new even smaller version.
If that’s not your cup of tea, here’s the code in plain old boring text:
(This is an updated version, a whopping 17 bytes smaller)
package { import flash.display.Sprite; public class STKI extends Sprite { // this stores all key states // For some reason this seems to be smaller when typed public var k:Object; private var block:Sprite; public function STKI () { k = { }; // shorthand for initializing a object // the trick is to use the dynamic nature of objects, // if the property exists it's overwritten, // if it doesn't it's created // the function actually gets a KeyboardEvent, but // having it untyped makes it smaller // So does using a regular ("keyDown") string instead // of the static one provided by the event. stage.addEventListener("keyDown", function(e:*):void{ k[e["keyCode"]] = true}); stage.addEventListener("keyUp", function(e:*):void{ k[e["keyCode"]] = false}); // this is just to show that it works block = new Sprite(); block.graphics.beginFill(0xff00ff); block.graphics.drawRect(-4, -4, 8, 8); block.x = 250; block.y = 250; addChild(block); addEventListener("enterFrame", handleEnterFrame); } private function handleEnterFrame(e:*):void{ // this is how you use it, just access the keyCode // in the object, it acts just as good old Key.isDown // from AS2 if (k[37]) { //left block.x -= 1; } else if (k[39]) { // right block.x += 1; } if (k[38]){ // up block.y -= 1; } else if (k[40]) { // down block.y += 1; } } } }
that’s fantastic, and here I thought this couldn’t get more ugly. nice work!
Hey, great tips! I used this technique in my 4k game entry, and actually improved on it a little. In the keyboard handler, change “true” and “false” to be 1 and 0, then in your update function, use: block.x += k[39] – k[37]; // Right – Left block.y += k[40] – k[38]; // Down – Up You have to initialize your k array to be equal to a string of 40 or 50 0’s, but I found that compresses really well, and the bytes saved are more than worth it. private var k:Array = [0,0,0,0,0,0,0 …. ,0,0,0]; Cheers! –clint
Nice one 🙂 I do use un-typed vars, but not until the very end because it stops lots of the context sensitive assists from working in FlashDevelop! (same for strings replacing constants)
I changed the event handlers into inline functions and that saved me a good 17 bytes. Thanks Richard. Using an array instead of an object actually added 2 bytes for me. You really should try using untyped arguments and plain strings instead of the constants, that’ll save you something like 11 bytes!
If you’d like to save yourself even more bytes you could do the following: 1) Use an array instead of an Object and 2) Wrap the function into the event listener call itself. Functions add quite a lot of extra bytes to the SWF, the less of them you have in your final game, the smaller it will be! Here’s the code I use: stage.addEventListener(KeyboardEvent.KEY_DOWN, function (e:KeyboardEvent) { keys[e.keyCode] = true; }); stage.addEventListener(KeyboardEvent.KEY_UP, function (e:KeyboardEvent) { keys[e.keyCode] = false; } );