Base64 Encoding BitmapData

Turn your BitmapData into a string and back! Great for storing images in XML, Databases, or transmitting them over a network. This post will cover Bitmap Encoding, PNG Encoding and JPG Encoding along with the pros and cons for each.

Bitmap Encoding - (link)

Actionscript:
  1. // Encode
  2. var encoded:String = BitmapEncoder.encodeBase64(bitmap.bitmapData);
  3.    
  4. // Decode
  5. var bd:BitmapData = BitmapEncoder.decodeBase64(encoded);

Advantages:
Keep transparency
Fastest Method
Does not require a Loader

Disadvantages:
Largest Filesize
Will only work with images up to a certain size

PNG Encoding - (link)

Actionscript:
  1. // Encode   
  2. var ba:ByteArray = PNGEncoder.encode(bitmap.bitmapData);
  3. var encoded:String = Base64.encodeByteArray(ba);
  4.  
  5. // Decode   
  6. var decoded:ByteArray = Base64.decodeToByteArray(encoded);
  7. var loader:Loader = new Loader();
  8. loader.loadBytes(decoded);

Advantages:
Keep transparency
Smaller filesize than Bitmap Encoding

Disadvantages:
Slower than Bitmap Encoding
Larger than JPG Encoding
Requires Loader

JPG Encoding - (link)

Actionscript:
  1. // Encode
  2. var jpgEncoder:JPGEncoder = new JPGEncoder();
  3. var ba:ByteArray = jpgEncoder.encode(bitmap.bitmapData);
  4. var encoded:String = Base64.encodeByteArray(ba);
  5.  
  6. // Decode
  7. var decoded:ByteArray = Base64.decodeToByteArray(encoded);
  8. var loader:Loader = new Loader();
  9. loader.loadBytes(decoded);

Advantages:
Smallest Filesize
Variable Quality

Disadvantages:
Slower than Bitmap Encoding
No Transparency
Requires Loader

Adding Server Side Captcha to Flash Forms

Problem:
Flash forms are very vulnerable to attacks. Spiders may not be able to easily iterate through your Flash content but they can sure spam your form submission URL. How can you be sure your form was submitted through Flash?

Definition:
A CAPTCHA or Captcha is a type of challenge-response test used in computing to ensure that the response is not generated by a computer.

Solution:
What if we have a user drag a circle onto a box? A spider would have a pretty hard time with that, right? WRONG. While this may be a good filter at the view level it still does not solve our problem. All the hacker would need to do is submit the form correctly one time and use a program like Firebug to sniff the submission URL. They could then completely bypass your view and submit the form as many times as they want.

The only way to ensure the Flash form is being used is to pull the logic out of the view and onto the server. The Flash merely serves up content and never knows what the 'answer' is. In this example we will use PHP to generate the image, MySQL to store the key value pairs, and Flash to display the content. This implementation does not require any images to be stored on the server so it NEVER re-uses an existing image. The PHP generates the image on the fly and serves it directly to the Flash application.

Here is a diagram representing the high level information. Blue lines represent Captcha generation and the red lines represent the Captcha verification.

Server Side Captcha in Flash

Server Side Captcha in Flash

Let's start with the PHP. There are already plenty of PHP scripts out there to generate Captcha. In this example I re-purposed a script called Securimage.

First we need a script that will retrieve the image:

PHP:
  1. <?php
  2. $flash_id = $_GET['flash_id'];
  3. include 'securimage.php';
  4. $img = new securimage();
  5. $img->show($flash_id); // alternate use:  $img->show('/path/to/background.jpg');
  6. ?>

Next we will need one that verifies the user input with the image:

PHP:
  1. <?php
  2.  
  3. $flash_id = $_GET['flash_id'];
  4. $captcha_text = $_GET['captcha_text'];
  5.  
  6. if ($flash_id && $captcha_text){
  7.     $con = mysql_connect('localhost', 'DB_USERNAME', 'DB_PASSWORD');
  8.     if (!$con) {
  9.         die('Could not connect: ' . mysql_error());
  10.     }
  11.     mysql_select_db("utils", $con);
  12.     $result = mysql_query("SELECT * FROM captcha WHERE flash_id = '".$flash_id."'");
  13.     $match = 0;
  14.     $valid = 0;
  15.     $answer = "false";
  16.     while($row = mysql_fetch_array($result, MYSQL_ASSOC))
  17.     {
  18.         if($row['valid'] == 1)
  19.         {
  20.             $valid = 1;
  21.            
  22.             if($row['captcha_id'] == $captcha_text){
  23.                 $match = 1;
  24.                 $answer = "true";
  25.             }
  26.         }
  27.        
  28.     }
  29.     if($valid == 1){
  30.         mysql_query("UPDATE captcha SET valid = '0' WHERE flash_id = '".$flash_id."'");
  31.        
  32.     }
  33.     echo $answer;
  34.     mysql_close($con);
  35. }
  36. ?>

Now that we have the PHP in place we can create the Flash. The display logic is separated from the view so you can re-use this code with any server side script. The Captcha class requires an ID and a URL to the image to display. It has optional styling parameters to match the look and feel of your webpage.

Generating a Captcha in Flash:

Actionscript:
  1. // Create a Captcha object
  2. _captcha = new Captcha( );
  3.  
  4. // Create a unique ID so the server can identify the Flash
  5. var date:Date = new Date();
  6. var id:String = "" + Math.floor(Math.random()*1000) + date.time;
  7.  
  8. // Pass in the url along with the ID so the Captcha can load
  9. _captcha.loadCaptcha("http://www.blackcj.com/utils/securimage_show.php?flash_id=" + id, id);

Verifying a Captcha in Flash:

Actionscript:
  1. var loader:URLLoader = new URLLoader();
  2. loader.addEventListener(Event.COMPLETE, formSuccess, false, 0, true);
  3. var request:URLRequest = new URLRequest("http://www.blackcj.com/utils/check_captcha.php?flash_id=" + _captcha.id + "&captcha_text=" + _text.text);
  4. loader.load(request);

Flash Demo and Source:

Server Side Captcha for Flash

Get Adobe Flash player

(click the image to manually refresh the captcha)

Full source code for Flash & PHP can be found here.

In the source code you will need to replace DB_USERNAME and DB_PASSWORD with your username and password. This example also requires a MySQL database with a table called captcha containing rows flash_id, captcha_id and valid. Valid is used to ensure the Captcha is only submit one time. Since we are always generating a new image there is no reason the Captcha should be allowed to be submitted twice with the same id.

Next Steps:
Additional steps could be taken to prevent robots. Failure rates and number of attempts could be stored for each IP address. No human should ever attempt to re-submit an old Captcha since each time it is randomly generated. The system could block anyone that attempted to re-submit a Captcha.

I would eventually like to make this accessible by integrating audio support. This is a feature of Securimage and would make the utility more versatile.

Build a Flash Game in Under 3KB

Here are three Flash games each built in under 3KB and in less than 4 hours. They may not be Half Life 2 but they are entertaining! Try your luck at the racing game, platform game, and a space shooter that I like to call Little Ship vs. Space.

Wait? Doesn't everybody have loads of bandwidth? Why create a game so small? Well, because it's fun, a good preparation for the 4KB challenge and most importantly size != entertainment. You may spend weeks designing, architecting, and developing a game only to find out it's not fun. Evolve your game.

Build a 4KB game. If you enjoy playing it then slowly build it up into something better. Add levels, create graphics, improve the structure but AFTER you've come up with a cool idea.

Lets play some games! Don't forget to vote for your favorite game in the poll bellow the games.

For all games click on the icon in the top right to re-start.

Racer Game (1.98KB):

Racing Game

Get Adobe Flash player

(Use the Left, Right, and Up arrows to move. Try and beat 20 seconds!)

Full source for the Racer game: zip (2.09KB)

Coin Collector (2.08KB):

Coin Collector

Get Adobe Flash player

(Use the Left, Right, and Up arrows to move. Try and beat 16 seconds!)

Space Shooter (2.99KB):
Notice: MAC users have reported issues with the arrow keys in the Space Shooter game. I will look into this shortly and post a new, functional, version. Looks like I need a MAC to test on ;)

Space Shooter

Get Adobe Flash player

(Use the Left, Right, and Up arrows to move. Ctrl (Command) to fire. Try to get more than 4 frags!)

How to do it:
After rudimentary tests Flash CS3 is the best enviornment to compile with. A pure AS3 project in Flex and a project built from CS4 add 500 bytes of overhead (Anyone know why? Maybe meta data?). You also save space by using an external AS file, so create a main.as file for your code. Put all of your code in this one file! Every additional AS file adds space rather than saves. Once your game is setup if you absolutely need one or two extra AS files than make them. Type all of your functions and variables. You'd think it would be the opposite but typed vars take up less space in the compiled SWF. Don't use MouseEvent.CLICK, use "click" to save some bytes.

Now for the game play.

All three games use the arrow keys as input. Individual key listeners / flags use way to much code! What are the values for left, right and up arrows? 37, 39, and 38. None of which are divisible by anything but themselves. So... lets add one key listener and multiply our single key value by the code value. Up = 38, Up * Left = 1406. That means that key value % expected value == 0 than our key is down. This only works for key values that don't have common denominators, key codes 2 and 4 would not work. Both 2 and 4 mod 4 would result in true. Looking back you could also push these codes into an array and do an index check which would allow more flexibility... mod is more fun though.

Actionscript:
  1. package {
  2.     import flash.display.MovieClip;
  3.     import flash.events.Event;
  4.     import flash.events.KeyboardEvent
  5.    
  6.     public class main extends MovieClip
  7.     {
  8.         private var k:int = 1;    // Keyboard number
  9.  
  10.         public function main()
  11.         {
  12.             this.addEventListener("enterFrame", eF);
  13.             stage.addEventListener("keyDown", kD);
  14.             stage.addEventListener("keyUp", kU);
  15.         }
  16.         private function eF(e:Event)
  17.         {
  18.             if(k%37 == 0)            
  19.                 trace('rotate object left');
  20.             if(k%39 == 0)
  21.                 trace('rotate object right');
  22.             if(k%38 == 0){ 
  23.                 trace('add velocity');
  24.             }else {
  25.                 // remove veloicty
  26.             }
  27.         }
  28.         private function kD(e:KeyboardEvent)
  29.         {
  30.             if(k%e.keyCode != 0)
  31.                 k *= e.keyCode;
  32.         }
  33.         private function kU(e:KeyboardEvent)
  34.         {
  35.             if(k%e.keyCode == 0)
  36.                 k /= e.keyCode;
  37.         }
  38.     }
  39. }

Both the Coin Collector and the Racer game use bitmap hit detection which is very little code and very powerful. Bitmap hit detection looks a bit like this:

Actionscript:
  1. /* Constructor */
  2. // Car BitmapData, built in the enter frame function
  3. sb = new BitmapData(500, 400, true, 0x00000000);
  4.  
  5. // Track BitmapData, doesn't move / change so lets build it here
  6. tb = new BitmapData(500, 400, true, 0x00000000);
  7. m = new Matrix();
  8. m.tx = t.x;
  9. m.ty = t.y;
  10. tb.draw(t, m);
  11.  
  12.  
  13. /* Enterframe loop */
  14. // First see if bitmap hit detection is needed.
  15. if(s.hitTestObject(t)){
  16.     // Clear our car bitmap data object
  17.     sb.fillRect(new Rectangle(0,0,500, 400), 0x00000000);
  18.    
  19.     // Create a matrix that defines the location and rotation of the car
  20.     m = new Matrix();
  21.     m.rotate((Math.PI/180) *s.rotation);
  22.     m.tx = s.x;
  23.     m.ty = s.y;
  24.    
  25.     // Draw the car to our BitmapData using the matrix
  26.     sb.draw(s, m);
  27.    
  28.     // Do a hit detection with the track BitmapData
  29.     if(tb.hitTest(new Point(0,0), 0xFF, sb, new Point(0,0), 0x11)){
  30.         v = 1.1;
  31.     }
  32. }

The space game deals with circles so that code uses Trigonometry for hit detection. We'll save that for another day. I need to clean it up a bit for it to really make much sense. Stay tuned for more on games!

Full source for the Racer game: zip

Q/A:

Why 3KB?
My initial goal was 4KB. I hoarded the KBs so much that they all ended up under 3KB. I suppose that means I should add more features / levels.

Whats with the sudden interest in games?
I actually used to be big into making games back in the AS2 days about 4 years ago. I built out a six level space shooter, 8-ball, and 9-ball billiards. My game programming was shelved for four years until one of my co-workers sparked my interest by mentioning the 4KB challenge :)

Can I have the source code for the other two games?
E-mail me with specific questions and I'll be happy to help. I built out the Coin Collector and space games using the Racer as a starting point. It wouldn't be fun if I gave away all the answers ;)

People who inspired me to make these games:
Iain Lobb
Game Poetry
Micheal Hills

Best of Flash on the Beach ‘09

Back in the U.S. and recovered from jet lag, I've compiled a list of the best sessions, restaurants, beer and more from FOTB09. Plenty of reasons to go back again next year!

Best Session:
Carlos Ulloa - Hello Enjoy. Carlos, the creator of PV3D, demoed three amazing projects. He even gave some insight as to how he solved challenges in those projects and provided a time line of effort between software packages.

Best Code Jam:
Joa Ebert - Live coding. All of the Jam sessions were great but Joa's live coding was beyond words.

Joa Ebert's java live coding at Flash on the Beach 2009 from Thomas Gabrielsen on Vimeo.

http://blog.joa-ebert.com/

Best Food:
Bill's - Produce store by day, restaurant by night. I didn't have any bad food in Brighton but this restaurant was the highlight of the trip. A must visit for anyone traveling to Brighton.

Map of Bill's Restaurant

Map of Bill's Restaurant


http://www.billsproducestore.co.uk/

Other notable restaurants include Pizza Express, Iguana, Bagleman's and a Japanese restaurant.

Best Beer:
Harveys Best Bitter

Harvey's Best Bitter

Harvey's Best Bitter

http://www.harveys.org.uk/

Best Destination:
The Brighton Pier - Loads of rides, food and sights to see at the Brighton Pier. I skipped out on a couple sessions one of the afternoons to check it out. Definitely worth while to check out. Make sure to bring some coins for the arcade machines.

Brighton Pier

Brighton Pier

Best Inspiration Session:
Joel Gethin Lewis - Joel walked through his experiences with Massive Attack and contributions to open source frameworks.

Best Hotel:
Premier Inn - The staff was great, the rooms were clean and the price was reasonable. I would highly recommend the Premier Inn to anyone attending Flash on the Beach or traveling to Brighton.

Until next year!