Problem solved: [BulkLoader] Failed to get content with url: “load_item_url” as type [xml]

I found a weird BulkLoader problem today. We had finished developing this game a few days ago, and it worked fine locally, and online, but when the client put it in their CDN it stopped working. A quick look under the hood with FlashTracer for Firefox showed that BulkLoader was throwing this error:

[BulkLoader] Failed to get content with url: 
"assets.xml" as type [xml]

… when I tried to use the assets.xml file I had loaded. So it was loading correctly, but for some reason BulkLoader couldn’t identify and parse it as XML. And this only happened when it was delivered through the client’s CDN.

It turns out, I was relying on BulkLoader’s ability to see that the file had a .xml extension and automatically identify it as XML, and parse it that way. When the file was fetched through their CDN, it was returned as a crazy long filename that would never make sense to a human and did not end in .xml.

The fix was easy—Tell BulkLoader that it’s an XML file up front. In the add function, the second parameter is a object where you can put, among other things, the id you want to refer to the loaded file by, and it’s type if it may be ambiguous. Like this (end of line 2):

var bulkLoader = new BulkLoader("myloader");
bulkLoader.add("assets.xml", {id:"assetsXML", type:"xml"});
bulkLoader.start();

Your options for the type are: “binary”, “image”, “movieclip”, “sound”, “text”, “xml”, “video” and it defaults to “text” if there is no extension and no type.

Load more content as the user reaches the bottom of your page, with jQuery

I recently built a project gallery for Primal Screen’s new website (not live yet). Instead of having the traditional < 1 2 3 4 5 > pagination setup, we decided to take a leap forward into the the world of modern browsers, ajax, and users with very short attention spans. In this on-demand world, we load the content as needed: when the user hits the bottom of page one, page two is loaded and appended, and so on until you run out of content, or the user’s scroll wheel breaks. It’s a never ending page, without a never ending load. You may have seen this functionality in the Firefox plugin, AutoPager, or the Chrome/Safari plugin AutoPagerize.

Anyway, basically it works like this:
1) User loads page with 15 thumbnails on it
2) User scrolls to bottom of page, triggering a jQuery event we set up
3) 15 more thumbnails appear like magic or voodoo or mindreading or something and the page gets longer! Without even clicking!
4) User scrolls some more, hits bottom of page again, jQuery event fires again and
5) 15 more thumbnails appear and the page gets longer, further blowing the user’s mind!
6) ?
7) Profit.

alreadyloading = false;
nextpage = 2;

$(window).scroll(function() {
	if ($('body').height() <= ($(window).height() + $(window).scrollTop())) {
		if (alreadyloading == false) {
			var url = "page"+nextpage+".html";
			alreadyloading = true;
			$.post(url, function(data) {
				$('#galleryThumbsCol').children().last().after(data);
				alreadyloading = false;
				nextpage++;
			});
		}
	}
});

Line 1 is a state variable. We set it to true when we start loading a new page, false when it's loaded and shown, and before we load a new page we check to make sure the variable is set to false to ensure that we don't try to load page three before page two is done loading.
Line 4 Standard jQuery scroll event. This fires several times per second when scrolling in a modern browser, but on old browsers it just fires once when you stop scrolling.
Line 5 Here we check to see if the user is at the bottom of the page.
Line 6 Here we check to make sure we aren;t already loading a page.
Line 7 This is where the magic happens. $.post is a jQuery function that loads the url you give it in it's first parameter, and runs the callback function you give it in it's second parameter (and that function get's the loaded data in it's one and only parameter, did you follow all that?).
Line 8 Now that we have the loaded page, we have to put it in our existing page. Translated to english, this line reads "find the element with the ID: galleryThumbsCol, find it's last child, and put the loaded data in after that child.
Line 9, 10 Then we set our variables so we're ready to load the next page.

Find the Pixel perfect position of an element with jQuery (and keep elements always visible)

If you need to know the exact x and y positioning of any element on your page (relative to the viewport), use jQuery like this.

var x = $("#myElement").offset().left;
var y = $("#myElement").offset().top;

Then you can do stuff like this

$(window).scroll(function() {
	var y = $("#myElement").offset().top;
	var scrollY = $(window).scrollTop();
	if (scrollY > y) {
		var padY = scrollY - y;
		$("#myElement").css("paddingTop", padY);
	}
});

This script would compare your scrollbar’s position and the position of the element, #myElement, every time you scroll (several times per second on good browsers, when you let go of the scrollbar on bad browsers). Then, if the top of the element is above the top edge of the viewport, it adds some padding-top to it to keep it locked there at the top of the screen.

Actionscript 3 Sound Manager Class

Note: SoundManager has been update, and there’s a post about that updated version here.

I’ve been making flash games and apps for a while now, mostly for my full time gig at Primal Screen. A growing part of our business is games for kids, and kids games have audio. Lots of audio. And not just individual files, played as needed. Timeouts, and pause-ons (when the player leaves their mouse over a button), sequences of audio that change depending on the game state, etc, etc. I was time to write a sound management class that we could use over and over. Here’s what we needed

  • Loading. We need to just give the class a filename, and it should load it and play it. I used BulkLoader for the loading.
  • Preloading. We also needed certain sounds to be ready the second they were needed.
  • Events. Sometimes we have to know when a sound finishes playing or preloading, so I implemented easy custom event dispatching.
  • Channels. The sound effects can all be going off at once, with one volume control for all of them, but the character should only be able to say one thing at a time. I implemented custom controls to separate sounds into channels, and to define whether a channel can have more than one sound playing, or if a new sound should cut off an old one.
  • Looping. Music and ambient loops. Infinite or a specific number of loops.
  • Sequences. We sometimes have to string together long sentences based on game state, made up of 5 to 10 files. I made this class so you can give it a single filename for a single sound, or an array of filenames and it will play them in sequence.
  • Delays/Timeouts. I made it so that if you put a number in a sound sequence, the number turns into a delay between the audio files. That’s how I do all my repeating instructions in kids games.
  • Controls. Stop all sounds, stop this sound, and stop all the sounds on this channel are all options. I haven’t had a need for pausing and resuming yet, so it’s not in this first release, but consider it coming soon.
  • Well documented and easy to use. So my coworkers can use it easily.
  • Open source. MIT licensed.

And here it is. Primal Screen Sound Manager(EDIT: link changed to Primal GitHub Repo) for Actionscript 3 Projects. Leave a comment if it helps.

Basic example of an Actionscript 3 Singleton

EDIT: ARGGGH, I missed a few things when I wrote the original article. What you had if you followed the old instructions was a local Singleton, one that prevented duplication within a given SWF, but could be duplicated in larger systems. I’ve edited the article below to fix the problems.

A Singleton is a class that you want to instantiate only once.

Let’s say you want to keep a class containing your state variables, and you want to access it from several other classes. If you try to just make a reference to your state class in each class you need to access it from, you’ll create multiple instances of it, which is not what you want.

Main.as – Class that needs a reference to your State singleton class:

package {
	import com.company.project.State;

	public class Main extends MovieClip {
		public function Main() {
			//var state = new State();
			var state = State.getInstance();
		}
	}
}

State.as – Our singleton, where we want to keep state variables to track our application state.

package com.company.project {
	public class State extends EventDispatcher {
		
		private static var instance:State;
		
		public static function getInstance():State {
			if (instance == null) {
				instance = new State(new SingletonBlocker());
			}
			return instance;
		}
		
		public function State(sb:SingletonBlocker):void {
			if (sb == null) {
				throw new Error("Error: Instantiation failed: Use getInstance() instead of new.");
			}
		}
	}
}
internal class SingletonBlocker {}

A quick explanation of what’s going on here:
Main.as 2: Make sure your application knows where to find the State class
Main.as 5: This is an example of how you would normally make a reference to your State class. This is the non-singleton way.
Main.as 6: We’re calling to the getInstance() method within the State class.

State.as 7: This getInstance() method is where the magic happens. The first time you call getInstance(), the instance variable will be null, so it will make a new instance of State and return a reference to it back to Main.as. We’ll get to that SingletonBlocker bit later. In every subsequent call to getInstance(), the variable instance will not be null, so it won’t try to make a new copy of State, it will just return a reference to the one already made. Now, SingletonBlocker. This is a failsafe against user error. If a user were to write var state = new State();, then when the State constructor is called, it would not have access to the hidden/internal SingletonBlocker class, so it would fail and throw that error. The internal designation of the SingletonBlocker class means it can only be accessed from within this file, such as from within the getInstance() function.

Trace all the properties of an Actionscript Object

Let’s say you have an object.

var myObj:Object = new Object();
myObj.myFirstProperty = "property string";
myObj.mySecondProperty = 42;
myObj.myThirdProperty = true;

And you want to see all of it’s properties in your output window.

myFirstProperty: property string
mySecondProperty: 42
myThirdProperty: true

You can loop through it the same way you loop through an array.

for (var x in myObj) {
	trace(x + ":  " + myObj[x]);
}

But what if you want to know the built in properties of of the object, the ones that it get’s from flash upon instantiation.

describeType(myObj);

That will tell you more than you ever wanted to know.