Tuesday, December 2, 2008

Towers of Brahma Game



A few months back, I came across a puzzle that I could not stop playing. The puzzle goes by various names: Towers of Hanoi, Towers of Brahma, and Towers of Benares. Apparently there is a legend connected to this puzzle. It states that there is a Hindu temple with a room containing 64 discs and three pegs. The priest of Brahma are charged with moving the stack of discs from the first peg to the third, one at a time, and only placing smaller discs atop larger ones. According to the legend, the completion of the last move will herald the end of the world. If the legend were true, and if the priests were able to move disks at a rate of one per second, using the smallest number of moves, it would take them roughly 600 billion years to complete the puzzle. Naturally, I decided to build the puzzle out in Flash.

The objective is quite simple: Move the stack of discs from the first platform to the third platform by stacking smaller discs atop larger ones. The puzzle begins with three discs. Each time you complete the puzzle, you enter a new level where an additional disc is added. Easy, right? But trust me despite its absolute simplicity, it is addicting… and a huge waste of time.

You can check out the puzzle in two slightly different versions. The first one is themed for the holiday season as the “Build a Snowman Game”. You can play it on the Disneyland Resort Holiday minisite, and the second, “Order a Short Stack” themed with photography and graphics from Disney’s Animal Kingdom, is the feature monthly game for Walt Disney World's Backstage Pass.

Create a username, password, login and play!

Monday, December 1, 2008

The Muppet Experiment




Check out the latest project I worked on, the Muppet Experiment Alternate Reality Game at www.theMuppetExperiment.com .

Monday, November 10, 2008

PV3D Card Opening Animation

Here is a little Papervision example from my latest project. It is a simple card opening sequence that we used as the introduction animation for the Disneyland Resort Holiday mini-site.

Click on the card to open and close.







Some quick notes:
1. The faces of the are MovieClipMaterials passed in as MovieClips through the buildCard() method.
2. These MovieClips were populated with text and video content defined in an external xml.
2. I implemented the AS3DMods Bend class to add some plasticity to the animation. Hard to see in this small demo, but check out the minisite to see the Card at 100% size.
3. The Card class automatically turns off papervision’s rendering capabilities upon completion of the animation and cache’s itself as a bitmap.


Download Source Code

Friday, October 17, 2008

Holy Cow! Papervision3D Materials Demo

Here is a little experiment with various Papervision3D and a static PointLight3D. Use the “shift” key to cycle through the various material skins.






I pulled the cow.dae model from a google search. I had to edit the dae a bit by stripping it of all the material, camera, and light references so that the file only defines the geometric mesh. This is so I can specify the camera and lighting in papervision and apply the materials dynamically through Actionscript. Also, for some reason I had problems swapping materials in the dae model using the Collada and DAE parser classes, as a result I had to convert it into a zip and then parse it using the KMZ parser.

The great thing about the KMZ parser is the ability to reference individual objects in the Collada (.dae). All Collada data is contained within the scene (registered as COLLADA_SCENE, not “scene”), I named the geometric mesh “Cow”. As a result, I was able to reference the cow mesh directly using my _cow DisplayObject3D variable and this simple line of code:
_cow = _KMZ.dae.getChildByName("COLLADA_Scene").getChildByName("Cow");

Then by referencing the material property of the _cow DisplayObect3D Flash can dynamically reskin the mesh with the material specified.


Download Source Code and Example

Thursday, October 9, 2008

Basic Interactivity with Papervision2.0

For the past few years the Flash community has reveled in the ability to create a virtual 3D environment using the open source Papervision3D engine. After a few hours playing with the code, one realizes the immense potential of Papervision and the exciting paths it has, and will continue, to pave for Flash Designers and Developers. We find it very easy to create three-dimensional objects, making it ideal for banging out quick prototypes and wowing our colleagues and friends with rotating cubes and other platonic solids. However, when we start to consider functionality and specific forms of interaction, things become slightly more complicated.

Depending on what we wish to accomplish, there are two primary ways to interact with our 3D scenes: 1. The flash.events packages inherent to Flash, and 2. The InteractiveScene3DEvent bundled with the Papervision code. Both these methods are valid and while at first seem as if they can be used interchangeably, we soon find that there are specific scenarios where we must choose one or the other. A quick and dirty , yet handy, generalization is that when we you wish to interact with the Scene or a 3D object as a whole use the InteractiveScene3DEvent. For interaction within 3D objects (i.e. with the materials) use flash.events.

To demonstrate these two methods of interactivity, I built a simple flipping card demo using the latest Papervision2.0 release (aka the “Great White” branch). The idea is to allow the user to flip the card by clicking on it while also allowing basic button interaction on the obverse side. I commented the code, and assume that the reader has a basic understanding of Papervision.

Download Source Code and Example







Code:
import gs.TweenLite;
import org.papervision3d.view.BasicView;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.materials.*;
import org.papervision3d.events.InteractiveScene3DEvent; //imports InteractiveScene3DEvents

var backface = new BackFace;//instantiates BackFace library asset

/*BasicView(viewportWidth:Number = 640, viewportHeight:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")*/
var view:BasicView = new BasicView(1,1,true,true);
view.buttonMode = true
view.camera.focus=100; //.camera is an inherrit property of the BasicView Class as is scene and viewport
view.camera.zoom=10; //focus to zoom ratio of 100:10 renders objects at their actual sizes

//Instantiates DisplayObject3D, which will act as the container for the front and back faces of our card

var card:DisplayObject3D = new DisplayObject3D;
/*MovieMaterial(movieAsset:DisplayObject = null, transparent:Boolean = false, animated:Boolean = false, precise:Boolean = false, rect:Rectangle = null)*/
var backMat = new MovieMaterial (backface,false,true,true);
backMat.smooth = true;
backMat.interactive = true; /*set the interactive property of the InteractiveScene3DEvent to true, since we want to be able to click to flip*/

//BitmapFileMaterial(url:String = "", precise:Boolean = false)
var frontMat = new BitmapFileMaterial ("cardFront.jpg");
frontMat.smooth = true;
frontMat.interactive = true;

/*Plane(material:MaterialObject3D = null, width:Number = 0, height:Number = 0, segmentsW:Number = 0, segmentsH:Number = 0)*/

var back:Plane = new Plane(backMat, 360, 200, 3,3);
back.rotationX = 180; //b/c it is the backside and we want it to be rightside up when we flip the card
back.z = 1; // places it one pixel back in z space

var front:Plane = new Plane (frontMat, 360,200,3,3);

addChild(view); //adds our BasicView to the stage
card.addChild (back);//adds back Plane to the card DisplayObject3D
card.addChild(front);//adds front Plane to the card DispalyObject3D
view.scene.addChild(card); //adds card DisplayObject3D to the scene of our BasicView

function addInteraction(e:Event = null):void {
back.addEventListener (InteractiveScene3DEvent.OBJECT_PRESS, flip);
front.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, flip);
}

/*we need to remove the InteractiveScene3DEvents when the mouse cursor is over the button on the obverse side since we do not want the card to flip when the button is clicked*/
function removeInteraction(e:Event):void {
back.removeEventListener (InteractiveScene3DEvent.OBJECT_PRESS, flip);
front.removeEventListener(InteractiveScene3DEvent.OBJECT_PRESS, flip);
}

function flip(e:InteractiveScene3DEvent):void {
TweenLite.to (card, .75, {rotationX:"180"}); /*Animates the Card Flip, 180 is in quotations so TweenLite reads it as a relative value*/
}

function render(e:Event):void {
view.singleRender();

}

addInteraction();
addEventListener(Event.ENTER_FRAME, render);
backface.addEventListener ("btnOver",removeInteraction); //listens for MouseOver event in BackFace library asset.
backface.addEventListener ("btnOut", addInteraction);//listens for MouseOut event in BackFace library asset



Monday, October 6, 2008

Look it up! The AS3 Dictionary Class

We are all familiar with the versatility of Arrays. Now, with AS3 comes a new addition of total awesomeness to these key- value methods of storing and retrieving information. All hail the Dictionary Class!

Like Arrays, the Dictionary Class associates values with a key. However, unlike Arrays, Dictionary keys do not have to be numeric indexes, they can be any object opening a wide array (pardon the pun) of unique opportunities.


For reference, here is the basic syntax:
import flash.utils.Dictionary;
var obj:Object = new Object();
var myDictionary:Dictionary = new Dictionary();
myDictionary[obj] = 'This is the value of the Dictionary key obj';

trace (myDictionary[obj]);


Check out Grant Skinner’s blog, for a general overview of the Class.