2013-09-29

個人常用的 Sublime Text 2 外掛

Sublime Text 的優點就不多說了,必裝的外掛為 Package Control。 安裝 Package Control 之後,可以注意一下最受歡迎的排行榜,前 100 個應該都可以查看一下。

個人常用外掛:
  1. Advanced​New​File
  2. Alignment
  3. All Autocomplete
  4. Bracket​Highlighter
  5. Convert​To​UTF8
  6. Hex​Viewer
  7. Highlight
  8. HTML-CSS-JS Prettify
  9. JSHint
  10. JsMinifier
  11. Keymap​Manager
  12. Side​Bar​Enhancements
  13. Sublime​Code​Intel
  14. Tag
  15. Terminal
  16. Theme - Soda
  17. Sublimerge Pro

2013-09-18

A deep-linking tool: Simrou

之前介紹過 用 jQuery Address 實現「深連結」
Simrou 的功能也是相同的,但個人覺得 Simrou 更為方便,看一下它的說明立即就能上手。
// 建立實體
window.simrou = new Simrou();

// 設定 deep-linking 規則
var postRoute = window.simrou.addRoute('/post/:id');

// 定義某 deep-linking 規則的事件處理
postRoute.get(function(event, params){
    // alert(params.id);
});

window.simrou.start();

連結寫法(同一般用法):
<a href="#/post/12">第 12 則<</a>

觸發的方式:
window.simrou.navigate('/post/'+myid);

2013-09-09

使用 beginContent() 和 endContent() 設定 Yii 的 layouts

Yii 的 views/layouts 是用來放置 layouts 的目錄,在預設的情況下會有 main.php 和 column1.php 和 column2.php。
main.php 內容定義了,<head> 以及 page header 和 footer 等。 column1.php 和 column2.php 是使用 main.php 的網頁佈局,但修改內容的部份。
例如,我們有個 layout 叫做 mylayout.php:
<?php $this->beginContent('//layouts/main'); ?>
<div>
    <?php echo $content ?>
</div>
<div class="sidebar">
    <ul>
        <li>option 1</li>
        <li>option 2</li>
    </ul>
</div>
<?php $this->endContent() ?>
beginContent('//layouts/main') 表示以 main 為佈局,在  beginContent() 和 endContent() 之間為 content 呈現的修改。 beginContent() 和 endContent() 之外的範圍不建議加入 HTML,否則會在 main.php 內容的前面或後面(<html> 標籤之前或 </html> 標籤之後)。

在 controller 裡可以這樣使用:
public function actionMylayout() {
    $this->layout = 'mylayout';
    $this->render('//site/index');
}
表示以 mylayout.php 為佈局,views/site/index.php 為內容。





2013-09-08

利用 renderPartial() 重複使用 view

Yii 可以利用 renderPartial() 引用某個 view。
例如有個 view 的路行為 views/common/part1.php,內容為:
<table>
    <tr>
        <td>Name</td>
        <td>Phone</td>
    </tr>
    <tr>
        <td><?php echo !empty($name) ? $name : 'anonymous'; ?></td>
        <td><?php echo !empty($phone) ? $phone : ''; ?></td>
    </tr>
</table>

在另外的 view 可以使用 renderPartial() 引用:
<?php
$this->renderPartial('//common/part1', array(
    'name' => 'John',
    'phone'=> '123456',
));
?>
renderPartial() 是 controller 的方法,所以也可以在 controller 裡面使用。
第一個參數為 view 的路徑,路徑中的 // 指的是 views/ 的路徑。
第二個參數為關聯式陣列,包含欲傳入的變數。
第三個參數為「是否回傳」,預設值為 false,就是直接輸出,不回傳。若為 true,則是不輸出,只回傳字串。

2013-09-07

啟用 Yii::trace() 功能

啟用 Yii::trace() 功能有兩個步驟:
1. 在專案目錄的 index.php 中 設定 (預設情況) :
defined('YII_DEBUG') or define('YII_DEBUG',true);

2. 將 config/main.php 中,log component 設定中移除註解:
'log'=>array(
 'class'=>'CLogRouter',
 'routes'=>array(
  array(
   'class'=>'CFileLogRoute',
   'levels'=>'error, warning',
  ),
  // uncomment the following to show log messages on web pages
  /*
  array(
   'class'=>'CWebLogRoute',
  ),
  */
 ),
),

以上設定好之後,會顯示所有 level 為 trace 的訊息,若只要顯示我們 trace 的訊息,可以設定 categories 限定:
'log'=>array(
    'class'=>'CLogRouter',
    'routes'=>array(
        array(
            'class'=>'CFileLogRoute',
            'levels'=>'error, warning',
        ),
        array(
            'class'=>'CWebLogRoute',
            'categories'=>'application',
        ),
    ),
),

2013-09-05

$scope.$watch() 監視 model

$scope.$watch() 可以用來監視 model 值。
<html ng-app>
<meta charset="utf-8">
<body ng-controller='myController'>
    <input ng-model="my.input" placeholder="填入整數" />
    <p>填入值: {{my.input}}</p>
    <p ng-bind="my.dots"></p>

    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
    <script>
    function myController($scope) {
        $scope.my = {
            input: 0,
            dots: ''
        };
        $scope.$watch('my.input', function(newValue, oldValue, scope) {
            // console.log(':::', newValue, oldValue, scope);
            alert('new value:' + newValue);
            var dot = '◎';
            var i = parseInt($scope.my.input);
            $scope.my.dots = '';
            while (i-- > 0) {
                $scope.my.dots += dot;
            }
        });
    }
    </script>
</body>
</html>
範例 ng_scope_watch.htm

AngularJS 非全域 controller 設定方式

<html ng-app='myApp'><!-- 設定模組名稱為 myApp -->
<meta charset="utf-8">
<body ng-controller='myController'>
    <p>Hello {{txt}}</p>
    <p ng-bind=" 'Hi ' + txt"></p><!-- 未完成動作前無顯示內容 -->

    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
    <script>
    // 建立名稱為 myApp 的模組。第二個參數空陣列表示 "建立", 沒有給表示 "取得"
    var myAppModule = angular.module('myApp', []);
    
    // 設定 controller
    myAppModule.controller('myController',
        function($scope) {
            $scope.txt = "John";
        });
    </script>
</body>
</html>
AngularJS 非全域 controller 設定方式:

  • 以 ng-app 設定模組名稱。
  • angular.module() 建立模組。
  • 以模組的 controller() 設定控制器。


ng-bind 和 {{}} 都是設定 data-binding 的方式。ng-bind 的優點是 AngularJS 尚未處理完時,不會出現模版文字。

AngularJS 概念

AngularJS 是目前相當熱門的 JS framework, 好像不學一下就快跟不上技術了。

最近看到的資源:
範例: http://tutorialzine.com/2013/08/learn-angularjs-5-examples/
影片教學: http://egghead.io/lessons

AngularJS 主要概念(參考  Oreilly AngularJS):

  • Client-Side Templates
  • MVC
  • Data Binding
  • Dependency Injection
  • Directives

練習、修改了書中的 Shopping Cart 例子,ng_cart01.htm
個人修改時的要點:
  • ng-init 初始化。
  • ng-repeat="item in items" 裡 $index 是預設的索引變數。
  • ng-keyup 事件在 1.1.5 之後的版本才有效。

2013-09-04

取得某網頁上 Facebook 的 like 「讚」數量


http://graph.facebook.com/?ids=http://stackoverflow.com/,http://qops.blogspot.tw/

直接 copy 上列,貼到瀏覽器的網址列,就可以得到如下的結果:

{
    http://stackoverflow.com/: {
        id: "http://stackoverflow.com/",
        shares: 14867,
        comments: 9
    },
    http://qops.blogspot.tw/: {
        id: "http://qops.blogspot.tw/",
        shares: 13
    }
}

利用以下的 PHP 可以得到讚的數量:

<?php
$links = array(
 'http://stackoverflow.com/',
 'http://qops.blogspot.tw/',
);

$my_graph = 'http://graph.facebook.com/?ids=' . implode(',', $links);

$likes_info = json_decode( file_get_contents($my_graph), true );

foreach($links as $link) {
 printf("%s<br/>%s<br/>", $link, $likes_info[ $link ]['shares']);
}

2-2 資料型別

在 AS1,每個變數都一視同仁,沒有型別的區別。宣告變數時使用關鍵字 var,下式是宣告一個變數 b 同時設定其數值為 10。

var b = 10;

在 AS3 和 AS2 一樣,宣告變數時可以不宣告型別。不過在此建議應該指明變數的型別。指明變數型別的方式是在變數名稱之後加上冒號,再加上型別名稱,如下式:

var b:Number;

一個變數只能做一次宣告,重複宣告相同變數時,會發生錯誤。指明型別的變數,在編譯的過程中會檢查變數是否設定不同型別的值,若是則會發生錯誤,無法編譯成功。下面是個錯誤的例子。

// variable1.fla 影格 圖層1:1
var b:Number = 10;
b = true;
trace(b);

測試影片(按【Ctrl】+【Enter】)時,在輸出面板顯示錯誤訊息,如下圖。

型別(類型)不符的錯誤

宣告變數時指明型別,主要有兩個好處:

  • 編程時的code completion提示。
  • 避免設定不同型別的值,減少程式臭蟲。

如下圖所示,當某個變數在宣告時指明型別,則往後在變數右側輸入點(dot)之後,會有自動提示的浮動視窗出現。

程式碼提示

2-2-1  基本型別和參照型別

AS3 的基本型別(primitive types),包含5種型別:Boolean、int、uint、Number 和 String。int 和 uint 是新增的型別,int 和 uint 都是佔 32-bit 的整數型別,int 為有號整數值(可表示正、負數),uint 為無號整數(只可表示正數)。

何謂參照型別(reference types)?原則上只要不是上述的 5 種基本型別,就屬參照型別。兩者主要的差異在於設定時,一個以值設定,另一個以參照設定。Object 和 Array 是常用的參照型別。

無設定值的變數,若未宣告型別,或型別以 * 宣告,其預設值為 undefined。未設定值的參照型別變數,其預設值為 null。基本型別的預設值,如下表所示,其中比較特別的是,Number 型別的預設值為 NaN(Not a Number)。

基本資料型別
預設值
Boolean
false
int
0
uint
0
Number
Number.NaN
String
null
表: 基本型別的預設值

2-2-2  布林值

布林值就是所謂的真假值,只有兩個值 true 或者 false。布林值看起來很簡單,然而它跟邏輯有密不可分的關係,尤其在流程控制時更顯得格外重要。宣告布林變數使用 Boolean 型別,設定其值時只能使用 true、false 或者運算結果為 true、false 的運算式。

var b1:Boolean = true;
var b2:Boolean = 7>3;

上式的大於(>)符號是比較運算子之一,它在比較左右兩邊數值之後會傳回布林值。7 大於 3,所以「7>3」的計算結果為 true。

2-2-3  數值

數值在 AS3 中又可以分成 int(整數)、uint(無號整數)和 Number(可表示整數或浮點數)。使用 Number 型別時,不必為整數和浮點數之間的轉換煩心。若一開始 Number 型別變數的值就設定為整數,則以整數的型態存在,必要時整數會自動被轉換成浮點數。

若只使用到整數時,應考慮使用 int 或 uint。int 和 uint 使用 4-byte 來表現整數。Number 型別使用 8-byte 來表現數值,由於自動轉換和使用較大記憶體的關係,Number 型別的變數會比 int 或 uint 型別的變數在處理上要來得慢一點點。

數值也可以使用科學表示法,使用 e 或 E 接上10的次方數,例如:100可以寫成 1e2,0.001可以寫成 1e-3。

// number1.fla 影格 圖層 1:1
var n1:Number = 5;
var n2:Number = 5.000000000000000001;
var n3:Number = 0.123456789123456789;
var n4:Number = 1e2;
trace("n1=", n1);
trace("n1/2=", n1/2);
trace("n2=", n2);
trace("n3=", n3);
trace("n4=", n4);

  • n2 設定數值時,由於小數點後超出數值可以表現的準確度,故 n2 設定為 5。
  • n3 設定數值時同樣超出可表現的準確度,故以近似值表示。
  • 5/2 在計算過程自動轉換為浮點數,所以得到 2.5。

number1.fla 執行結果

整數除了以一般十進位表示之外,也可以使用十六進位表示。十六進位的數值以 0x 為開頭,使用的數字符號為 0~9 及 a~f(或 A~F)。以十六進位指定數值的變數和以十進位指定數值的變數是一樣的,在輸出時都會以十進位表示。int、uint 和 Number 都可以使用十六進位的表示法,如 number2.fla。

// number2.fla 影格 圖層 1:1
var i:int = 0x66;
var u:uint = 0x66;
var n:Number = 0x66;
trace("i=", i);
trace("u=", u);
trace("n=", n);

number2.fla 執行結果

數值型別的表現範圍並不是沒有限定的,由 number1.fla 就可以了解 Number 型別有準確度的問題。數值類別的 MAX_VALUE 和 MIN_VALUE 表示數值可以表現的最大值和最小值。Number 型別的變數,若大於 Number.MAX_VALUE,則以 Infinity 表示;若大於 0 而小於 Number.MIN_VALUE,則以 0 表示。number3.fla 是個數值型別顯示範圍值的例子。

// number3.fla 影格 圖層 1:1
trace("int.MAX_VALUE=", int.MAX_VALUE);
trace("int.MIN_VALUE=", int.MIN_VALUE);
var i:int = int.MAX_VALUE+1;
var j:* = int.MAX_VALUE+1;
trace("i=", i);
trace("j=", j);
trace("uint.MAX_VALUE=", uint.MAX_VALUE);
trace("uint.MIN_VALUE=", uint.MIN_VALUE);
trace("Number.MAX_VALUE=", Number.MAX_VALUE);
trace("Number.MIN_VALUE=", Number.MIN_VALUE);


  • int 型別的最大值再加 1,再設定給 int 型別變數,其值將會變成 int.MIN_VALUE。int 和 uint 一樣,在處理超出範圍的整數時,以循環的方式處理,也就是 int.MAX_VALUE+2 的值將變成 int.MIN_VALUE+1,依此類推。
  • 變數j宣告成萬用型別。由於運算的過程,數值會被轉換成 Number 型別,所以可以表現比 int.MAX_VALUE 還要大的值。
  • Number 型別表現整數時,可以使用53 bits(int為 32 bits),其最大值和最小值是針對浮點數而言。


number3.fla 執行結果

不同數值型別的變數值在相互設定時要注意,由於 int 和 uint 表現數值的範圍比 Number 小,Number 型別的變數不要任意轉換成 int 或 uint 型別,否則可能發生數值不如預期。

// number4.fla 影格 圖層 1:1
var m:Number = -2;
var n:Number = -1.23;
var i:int = m;
var j:int = n;
var u:uint = m;
var v:uint = n;
trace(i, u);
trace(j, v);

Number 型別轉 uint 型別時,可以想成先轉成 int,再依位元解釋數值。所以,-2147483648 ~ -1 將被轉換為 2147483648 ~ 4294967295。

number4.fla 執行結果

2-2-4  字串

ActionScript 沒有字元的型別,只有字串型別。字串常數是使用雙引號「"」或單引號「'」前後包起來。若以雙引號開頭,就必須以雙引號結尾;同樣地,若以單引號開頭,就必須以單引號結尾。你可以將雙引號放入字串內,只要使用單引號包起來就可以了,反之亦然。

// string1.fla 影格 圖層 1:1
var s1:String = "abc";
var s2:String = '您好啊';
var s3:String = "qop's blog";
var s4:String = '>"<';
trace("s1=", s1);
trace("s2=", s2);
trace("s3=", s3);
trace("s4=", s4);

string1.fla 執行結果

跳脫表示法

如果某個字串包含雙引號也包含單引號,那麼應該如何指定字串呢?這個時候就必須使用跳脫(Escape)表示法。所謂跳脫表示法,就是使用特定的符號表示某一個字元,該字元可能是沒有符號的(如跳格、換行)或有特別意義的。下表為跳脫表示法及說明。

跳脫表示法
說明
\”
雙引號
\’
單引號
\\
反斜線
\t
相當於按下「Tab」跳格
\n
相當於按下「Enter」換行
\r
\n 相同
\uXXXX
Unicode字元編碼表示一個字元,XXXX為四位的十六進位數值

跳脫表示法可以使用於 trace 輸出,也可以使用於 TextField 物件。我們以 string2.fla 為例子說明。如下圖,在場景上拉一個較大的 TextField,設定為「Dynamic Text」(動態文字),取名為 tf_txt,並設定為「Multiline」(多行)及顯示邊框。

設定名為tf_txt的TextField物件
影格內輸入如下的script。

// String2.fla 影格 圖層1:1
var s1:String = "單引號\' 和雙引號\"換行\n";
var s2:String = '反斜線\\跳格\t換行\r';
var s3:String = "\u798f氣";
trace(s1+s2+s3);
tf_txt.text = s1+s2+s3;

  • 加號在此的功能為字串串接,將三個字串連接後設定給 trace 輸出。
  • 將三個字串連接後設定為 tf_txt 的字串內容。執行結果如下圖。跳格會因字型而影響位置,並不常用。

string2.fla 執行結果

字串的方法

字串的唯一屬性為 length,可以求得字串所包含的字元數目(或稱字元長度)。字串常用的方法列於下表。

String的方法
說明
charAt(index)
回傳字串中索引值為index的字元。
charCodeAt(index)
回傳字串中索引值為index的字元字碼。
concat(s)
字串本身連接字串s。和執行「+=s」運算相同。
fromCharCode(c)
String的靜態方法,將c字碼轉換成字串。
indexOf(s, start)
從索引值為start處開始尋找子字串s。若start省略則從頭開始找。找到子字串回傳子字串索引,若否則回傳 -1
lastIndexOf(s)
尋找子字串最後的索引。
slice(start, end)
擷取索引indexend的字串。若end省略則擷取至最後一個字元。
search(pattern)
使用正規表示法(Regular Expression)尋找子字串。回傳子字串索引,若找不到則回傳 -1
split(s)
將字串依特定字串s分割成元素,回傳字串陣列。
substr(index, length)
從索引為index處擷取長度為length的字串。
substring(start, end)
擷取索引indexend的字串。若end省略則擷取至最後一個字元。
toLowerCase()
轉換為小寫字母。
toUpperCase()
轉換為大寫字母。

string3.fla是使用一些字串方法的例子。

// string3.fla 影格 圖層 1:1
var s1:String = '感覺\'Happy\'就是\"幸福\"';
trace("s1的字元數為: "+s1.length);
trace(s1.charAt(0)+": "+s1.charCodeAt(0));
trace('\\u611f : '+ '\u611f');
trace( String.fromCharCode( s1.charCodeAt(0) ) );
trace(s1.slice(2, 9));
trace(s1.substring(11));
trace(s1.toUpperCase());
trace(s1.toLowerCase());
var s2:String = "12-34-567";
trace(s2.split("-"));


  • 第1行,s1 字串中包含了單引號和雙引號。
  • 第3行,字串中字元的索引值從 0 開始,故第一個字元的索引為 0。輸出的字元碼是 Unicode 編碼。
  • 第4行,輸出 '\u611f',其實就是「感」,可以計算一下 0x611f 是否為 24863。
  • 第5行,以 String 的靜態方法 fromCharCode() 將字碼轉換為字元。
  • 第6行,擷取索引 2~8 的字元(不包含索引為 9 的字元)。
  • 第7行,擷取索引 11 至最後一個字元。
  • 第8行,將字串轉換成全大寫輸出。
  • 第9行,將字串轉換成全小寫輸出。
  • 第11行,以「-」為分割字串,將s2轉換為陣列。

string3.fla 執行結果


目錄

2-1 變數

在 ActionScript,數值符號(literal)由0~9、小數點(.)和正負號(+、-)組成。一個數值符號表示一個數值常數,下列是數值常數的一些例子:

13
6.5
-123
0.9999

相對於常數,變數是用來存放數值的一個小區塊記憶體。我們可以要求取得一個記憶體區塊,並給予一個名稱,接著再將數值設定給該記憶體區塊。下式為設定的方式:

a = 16;

上式的意思是「把數值 16 存放到稱為 a 的某個小區塊記憶體內」。a 位於記憶體中的哪裡,對我們來說並不重要,我們只要認得 a 就可以了。a 的內容是可以變動的,例如,下式把 a 的內容設定成 7,此時 a 的內容就不是 16,而是 7。

a = 7;

記憶體可以存放的資料不僅僅只有數值,同樣的,變數也不只可以存放數值,還可以存放布林值、字串和參照(Reference)。參照變數可以看成是代表物件的變數,其內容為參照(參考到物件實體的相對位址)。

上述的例子,若 a 一開始沒有宣告,在預設的 Strict Mode 下,編譯的過程將產生錯誤「1120: Access of undefined property a」。建議在使用變數前,先宣告(變數宣告請看下一節)。或者,取消使用 Strict Mode,方式是先點選命令列「File」→「Publish Settings」,開啟 Publish Settings 面板,點選「Settings」按鈕,如下圖所示。

在 Publish Settings 面板,點選「Settings」按鈕

接著在「ActionScript 3.0 Settings」面板的 Errors 項,取消勾選「Strict Mode」,即可不宣告而使用變數。不過,在此筆者建議使用 Strict Mode,越嚴謹越不容易出錯。

取消勾選「Strict Mode」


目錄

以 Facebook 登入網站

許久沒有做 Facebook 相關的功能了, 記錄一下。

window.fbAsyncInit 是 Facebook JS SDK 載入後執行。
FB.getLoginStatus 判斷用戶目前對 App 的狀況。
FB.login 做授權登入。

JS SDK 和 PHP SDK 一起用時, 記得要將 FB.init 的 status cookie 設定為 true。

2013-09-01

1-8 程式除錯

ActionScript 的程式主要有兩種方式,一種是設定中斷點並使用 Flash 內的影片除錯模式,另外一種是使用 trace 函式。

1-8-1  使用中斷點及除錯模式

請開啟「debug.fla」。設定程式中斷點有兩種方式:第一種如下圖,點選「Debug options」→「Toggle Breakpoint」,在游標所在的程式行上設中斷點;第二種如下下圖,直接在該行前的設定區擊點即可設定。完成中斷點設定者該行會標上紅色的圓點。

使用「Debug options」→「Toggle Breakpoint」,設定或移除中斷點

直接點選該行前的設定區,設定中斷點

設定中斷點之後,點選命令列的「Debug」→「Debug Movie」,或按【Ctrl】+【Shift】+【Enter】以除錯模式測試影片。

點選命令列「Debug」→「Debug Movie」

啟動除錯模式測試影片時,會出現如下圖的除錯模式。在「Variables」面板下,點選物件名稱this,即可展開並查看各變數及子物件的狀況。

除錯模式

下圖為 Debug Console 的功能圖示。綠色三角形為「繼續」圖示,按下後 AS 會開始執行,遇到中斷點後暫停。紅色叉叉為「離開除錯模式」圖示,按下後回到原來的編輯模式。另外三個圖示依序為「下一行」(Step Over)、「下一行進入函式」(Step In)和「下一行離開函式」(Step Out)。通常會使用「下一行」慢慢除錯。

Debug Console的功能圖示

1-8-2  trace

在某些時候中斷點不見得好用,此時可以使用 trace 輸出你想看的變數。trace 是一個函式,使用的方式很簡單只要將變數名傳給它即可。例如,我們開啟 debugTrace1.fla,在其 AS 中加入第18行(下圖),測試影片時,會顯現「Output」視窗,並將輸出的結果顯示出來(下下圖)。

加入「trace(tx, ty)」,多個變數用逗號隔開

Debug_trace1 執行時的輸出視窗

在上圖中,你可以看到一串數值,但是無法得知迴圈的控制變數和顯示數值之間的關係。此時為了標示數值的順序,可以將迴圈控制變數i加入輸出(於 debugTrace2.fla),如下式:

trace(i + ": " + tx + ", " + ty);

上式取代原來的第18行(下圖),能在輸出時標示迴圈控制變數i的值(下下圖)。


取代為「trace(i + ": " + tx + ", " + ty)」

debugTrace2 執行時的輸出視窗
trace 的變化很多,你可以使用如下的式子監看多個變數:

trace("a:"+a, "b:"+b, "obj.c:"+obj.c);

使用中斷點除錯是很好的選擇,然而有些疑難的Bugs,必須使用trace才能有效率地除錯,因此trace的使用必須多加練習。

1-8-3  使用自製的工具

以 trace 查看較複雜的資料物件時,無法直接顯示其資料內容。例如,用 trace 直接輸出 Object 型別的物件,只會看到 [object Object]。為了更方便針對這類的物件除錯,筆者自製了QopDump 類別,只要將光碟中的 QopDump.as 和 FLA 檔放在一起即可使用。

或者使用更理想的做法,將 QopDump.as 放在設定的類別路徑上。點選「Edit」→「Preferences」開啟面板,在面板左側選擇「ActionScript」分類,然後點選「ActionScript 3.0 Settings」,如下圖所示。

點選「ActionScript 3.0 Settings」

在「ActionScript 3.0 Settings」面板內,新增類別路徑「C:\AS_classes」(路徑目錄可以自行決定),如下圖所示。路徑設定好後,將 QopDump.as 複製到「C:\AS_classes\」目錄下,即可使用。

新增類別路徑「C:\AS_classes」

QopDump 是個類別,提供兩個靜態方法,echo 和 go。go 方法是將 Object 屬性以換行和縮排的方式一一列出成有層次的字串,echo 則是將這些文字資料輸出到 Output 面板。debugQopDump.fla 為測試檔,其 Frame Actions 如下圖所示,執行結果如下下圖。

debugQopDump.fla 的 Frame Actions

debugQopDump.fla的執行結果

QopDump.as 本身為一個類別檔,若有興趣其運作方式,請在看完物件導向的內容後,再查看原始碼。


目錄

1-7 使用「動作」面板

動作面板(Actions Panel)是撰寫 Frame Actions 的工作區,撰寫 AS 類別檔的工作環境和動作面板差不多,就不多作介紹,我們將以動作面板為主要說明對像。

開啟 ActionsPanel.fla 後,點選第一影格,並開啟動作面板(按【F9】)。動作面板開啟後(如下圖),可以看到三個區域。左上方為參考區;左下方為快速選取區;右方為 AS 編輯區。快速選取區中,目前選取範圍為「Layer 1:1」,表示選取的是圖層名稱為「Layer 1」的第 1 影格。面板的左上角標題列顯示「Actions - Frame」,表示目前編輯 Frame Actions。

動作面板-選取圖層「Layer 1」的第1影格

在 Flash 影片編輯區,點選橢圓形的影片片段物件,AS 編輯區會顯示「Current selection cannot have actions applied to it.」,表示不能使用Object Actions(如下圖)。

不能使用 Object Actions

動作面板的AS編輯區有一列功能圖示,每個圖示的意思如下圖所示。

AS 編輯區上方的功能圖示列

點選「新增動作指令」時,會出現多層次的選單,讓你方便加入項目,如下圖所示。

增加新的動作指令到 AS 編輯區

「尋找」可用來尋找程式碼中字串的位置及取代字串。按下「插入物件路徑」後,將蹦出插入目標路徑視窗(如圖1-11),點選其中的物件即可插入該物件的路徑。

插入目標路徑視窗

寫完一段程式後,可以按「語法檢查」,檢查程式的語法是否有錯誤。若有錯誤的語法,則錯誤的訊息將輸出至輸出面板(Output Panel);若沒有錯誤,會顯現如下圖的視窗,提示你語法沒有錯誤。

語法無誤

當觀看別人或自己的程式碼時,若程式沒有排得很好,將不易閱讀及了解,此時可以按下「自動格式化」依設定將程式碼排列整齊。編寫程式的過程中,也可以按下「顯示語法提示」,讓它幫你完成部份的程式敘述或物件路徑。「除錯選項」中有除錯相關的功能,我們將在下一節討論。

顯示語法提示

「收摺程式區塊」可以將某個程式區塊收摺起來,如下圖。

收摺程式區塊

「收摺選擇區域」可以將某個選取區域收摺起來。「全部展開」能將所有收摺起來的程式碼展開。

收摺選擇區域

「換成多行註解」可以將選取的區域,以多行註解標註。

以多行註解標註

「換成單行註解」能將選取的區域,以單行註解標註。

以單行註解標註

「移除註解」可以移除選取區域裡所有的註解標示符號。

移除註解標示

「打開或收起工具區」能將工具區打開或關閉。

打開或收起工具區

動作面板的右上方還有兩個功能圖示,如下圖所示。按下「Help」,可以顯現「說明」視窗。「Script Assist」則是幫助 Script 生手方便設定,在此不建議使用。

動作面板右上方的功能圖示

動作面板的右上角有個下拉圖示,按下後以文字選項顯示各功能圖示的功能。其中「Auto Format」可以設定自己偏好的程式編排格式;「Preferences」可以設定編碼、AS編輯區的文字大小及顏色等相關設定。

文字選項顯示各功能圖示的功能

偏好設定


目錄

1-6 麵條與肉醬

在 Flash 5 時期,我們可以看到 Actions 一小段一小段零星散佈在影格上、物件上,有時要找某個功能的 Actions,要找上老半天。有人把這種情形稱為「意大利麵」,肉醬(Actions)和麵條(MovieClip 或 Button)整個和在一起,在管理上非常不方便。例如,要重複使用某段 Actions 時,就是把它找出來,然後以複製的方式 copy 到另一段影片裡,有時找 Actions 就要花費不少時間。

在 Flash MX 時期,有了 #include 指令。通常將常用的函式放在一個 AS 檔裡,要用的時候再以 #include 一股惱兒全部匯入。這種方式雖然可以改善一點 ActionScript 的管理情況,將大部份的 AS 集中,但依然不理想,而且一定要以 Frame Actions 去 include 一個AS檔。

到 Flash MX 2004 之後,更向物件導向靠攏,可以開發 AS 類別檔。AS 類別檔的重複使用性相當高,相關功能的類別檔放在某個套件內,要套在 MovieClip 上時,不必寫 Frame Actions,以連結的方式就可套用。欲在另一個類別檔使用時,也可以 import 引入。方便性自然不在話下,也可以避免意大利麵的問題。

然而,由於版本的向下相容,你還是可以在 Flash MX 2004 版和 Flash 8 使用 AS1,不過還是應該儘量使用 AS2。遵守以下的規則,可以讓你的AS更容易管理:「可以用類別檔和 MovieClip 連結時,就以連結的方式。不然就使用 Frame Actions,少用 Object Actions。」

到了 Flash CS3,若選用 AS3,以往編寫的 AS2 檔案就不能用了,而且應儘量以物件導向的方式編寫 ActionScript。當類別檔越來越多時,專案的開發速度應該會越來越快。如果因為專案時程問題,而無法遵守以上的規則,則以快速為優先。


目錄

1-5 SWF

Shockwave 本來是 Macromedia 使用在 Director 上的一種多媒體技術,可以將聲音、動畫、圖像、Script(Lingo)放在一個壓縮過的檔案裡。Director 格式的 Shockwave 在網路環境並沒有很成功,主要原因包括 Director 使用的是點陣圖(目前 Director 也可以和 Flash 結合),製作出來的檔案體積無法壓到很小,而且其播放器的體積對當時而言算蠻大的。

但是,Macromedia 利用 Shockwave 的經驗推出 Flash(Shockwave Flash),由於簡單向量圖所佔的體積很小,而且 Flash Player 也很小。很快地,體積小、有趣的 Flash 動畫如野火般遍佈 WWW 的世界。

Macromedia 後來公佈了 SWF 檔案的格式,以利其它協力公司開發相關的軟體,你可以在「http://www.adobe.com/licensing/developer/」下載 SWF 檔案格式的規格書。基本上,SWF 檔案的格式和開發 Flash ActionScript 應用程式是不同層面的問題,你可以完全不了解 SWF 的格式,也可以開發出頂級的 Flash 應用程式。在此我們來了解一下 FLA 檔編譯成 SWF 檔的一些觀念。

不論是以 include 匯入某個 AS 檔或是以 import 引入一個 AS 類別檔,在發佈成 SWF 檔之後,AS 檔和 FLA 檔的資訊都會被放到 SWF 檔裡面。只要有 SWF 就可以播放整個影片,而不需要 AS 檔。

編譯成 SWF 檔

將 FLA 編譯成 SWF 後,ActionScript 會被編譯成 Bytecode(位元組碼)。Bytecode是一種可以讓 Flash Player 快速解譯成機器碼的格式,因此 Bytecode 比 Text 要來得好。由於 Bytecode 不是機器碼,所以也很容易被反組譯成 Text(ActionScript程式碼)。

目前還未有 AS3 的反組譯軟體出現(目前已經有了哦),不過相信不久的將來會有公司推出。AS2  的反組譯較為著名的有 Buraks.com(http://www.buraks.com/asv/)的 ActionScript Viewer 和 SourceTec Software(http://www.sothink.com/product/flashdecompiler/)的 Sothink SWF Decompiler,這些軟體並非免費軟體。在此筆者並不鼓勵使用 ActionScript 反組譯器,但是一定要知道有這類的東西存在。

相對於反組譯軟體,站在保護源碼的角度,我們可以使用擾亂器(obfuscator)。擾亂器主要是針對有意義的變數名或識別字,利用隨機字串替代,如此即使AS被反組譯了,也不容易被看懂。你可以在 Genable.com(http://www.genable.com/aso/)找到一個免費的 AS2 擾亂器。

另外,SWC 檔是包含 SWF 的 ZIP 壓縮檔,可以方便組件的散佈,同時保有不公開源碼的功能。

目錄

1-4 Frame Actions所在位置與執行順序

按鈕元件裡的影格不能放 Frame Actions,影片片段的影格裡才能使用 Frame Actions。

一般程式語言可以利用編譯器將程式轉換成可執行的機器碼,或者以解譯器執行。Scripts 和一般的程式語言不同的地方,在於 Scripts 通常有個 Host(寄主,執行系統),而且可以控制 Host 中的預設物件。例如,JavaScript 的 Host 是瀏覽器,藉由瀏覽器中的 JavaScript 解譯引擎執行,利用 JavaScript 可以控制 Document Objects,建立動態網頁。

ActionScript 的 Host 可不是 Flash 編輯軟體,而是 Flash Player。Flash 編輯軟體是開發 Flash 動畫、應用軟體的整合開發環境。開發編譯完成的 swf 檔,才能在 Flash Player 環境中解譯執行。

ActionScript 通常是位於前面影格的 Actions 先執行。例如,runSequence1.fla 中有 2 個影格,其中分別有下面 2 段 Frame Actions:

trace("第一格動作");

trace("第二格動作");
stop();

測試影片(按「Ctrl」+「Enter」)的結果會在輸出面板(Output panel)得到:

第一格動作
第二格動作

變數有宣告才能使用,宣告的位置不一定要在最前面;但是未宣告的變數,不能使用。例如,runSequence2.fla 中有 2 個影格,其中分別有下面 2 段Frame Actions:

var a:int = 10;
trace(a);
trace(b);
trace(c);

var b:int = 20;
stop();

執行的結果會在輸出面板得到:

10
0
ReferenceError: Error #1065: 變數 c 未定義。 at runSequence2_fla::MainTimeline/runSequence2_fla::frame1()

b 有在第 2 格宣告,所以可以使用,預設值為 0。c 則未宣告,故在測試影片時發生錯誤。

如果是函式定義,不論定義在哪個影格皆可使用,和影格的順序沒有關係。例如,runSequence3.fla 中有 2 個影格,其中分別有下面 2 段 Frame Actions:

f2();
f1();
function f1(){
  trace("呼叫 f1 函式");
}

function f2(){
  trace("呼叫 f2 函式");
}
stop();

執行的結果會在輸出面板得到:

呼叫 f2 函式
呼叫 f1 函式

另外,父影片物件的 Frame Actions 會比子影片物件的 Frame Actions 先執行。這一點也要小心留意,以避發生程式 Bugs。若兩物件位處相同的物件內,z-index 較小的,其 Frame Actions 先執行。

例如,runSequence4.fla 中有 3 個影片片段元件:mcA、mcB 和 mcC。其中 mcA 元件包含一個 mcB 實體和一個 mcC 實體,mcC 實體的 z-index 比 mcB 實體的要來得小。場景包含一個 mcA 實體(物件架構類似 1-3 的圖)。場景和每個元件的第一個影格都有一行敘述,用以輸出訊息,測試結果如下圖。

父影片物件的 Actions 會比子影片物件的 Actions 先執行

目錄

1-3 物件路徑

在使用 AS 控制影片片段時,一個影片片段視為一個物件,影片片段中的子影片片段視為該物件的子物件。取用某物件的子物件時,使用點(dot)表示法。例如,在場景(root)中有個 a_mc 的影片片段,a_mc 之中又包含了 b_mc 的影片片段,若要在 root 的影格中設定 b_mc 為隱藏可以使用下式:

a_mc.b_mc.visible = false;

在 root 中只能先看到 a_mc,不能直接看到 b_mc,所以必須先以「a_mc.」指出 b_mc 的位置,這就是所謂「物件路徑」。

如果上述的 a_mc 中還包含另一個影片片段 c_mc。在 a_mc 所屬的時間軸影格中,可以使用下式將 c_mc 設定成隱藏:

c_mc.visible = false;

若我們希望在 b_mc 的影格中控制 c_mc 的顯現或隱藏,應該怎麼做呢 ?如下圖所示,在 b_mc 中看不到 c_mc,所以必須將觀察點移至 a_mc,才能看到 c_mc。

在 b_mc 中必須先將觀察點移至 a_mc,才能看見 c_mc

所以可以使用下兩式中的任何一式,於 b_mc 的影格中設定 c_mc 為隱藏:

parent.c_mc.visible = false;

this.parent.c_mc.visible = false;

在 b_mc 的影格中,this 表示目前物件,parent 表示父物件也就是 a_mc,在 a_mc 中才能看到 c_mc。在此 this 可以省略,所以上兩式是相同的意思。以目前的位置為參考點,進而取用其它物件,稱為「相對路徑」。上兩式就是使用相對路徑。

把觀察點拉到舞台上,先看到的會是 root(如下圖),這種以 root 為開頭的路徑表示法稱為「絕對路徑」。

將觀察點拉到舞台上

下式可以設定 c_mc 為隱藏:

root['a_mc'].c_mc.visible = false ;

上式中,root 為絕對路徑的判別字,不能省略。使用絕對路徑時,可以不用考慮目前 Frame Actions 所在的位置。如果使用相對路徑,務必注意「Actions 位於何處」(觀察點的位置)。

什麼時候使用「相對路徑」?什麼時候使用「絕對路徑」?通常以 Actions 敘述的長短而定。以上面的例子來說,若在 a_mc 中設定 c_mc 的屬性可以直接使用下式:

c_mc.屬性 = 設定值;

而不會使用下式:

root['a_mc'].c_mc.屬性 = 設定值;

有時為了避免混淆,可以使用絕對路徑。若要讓 MovieClip 方便重複使用,應該使用相對路徑。

目錄

1-2 影片物件的巢狀結構

本書的主題是 Flash CS3 的 ActionScript 3.0,若無特別強調,所有的環境都是在 Flash CS3(ActionScript 3.0)下運作。

開啟新檔案時,選用 Flash File(ActionScript 3.0)

Flash 中有三種元件(Symbol):影片片段(MovieClip)、按鈕(Button)和圖像(Graphic)。其中,MovieClip 的功能最多;Button 可以增加互動性;Graphic 則局限於動畫表現。在 Flash 應用程式中,影片片段是最常被使用的元件,因此我們會將焦點放在影片片段上。

Flash 的頂層物件是舞台(stage),stage本身是個視覺物件(DisplayObject),它可以容納(包含)其它的視覺物件。通常在 stage 裡是主場景(root), root 本身就是個 MovieClip,它可以容納(包含)其它的影片片段、按鈕或圖像。所有的影片片段都有相同的性質,可以包含其它影片片段、按鈕或圖像。影片片段可以由多個圖層組成,每個圖層又可以由一連串的影格(frames)組成,每個 frame 又可以容納其它的影片片段,因此能形成千變萬化的巢狀結構。

影片片段的結構

上圖為 cursorTest.fla 裡 Cursor3 元件的時間軸。由時間軸可以看出該影片片段有 2 個圖層,每個圖層有 3 個影格。圖層 1 中的每個影格分別包含了不同元件的實體。

目錄

1-1 ActionScript 3.0 來襲

ActionScript 3.0(AS3)的時代已經來臨,Flex 2和Flash CS3都支援AS3。然而Flex 2已經不支援ActionScript 2(AS2),Flash CS3則是開發者自由選擇使用ActionScript的版本。

 在Flash CS3,你可以選擇使用舊的AS2或者使用新的AS3,差別有多大呢?最重要的差別是物件導向語法的不同。而且,AS3已經不支援物件上的動作了(Object Actions),Actions只能寫在影格上或者AS檔裡。可想而知,將來Flash的新版本和新功能都一定是以AS3為主要的支援對向,AS2就不敢保證了。學習AS3是目前所有閃客(Flashers)的當務之急。

好消息是Flash CS3的影格和影片物件的架構並沒有改變,而且AS3和AS2也有很高的相似度,在寫影格動作(Frame Actions)方面並不會有太大的差異。如果你已熟悉AS2,那麼別擔心,跟著本書的學習順序,AS3也是手到擒來的。


目錄

FB 留言