Tutorials, Videos

Become an AIR pilot

17 Comments 14 May 2010

Become an AIR pilot

Last week, I had this crazy idea looking for new ways to use Adobe AIR on Android phones. I believe that the next generation of web applications will be “live interactive applications“, with multiple users connected in real time. The gaming industry understood that, but it can also answer the business needs of large accounts such as a bank who wish to improve the relationships with their customers. Actually, we have on this topic a significant success story in Germany, with IMPULS, an insurance company that uses the real-time skills of the Adobe Flash Platform to acquire new customers online.

That said, I wanted to experiment something fun. I may come back in few weeks with an Enterprise application connected in real-time, but today, let’s become a pilot! First, I need to thank the developer of ABCflyer (http://wonderfl.net/c/f2Xu/), a Flash coder who open-sourced a AS3 experience that leverages the 3D API of Flash Player 10.   Once the code downloaded and analyzed, I just had to embed the class in a Flex project. Instead of extending a Sprite, as in the original code, you need to extend a UIComponent. Then your Flex application will be able to display it as a classic visual component. I also had to extend the code of this class a little bit to expose public methods, getSomethingDown and getSomethingUp, that are waiting for Keyboard events (on key UP, and on key DOWN). In the original game, you just need to press the arrows on your keyboard to control the plane and fly over the 3D landscape.

My goal is to use my Android phone as a remote control. Using the new accelerometer API of Adobe AIR on Android, I’d like to detect the orientation of my mobile in a 3D environment, and then dispatch events. To enable a real-time bridge between my phone and my Flex application, I’ve devised to use LiveCycle Data Services and the Real-time Message Broker. I could also use the free and open-source BlazeDS project, although I wouldn’t be able to use the RTMP protocol (BlazeDS only pushes HTTP messages).

First, let’s have a look at the result, and then I’ll explain you how to develop it:

plane from michael chaize on Vimeo.

Here are the steps needed to code the Mobile application (AIR application that runs on a Android mobile phone):

STEP 1 – the accelerometer

In my AIR phone application, I declare a new Accelerometer object and add an eventListener to detect when the Accelerometer sends an UPDATE event. Depending on the axis, I can predict the orientation of the phone and decide to simulate a LEFT, RIGHT, DOWN, or UP keyboard event. Here is how it looks like:

public var myAcc:Accelerometer = new Accelerometer();
(…)
myAcc.addEventListener(AccelerometerEvent.UPDATE, onUpdate);
(…)
private function onUpdate(event:AccelerometerEvent):void {
if((event.accelerationX > 0.7) && (currentHstatus != "left")) {
   send("left");
   currentHstatus = "left";
}
(…)
}

I store two flags: currentHstatus and currentVstatus to send a message just when necessary. This is just for optimization reasons on the network and to minimize the number of messages transmitted to LCDS. I call the send() method  and set potentially six different values depending on the status of accelerationX and accelerationZ variables: “left”,”right”, “flatX”, “up”,”down”, “flashZ”.

STEP 2 – Build and send a message to LCDS

In my AIR mobile application, I add the fds.swc library that you can get in the LCDS SDK. Then I can declare Channels and a Messaging destination setup on my LCDS server. The first channel added is leveraging the RTMP protocol only available in LCDS. If the connection fails (because of a firewall for instance), the system will try to communicate with the second channel, using AMF streaming as a fall back channel. I also declare a Producer tag, as my mobile app sends live message. I use the destination “chat”, which is one the destinations declared by default in the LCDS samples. Here are these declarative tags:

<fx:Declarations>
<mx:ChannelSet id="channelSet">
<mx:RTMPChannel id="rtmpChannel" url="rtmp://yourLCDSserver:2037"/>
<mx:StreamingAMFChannel id="streamingAMFChannel" url="http://yourLCDSserver:80/lcds-samples/messagebroker/streamingamf"/>
</mx:ChannelSet>
<mx:Producer id="producer" destination="chat" channelSet="{channelSet}"/>
</fx:Declarations>

STEP 3 – Build and send the message to LCDS

The send() method creates a message and sent it to the destination declared in the Producer tag. I can define all the parameters I need in the body of the message. In this particular case, this is very easy as I just need to send the direction of the plane (left, right, etc…). To create a dedicated connection between my mobile and my desktop AIR application, LCDS can filter the messages. To do so, you just need to generate a randomized ID number (an Integer) and add it in the header of your messages. If you don’t filter your messages, ALL the users that will play with the plane at the same time will receive your messages which is of course not suitable from a network perspective. Here is the code of the send() method:

private function send(direction:String):void
{
   var message:IMessage = new AsyncMessage();
   message.headers = new Array();
   message.headers["myPlaneID"] = myUniqueID;
   message.body.direction = direction;
   producer.send(message);
}

Now let’s look at the steps in the Flex project to consume these messages:

STEP 1: Enable the communication with LCDS

Of course, you need to declare the same channels and become a consumer of the LCDS messages coming from the destination “chat”. In my Flex project, I ask the user to enter the randomly generated ID that is displayed on the mobile screen. To add a filter and only get the right messages, I use the “selector” property on my Consumer object.

First I declare the channels and the Consumer object:

<mx:ChannelSet id="channelSet">
<mx:RTMPChannel id="rtmpChannel" url="rtmp://tourdeflex.adobe.com:2037"/>
<mx:StreamingAMFChannel id="streamingAMFChannel" url="http://tourdeflex.adobe.com:8080/lcds-samples/messagebroker/streamingamf"/>
</mx:ChannelSet>
<mx:Consumer id="consumer" destination="chat"  channelSet="{channelSet}"
message="consumer_messageHandler(event.message)"/>

Notice that when I’ll receive a message, it will be handled by the consumer_messageHandler() method. Then, once the user has entered the ID and pressed the START button, I can set the properties of my Consumer object:

protected function btnStart_clickHandler(event:MouseEvent):void
{
   consumer.selector = "myPlaneID="+tiPlaneID.text;
   consumer.subscribe();
   currentState = "planeScreen";
   btnStart.addEventListener(KeyboardEvent.KEY_DOWN, myKeydown);
   btnStart.addEventListener(KeyboardEvent.KEY_UP, myKeyup);
}

I also add two event listener of the Start buttons: on Key Down, and on Key Up has I plan to emulate Keyboard events.

STEP 2: Handle the incoming messages coming from LCDS

I will get messages and the “direction” property transmitted by the mobile application. If I receive a “down” direction, I’ll create a emulate the fact that the user presses the KEY-UP button (the controls are reversed when you pilot a plane). If I receive a “left” direction, then I emulate a KEY_DOWN on the Keyboard.LEFT key. If I receive “flatX” or “flatZ” directions, then I emulate KEY_UP events to come back to the default state of the plane. To emulate a Keyboard event, I create in ActionScript the event, and then I just need to dispatch it on my button “btnStart”.

The code looks like this section:

protected function consumer_messageHandler(message:IMessage):void
{
if (message.body.direction == "left"){
   var keyCode:uint = Keyboard.LEFT;
   var e:KeyboardEvent = new KeyboardEvent( KeyboardEvent.KEY_DOWN, true, false, 0, keyCode );
   testbtn.dispatchEvent( e );
}
(…)
if (message.body.direction == "flatX"){
   var keyCode:uint = Keyboard.LEFT;
   var e:KeyboardEvent = new KeyboardEvent( KeyboardEvent.KEY_UP, true, false, 0, keyCode );
   testbtn.dispatchEvent( e );
   var keyCode:uint = Keyboard.RIGHT;
   var e:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, keyCode );
   testbtn.dispatchEvent( e );
}
}

STEP 3: Send the keyboard events to the AS3 game

When a keyboard event is dispatched on the button, the event handlers are called. Then I call the internal method of the Plane AS3 game to start the associated action (with the Key mapper object of the game).

private function myKeydown(evt:KeyboardEvent):void {
   thePlane.getSomethingDown(evt);
}

Now, I invite you to download and explore the source code of both projects (desktop and mobile AIR applications):

Source code of the desktop application
Source code of the mobile AIR application

Unfortunately, I’m still not authorized to show you how I converted my AIR project to an native Android application but be patient, I’ll share the mechanism very soon.

Post to Twitter

Your Comments

17 Comments so far

  1. Mete says:

    Cool usage of LCDS messaging!

  2. Jean-Marc says:

    Amazing!

    We are working on something very similar.

    I sent you an e-mail last night with a small demo. We didn’t consider using the phone as a remote control but it might be very fun too!

    Regards,

  3. admin says:

    Thanks. I didn’t get the time to play with your demo, but I’ll definitely will in the coming days !

  4. Jose Campos says:

    Really nice app, i will take the time to play with the accelerometer, thanks for your post!

  5. Mike Collins says:

    cool demo. getting an evo 6/4. You should contact Comcast, directTV etc. How cool to actually use as a tv remote. you browse shows, filter, etc then actually have it interact with your dvr , cable box. great ad business model too.

  6. Jeff says:

    nice work :)

    The latency seems quite large though?

    I did something similar a while ago, turning my android phone into a flight/game controller for Air desktop, as well as a unity app, using UDP:

    http://jeffwinder.blogspot.com/search?updated-max=2010-03-27T07%3A49%3A00-07%3A00&max-results=1

    Jeff.

  7. admin says:

    wow, interesting.
    We should be able to leverage the new P2P features of AIR, maybe using LiveCycle collaboration Services. I should check the API and post an experiment.

  8. mohan says:

    please help to generate pdf with different languages for flex

  9. congchao says:

    nice project。。 but can you show how to build a projcet of “AIR for android with LCDS or BlazeDS” ?

  10. why says:

    is it fair to instanciate a “new Accelerometer” since it’s supposed to be a kind of link to an existing hardware ? Shouldn’t it be a static or singleton maybe ? It’s still working anyway ; i was just wondering.

  11. jason says:

    Unfortunately, I’m still not authorized to show you how I converted my AIR project to an native Android application but be patient, I’ll share the mechanism very soon.

    have you now post the solution for converting the AIR project to an native Android application?

  12. admin says:

    @jason. Download the latest AIR 2.6 SDK. Use adt inside the SDK to package your app into Android or iOS apps.


Trackbacks/Pingbacks

  1. Adobe AIR on Android Controlling Desktop Application | Android Dudes - May 14, 2010

    […] is another demo from Adobe Evangelist at the Flash Content on Android. This time Adobe Evangelist Michael Chaize has created and Adobe AIR Application which runs on Nexus One. The application uses the Android […]

  2. 使用 AIR for Android 驾驶飞机 | SWFever.com - May 15, 2010

    […] 顿时为这个本来就很酷的 Demo 增色不少。作者还为此撰写了教程并提供源代码下载(桌面端使用 LCDS 进行通讯)。Great Job, […]

  3. AIR 2.5 et Android: les news « Code moi un mouton - August 23, 2010
  4. Próxima versión de Air Adobe para Android Market | androidda.com - September 28, 2010

    […] Recibir los eventos provenientes del sensor de posición del dispositivo Android con la clase Accelerometer […]

  5. Scott Janousek » Blog Archive » AIRWolf [DECLASSIFIED] will be shown at Adobe MAX at FITC unconference & 360|MAX - October 22, 2010

    […] device to a large screen apps (typically games) via mobile device(s) (e.g. Brass Monkey, MegaPhone, AIRPilotetc) … pretty cool. These ideas have been around for quite some time (years, infact), but the […]

Share your view

Post a comment

Who am I ?

I'm Michaël CHAIZE, Adobe Flash Platform Evangelist based in Paris. I'm a big fan of Rich Internet Applications and I promote the Flash Platform in the Enterprise world.
You can follow me on twitter: http://twitter.com/mchaize

Magazine

Follow us on Facebook

© 2018 RIAgora. Powered by WordPress.

Daily Edition Theme by WooThemes - Premium WordPress Themes