Adobe

“Flash Professional” Archives

Week of AFCS Revisited: SharedObject

After my trainwreck post on using CollectionNode in AFCS Nigel suggested that I try to recreate my example using the higher level APIs instead of trying to build everything from scratch with NodeCollection. As I mentioned in the previous post, the AFCS team did a great job of creating very basic APIs like CollectionNode and then building on top of those to make APIs that are easier to use. SharedObject is a perfect example of that.

Here’s what I wanted to accomplish: Create a basic multiplayer game where players try to match colors with each other using a ColorPicker. Using the SharedObject class it’s really pretty easy. The first thing I did was set up a room where guests are automatically promoted and no username/password is required. Then I used a combination of AFCS components and Flex components to create a user interface for entering a display name, picking the color, and showing how many players there are:

<rtc:AdobeHSAuthenticator id="auth" />
     <rtc:ConnectSessionContainer id="cSession" 
          authenticator="{auth}" 
          roomURL="{_roomURL}"
          synchronizationChange="cSession_synchronizationChangeHandler(event)"
     <mx:Panel id="panelColor" title="Pick a Color!"
          horizontalCenter="0" verticalCenter="0" alpha=".3" 
          width="200" height="200" enabled="false"
          <mx:ColorPicker id="color" change="color_changeHandler(event)" width="100%" height="100%" />
          <mx:Label text="Playing with {cSession.userManager.userCollection.length - 1} other people" />
     </mx:Panel>
 
     <mx:TitleWindow id="tw" horizontalCenter="0" verticalCenter="0"
          <mx:TextInput id="username" width="150" text="Enter A Username" focusIn="{username.text = ''}" />
          <mx:Button id="btnLogin" label="Login" click="btnLogin_clickHandler(event)" /> 
     </mx:TitleWindow>
</rtc:ConnectSessionContainer>

Nothing major there, notice we’re using the userManager class to get the number of other users in the room (and that it’s bindable). The big thing is the synchronizationChange event handler. In that function we’re going to configure our node and create the SharedObject.

public var sharedColor:com.adobe.rtc.sharedModel.SharedObject;
 
protected function cSession_synchronizationChangeHandler(event:SessionEvent):void
{
     if( event.type == SessionEvent.SYNCHRONIZATION_CHANGE )
     {
          var config:NodeConfiguration = new NodeConfiguration();
          config.userDependentItems = true;
 
          sharedColor = new com.adobe.rtc.sharedModel.SharedObject();
          sharedColor.sharedID = "color";
          sharedColor.setNodeConfiguration(config);
          sharedColor.subscribe();
          sharedColor.addEventListener(SharedObjectEvent.PROPERTY_ADD, onPropertyChange);
          sharedColor.addEventListener(SharedObjectEvent.PROPERTY_CHANGE, onPropertyChange);
          sharedColor.addEventListener(SharedObjectEvent.PROPERTY_REMOVE, onPropertyRemove);
     }
}

We have to use the full namespace when we reference the SharedObject in AFCS because it conflicts with the normal Flash SharedObject. We first do a check go make sure we’re in a SYNCHRONIZATION_CHANGE event and then start setting things up. The only change I make to the default NodeConfiguration is to make it so that when a user leaves the room, they take their items with them so we don’t have “ghost” matches. That’s done by setting the userDependentItems property to false.

Next we create our SharedObject. I give it a sharedID of “color” and then make sure the application is subscribed to the SharedObject so that it sees any changes. Finally I set up event handlers for whenever a property is changed, added and removed. The add and change properties use the same function, onPropertyChange.

Let’s first take a look at how we create the SharedObject; something that happens whenever we change our color selection.

protected function color_changeHandler(event:ColorPickerEvent):void
{
     sharedColor.setProperty(cSession.userManager.myUserID,color.selectedColor);
}

We use the setProperty() method on the SharedObject to give it information. A SharedObject is just a name/value pair, or in this case, a propertyName/value pair. I set the propertyName to the userID so we can know where the color came from and then set the value to our selected color. Whenever we set that property it will create a property change event and call our event handler.

protected function onPropertyChange(event:SharedObjectEvent):void
{
     if( event.propertyName != cSession.userManager.myUserID)
     {
          if(event.value == color.selectedColor)
          {
               var user:UserDescriptor = cSession.userManager.getUserDescriptor(event.propertyName);
               sharedColor.removeProperty(cSession.userManager.myUserID);
               Alert.show("You matched with " + user.displayName + "!");
          }
     }
}

This is where the game starts to happen. The way AFCS works is that when you change a something locally inside of your application it is sent to the server and then you get a change event when it comes back. This is so you can be sure the change was successful. In our game we want to make sure that we’re not dealing with the event we just sent so I use the propertyName property and compare it to myUserID to see if it’s an event that the user sent him or herself. If it isn’t, we look for a match using the value property and our selectedColor. If we have a match I use the UserManager class to get the display name of the matched user and pop up an alert box to show that we found a match.

The other thing I do is to call the removeProperty() method the user’s SharedObject. I ran into an issue where when a user selected a color that matched another one, the other user would get the popup but there was no easy way to notify the user who selected the color that it was a match. I solved this by removing the property which would then trigger a PROPERTY_REMOVE event and fire our event handler.

protected function onPropertyRemove(event:SharedObjectEvent):void
{
     var user:UserDescriptor = cSession.userManager.getUserDescriptor(event.propertyName);
     if( event.propertyName != cSession.userManager.myUserID && user != null)
     {
          Alert.show("You matched with " + user.displayName + "!");
     }
}

It looks similar to our change event handler. I first get the user information for the popup and then I check a couple of things. First, I make sure that the event isn’t coming from the current user, but the user I have the match for. I also want to make sure that the SharedObject wasn’t removed by someone just logging out (remember our NodeConfiguration settings). If my user is null then that means the user is gone and the event fired because the user left the room and not because I specifically removed it.

That’s pretty much all there is to it. You can grab the project here or I’ve embedded the game below (and here’s a direct link), so feel free to play and see if you can match colors!


data="http://www.digitalbackcountry.com/afcs/colorgame/ColorGame.swf"
width="450"
height="400">


1080p dynamic streaming demo source

I previously posted a 1080p dynamic streaming demo. In case you'd like to customize this for your own demo or website, here is the source code (Flash CS4 required). Enjoy!

New RTMPe content protection white paper

A new white paper is available on the Adobe Developer Center describing the characteristics and best practices for RTMPe protection for Flash Media. RTMPe is very scalable, popular and easy to deploy protocol-based content protection for Flash streaming. Furthermore the white paper compares RTMPe to file based protection with the Flash Media Rights Management Server (FMRMS).

New Content in the Adobe Developer Connection

As part of our weekly content launches in the Adobe Developer Connection, we’ve recently published some new articles for Flash Platform developers.

The new skinning architecture in Flex 4 beta makes it easy to completely change the look and feel of an application. Follow Ryan Frishberg to learn about the new improvements by writing a basic skin for a button and then delving into skinnable components. Building on what you’ve learned there, Evtim Georgiev addresses a number of pain points in skinning, CSS, components, states, animation, text, and graphics tags. He also shows you how to create a custom layout in his article, Spark layouts with Flex 4 beta. Meanwhile, read Tim Buntel's article to learn how a brand new approach in Flash Builder beta can simplify the development of data-centric applications.

If you are working with web video, you'll want to learn how to customize the ActionScript 3 FLVPlayback component, the built-in solution in Adobe Flash CS4 Professional for displaying video on the web. Also be sure to download two updated templates: spokesperson presentation with synchronized graphics and showcase website for personal video.

Flash animators: Dig into Chris Georgenes' popular series covering the entire process of creating a digital animated character in Flash CS4 Professional. And there's a bonus: a killer animation technique that creates convincing 3D effects while remaining in the 2D realm. Also be sure to check out Tom Green's article on Integrating Flash CS4 with After Effects CS4.

To get e-mail updates of our new content, subscribe to our newsletters: News Flash, The Edge, and the ADC update. You can also visit the Adobe Developer Connection to check for new content.

New tutorial on SWF framerate optimization

framerate.gif

I just finished uploading a new tutorial that explains how you can optimize your Flash movie’s framerate so that it only uses the resources that it needs to. Most of the time you only need a fast framerate for animation and you can structure your movie so that the rate is high only during those [...]

Custom Flex preloader video tutorial

flexpreload.gif

This week I set out to try and create five new tutorials in five days. Well I have just uploaded the fifth tutorial that shows you how to create a completely customized Flex preloader using Flash CS4. One thing that really bugs me about most Flex applications is the standard aqua loading screen. This video [...]


New video tutorial on using SWFAddress

swfaddress.gif

I just uploaded a new tutorial that shows you how to enable direct and deep linking using the SWFAddress library. Deep linking is just another name for making the back button work. This tutorial also goes over a couple of potential gotchas that you need to avoid in order to get SWFAddress working properly. Adding [...]


New tutorial on 3D photo panels

photopanels.gif

I just uploaded a new tutorial that shows how to make a cool 3D photo panel. This type of 3D effect is very common and is a good skill to have in your toolbox. When you click on an image it scales up into focus. This tutorial also serves a dual purpose as being a [...]


New video tutorial on runtime font loading

runtimefonts.gif

I just uploaded a new tutorial showing the best practice method of creating and using external font SWF files using Flash CS4. You can now easily create font files with a subset of characters using the new Flex metadata support. This was not possible prior to Flash CS4 and the new workflow speeds things up [...]


1