Travels

Wednesday, June 11, 2008

WeatherBug API: A lesson in XML


Recently I was asked to make a WeatherBug widget for my company's local intranet. Making the widget was easy enough, I wrote a class that connects to WeatherBug and retrieves the current weather conditions. The tricky part was parsing the XML in Flash since it has many levels of nested nodes and some of those nodes use a namespace. Because it took me a while to work through parsing the XML I've decided to make my code open source.

The WeatherBug class and the .fla file I've made which demonstrates its use may be downloaded here: http://sizzlepopboom.com/open_source/weatherbug.zip
You can see the widget in action here:
http://sizzlepopboom.com/open_source/weatherbug.html

Don't forget to register to get you WeatherBugAPI Key and put it in the WeatherBug.as file otherwise it will not work.

Here's a bit of advice on traversing the XML. There are three main issues I encountered in parsing my XML: 1. How do you access nodes within a namespace?, 2. How do you access nodes with names that use restricted characters?, 3. What's an easy way to traverse the XML without having to know the entire heirarchy of a node?

Here are my answers:
1. To access nodes within a namespace make a namespace object for the XML you are using:
ex: var weatherNS:Namespace = new Namespace("http://www.aws.com/aws");

Then use the format:
namespace::nodeName
namespace::@attributeName
ex: var highTemp = weatherXML..weatherNS::["temp-high"];

Here's a tricky one to show you an attribute "hour-24" within the node "hour":
ex: var riseHour = weatherXML..weatherNS::sunrise..weatherNS::["hour"].@["hour-24"];

2. Use brackets when you are trying to access nodes whose names use reserved characters; in fact if you want you can use brackets for regular names to if you want things to look consistent.
ex: var monthlyRain = weatherXML..weatherNS::["rain-month"];
var link = weatherXML..image["link"]; //without a reserved character

3. Use .. to search through the entire XML document without knowing the exact heirarchy; this is similar to the // used in XPath
ex: var link = weatherXML..image["link"];
var monthlyRain = weatherXML..weatherNS::["rain-month"]; //within a namespace

-When you are using .. be sure to check your results, if there are multiple nodes with the same name within an XML document you might end up with the values of several nodes. When there are multiple nodes, be sure to reference the parent of your target node to ensure you get only its value as a result. See the link tag in the example above.

Hopefully this helps you solve any of the tricky problems you may have using WeatherBug's API. If you do have more questions about using XML in Flash look at the source code I've provided and check out these sites:
http://www.kirupa.com/developer/flashcs3/using_xml_as3_pg1.htm
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/XML.html

plus there is a whole chapter on XML in Colin Moock's excellent book: Essential Actionscript 3


















Now that you know how to get WeatherBug information into Flash, I'd like to suggest some interesting ways you might be able to use the information.


I come from a background of making games so I've been intrigued with the idea of using real-world information in the form of XML feeds (like WeatherBug's) to control and influence elements within a game. The first thing I thought of was getting the current weather conditions and then replicating them within the world of the game. If you are playing on a rainy day, it will be raining in the game world. This becomes more interesting if you have characters, abilities, paths that are effected by the weather. A character could act more depressed if it's raining. Electric shock powers would be more powerful in very dry weather and more conductive in rainy weather. A path over a bridge could be flooded and inaccessible on rainy days.

Weather could also be used to drive a game's economy (especially in agrarian societies). Good weather means higher yield of crops and lower prices. This way you would have realistic variation in your economy without having to make it very intelligent.

Weather patterns can also be used to make cultural assumptions which can be useful in increasing the immersion of a player in the game. For example, if there has been a heavy snow children in a game might be staying at home instead of at school. The children would act happier being able to play all day and the adults would be more stressed from dealing with increased traffic. If the temperature has been exceptionally high characters in the game might go swimming more and as a consequence be tanner or sun-burnt. As you see, many assumptions can be made by analyzing weather patterns. Using these assumptions in a game environment will create much more realistic patterns of behavior with less complex AI. The use of weather information and the assumptions that can be made by analyzing it will greatly increase the sense of immersion in games as well as the overall cool factor of games seeming to know about the real world around it.

If you are interested in parsing weather conditions with WeatherBug's feed here's a link to all the possible weather descriptions:

http://weather.weatherbug.com/corporate/products/API/Cond_Icon_Desc.txt


There are about 178 possible descriptions so here is my suggestion for parsing the information to something more manageable:

Use indexOf to search a string for:
Cloud

Snow
Frozen
Flurry
Sleet

Rain
Storms
Thunder
Showers

Windy

Fog

Hazy

Clear

Searching for these words ought to give you a fair idea of what the weather is doing in most of the 178 different options. You can use sunny as the default weather.

Monday, March 10, 2008

Yahoo Pipes is Awesome!

For anyone who hasn't tried Yahoo Pipes yet check it out. Pipes allows you to create custom RSS feeds. This is very cool for making complex mash-ups. For example, a friend of mine is looking for an audio position in New York City. I created a simple pipe that uses Google's Job Search and the keyword audio and out came a list of job postings that were mostly relevant. After you make a pipe you can save it to your Yahoo or Google homepage, or access it as an RSS feed, etc.

I heard about Yahoo Pipes from an installation artist who was searching news feeds for different words and then applying that data to a device that dripped paint on a canvas depending on the amount of data received. I was really impressed how easy it was for him to parse so much data down to a single feed.

After playing with Pipes, I think it may be a good solution to an experiment I've been wanting to try. The idea is to get all sorts of real-world data into Flash, use that data to make inferences based on culture and psychology and then have it influence an interactive pet's emotion engine. More simply, if I know it's been rainy and there are a lot of negative keywords in the news the pet could be sadder than usual. If it is close to a cultural, religious, federal holiday the pet could be happier. It is my hope that by creating an emotion engine fed by this data, and then creating a personality that reacts to this data in a certain way, much more realistic virtual characters and environments could be created. Best of all if I use Pipes, I can keep most of the complex parsing out of Flash and use a single feed to get all the information I need.

Thursday, March 6, 2008

Making games accessible

Recently I've been making some games I've been working on accessible to the mobility and vision impaired to satisfy 508 compliance. This usually involves setting up tabIndex attributes and adding tags that screen readers can pick up.

Here's a quick overview for adding accessibility using AS2

Adding tabIndex is easy; just write:
someObject.tabIndex = 3;
to change it simply reassign the tabIndex a new value

Adding alt tags for screenreaders requires a little bit more code;
someObject._accProps = new Object();
someObject._accProps.name = "Text for the screen reader";
Accessibility.updateProperties();

The last line updates the alt text; so if you want to change the alt text after setting it once:
someObject._accProps.name = "Next alt text";
Accessibility.updateProperties();

That's about it, not too hard but the key is to test it out. Tabbing is easy enough you can test it straight from Flash, just make sure the Control>>Disable Keyboard Shortcuts is turned off

Testing the alt tags is trickier. You'll need screenreading software. I use a demo version of Windows Eyes. JAWS has also been recommended to me.
The demo only lasts about 30 min every time you open it, so I have it in a virtual machine which I restart whenever I need without rebooting my computer.

So far I've found one bug with tabbing. If you have tabbed onto an object and then set its ._visible = false; the tabbing order (sometimes) will skip ahead of the expected next object. I did some testing and so far I've found that if you use unloadMovie instead of _visible there is no problem.

FYI if you remove an object that you are currently tabbed to, the expected result of removing it or making it's tabindex = undefined is that the next object will be the one with the lowest tabIndex (the first object in the tabbing list).

To remove tabbing from an object:
someObject.tabIndex = undefined;

To stop alt text from being read by a screen reader, either
someObject._accProps.name = "";
Accessibility.updateProperties();

or

someObject._accProps._silent = true;

Here are some techniques I use for controlling accessibility:

I make variables to act as switches for tabbing and screen reader accessibility.

The tabbing var I set to false, then if tab is pushed I switch it to true.
The screen reader var I set to false and then set to true using Accessibility.isActive();

I usually set the screen reader switch within a keypress handler or some other function that runs soon after the movie is loaded. I do this because if you check Accessibility.isActive(); first thing, you may get a false negative.


Here are some useful links for reading up on Flash accessibility:
AS2:
http://livedocs.adobe.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001895.html
(try the white paper below for a better list)

AS3:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/accessibility/AccessibilityProperties.html

For a good source of accessibility answers for Flash check out:
http://www.adobe.com/accessibility/

The white paper by Bob Regan is an excellent read for getting a better understanding of what accessibility means and how to make Flash accessible.

Thursday, January 10, 2008

I ♥ caller

Since I posted about the wonderfulness of the Delegate class for AS2 I've learned a little bit more useful info I'd like to pass on. As you may remember, the Delegate class is very useful for managing the scope of your code. The biggest problem I still ran into though was passing and accessing variables from my the custom handlers I made with the Delegate class. Thankfully , there is an easy way to pass variables. Simply add it as an attribute to the event handler.
E.G.

//import the Delegate class
import mx.utils.Delegate;

//add a variable to pass to your handler
something.onPress = Delegate.create(this, someHandler);
something.onPress.myVariable = "pass me";

//now to access that variable use caller
function someHandler(){
var passedVar= arguments.caller.myVariable;
trace(passedVar);
}

Voila! Now you can enjoy the satisfaction of passing variables to your custom handlers.

Wednesday, November 21, 2007

Chumby

Recently I came upon a device called the Chumby. If you haven't heard of it, the Chumby a compact computer that displays information from the web via wireless. It has a touchscreen, 2 usb 2.0 ports, an accelerometer and a squeeze sensor. Best of all, it is designed to be easily hacked both for software and hardware. Anyone can make widgets for the Chumby using Flash Lite 3.0 as well as a variety of other languages (Chumby is Linux based). The screen is 320*240 and the recommended framerate is 12fps. Looking over Chumby.com's wiki, it looks like things are very well documented with example files to download and try out.

I think the idea of the Chumby is very cool and I'm excited to try it out for myself. At $179.95 it is a little pricey but, it is exactly what could integrate the internetin new ways to affect our daily lives (especially with web 2.0 technology like RSS). Imagine having a Chumby in your kitchen, you could get recipes off the intenet, watch online video, listen to internet radio, check the weather and traffic while you have breakfast, and read the daily news. I myself would be interested in a Skype widget so I could use it like a phone.

There's a bunch of cool widgets and features already available for the Chumby at the official website: www.chumby.com.
So check it out for yourself.

Monday, November 12, 2007

Making Flash games for the Wii

Recently I was shopping at Circuit City and found something interesting. It was a program called my Wii Manager. This software that allows you to download, edit, and share your Mii characters; so far you might not be impressed. But what the software actually is, is much different. It includes a programmable input emulator with an archive of programs for using the Wiimote on the computer. So it allows you to relatively easily connect your Wiimote to your computer and receive and use its serial input to control your mouse. It runs without a UV sensor so all moving is done by tilting the Wiimote; the cool bit is that it can detect tilt, thrust, and some other movement as well as make the Wiimote vibrate and light up its LEDs.


The real reason why I bought the software was that it came with a Bluetooth dongle and the whole thing cost about $20. When I was searching for a single Bluetooth dongle, the prices were usually closer to $30. So with this software you not only get the dongle but the emulator with program archive and some documentation. For my money, this is a pretty good deal. The main thing that had been keeping me from playing with making Flash games for the Wii, was that it was too much work to figure out how to set everything up and get it working reliably before I could get to making games. So if you're curious about making Flash games for the Wii, check out my Wii Manager.

After setting everything up (took about half an hour of reading and fiddling about) I played with a couple of old Flash toys I made. The results were pretty encouraging. A while ago I started working on a gesture class that maps various types of mouse movement to specific gestures. The goal was to add a greater sense of immersion to gameplay through more familiar and intuitive interactions. When I tried playing with the old toys I made using this class, they mapped wonderfully to the Wiimote and the interaction felt nice. So I've decided to slowly make a bunch of minigames using the class which later on I'll put together in one larger game. This will take a while though since I'm still in the middle of redesigning my website. Hopefully I'll be able to squeeze in a minigame or two along the way. Once I've finished a couple of minigames, I'll post the code and the games at my website.

Thursday, October 25, 2007

The Delegate Class: Brother where have you been?

Eureka! I've had a specific problem when writing AS2 classes for some while now. Namely, whenever I use code to make an interactive element (Let's say a movie clip that bounces away when you click on it), I have to nest the event handler's method. The problem is that this changes the scope and so the handler method can't access my classes base methods. The way I used to fix this was by making the methods I want to access Static, and accessible by anything in my class. The problem with this is that if I make a method static I have to make its variables static, and that can create a domino effect of making things static just to solve the original problem. This is pretty wordy so I'll post code that is easier to follow. Here's the old way I did things:

class SomeClass {
//constructor
public function SomeClass(someMC) {
//initialize object
initialize(someMC);
}
//this is static so the onPress method can access it
private static function doSomething() {
trace("Ok, I'm doing something");
}
private function initialize(someMC) {
trace(someMC);
//define what it needs to do when it loads
someMC.onPress = function(){
doSomething();
}
}
}

This is a very simple version of the problem. In reality the method my handler calls would probably be called by other methods and use variables that all would need to be made static. I knew this was not a good way to do things but until now I didn't know what else I could do.

Thanks to the Delegate class though, I'm able to specify the scope and therefore access the methods at my class' base level. Here's the same code as above but made with the delegate class:

//import the Delegate class
import mx.utils.Delegate;
class SomeClass{
//constructor
public function SomeClass(someMC) {
//initialize object
initialize(someMC);
}
private function pressHandler() {
trace("You pressed it.");
}
private function initialize(someMC) {
//define what it needs to do when it loads
someMC.onPress = Delegate.create(this, pressHandler);
}
}

Now there is no need for static so things are much easier when I need to tweak things later on.
While I was researching how to solve this problem I found other possible solutions but this was the one I understood best and was able to easily implement.

You can read all about the Delegate Class here: http://www.actionscript.org/resources/articles/205/1/The-Delegate-Class/Page1.html

This is all great to know but this problem has been resolved in Actionscript 3 thanks to its addEventListener method. Still if you're using on Flash Lite or like me your work doesn't want you to use AS3 until the Flash PLayer 9 adoption rate is higher you may find this very useful.

Good luck using the Delegate Class, and if you have other solutions I'd love to see what you have come up with.