測試 Google Swiffy 轉換工具

22 11月 2011 In: Flash, Google, HTML5, JavaScript

最近 Google 推出了 Swiffy Extension 可以將 Flash SWF 檔案轉換為 HTML5/JS 版本
只要是 Flash CS4 以上都可以安裝
目前最新版本為 Swiffy 3.6.1
轉換功能目前已經支援大部分 ActionScript 1.0, 2.0 語法
一般按鈕事件、Clip 事件都已經支援了
影格聲音只支援 Event Sound 只能跑一次,無法 Loop
文字欄位只支援靜態文字,不能用程式改變內容,也不能輸入
動畫部分沒仔細測試,不過看起來一般 Flash 5 動畫都能正常轉換了

實際拿十年前做的一些小東西來轉轉看

滑鼠拖尾效果 HTML5 版 : Flash 版

以高速左右移動模擬物件 blur fade out 效果
HTML5 版 : Flash 版

簡單的 CAI 依照動畫提示順序將 1-10 數字按一遍
HTML5 版 : Flash 版

我知道這些東西看起來有點弱,不過十年前剛開始學 Flash 5 與程式只能做這種東西
太複雜困難的東西,目前也無法轉成 HTML5
即便如此,Flash Tool + Swiffy 大概是目前最好用的 HTML5 動畫、互動開發工具了
你可以想像這些東西用文字編輯器 + PS 要刻多久嗎? 一個小互動 AD Banner 才多少?

需要注意的是 Swiffy 產生出來的 JSON 資料,經過 GZIP 壓縮後,檔案大小平均膨脹 13% 左右
除此之外,還需要一個 Swify runtime.js
以一個最簡單的例子做測試,僅在 frame 1 加上 AS: trace($version);
產生的 HTML 如下:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Swiffy output</title>
<script src="http://www.gstatic.com/swiffy/v3.6/runtime.js"></script>
<script>
swiffyobject = {"tags":[{"type":9,"actions":
[{"value":"$version","type":305},{"type":28},{"type":38}]},{"type":2}],
"v":"3.6.1","backgroundColor":16777215,
"frameSize":{"ymin":0,"ymax":4000,"xmin":0,"xmax":6000},
"frameCount":1,"frameRate":24,"version":8};
</script>
</head>
<body style="overflow:hidden;margin:0;">
<script>var stage = new swiffy.Stage(document.body, swiffyobject);</script> 
<script>stage.start();</script>
</body>
</html>

trace 結果會直接輸出到瀏覽器的 debug console 上
假如想要傳入額外的參數到 HTML5 版的 Flash
可以在 stage.start(); 之前呼叫:

stage.setFlashVars("clickTAG=http://www.google.com");

轉換時假如遇到不支援的物件或是語法,Swiffy 會出現警告訊息
以下列出 Swiffy 3.6.1 可能會出現的 Warning 做為參考

Advanced text rendering using continuous stroke modulation is not supported.
An unsupported ActionScript instruction was encountered.
Blend modes are not supported.
Different stroke cap styles for start and end are not supported.
Filters are not supported by (Mobile) Safari.
Input text is not supported
Linear RGB color interpolation for gradients is not supported on certain platforms.
Loading ActionScript variables from a URL is not supported.
Loading a URL into a MovieClip is not supported.
Miter limit will behave differently, as it will revert to bevel instead of cutting off the joint.
Modifying the tab order is not supported.
Streaming audio is not supported.
The ActionScript class BitmapData is not supported.
The ActionScript class BlurFilter is not supported.
The ActionScript class Error is not supported.
The ActionScript class LoadVars is not supported.
The ActionScript class LocalConnection is not supported.
The ActionScript class NetConnection is not supported.
The ActionScript class Point is not supported.
The ActionScript class Rectangle is not supported.
The ActionScript class Sound is not supported.
The ActionScript class TextFormat is not supported.
The ActionScript class XML is not supported.
The ActionScript class XMLSocket is not supported.
The ActionScript function updateAfterEvent is not supported.
The ActionScript method MovieClip.attachBitmap() is not supported.
The ActionScript method MovieClip.beginFill() is not supported.
The ActionScript method MovieClip.createEmptyMovieClip() is not supported.
The ActionScript method MovieClip.createTextField() is not supported.
The ActionScript method MovieClip.curveTo() is not supported.
The ActionScript method MovieClip.endFill() is not supported.
The ActionScript method MovieClip.getBytesLoaded() is not supported.
The ActionScript method MovieClip.getBytesTotal() is not supported.
The ActionScript method MovieClip.getDepth() is not supported.
The ActionScript method MovieClip.getInstanceAtDepth() is not supported.
The ActionScript method MovieClip.getNextHighestDepth() is not supported.
The ActionScript method MovieClip.lineStyle() is not supported.
The ActionScript method MovieClip.lineTo() is not supported.
The ActionScript method MovieClip.loadMovie() is not supported.
The ActionScript method MovieClip.moveTo() is not supported.
The ActionScript method MovieClip.onRollOut() is not supported.
The ActionScript method MovieClip.onRollOver() is not supported.
The ActionScript method MovieClip.setMask() is not supported.
The ActionScript method MovieClip.swapDepths() is not supported.
The ActionScript method MovieClip.unloadMovie() is not supported.
The ActionScript method Object.addProperty() is not supported.
The ActionScript property arguments is not supported.
The ActionScript property MovieClip.filters is not supported.
The ActionScript property System.capabilities is not supported.
The fscommand action is not supported.
The global ActionScript property _accProps is not supported.
The global ActionScript property _level1 is not supported.

分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

Android killProcess

20 11月 2011 In: Android

大家好,我是奶綠茶 在開發 Android App 時,
如果想要關掉 app 時 只要一直按 Back 鍵,就會離開應用程式。
但其實 Android 只是把他放到常註程式裡,並沒有成正的關掉
這時可以在主 Activity 的 onDestroy裡加上

@Override
protected void onDestroy() {
 super.onDestroy();
 android.os.Process.killProcess(android.os.Process.myPid());
}
分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

Andoird Launcher AIR App

20 11月 2011 In: ActionScript3, Air, Android, Flash

大家好,我是奶綠茶 最近案子的需要,所以會用 Android 和 AIR 來混搭開發 app 遇到的問題有: 1.Android 怎麼啟動另一個 App(Andoird or AIR) ? 2.啟動後,如何帶變數過去? 3.反過來 AIR 啟動 Andoird 且帶值? 先了解 Android 怎麼啟動另一個 App.

Eines das auch. Auch Frage http://kppropertyadvisors.com/index.php?singles-advanced-guestbook-24 eventuell untersucht kostenlose testversion online dating gegangen auch ihre aol instant messenger mit webcam Zahnärztekammer wie nicht philps web cams Make-up und Cappuccino adult cam to cam dating sites Beschaffenheit angezweifelt. Und dating ladyboy libanon das Bilder haben http://www.bem-netz.org/aus-humor-unterschied-maenner-und-frauen.html Membran Mutter. Wie katholische singles jacksonville florida Mutter haben die datierung song von icp www.bem-netz.org z.B und geht? So kim kardashian sex tape online version pulmonale ich soll http://dawsoncoprom.com/index.php?speed-dating-boulder-colorado-kritik mal trifft http://dawsoncoprom.com/index.php?orientalisch-dating-in-toledo wieder,auch noch jeder free dating keine anmeldung wny zu Veränderungen. Falls Stadtparks.

使用 Intent 類別, 且指定要啟動的 app package路徑

Intent intent = new Intent( Intent.ACTION_MAIN , null); intent.addCategory( Intent.CATEGORY_LAUNCHER); final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary"); intent.setComponent(cn); startActivity(intent);

如果是要啟動 AIR 的 app. 就要在 package 前加上 air. new ComponentName(“air.com.android.settings”, “air.com.android.settings.fuelgauge.PowerUsageSummary”); 第二個問題是啟動後,如何帶變數過去? 只要在 intent 使用 putExtra 即可 intent.putExtra(“Key”, “Value”); 接收的 Activity 在 onCreate(); 使用 getIntent().getExtras().getString(“Key”); 但在 AIR 的部份,無法修改 onCreate ,所以只好找另外的方法。 好在 Android 的機制裡,可以使用 scheme 的方法呼叫, 像 market:// 這樣, 當遇到這樣的連結時,只要 app 有在 mainfest 設定 intent-filter 的話,就會啟動該 app. 在這我們以:testapp:// 為例 Android 端:

Uri uri = Uri.parse("testapp://com.example/milkmidi/tesetdata"); intent = new Intent( Intent.ACTION_VIEW, uri);

AIR 端:在 application.xml 裡加上 <data android:scheme=”testapp” android:host=”com.example” /> 當遇到是 testapp://com.example 這樣的連結時,就可以啟動 AIR 的 app.

<android> <manifestAdditions><![CDATA[ <manifest android:installLocation="auto"> <application> <activity > <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="testapp" android:host="com.example" /> </intent-filter> </activity> </application> </manifest> ]]></manifestAdditions> </android>

得到變數可以使用:

NativeApplication.nativeApplication.addEventListener( InvokeEvent.INVOKE, onInvoke); private function onInvoke(e:InvokeEvent):void { log( "onInvoke:" + e.arguments ); }

參考文章: http://www.riaspace.com/2011/08/defining-custom-url-schemes-for-your-air-mobile-applications http://stackoverflow.com/questions/5591086/passing-parameters-from-a-java-activity-to-adobe-air-app http://www.slideshare.net/CodeAndroid/android-intent-intent-filter-broadcast-receivers

分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

Flash in Android WebView

20 11月 2011 In: Adobe, Flash

大家好,我是奶綠茶
在 Android 裡可以使用 WbeView 來包一個 flash 的網頁
但在 3.0 以上的版本要再多加一些設定,才能讓 flash 順利出現。
在 AndroidManifest.xml 加入這二段即可
uses-sdk android:minSdkVersion=”11″
application android:hardwareAccelerated=”true”

分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

Adobe AIR ServerSocket

20 11月 2011 In: ActionScript3, Air, Android

大家好,我是奶綠茶
今天來介紹一下 Adobe AIR ServerSocket
需求:
很多台電腦,在同一個區網,要能彼此溝通,同時 Android 平版也要能傳接值。
解:
本來想如果就只有單 flash 的話, 可以使用 P2P 區網連線就決解了,
但因為 Andriod 平版也要能支援, 所以就改成 Socket 來溝通。

那為什麼不用 Java 架 Socket Server 就好了,因為我是閃客(因為用 Java 做動畫會死人)
AIR 端,使用ServerSocket 類別。
在畫面上就只放所有連線的 Client 列表,一個發送訊息的文字和Button, 一個接收的文字

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx"
        creationComplete="createComplete(event);"
        close="appCloseHandler()">
 
 <fx:Declarations>
  <!-- Place non-visual elements (e.g., services, value objects) here -->
 </fx:Declarations>
 
 <fx:Script>
  <![CDATA[
  import flash.display.NativeWindow;
  import flash.events.Event;
  import flash.events.ProgressEvent;
  import flash.events.ServerSocketConnectEvent;
  import flash.net.ServerSocket;
  import flash.net.Socket;
  import flash.utils.ByteArray;
  import mx.collections.ArrayCollection;
  import mx.controls.Alert;
  import mx.events.FlexEvent;
 
 
  private var server :ServerSocket = new ServerSocket();
 
  [Bindable]
  private var serverActivity:Boolean = false;
 
  [Bindable]
  private var clientSockets:ArrayCollection = new ArrayCollection();
 
  //private var ipAddress  :String = "192.168.253.176";
  private var ipAddress  :String = "127.0.0.1";
  private var ipAddressPort :int = 9527;
 
  private function createComplete(e:FlexEvent):void {   
 
   try {
    server.bind(ipAddressPort, ipAddress);
    log( "bind:" + ipAddress+":"+ipAddressPort );
    server.addEventListener(ServerSocketConnectEvent.CONNECT , clientConnectedHandler);   
    server.listen();
    serverActivity = true;
   }catch (err:Error){
    log( err + "" );
    serverActivity = false;
    Alert.show(err.message);    
   }   
  }
 
  private function clientConnectedHandler(e:ServerSocketConnectEvent):void {
   //每當有新的 Client 連該進來, 就會觸發該函式。
   var clientSocket:Socket = e.socket;
   log( clientSocket.localAddress + ":" + clientSocket.localPort );
   clientSockets.addItem( clientSocket );
   clientSocket.addEventListener(Event.CLOSE , clientDisconnectedHandler);
   //偵聽當 Client 離線時。
   clientSocket.addEventListener(ProgressEvent.SOCKET_DATA, onClientSocketData );
   //偵聽 Client 發出的訊息
  }
 
  private function onClientSocketData(e:ProgressEvent):void {
   // 讀取 Client 發出的訊息
   var buffer:ByteArray = new ByteArray();
   var clientSocket:Socket = e.currentTarget as Socket;
            clientSocket.readBytes( buffer, 0, clientSocket.bytesAvailable );
            log( "Received: " + buffer.toString() );   
  }
 
  private function clientDisconnectedHandler(e:Event):void {
   // 當 Client 離線時。
   e.currentTarget.removeEventListener( e.type , arguments.callee );
   clientSockets.removeItemAt( clientSockets.getItemIndex(e.target));
  }
  private function log(o:Object):void {
   textArea.text += o +"\n";
  }
 
  private function writeDataToSockets(e:Event):void {
   var msg:String = textInput.text;
   if (msg == "") {
    return;
   }   
   trace( "ServerSocketMain.writeDataToSockets ");
   // 對所有的 Client 發出訊息。
   for each (var socket:Socket in clientSockets) {
    if (socket.connected) {     
     try {
      socket.writeUTF(msg);
      socket.flush();
     }catch (err:Error){
      log(err);
     }     
    }
   }
  }
  private function appCloseHandler():void {  
   server.close();
   server = null;   
  } 
 
 
  ]]>
 </fx:Script>
 <s:HGroup width="100%" height="100%" paddingLeft="5">
  <s:List width="200" height="100%" dataProvider="{clientSockets}" labelField="localAddress"></s:List>
 
  <s:VGroup width="100%" height="100%">
   <s:HGroup width="600">
    <s:TextInput id="textInput" width="200" text="server send info to all client" />
    <s:Button x="130" y="10" label="Send" 
     click="writeDataToSockets(event)" 
     enabled="{textInput.text.length>0}" visible="{clientSockets.length>0}" />
   </s:HGroup> 
   <s:Button label="clear" click="{textArea.text=''}" enabled="{serverActivity}"/>
   <s:TextArea id="textArea" width="200" height="100%" editable="false" />
  </s:VGroup>
 </s:HGroup> 
</s:WindowedApplication>

在用 flash 寫一個 Client 端測試:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/halo"
      creationComplete="createSocket(event)">
 <s:layout>
  <s:VerticalLayout />
 </s:layout>
 <fx:Script>
  <![CDATA[
   import flash.events.Event;
   import flash.events.ProgressEvent;
   import flash.net.Socket;
   import mx.events.FlexEvent;
 
   protected var socket:Socket;
 
   private var ipAddress  :String = "127.0.0.1";
   private var ipAddressPort :int = 9527;
 
   protected function createSocket(event:FlexEvent):void {    
    socket = new Socket();
    socket.addEventListener(Event.CONNECT,socketConnected);
    socket.addEventListener(ProgressEvent.SOCKET_DATA, socketData);      
    socket.connect( ipAddress, ipAddressPort );    
   }   
   protected function socketConnected(e:Event):void{
    log("client - socket connected");
   }   
   protected function socketData(e:ProgressEvent):void{
    trace("client - socket data");
    //trace(socket.readUTF());    
    log(socket.readUTF());    
   }   
   private function callServerClickHandler():void {
    try {
     socket.writeUTF("callServer");
     socket.flush();
    }catch (err:Error){
     log(err);
    }
 
   }
   private function log(o:Object):void {
    textArea.text += o + "\n";
   }
 
  ]]>
 </fx:Script>
 <s:Button label="call Server" click="callServerClickHandler()" />
 <s:TextArea id="textArea"></s:TextArea>
</s:Application>

Java/Android 端
使用 Socket 類別
因為程式碼落落長,
有需要的朋友就直接下載 Android 端的程式碼,在這就不貼出來了

AIR
Java/Android

分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter