Posted on

Flex裡綁定(Bindable)相關函數及使用方式

在flex裡,最強大的標籤應該就是[Bindable]的綁定標籤了
因為某次的需求,我需要研究將Bindable綁定至函數
也順便研究了ChangeWatcher和BindingUtils的使用

【BindingUtils】
官方的說明在此:
http://help.adobe.com/zh_TW/FlashPlatform/reference/actionscript/3/mx/binding/utils/BindingUtils.html
這是Flex內綁定的工具,裡面有兩個屬性,一個是綁定到函數(bindSetter),另一個則是綁定到某物件的某屬性(bindProperty)

使用範例如下
1. 綁定到函數(bindSetter)










2. 綁定到某物件的某屬性(bindProperty)










【ChangeWatcher】
官方的說明在此:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/binding/utils/ChangeWatcher.html
因為此次我們要綁定的函數裡是有帶多個參數的,因此BindingUtils的bindSetter便無法使用
這時就需要使用BindingUtils所用的ChangeWatcher來自己做綁定的動作
ChangeWatcher的使用方式如下
var model:Model = new Model();
watcherInstance = ChangeWatcher.watch(model,[“totalItems”],itemsChanged);
根據官方文件watch的傳入的東西依序為”要綁定的物件”、”要綁定的屬性”、”要綁定的函數”

下面便是我根據這些所寫的小範例
MyBindingUtils.as
package {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.system.Capabilities;
import flash.utils.getTimer;

import mx.binding.utils.ChangeWatcher;
import mx.controls.Alert;
import mx.resources.ResourceManager;

public class MyBindingUtils extends EventDispatcher {

private static var _objs:MyBindingUtils;

public static function getInstance():MyBindingUtils {
if (_objs == null) {
_objs = new MyBindingUtils();
}
return _objs;
}

public function changeLanguage(lang:String):void {
ResourceManager.getInstance().localeChain = [lang, “en_US”];
this.dispatchEvent(new Event(“ChangeLanguage”));
}

[Bindable(event=”ChangeLanguage”)]
public function getString(type:String, key:String, parameters:Array = null, locale:String = null):String {
return ResourceManager.getInstance().getString(type, key, parameters, locale);
}

public function bindString(target:Object, prop:String, type:String, key:String, parameters:Array = null):String {
var w:ChangeWatcher = ChangeWatcher.watch(this, [“getString”], null);
var result:String = getString.apply(null, [type, key, parameters]);
if (w != null) {
var invoke:Function = function(event:*):void
{
result = getString.apply(null, [type, key, parameters]);
target[prop] = result;
};
w.setHandler(invoke);
invoke(null);
}
return result;
}
}
}

完整範例檔案可按此下載

Posted on

在as3裡取得函數呼叫者資訊

補充:這個方法只可以在flash player的debugger版本可用,
因為在一般非debugger的player無法用”e.getStackTrace()”來抓取歷史資訊

再補充:非debugger的版本只需在flex的compiler arguments裡加上
-swf-version=18
這串參數,就會可以正確的取得”e.getStackTrace()”的值了!

如果我們在某個函數兩要知道有關傳進的參數的相關資訊
可以使用arguments去取得

下面網址有介紹arguments的使用方式
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/arguments.html

package {
import flash.display.Sprite;

public class ArgumentsExample extends Sprite {
public function ArgumentsExample() {
println(“Hello World”);
}

public function println(str:String):void {
trace(arguments.callee == this.println); // true
trace(arguments.length); // 1
trace(arguments[0]); // Hello World
trace(str); // Hello World
}
}
}

但是過去在as2裡,arguments可以用caller去知道呼叫此函數的地方
在as3裡,卻將此一屬性拿掉了。
那我們在as3裡該如何知道是誰呼叫了這個函數呢?

我在一個別人的部落格裡找到一個別人寫好的解法
是先丟出一個錯誤訊息,然後去getStackTrace(),再去解析之前呼叫者的資訊
try { throw new Error(); }
catch ( e: Error ) { stackTrace = e.getStackTrace(); }

原始部落格在此
Looking up the calling function

原始碼如下:
var stackTrace:String;

try { throw new Error(); }
catch (e:Error) { stackTrace = e.getStackTrace(); }

var lines:Array = stackTrace.split(“\n”);
var isDebug:Boolean = (lines[1] as String).indexOf(‘[‘) != -1;

var path:String;
var line:int = -1;

if(isDebug)
{
var regex:RegExp = /at\x20(.+?)\[(.+?)\]/i;
var matches:Array = regex.exec(lines[2]);

path = matches[1];

//file:line = matches[2]
//windows == 2 because of drive:\
line = matches[2].split(‘:’)[2];
}
else
{
path = (lines[2] as String).substring(4);
}

trace(path + (line != -1 ? ‘[‘ + line.toString() + ‘]’ : ”));

Posted on

AS3.0中三角函數的使用

先用Math.atan2()去求得圓的弧度
用法是弧度 = Math.atan2(x,y)
x與y指的是在坐標軸上形成三角型的那個點的x,y

然後再用弧度轉角度的公式去求出角度

//弧度轉角度
var arc:Number=1 //弧度
var angle=(arc*180)/Math.PI; //角度

//角度轉弧度
var angle:Number=30 //角度
var arc=angle/180*Math.PI; //弧度

另外Math.sin、Math.cos裡面要傳入的值,則是弧度
所以若我們要算sin60的值,需要這樣去代入
Math.sin(60*Math.PI/180);
那sin = 對邊/斜邊
所以要求出對邊就是 Math.sin(60*Math.PI/180) * 斜邊
其他的亦同。

語法結構:
Math.sin(數值或表達式);
Math.cos(數值或表達式);
Math.tan(數值或表達式);
Math.asin(數值或表達式);
Math.acos(數值或表達式);
Math.atan(數值或表達式);
Math.atan2(數值或表達式);
註:數值或表達式的結果值應介於-1和1之間。
範例:
myNum = Math.sin(60*Math.PI/180);
以表達式60*Math.PI/180的運算結果為參數求取正弦值並存入變量myNum中。
myNum = Math.cos(0.49);
以數值0.49為參數求取餘弦值並存入變量myNum中。
myNum = Math.tan(60*Math.PI/180);
以表達式60*Math.PI/180的運算結果為參數求取正切值並存入變量myNum中。
myNum = Math.asin(45*Math.PI/180);
以表達式45*Math.PI/180的運算結果為參數求取反正弦值並存入變量myNum中。
myNum = Math.acos(0..49);
以數值0.49為參數求取反餘弦值並存入變量myNum中。
myNum = Math.atan(30*Math.PI/180);
以表達式30*Math.PI/180的運算結果為參數求取反正切值並存入變量myNum中。
myNum = Math.atan2(30,50);
求取點50,30到X軸的角度並存入變量myNum中。

Posted on

AS3.0中製作直式書寫的方式

在as3.0中有 FTE可針對文字去測量其寬度、高度等
針對個別的文字去做處理
相關官網的說明可見此
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS6C0BB8ED-2805-467a-9C71-F9D757F33FB6.html

ElementFormat是定義文字的相關屬性(字型、大小、顏色等等)
然後再new一個TextElement設定文字格式和文字內容
再將其放到一個TextBlock裡面

TextBlock裡面則有許多相關的操作函數
可以對個別的文字做旋轉、定位等等
http://livedocs.adobe.com/flex/3_cn/langref/flash/text/engine/TextBlock.html
詳細的手冊說明在上面

裡面的lineRotation將角度設為九十度(TextRotation.ROTATE_90)時
文字就會呈現傳統的中文直式書寫方式呈現

下面的是將文字改為直式文字的範例程式

package {
import flash.display.Sprite;
import flash.text.engine.FontDescription;
import flash.text.engine.TextBlock;
import flash.text.engine.TextElement;
import flash.text.engine.TextLine;
import flash.text.engine.TextRotation;
import flash.text.engine.ElementFormat;

public class TextBlock_lineRotationExample extends Sprite {

public function TextBlock_lineRotationExample():void {
var s:String = “一向批判電影不會「口下留情」的大陸媒體,竟在李安導演《少年PI的奇幻漂流》內地上映後,於中國最大入口網站搜狐,罕見大讚道:『影片美輪美奐的視覺奇觀,身臨其境的3D效果。』”;

var fontDescription:FontDescription = new FontDescription(“MS Mincho”);
var format:ElementFormat = new ElementFormat();
format.fontSize = 15;
format.fontDescription = fontDescription;

var textElement:TextElement = new TextElement(s, format);
var textBlock:TextBlock = new TextBlock();
textBlock.content = textElement;
textBlock.lineRotation = TextRotation.ROTATE_90;

var linePosition:Number = this.stage.stageWidth – 120;
var previousLine:TextLine = null;

while (true) {
var textLine:TextLine = textBlock.createTextLine(
previousLine,
300);
if (textLine == null)
break;
textLine.y = 30;
textLine.x = linePosition;
linePosition -= 24;
addChild(textLine);
previousLine = textLine;
}
}
}
}

Posted on

使用Flex編譯出ios的ipa檔案

這邊提供一些我看到的教學影片及連結

1.在Windows上一步步發佈的方式

http://support.brightcove.com/en/docs/step-step-guide-publishing-apple-app-store-using-windows

2. 使用Flex編出ipa的教學

http://tv.adobe.com/watch/adc-presents/build-ios-applications-using-flex-and-flash-builder-45/

3. 怎麼在windows上產生.p12檔案

4. 在Flex裡安裝AIR SDK的方式

http://helpx.adobe.com/flash-builder/kb/error-run-debug-deploy-ios.html

http://www.flashdeveloper.co/post/10985842021/overlay-adobe-air-32-in-flash-builder-46

其實最基本的可以就依照這篇文章去做一步步的發佈設定

如果不想太快買開發者身份 也可以到google 打上fake .p12 ,下載破解檔案

就可以直接做發佈的設定了!

===================================

另外也提供不使用flex去做發佈的方式

1.安裝 adobe AIR SDK,請將以下壓縮檔,解到自己電腦任意目錄中

 http://www.adobe.com/devnet/air/air-sdk-download.html

例如,我電腦中,我解到:E:\software\AdobeAIRSDK

 

2.準備 command line 批次檔 build.bat,檔案內容如下:

 

set SDK_HOME=E:/software/AdobeAIRSDK à 換成你放 air sdk 的位置

set ADT_JAR=%SDK_HOME%/lib/adt.jar

 

set APP_NAME=HorseRacingDemo à 換成你專案的名稱,會用來找對應的 xxx.swf 與 xxx-app.xml,並發布成 xxx.ipa

set APP_ROOT_DIR=C:/Users/ben.chang/Desktop/新增資料夾 à 所有東西放置的資料夾

set BUILD_DIR=%APP_ROOT_DIR%

set APP_ROOT_FILE=%APP_NAME%.swf

set APP_DESCRIPTOR=%APP_NAME%-app.xml

set IPA_NAME=%APP_NAME%.ipa

set STORETYPE=pkcs12

set KEYSTORE=FakeCert.p12

set STOREPASS=1234

set PROVISIONING_PROFILE=Fake.mobileprovision

 

java -jar %ADT_JAR% -package -target ipa-debug -provisioning-profile %APP_ROOT_DIR%/%PROVISIONING_PROFILE% -storetype %STORETYPE% -keystore

 

%APP_ROOT_DIR%/%KEYSTORE% -storepass %STOREPASS% %APP_ROOT_DIR%/%IPA_NAME% %APP_ROOT_DIR%/%APP_DESCRIPTOR% -C %BUILD_DIR% %APP_ROOT_FILE%

 

pause

 

3.準備 xxx-app.xml

 

我的 Flash CS 5.0,設定輸出 ipad 產出的 xml 為:

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no” ?>

<application xmlns=”http://ns.adobe.com/air/application/2.0“>

<id>no-name</id>

<version>1.0</version>

<filename>?芸??1</filename>

<description/>

<name>?芸??1</name>

<copyright/>

<initialWindow>

<content>?芸??1.swf</content>

<systemChrome>standard</systemChrome>

<transparent>false</transparent>

<visible>true</visible>

<fullScreen>false</fullScreen>

<aspectRatio>portrait</aspectRatio>

<renderMode>auto</renderMode>

<autoOrients>false</autoOrients>

</initialWindow>

<icon/>

<customUpdateUI>false</customUpdateUI>

<allowBrowserInvocation>false</allowBrowserInvocation>

<iPhone>

<InfoAdditions>

      <![CDATA[<key>UIDeviceFamily</key><array><string>2</string></array>]]>

    </InfoAdditions>

</iPhone>

</application>

 

設定輸出 iphone 的 xml 為:

 

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no” ?>

<application xmlns=”http://ns.adobe.com/air/application/2.0“>

……

……

<iPhone>

 <InfoAdditions>

      <![CDATA[<key>UIDeviceFamily</key><array><string>1</string></array>]]>

    </InfoAdditions>

</iPhone>

</application>

 

設定輸出 iphone 與 ipad 的 xml 為:

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no” ?>

<application xmlns=”http://ns.adobe.com/air/application/2.0“>

……

……

<iPhone>

 <InfoAdditions>

      <![CDATA[<key>UIDeviceFamily</key><array><string>1</string><string>2</string></array>]]>

    </InfoAdditions>

</iPhone>

</application>

 

4.資料夾中準備好相關檔案:

 

l   xxx.swf

l   xxx-app.xml

l   build.bat

l   FakeCert.p12

l   Fake.mobileprovision

 

譬如,我在自己電腦桌面上開一新資料夾,如下畫面:

執行 build.bat 大約一兩分鐘 就可產出 *.ipa

 

Posted on

在flex裡內嵌字型

在flex裡內嵌文字有幾種方式
1. FLEX 動態更換中文字型 ( 非嵌入方式 )
這個請參考下面這篇的教學
http://blog.corausir.org/programing/ausir-777
不過上面的方式 必須以PHP配合
並且空間要支援PHP的EXEC呼叫外部EXE檔的功能
許多空間伺服器並沒有支援這個功能
另外我在測試時也發現一個問題
就是當我要產生的文字過長(ex: 400~500字)
會發生讀取錯誤的問題

2. 直接內嵌字體
(1) 使用css

@font-face {
    src: url("location") | local("name");
    fontFamily: alias;
    [fontStyle: normal | italic | oblique;]
    [fontWeight: normal | bold | heavy;]
    [advancedAntiAliasing: true | false;]
}

(2)使用as3嵌入

package
{
import flash.text.Font;

public class ArialFont
{

[Embed(source=’assets/fonts/arial.ttf’, fontName=’ArialV’, mimeType=’application/x-font’, embedAsCFF=”true”)]
private static var ArialF:Class;

[Embed(source=’assets/fonts/arialbd.ttf’, fontName=’ArialV’, fontWeight=”bold”, mimeType=’application/x-font’, embedAsCFF=”true”)]
private static var ArialBoldF:Class;

[Embed(source=’assets/fonts/ariali.ttf’, fontName=’ArialV’, fontStyle=”italic”, mimeType=’application/x-font’, embedAsCFF=”true”)]
private static var ArialItalicF:Class;

[Embed(source=’assets/fonts/arialbi.ttf’, fontName=’ArialV’, fontWeight=”bold”, fontStyle=”italic”, mimeType=’application/x-font’, embedAsCFF=”true”)]
private static var ArialBoldItalicF:Class;

public function ArialFont()
{
Font.registerFont( ArialF );
Font.registerFont( ArialBoldF );
Font.registerFont( ArialItalicF );
Font.registerFont( ArialBoldItalicF );

}
}
}

直接嵌入文字會遇到一個很大的問題,就是文字太肥了,
這時,若我們只需要嵌入該字型檔的部份字型,而不需要全部嵌入
就可以設定unicodeRange
例如下面的範例





@font-face {
src:url(“../assets/MyriadWebPro.ttf”);
fontFamily: myFontFamily;
advancedAntiAliasing: true;
unicodeRange:
U+0041-U+005A, /* Upper-Case [A..Z] */
U+0061-U+007A, /* Lower-Case a-z */
U+0030-U+0039, /* Numbers [0..9] */
U+002E-U+002E; /* Period [.] */
}

TextArea {
fontFamily: myFontFamily;
fontSize: 32;
}




The Text Uses Only Some of Available Characters
0 1 2 3 4 5 6 7 8 9.



可以只嵌入部份的文字,
若我們希望只嵌入中文字的話,則可以參考flash-unicode-table.xml裡面
有一般文字檔案的unicode編碼字集範圍
這樣可以大大改善embed文字造成檔案過大及編譯過久的問題了!

參考資料: http://hi.baidu.com/sitoto/blog/item/12528ab1124a345c0923028b.html

Posted on

在flex4裡用spark建置可拖動panel

在flex4裡面的spark組件的panel是沒有內建拖動的功能的
因此若我們希望這物件要可以被拖動
我們必須要去自己實做當使用者拖動topGroup的區塊時的拖動動作

範例程式碼如下:
package components
{
import flash.events.MouseEvent;

import mx.managers.DragManager;

import spark.components.Group;
import spark.components.Panel;

/**
* A simple extension of the Spark Panel component
* that enables dragging.
*/
public class DraggablePanel extends Panel
{
//————————————–
// Constructor
//————————————–

public function DraggablePanel()
{
super();
}

//————————————–
// Skin Parts
//————————————–

/**
* The skin part that represents the title bar of the underlying Panel.
* NOTE: The default PanelSkin already has this, it’s just not defined as a skinPart in the Panel class.
* We want it so that we can capture dragging.
*/
[SkinPart(required=”true”)]
public var topGroup:Group;

//————————————–
// Overridden Methods
//————————————–

protected override function partAdded( partName:String, instance:Object ) : void
{
super.partAdded( partName, instance );

if (instance == topGroup)
{
Group( instance ).addEventListener( MouseEvent.MOUSE_DOWN, topGroup_mouseDownHandler );
Group( instance ).addEventListener( MouseEvent.MOUSE_UP, topGroup_mouseUpHandler );
}
}

protected override function partRemoved( partName:String, instance:Object ) : void
{
super.partRemoved( partName, instance );

if (instance == topGroup)
{
Group( instance ).removeEventListener( MouseEvent.MOUSE_DOWN, topGroup_mouseDownHandler );
Group( instance ).removeEventListener( MouseEvent.MOUSE_UP, topGroup_mouseUpHandler );
}
}

//————————————–
// Event Handlers
//————————————–

protected function topGroup_mouseDownHandler( event:MouseEvent ):void
{
if ( !DragManager.isDragging )
startDrag();
}

protected function topGroup_mouseUpHandler( event:MouseEvent ):void
{
stopDrag();
}
}

Posted on

如何在flex4裡自製resize事件

首先resize事件是針對該元件大小被縮放時才會產生
所以要在根元件去監聽resize的事件

很必需注意的一點,是flex4的spark元件預設會自動無視超出範圍大小的東西
因此會發現當我們把視窗縮小時,
因為超出的大小被無視了
無法偵聽到resize事件
這時候我們要在根容器上加上 clipAndEnableScrolling=”true”屬性
這個屬性主要是告訴我們要不要自動無視超出的範圍
group的預設值是false 也就是無視他
因此我們要先將 clipAndEnableScrolling設定為true
才可以偵聽到縮小視窗的事件

Posted on

ResourceManager動態載入多國語系的實現

事前準備工作
1.[撰寫Ant編譯時所使用的XML檔]
依照原有的XML去設定自己的SDK的位置,並且寫入要載入的語言檔

<?xml version="1.0" encoding="utf-8"?>
    <project name="Example resource bundle builder" basedir="." default="main">
    <!--這邊應設定為自己電腦的flex sdk的位置-->
    <property name="FLEX_HOME" value="C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.0" />
    <property name="APP_ROOT" value="${basedir}"/>
    <!--這邊需要載入ant編譯as檔案所需的flexTasks.jar以及所有相關編譯所需的函式庫-->
    <taskdef resource="flexTasks.tasks" >
        <classpath> <pathelement path="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
            <pathelement path="${FLEX_HOME}/lib/flexTasks.jar"/>
            <fileset dir="${FLEX_HOME}/lib">
                <include name="**/*.jar"/>
            </fileset>
        </classpath>
    </taskdef>
    <!--定義所有的語言-->
    <target name="main">
        <antcall target="en_US"></antcall>
        <antcall target="zh_TW"></antcall>
    </target>
    <target name="en_US">
        <mxmlc>
            <locale>en_US</locale>
            <source-path>locale/{locale}</source-path>
            <include-resource-bundles>test</include-resource-bundles>
            <output>src/Resources_en_US.swf</output>
        </mxmlc>
    </target>
    <target name="zh_TW">
        <mxmlc keep-generated-actionscript="true">
            <allow-source-path-overlap>true</allow-source-path-overlap>
            <locale>zh_TW</locale>
            <source-path>locale/{locale}</source-path>
            <!--載入相關的函式庫-->
            <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
                <include name="libs" />
                <include name="locale/{locale}" />
            </compiler.library-path>
            <!--定義要載入的語言檔案(可以用很多檔案)-->
            <include-resource-bundles>test</include-resource-bundles>
            <!--<include-resource-bundles>other</include-resource-bundles>-->
            <output>src/Resources_zh_TW.swf</output>
        </mxmlc>
    </target>
</project>

2.[設定Ant環境]
(a)Help->Software Updates更新flash builder的Ant編輯程式
(b)Windows->Show View->Other->Ant->Ant把視窗叫出來
(c)按Ant編譯視窗最左邊的Add Buildfiles,選擇剛剛寫的xml
(d)RUN他

3.[設定要產出的flex專案檔的編譯locale參數]
如果是要中文+英文則為-locale en_US zh_TW,如果少了這個動作在變語言時會發生缺少核心語言CORE檔案的問題。

4. locale檔副檔名是.properties

====================================
1. flex版本的實現及範例下載
http://www.nbilyk.com/flex-localization-example

2. 為flash builder安裝ant
http://www.judahfrangipane.com/blog/2007/12/13/flex-builder-3-ant-support/

3. 官方關於ResourceManager的類別資料
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/ResourceManager.html

4. 在flash裡實現多國語系
http://ticore.blogspot.com/2010/07/as3-project-multi-languages.html

5. 各種實現方式
http://blog.csdn.net/fireson/archive/2010/01/12/5181343.aspx

[學習經歷]
首先先至[flex版本的實現及範例下載]下載多國語系範例
然後到[為flash builder安裝ant]實際編譯ResourceManager的語言檔為swf
再依範例自行試看看如何實現