[AIR 4 / Flash10+]
Juin 2014
Adobe AIR – Wand
*update*
Wand.swc is now gamepad.swc
android-air-devices-as-gamepads.html and can be found in the AIR Sdk ( frameworks\libs\air\gamepad.swc )
***
Android Air runtime is now shipped with a ‘secret’ feature known as the ‘Wand’.
Thx @FlashDailyNet for this news :D
There is an official post on Adobe devnet.
In a nutshell it allow the mobile device to share, Touch Events, Gesture and Accelerometer.
You can also send some stuff from the .swf like a background image or vibration request.
Yep, it’s an Android only feature but it won’t hold me to use it.
- Today 8 mobile device out of 10 use Android
- Air runtime is one of the most installed app
- The Wand API is quick and simple :)
- This second screen allow a lot of stuff ( application shortcut, gamepad for a second player ! )
- Yes, you can already do it since flash 10 using rtmfp and IPMulticast but here people don’t have to DL your custom remote and there is no anoying security popup
This is just a quick test but the idea is
.1st player control the plane with keyboard
.2nd player control the mines
Please click on the .swf to give focus and use keyboard.
Some stuff i want to say about this Wand.swc
- I Love It !
- the default skin ‘metal-like’ image is ugly :p
- you cannot play sound trought the Wand
- you cannot play video trought the Wand
- you cannot send partial image
- you have to create and encode your bitmapdata (synchronous operation)
- If you generate a smaller image, the image is streched ( witch is cool because you don’t have to create full res image some android device are 2560* 1600 px !)
- Each gamepad state is a different image, it mean that you have to generate 19 differents images for a basic 4-way/2 buttons gamepad :/ ; and all states must be generated and cached due to the synchronous JPEGEncoding (workers can be usefull here -not tested- )
Stuff I would like to see in this Wand
- Sending a bitmapdata with clipRect and transform matrix instead of a full JPEG ( even better a movieclip or a swf)
- Audio
How to use it
if ( !Wand.connected ) { Wand.connect( this.stage ); Wand.addEventListener(Wand.EVENT_CONNECT, _createAndApplySkin ); Wand.addEventListener(Wand.EVENT_DISCONNECT, _onWandDisconnect ); }
protected function _createAndApplySkin(e:Event):void { // -- creating a background image for the device var dim:Point = Wand.screenDimensions; var tf:TextField = new TextField(); tf.defaultTextFormat = new TextFormat("Arial", 48, 0xFFFFFF, true, null, null, null, null, TextFormatAlign.CENTER); tf.width = dim.x; tf.text = "Welcome !"; var ba:ByteArray = new ByteArray(); var dat:BitmapData = new BitmapData(dim.x, dim.y, false, 0x0); dat.draw(tf, new Matrix(1,0,0,1,0,(dim.y * .5) - 24 )); dat.encode( dat.rect, new JPEGEncoderOptions(60), ba ); // encoding to jpeg try{ Wand.applySkin(ba); } catch(e:IllegalOperationError){ trace("IllegalOperationError : " +e); } // note : touch event are => import flash.events.TouchEvent; Wand.addEventListener( TouchEvent.TOUCH_BEGIN, _onTouchBegin ); Wand.addEventListener( TouchEvent.TOUCH_MOVE, _onTouchMove ); Wand.addEventListener( TouchEvent.TOUCH_END, _onTouchEnd ); }
private function _onTouchBegin(e:TouchEvent):void { // ... your code here Wand.vibrate(50); // send a vibration ! } private function _onTouchMove(e:TouchEvent):void { // ... your code here } private function _onTouchEnd(e:TouchEvent):void { // ... your code here } // Clean private function _onWandDisconnect(e:Event):void { // ... your code here }