2013年5月29日 星期三

Adobe AIR: use ExtensionContext call api on android

為了這個功能我搞了快2天,難的地方在於下command...
很多教學都是把command的格式打上,可是對於不常用的我來說 根本不知道要怎麼填〒▽〒
總而言之 後來我會了 之前都是用flash build生成apk,現在不僅會用adt生apk跟ane,還學會ant耶~
即然air有了這個功能,當然是要把所有遊戲中可能會用到的 admob、facebook、iap都實作一次~
這裡先來講~單純的flash ExtensionContext 類別的實用~而native就用toast驗證一下是否成功就好惹~


需要做的東西:
1.一支jar,實作android的功能,我把命名為AndroidExtension.jar
2.一支swc,實作AndroidExtension.jar跟air的interface,我把命名為AirExtensionLib.swc
3.一支swf,就是用air做出來的介面,我把它命名為AirExtensionUsage.swf


實做的流程:
1. AndroidExtension.jar ,先把要擴充的功能實作出來,並且試試看效果(在這裡是把toast做出來,雖然沒2行= =)
2.AirExtensionLib.swc實作
3.AirExtensionUsage.swf實作
4.生成ane檔(air的資源檔),把AndroidExtension.jar跟AirExtensionLib.swc包成ane。
   AndroidExtension.jar裡如果使用到其它jar,需要先把這些jar統統包成一包,包完也叫AndroidExtension.jar就好了
5.再把ane檔跟swf以及app.xml(air 裡的設定檔)統統包成apk 
6.測試->完成

批次檔 LOOP FOR 對所有資料夾做動作

echo echo start > temp.bat
for /f %%i in ('dir/AD/B') do (
echo COPY data.txt %%i >> temp.bat
)
call temp.bat
pause
del temp.bat

※由於for迴圈中 只能有一行描述句
故在一開始先建立一個temp.bat
並寫入命令 echo start
該迴圈訪問所有的資料夾
並在每個迴圈中將命令句 COPY data.txt %%i 加入 temp.bat中
 ※>是建立檔案並寫入(a),>>是寫入檔案(w)
迴圈結束後,
再執行(call) temp.bat
最後 使用del 將 temp.bat刪除

FMS-FLASH MEDIA SERVER 視訊網站架設教學(2)

這篇主要建立一個簡易的聊天室
登入後,會更新房間人員的清單
發送聊天訊息
使用同一人名登入 會顯示登入失敗

SERVER CODE-main.asc

var roomUser = new Array();
var ERROR_REPEAT_LOGIN=0;
application.onAppStart = function (){ 
 
}
// Called when a client connects
application.onConnect = function(client,userName) {
 var _user=getUserByUserName(userName);
 if(_user)
 {
  application.rejectConnection(client,ERROR_REPEAT_LOGIN);
  return;
 }
 
 var user=new Object();
 user.userName=userName;
 user.id=client.id;
 user.client=client;
 roomLogin(user);
 
 client.chatToAll = function(msg) {
  var user=getUserByClient(client);
  application.broadcastMsg("chatReceive",user.userName,msg);
 }
}

// Called when a client disconnects
application.onDisconnect = function(client) {
 var user=getUserByClient(client);
 removeUser(user);
}

function roomLogin(user)
{
 application.acceptConnection(user.client);
 application.broadcastMsg("systemMessage", user.userName+" in room");
 roomUser.push(user);
 application.broadcastMsg("userList",roomUser);
}

function removeUser(user){
 var ind=roomUser.indexOf(user);
 if(ind!=-1)
 {
  roomUser.splice(ind,1);
  application.broadcastMsg("userList",roomUser);
 }

}

function getUserByUserName(userName){
 for(var i=0;i<roomUser.length;i++)
  {
   if(roomUser[i].userName==userName)
   {
    return roomUser[i];
   }
  }
  return null;
}

function getUserByClient(client){
 for(var i=0;i<roomUser.length;i++)
  {
   if(roomUser[i].client==client)
   {
    return roomUser[i];
   }
  }
  return null;
}





CLIENT CODE-chatRoom.mxml

<?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" applicationComplete="application1_applicationCompleteHandler(event)"
      xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
 <fx:Script>
  <![CDATA[
   import flash.net.NetStream;
   import flash.utils.setTimeout;
   
   import mx.collections.ArrayCollection;
   import mx.controls.Alert;
   import mx.events.FlexEvent;
   
   private var server_ip:String="rtmp://localhost/chat";
   private var mineNc:NetConnection;
   private var mineNs:NetStream;
   [Bindable]
   private var userArr:ArrayCollection=new ArrayCollection();
   protected function application1_applicationCompleteHandler(event:FlexEvent):void
   {
    chat_input.addEventListener(KeyboardEvent.KEY_UP,onChatKeyUp);
   }
   private function login():void
   {
    var name:String=name_txt.text;
    if(name!="")
    {
     mineNc = new NetConnection();
     mineNc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
     mineNc.connect(server_ip,name);
     login_group.visible=false;
     
     var ncClient:Object = new Object(); 
     mineNc.client = ncClient; 
     ncClient.systemMessage = systemMessage;
     ncClient.userList = userList;
     ncClient.chatReceive = chatReceive;
    }
    else
     Alert.show("請輸入登入別名", "ERROR", Alert.OK,null);
   }
   private function netStatusHandler(event:NetStatusEvent):void
   {
    trace(event.info.code);
    switch (event.info.code)
    {
     case "NetConnection.Connect.Success":
      break;
     case "NetConnection.Connect.Closed":
      Alert.show("Closed", "ERROR", Alert.OK,null);
      break;
     case "NetConnection.Connect.Rejected":
      loginFail(event.info.application); 
      break;
    }
   }
   private function loginFail(type:int):void{
    switch(type)
    {
     case 0:
      Alert.show("重覆登入", "ERROR", Alert.OK,null);
      break;
     default:
      Alert.show("Rejected", "ERROR", Alert.OK,null);
      break;
    }
   }
   private function onChatKeyUp(evt:KeyboardEvent):void
   {   
    if (evt.keyCode == Keyboard.ENTER)
    {
     mineNc.call("chatToAll", null,chat_input.text);
     chat_input.text="";
    }
   }
   
   private function systemMessage(msg:String):void
   { 
    msg+=String.fromCharCode(13);
    content_txt.text+=msg;
   }
   
   private function userList(list:Object):void
   {
    userArr=new ArrayCollection;
    for(var i:int=0;i<list.length;i++)
    {
     userArr.addItem(list[i]);
    }
   }
   
   private function chatReceive(senderName:String,msg:String):void
   {
    msg=senderName+":"+msg+String.fromCharCode(13);
    content_txt.text+=msg;
   }
  ]]>
 </fx:Script>
 <s:HGroup width="100%" height="100%">
  <s:List id="room_list" width="20%" height="100%" dataProvider="{userArr}" itemRenderer="userItem" verticalScrollPolicy="auto" horizontalScrollPolicy="off" contentBackgroundAlpha="0.0" borderVisible="false"/>
  <s:VGroup  width="80%" height="100%">
   <s:TextArea editable="false" id="content_txt" width="100%" height="90%"/>
   <s:TextInput id="chat_input"  width="100%" height="10%"/>
  </s:VGroup>
 </s:HGroup>
 <s:HGroup id="login_group" right="10" top="10">
  <s:TextInput width="100" id="name_txt"/>
  <s:Button label="login" click="login()"/>
 </s:HGroup>
</s:Application>


CLIENT CODE-userItem.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" width="90" height="21" creationComplete="itemrenderer1_creationCompleteHandler(event)">
 <fx:Script>
  <![CDATA[
   import mx.events.FlexEvent;
   
   protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void
   {
    // TODO Auto-generated method stub
    
   }
   
  ]]>
 </fx:Script>
 <s:Label text="{data.userName}" verticalCenter="0"/>
</s:ItemRenderer>


這篇要注意的幾點
server呼叫單一個client的method 是使用client.call
server廣播所有client的method是application.broadcastMsg
以上2個方法 都需要在application.accept
Connection(client);
允許該client加入之後 ,才可使用。

application.rejectConnection(client,ERROR_REPEAT_LOGIN);
若不同意使用者登入 可以使用rejectConnection
rejectConnection是可以帶參數回去的

其餘的應該都很簡單 就不多做講解了~

FMS-FLASH MEDIA SERVER 視訊網站架設教學(1-基本認知)

flash media server 是一套在server上運行as語言的工具
主要是用來當as3的連線server,可以用來做多人視訊,多人遊戲,live播放等需要server的功能
以下簡稱fms

fms的寫作方式 較不同於as3,主要是不能給型態
var i:int=3;
function foo():void
這些都會發生error
且能使用的function、api也是自成一套
http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11aff5ba-7f8b.html
這裡是線上的api 可供參考
至於ide,也無法使用flash builder 或 flash developer
目前找到能用的ide是SEPY ActionScript Editor,用起來還過的去- -

fms也無法使用namespace
舉反 public private等...都是無法使用的

trace的功能,會印在該server的log裡

fms上所有server都放在applications/底下
要增加一個新的server就多開一個資料夾
起始檔是main.asc (後綴是.asc)

import的方式需改成 load
例如: load("config.asc");
load的使用方式基本上跟import一樣
共用的package會放在scriptlib/底下
※例如我們新建一個json.asc
所有的server都有可能會用到,我們就把這個asc檔存放在scriptlib底下
使用時 load("json.asc");

在main.asc裡,application這個變數是內部變數,就是指目前的server
其自帶的屬性跟function請參考這裡
http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11afc95e-7edf.html
所有server的狀態都可以由這些方法得知跟實現

當有使用者登入,會自動參生一個client的變數,代表該位使用者
跟server一樣,client也有自已的class集成,參考以下
http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11afc95e-7ec3.html

ok 以上是基本認知
接下來我們會以做個簡易聊天室來了解fms的寫作方式~

2013年5月14日 星期二

烏鴨女

美國土 先捏出大體

修一下

細節處理







頭毛先裁斷,翻完模之後再用補土接上




只翻身體 矽膠翻模

還不錯


腳就用水晶土翻了 不然太浪費時間跟金錢了

水晶土真的要好好翻 不然之後打磨可能會很痛苦













done