Blog Archives

Monday, December 29th, 2008 | Author: Dave

Yeah… so it’s been too long. But time flies when you have a baby… whew does it. But, here’s a link to some pictures Jackie has posted on the Kodak site… more to come.

http://www.kodakgallery.com/ShareLanding.action?c=o1r4veu.9ctvhrwe&x=0&h=1&y=-tx68zn&localeid=en_US

Category: Life  | One Comment
Wednesday, November 26th, 2008 | Author: Dave

Kaden was delievered at 11:48 am. He weighed 6 lbs 10 oz and was 19.5″ long. The pitocin did exactly what it was supposed to do – the nurses and doctor Leonhardt were all really great and it went as smooth as we could’ve ever hoped for. Jackie was awesome… she pushed so hard. She was beautiful. We took a bunch of pictures and I will get them posted sometime tomorrow evening if I can find some time.

Category: Life  | Comments off
Wednesday, November 26th, 2008 | Author: Dave

The day has finally arrived – well tomorrow actually. Jackie is being induced because her blood pressure was a bit elevated and they worried about preeclampsia, so they’re giving here Pitocin early tomorrow morning. I’m a little nervous about that – Pitocin isn’t exactly safe according to some sites I’ve been reading. Anyway, I’ll have pictures later tomorrow or Thursday… stay tuned

Category: Life  | One Comment
Saturday, November 15th, 2008 | Author: Dave

I got some Chuck Norris facts in my email yesterday and it reminded me how funny those are. Here are a few of my favorties:

If at first you don’t succeed, you are not Chuck Norris.

The chief export of Chuck Norris is pain.

Chuck Norris cannot love, he can only not kill.

Chuck Norris ordered a Big Mac at Burger King, and got one.

If you have $5 and Chuck Norris has $5, Chuck Norris has more money than you.

Aliens do exist. They’re just waiting for Chuck Norris to die before they attack.

Kenny G is allowed to live because Chuck Norris does not kill women.

Chuck Norris’ tears cure cancer. Too bad he has never cried.

Chuck Norris is what Willis was talking about.

Chuck Norris does not believe in Germany.

Chuck Norris does not sleep. He waits.

Chuck Norris counted to infinity – twice.

Chuck Norris can divide by zero.

For Chuck Norris, each testicle is larger than the other one.

The last digit of PI is Chuck Norris. Chuck Norris is the end of all things.

Category: Humor  | Comments off
Monday, November 10th, 2008 | Author: Dave

A couple of days ago, in the flash.sitedesign forum, someone asked about creating a flashing random thumbnail gallery – and cited http://www.stevenlippman.com/ as what they had in mind. Lucky for you, I thought it would make for a good tutorial.

If you look at that site long enough, you’ll see it’s not actually random at all and its not even dynamic. Probably it’s hand placed movie clips with time line animation. That’s what I call the hard way. The easy way is programmatic, dynamic, and easily modified.

Here’s an example of the finished product

First let’s consider the various components:

  1. Get a list images to use
  2. Create grid of MovieClips to load these images into
  3. Each clip loads images in random order with random timing

Get a list of images to use:
There are a few ways this could be handled. For this tutorial I have chosen to use XML to define the images. XML files are nice because they are human readable and modified by anyone.

Create grid of MovieClips:
A little bit of math will make easy work out of creating a grid of movie clips in any combination of columns and rows.

Each clip randomly loads and displays images:
An ActionScript class that extends MovieClip will allow you to easily hang custom code off of all your script created grid clips.

Part A/2 – Init
First, create a folder for this tutorial. Name it something like ‘flashingThumbs’ and use that as the project folder to place all the files in. Within this folder also create an ‘images’ folder – to house the thumbnails that will be displayed.

Part A – The XML
Copy the following XML, paste into a text file, and save it in your project folder as gallery.xml

<gallery>
	<image title="Title a">a.jpg</image>
	<image title="Title b">b.jpg</image>
	<image title="Title c">c.jpg</image>
	<image title="Title d">d.jpg</image>
	<image title="Title e">e.jpg</image>
	<image title="Title f">f.jpg</image>
	<image title="Title g">g.jpg</image>
</gallery>

Although it’s simple – it could be made even simpler by leaving out the title attribute. However, I added this on purpose, both to show reading of attributes, and to make expansion in the future more straight forward. More on that later.

Don’t worry about the images themselves, you can get all of them in the project .zip file at the end of the tutorial. I even stole them from the Steven Lippman site. Of course you can, and should, use your own thumbs – just make sure they’re all 40×40 like the ones supplied.

In Flash, start a new AS 2.0 movie, set it’s size to 730 x 400, and give it a black background. Add the following script to the first frame of the default layer, Layer 1:

var theXML = new XML();
theXML.ignoreWhite = true;
 
//an array of image objects populated from xml
var gallery:Array;
//folder containing the images that are defined in the xml
var thumbFolder = "images/";
 
//called automatically when the xml is done loading
theXML.onLoad = function(success)
{
  if (success) {
    gallery = new Array();
    theXML.parseXML();
    var len = theXML.firstChild.childNodes.length;
    trace(len);
    for (var i = 0; i < len; i++) {
      var item = new Object();
      item.title = theXML.firstChild.childNodes[i].attributes.title;
      item.image = theXML.firstChild.childNodes[i].firstChild.nodeValue;
      gallery.push(item);
    }
    buildGallery(135);
  }
};
 
theXML.load("gallery.xml");
stop();

Save the movie as gallery.fla in your project folder and compile and run the movie. You should see ‘7′ appear in the output window – the number of images defined in the xml file. if you run the movie without saving first, you’ll get an error about the gallery.xml file not being found. Both the Flash file and the xml file need to reside in the same folder – since no path is specified – just ‘gallery.xml’.

First the gallery.xml file is loaded and when complete the onLoad method of the xml object is called.  If success, then no error occured and the remainder of the function executes. The returned xml is parsed and a for loop is used to iterate the nodes. For each node an object ‘item’ is created and given two properties title, and image – their values being fed from the xml. The item is then pushed onto the gallery array and the loop continues.

When complete you have an array ‘gallery’ with as many items as there are images defined in the xml. Each item in the array is an object with title and image properties. It would look something like:

gallery = [{title:"Title a", image:"a.jpg"}, {title:"Title b", image:"b.jpg"}, {title:"Title c", image:"c.jpg"}, ...{}]

If you want the first image in the array you merely need do:

firstImage = gallery[0].image;

This is the reason I added the title attribute to the xml file. If the xml had contained only the image listing, and no attributes, an array would’ve sufficed. With the title attribute defined, it warranted a more complex data type – an array of objects. Also nice because it gives you the ability to select data by name. If you add more attributes to the xml, simply add them to the object as well, inside the for loop. The underlying gallery array, and any code that consumes it, need not change at all – unless you want to make use of the newly expanded data within the objects.

Don’t worry about the call to buildGallery() – we’ll get to that momentarily.

PS – you can remove the trace from the onLoad as you know it’s working properly.

Part B – Create a grid of clips

First, you’ll need an empty movie clip that will be used as a place holder to load the images into. We’ll use a clip from the library as opposed to creating a clip from code, so that a custom class can easily be linked to each of the clips.

On the Flash stage press Ctrl-F8 – to open the create symbol dialog. Press the advanced button at lower right to display the full dialog:

Give your clip the same settings as is shown – be sure to differentiate between ‘thumb’ and ‘Thumb’ in the identifier and class fields.

Click OK, to close the dialog.

Select the script icon on frame 1, and open the script editor. Near the top of the script, Immediately after the declaration for the gallery array and right before the onLoad definition, add the following:

var thumbsPerRow = 15;
var thumbWidth = 40;
var thumbHeight = 40;
var thumbSpace = 8;
var startX = 10;
var startY = 10;
 
 
function calcPosition(ind:Number):Array
{
  var whichCol = ind % thumbsPerRow;
  var whichRow = Math.floor(ind / thumbsPerRow);
 
  var curThumbX = startX + (whichCol * (thumbWidth + thumbSpace));
  var curThumbY = startY + (whichRow * (thumbHeight + thumbSpace));
 
  return [curThumbX, curThumbY];
}

This is the little bit of math I alluded to earlier. The variable usage should be pretty self evident by their naming. As in the example, we’ll use 15 thumbs per row, and each thumb will be 40×40.  If you do want to use a different thumb size, this is the place to change it. There will be eight pixels between thumbs, and the grid will begin at 10, 10. Simple enough. Using that information the calcPosition function will return the x,y point where any thumbnail should be – given the thumbnails number: 0 – n.

First, the column is found by using the mod operator: % – which returns the remainder of integer division. Dividing the thumb number by how many thumbs per row there are, and then seeing how many are left, gives the column. For example, take the whole first row, thumbs 0 – 14 – you can’t divide any of those by 15 with integer math. What’s left is the number itself: 0 – 14. In the second row, thumbs 15 – 29, it goes like so: 15 goes into 15 evenly, with no remainder – so 0 is returned. 15 goes into 16, with 1 as the remainder. etc, etc. If you create 135 thumbs (0 – 134) then the last thumb goes into column: 134 % 15 = 14. Nifty. From there, getting the x position of the thumb is a bit of simple math.

To get the row, we again divide the thumb number by the number of thumbs per row, but this time we use regular division. If we’re at thumb 134 then 134 / 15 = 8.93333. The floor method is used to get the closest integer less than, or equal to, the target. The floor of 8.9 = 8. So, thumb 134 goes into row 8 – given the 0 based system – that is really row 9. Again, with a bit of math, it’s now easy to find the y value where the thumb should go.

The x,y value is then returned in an array. All we need now is a function that will attach n clips from the library, and position them using calcPosition(). Enter buildGallery(). Paste the following right after the calcPosition() function:

function buildGallery(numThumbs:Number)
{
  //uses the records in the gallery array
  for (var i = 0; i < numThumbs; i++) {
    var p = calcPosition(i);
    var aThumb = this.attachMovie("thumb", "thumb" + i, 10 + i, {_x:p[0], _y:p[1]});
    aThumb.init(gallery, thumbFolder);
  }
}

As you noticed earlier, buildGallery(135) is called once the xml is loaded and the gallery array is built. All buildGallery does is attach the empty thumb clip you created earlier, at the position indicated by calling calcPosition().

Additionally, an init method is called on every thumb created – and both the gallery array, and the thumb folder are passed in. The init method is located in the Thumb class, the class attached to all instances of the thumb clip.

You should save your Flash movie. If you compile and run the movie now, your grid will be created – you just won’t be able to tell since all the attached clips are blank.

At this point, if you’d like to see the grid, you can double-click the empty clip in the library to edit it, add a 40×40 gray rectangle (at 0,0) and then run the movie. You should see a grid of gray clips now. Be sure to remove the rectangle when you’re done.

Part C – Each clip loads images in random order, with random timing

With the grid working, and the gallery xml loading properly the final thing to do is create the Thumb class. This class will extend the MovieClip class, and bestow our empty thumb clips with additional powers. Specifically, they will randomize and store their own copy of the gallery array, and then load the images one after another, at random intervals.

To create the class (Thumb.as) you can use Flash, or any number of external editors. I prefer FlashDevelop myself, which you can find here:

If you’re using Flash, just select File > New > ActionScript File

Add the following:

class Thumb extends MovieClip
{
private var imageFolder:String; //user defined, used by onLoad to load images from the folder
private var myArray:Array; //the thumbs own randomized copy of the gallery array
private var curIndex:Number; //the current index within the gallery array - the current thumb
private var myMCL:MovieClipLoader;
private var myLis:Object; //listener for the movie clip loader
private var myTimer:Number; //random timer that calls doLoad() when it times out
private var usedClips:Array; //used image clips - used to be able to delete old images
 
//CONSTRUCTOR
function Thumb()
{
  myMCL = new MovieClipLoader();
  myLis = new Object();
  myLis.classRef = this;
  myLis.onLoadInit = function(){
    this['classRef'].oli();
  }
  myMCL.addListener(myLis);
}
 
//local onLoadInit
function oli(){
  if(usedClips.length > 1){
    var d = usedClips.shift();
    var i = curIndex;
    d.unloadClip();
    d.removeMovieClip();
  }
  curIndex++;
  if(curIndex >= myArray.length){
    curIndex = 0;
  }
  myTimer = _global.setTimeout(doLoad, Math.ceil(Math.random() * 3000) + 500, this);
}
 
//called by code that attaches thumb
function init(gallery:Array, fold:String)
{
  imageFolder = fold;
  myArray = new Array();
  usedClips = new Array();
  var tempArray:Array = gallery.slice(); //duplicate gallery
  while(tempArray.length > 0){
    var it = tempArray.splice(Math.floor(Math.random() * tempArray.length), 1);
    myArray.push(it[0]);
  }
  curIndex = 0;
  doLoad();
}
 
//internal class method that loads the current image into a new movieClip
private function doLoad(scope)
{
  var cScope = scope == undefined ? this : scope;
  var lastRef = cScope.createEmptyMovieClip("pic" + cScope.curIndex, 10 + cScope.curIndex);
  cScope.usedClips.push(lastRef);
  cScope.myMCL.loadClip(cScope.imageFolder + cScope.myArray[cScope.curIndex].image, lastRef);
}
}

OK, that’s it for the code. Save the ActionScript as Thumb.as – within your project folder. Now, every time an instance of the thumb clip is attached, this class’s constructor (the Thumb() function) will be executed. You don’t have to call it, it runs automatically. The constructor simply initializes a MovieClipLoader so that the thumb can load images. A listener is also created, which calls the class method oli() whenever a new image is loaded.

Recall that the buildGallery() function calls each thumbs init() method as it is attached.  The init() method is passed the main gallery array, and a string giving the name of the folder containing the images. It stores the passed in folder name in a local class variable (so it can be used in doLoad), initializes the two arrays to empty and begins the task of randomizing the passed in gallery array. First, the array.slice method is used, which when passed no parameters returns a duplicate of the original array. You want a duplicate because arrays are passed by reference and you don’t want to alter the original. A while loops is used to iteratively get items at random places in the array, and build myArray. The array.splice method is used to return the random item, and delete it from tempArray. The item is then pushed onto myArray. The while loop continues to execute as long as there items remaining in tempArray. This suffices to shuffle the original array, storing the items in the class variable myArray. The curIndex variable is then reset to 0 and an initial call to doLoad() is made.

The doLoad method first tests the scope variable, and if undefined sets cScope to ‘this’ – class scope. If it is defined then cScope is set to it. This is done because doLoad is also called from the timeOut object and when it is ‘this’ references that object – and not the class. I solved it by passing a class reference to the method, from the timeout object. There are other ways to deal with scope issues in AS2, including the use of the Delegate class, but I chose this method. Note that doLoad is defined to be private because it shouldn’t be called from outside the class.

So, using the cScope variable a new movieClip is created within the empty thumbnail, both its new name and depth are functions of the currentIndex. A reference to the clip is pushed onto the usedClips array and then the loadClip method is called, loading the current image into the new clip.

When the image is loaded the onLoadInit method the MovieClipLoader class will be invoked, and a call to the oli() (short for onLoadInit) class method will be made. I call oli() from onLoadInit in order to invoke it in the class’ scope – otherwise the code within the oli() method would need references to any class variables or methods – because again ‘this’ within onLoadInit will refer to the loader and not the class.

The oli() method is quite simple really, it’s main function is to simply increment curIndex and then set a timeout to call onLoad after some random interval. The other thing it does is process the usedClips array. Whenever the array has more than one clip reference, the first item is removed (using array.shift), the image is unloaded and the clip is deleted. This prevents a stack of ‘pic’ clips from forming, and frees memory as well. Note that the removal of old clips works because new clip references are ‘pushed’ onto the usedClips array, and old clips are removed from the array using shift. Push adds an object to the end of the array, while shift removes an object from the beginning. The result of this push/shift is sometimes known as a LIFO, or Last In First Out.

Calling setTimeout in the _global object space is required from within a class file. It prevents the compiler from complaining that the setTimeout method is not defined.


The movie should now compile and run without problem. If you don’t have a group of thumbnails to use you can use those included in the source zip file below.

Download the source files, as well as thumbnail images here.

Category: Flash  | Comments off
Sunday, November 09th, 2008 | Author: Dave

I thought I’d write a quick summary of some bug hunting goodness over the weekend. For some time I have used a custom file loading class that allows me to pass it an array of targets, and URL’s and it happily loads them one after another and calls a listener when complete. Its always worked great – until this time.
Within the class I pop an element off the top of the passed in loader array, using the shift() method. The shift() method deletes the element – so when the array is empty everything has been loaded. The problem appeared when I later wanted to reference an item in the original loader array, within my movie, and found it was empty. The problem can be seen in this code clip from the class:

private var loaderArray:Array;
 
public function init(loadArray:Array):Void
{
    this.loaderArray = loadArray;
}

Some of you will recognize the issue immediately – and I would have too, had I ever needed to use the original array before. The problem is that arrays are not passed by value. When you set loaderArray = loadArray you are not placing a copy of loadArray into loaderArray. What you are doing is simply setting loaderArray to a memory address, so that it references (points to) the same array. Most of the time this is desirable as it saves on memory, and as long as you’re aware of how it works there is no problem. But sometimes you forget.
So, after finally realizing why my original array was getting erased I corrected it by copying the array instead:

private var loaderArray:Array;
 
public function init(loadArray:Array):Void
{
    for(var i = 0; i &lt; loadArray.length; i++){
        loaderArray.push(loadArray[i]);
    }
}

At least I thought I had corrected it. Anyone see the problem now? The compiler doesn’t see anything wrong either. However, loaderArray doesn’t get anything pushed to it – because it was never initialized. It’s a null object. The compiler doesn’t see anything wrong because loaderArray is typed as array, so push is fine. Fixing is as simple as:

private var loaderArray:Array;
 
public function init(loadArray:Array):Void
{
    loaderArray = new Array();
 
    for(var i = 0; i &lt; loadArray.length; i++){
        loaderArray.push(loadArray[i]);
    }
}

This is only an issue in the AS2 compiler, if you try this in AS3 you’ll get a compiler error like so: Error #1009: Cannot access a property or method of a null object reference. telling you exactly what the problem is. You can’t use the push method on an object that hasn’t been initialized.

PS- this is only an example – you can make a duplicate of an array a lot simpler using the slice method:

private var loaderArray:Array;
 
public function init(loadArray:Array):Void
{
	loaderArray = loadArray.slice();
}
Category: Flash  | Comments off
Thursday, November 06th, 2008 | Author: Dave

I have a habit of looking stuff up when I don’t know the answer. So, here’s a few recent things I looked up:

Q: Do sharks have eyelids?
A: Sho-enuff. They don’t use them, but they have both an upper and a lower. And some sharks have a third “eyelid” called a nictitating membrane that can cover the eye for protection. Like when they’re feasting on a seal.

Q: First american woman in space?
A: Sally Ride – 1983 – easy to remember if you just think of the song, Mustang Sally: ride sally ride…

Q: First guy?
A: Alan Shepard – 1961

Q: What the hell is this brimstone we’re always hearing about?
A: It is Sulfur

Category: Questions  | Comments off
Wednesday, October 29th, 2008 | Author: Dave

I took this from the old blog because it’s good shit.

I’ve been working on letting users save a jpeg from Flash to their own machine, which for the most part is no biggy even in AS2. The problem area for AS2 is the amount of data that must be sent to the server – typically an array of color values, one for every pixel in the image. So, even a small 200×200 image will generate an array with 40,000 entries – each being a 6 byte hex value. And, when you turn that into a string for posting to the server you get a 1 byte comma added between each entry. So, a 200×200 image turns into approximately a 280K upload – that will likely end up being a 30K jpeg. Which is crap.
So, the trick is to try and minimize the amount of data you send, which can be done in various ways including things like base64 encoding, or using LZW compression. I did try those methods, and while they do work, they were taking far too long (at least in VM1) to do their thing. Uploading the big-ass string was faster than compressing and uploading the small version. I was resigned to just sending the big string, but kept thinking there must be a way to somewhat minimize the impact. That’s when I hit on this simple array compression technique that is reminiscent of RLE.
Here’s the function:

function compressArray(orig:Array):Array{
  var l = orig.length;
  var comp:Array = new Array(); //new compressed array
  for(var i = 0; i &lt; l; i++){
    comp[i] = “”;
  }
  comp[0] = orig[0];
  var lastEqualIndex = 0;
  for(var i = 1; i &lt; l; i++){
    if(orig[i] != comp[lastEqualIndex]){
      //new color
      comp[i] = orig[i];
      lastEqualIndex = i;
    }
  }
  return comp;
}

It works like so – a new array, comp, is created, the same length as the original, and filled with “” – empty strings.
The first item in the new array is set to the first item in the original, and the initial 0 index is stored in lastEqualIndex – since the two arrays are now identical at index 0.
The original array is then iterated starting at the second item in the array – index 1, and going to the end. If the current item in the original array is different from the item in the comp array at the lastEqualIndex, then a new value has been encountered. It is stored in the new, comp, array and the lastEqualIndex is updated to reflect the current index in the loop.
What this accomplishes is creating a new array where runs of duplicate data are eliminated and only the initial value in the run is kept. The other items in the run are kept at their initial empty string values.
Example:

original: [FFFFFF, FFFFFF, AAAAAA, BBBBBB, AAAAAA, AAAAAA, AAAAAA, AAAAAA]
new version: [FFFFFF, , AAAAAA, BBBBBB, AAAAAA, , , ]

original: 55 bytes
new version: 31 bytes

A full 44% reduction

Here’s some actual examples when the array is filled with color values:

As you can see, some images are more compressible than others, as is normal. I couldn’t believe the last image saw an 86% reduction, I expected much worse from it.
The nice thing about this method, aside from the fact that it’s extremely fast, is that the array indexes are preserved and so it’s very easy to reconstruct the original array: If a value in the array is “”, just use the last item (color) that wasn’t empty. Simple as that.

Category: Flash  | 2,802 Comments
Wednesday, October 29th, 2008 | Author: Dave

I’ve decided to move this blog over to our own domain, and also start using WordPress instead of Blogger.


Press the “button” in the lower-right corner to redraw the trees.

Category: Flash  | Comments off