2013-12-27

Snap.svg 載入 svg 檔時的兩三事

使用 Snap.load() 時, 載入的檔案內容會變成 Fragment 物件。而 Fragment 物件只有兩個方法: select() 和 selectAll()。

在載入之後, 即刻使用 select() 可以取得一個 Element 物件; 而使用 selectAll() 是將樹狀結構攤平, 取得符合條件的 Elements, 結果是 type 為 set 的物件 (也可以視為 Array 操作)。

當 Fragment 物件被加到 (append) DOM 裡面時, select() 和 selectAll() 就會失效。文件上敘述的很少, 只寫到 Fragment.select 同 Element.select, Fragment.selectAll 同 Element.selectAll。一開始使用應該很容易踩到這個雷吧。

--- ---

Snap.select() 和 Snap.selectAll() 從整個 Paper 物件去取得 Element(s)。

--- ---

另外, 載入的 svg 檔通常最外層就是一個 <svg> 標籤, 我們可以將這個 Fragment 物件直接放到一個 g element 裡, 操作 g element 就可以改變整個載入的圖形。svg 標籤可以是多層的結構。
Snap.load("some.svg", function(fragment) {
    var wrapper = paper.g();
    wrapper.append(fragment).drag().transform('t200,100s1.2');
});

--- ---

最外層的 <svg> 標籤稱為 Paper 物件。Paper 物件的行為和 Element 類似, 但目前建立 Element 物件只能使用 Paper 物件 (例如: Paper.g(), Paper.rect() 等)。

--- ---

Element 物件的屬性:
    node 指向 DOM element object (用  setAttribute() 可以設定 id 屬性)
    paper 指向 Paper 物件
    type 為標籤名稱 (字串)
    id

--- ---

有時搭配 jQuery 使用很方便。


2013-12-26

字型轉換為 SVG

想在網頁上放幾個中文字, 但並非固定的字, 就找找看有沒有字型轉換為 SVG 格式的工具。結果找到 Apache Batik SVG Toolkit, Java 寫的工具包, 這工具包大概有五、六年沒更新了, 試用了一下, 用 command line:

java -jar batik-ttf2svg.jar ./BHei01e.ttf -l 24503 -h 24503 -id mysvg -o mysvg.svg

再用 Inkscape 打開 svg 檔, 並沒有看到我要的結果; 接著用 sublime 查看, 原來是放在 defs 標籤裡。格式長這樣子:

<glyph unicode="!" glyph-name="null" d="M207 805L214 229H298L312 805H207ZM200 116V-7H323V116H200Z" />

於是異想天開地想用 PHP 的 shell_exec() 呼叫 Java 程式拿到某幾個字元的 SVG 格式。事與願違, 要 3 個字的資料 PHP 跑了 1 秒多, 要 6 個字的資料跑了近 3 秒, 這樣看起來是行不通的。原因應該是, 取得一個字的資料 Java 就開檔、關檔一次, 耗時間是難免的。

2013-12-23

Snap.svg Objects rotating animation problems

Snap.svg 旋轉動畫的問題

用 Snap.svg 做 element.animate() 旋轉動畫時, 若圖案的中心對準原點 (如 上篇), 則以中心點當旋轉中心, 動畫會是正常的。但若偏移中心點做旋轉, 會伴隨縮放的發生, 明明就沒有要做縮放啊 ? 問題應該是 animate() 用 Matrix 的 a, b, c, d, e, f 去做值的改變, 而造成的, 跑出來的動畫就是很白痴...

2013-12-20

Snap.svg 測試感想

看到 Snap.svg 官網的範例, 感覺可以做很多東西, 於是動手用 Snap 做了 Merry Xmas 測試網頁。完成這個小例子之後, 有以下幾點感想:
  1. Snap.svg 目前是 0.4.2 版, 版號雖然看起來不大, 但由於 Snap 作者之前 Raphael 專案累積的經驗, Snap 的功能其實已算完備。但在文件上還有許多改善空間。Snap 和 Raphael 的一些 functions 設計的方式雷同, 所以有時我是看 Raphael 的文件, 才知道 Snap 某個 function 的用法。

2013-12-18

最近遇到 Silex 之 Built-in Service Providers 的問題

Silex 是 PHP 的一種微框架。使用 Silex 而沒有選用 Slim 的原因是 Silex 的肥版內置了常用的功能, 而且 Silex 是 Symfony2 相關的專案。

目前裡面的 Twig 和 Doctrine DBAL 是用得還滿開心的, 但 Session 和 Swiftmailer 就用不太習慣, 或遇到狀況。

寄 mail 的功能, 個人長時間習慣使用 PHPMailer。Swiftmailer 寄未認證信時, 常收不到; PHPMailer 至少會在垃圾郵件中找到。

Session 的問題是 Silex 使用 SessionServiceProvider, 並非 PHP 原先內建的 $_SESSION功能。在混用 Securimage 做 captcha 功能時, 由於 Securimage 使用的是內建的 $_SESSION, 而造成 SessionServiceProvider 無法啟用。
RuntimeException: Failed to start the session: already started by PHP ($_SESSION is set).
後來的解決方式是乾脆 把 SessionServiceProvider 給關了, 直接使用 $_SESSION。



2013-12-14

使用 Inkscape 做 SVG 檔案的最佳化 (最小化)

參考這篇 Optimizing Inkscape SVG size for the Web

「檔案」 > 「另存新檔」 > 「存檔類型」選「最佳化的 SVG」 (倒數幾個選項)」 > 按「儲存」, 再依據需求於面板上勾選去除或包含的項目, 按「確定」後完成。

在參考的 blog 裡發現了一個會動的 SVG clock2, 感到相當驚奇, 偷看一下原始碼, 原來是放了 <script> 標籤 XD。



2013-12-13

用 KineticJS 改寫 Shadow Maze 2D

Shadow Maze 2D 是 AS3/starling 寫的 app, 試著用 KineticJS 改寫, 感覺上跟 starling 作法差不多。由於是 web app, 所以把儲存和記錄的功能拿掉了。圖片素材都一樣, 改寫起來還算快。

shadow_maze 是完成的結果, 在桌機上用鍵盤的方向鍵操作, 在手機上用 device orientation 功能操作。

測試過 Chrome、IE 11、Safari 和 iOS 7 Safari 是可以正常執行, 但 Firefox 25/26 會當掉, 關掉大部份的 Firefox plug-in 之後, 執行 20秒左右也當了, 殘念。Firefox 執行 KineticJS 做的 app 似乎有不少人遇到麻煩, 不知道是 Firefox 的問題還是 KineticJS 的問題 ... 我懷疑前者的支援度不佳 ...

條列筆記:

  • Sprite 圖形是之前用 Flash CS6 功能輸出的。
  • 類別使用 createNew 的方式實作。
  • Kinetic.Layer 在 DOM 裡是 <canvas> 元素。
  • toImage() 類似 AS3 的 cacheAsBitmap。
  • 將 Kinetic.Node 做 toImage() 時, 該物件必須已經放在 Layer 上面。
  • 做 toImage() 時, protocol 需是 http 不能是 file。
  • toImage() 得到的是 JS Image 物件, 不是 Kinetic.Image 物件。
  • 裝置方向參考 Using Device Orientation
  • 裝置方向事件處理, 若先 remove 再 add, 可能會拿到先前的舊值, 造成 bug。
  • 上述動畫進行中, 可用一變數去忽視裝置方向事件。
  • 善用 Group。
  • 按鈕可以寫成 Component。
  • JS 合併縮小用 UglifyJS



2013-12-11

HTML5 的 SVG 和 Canvas

SVG (Scalable Vector Graphics) 和 Canvas, 同樣是 HTML5 的標準內容, 但兩者似乎有相互競爭的意味。主要的差異在於, SVG 是以 tag 的方式存在 (DOM 的一部份), 而 Canvas 純粹是用 JavaScript 來建立。

粗略來說, 當圖案越複雜時, SVG 會越龐大, render 的速度會越慢; Canvas 則是看變動區域的大小和複雜程度。

2012 年中, 就有針對 SVG 和 Canvas 效能問題做測試和討論 The Road to HTML5: SVG, Canvas, and faster performance。結論是 Canvas 效能比 SVG 要來得好, 但比較不好寫 (應該說 JS 要寫較多的行數)。

也有一派認為 SVG 的優點比較多, 他們偏好使用 SVG, 7 Reasons to Consider SVGs Instead of Canvas 。簡述一下文中條列的 SVG 優點:
  • SVG 是可縮放的
  • 有現成的編輯工具: 如免費的 Inkscape , 椅拉也有支援
  • 程式語言/框架的支援: 文中其實只提 Simple XML, 意義是後端可以做些處理
  • 大部份的瀏覽器都有支援: 以 Raphaël 為例
  • 可得性與 SEO 佳
  • DOM 操作
  • 有 CSS, webfont, JS 支援

上列的林林總總, 好像 SVG 真的比 Canvas 好。其實也是得看用途, 在 2D 網站最佳化的過程, 會因種種特性, 兩者選其一, 亦或兩者都用。

另外, 如何開始, 啃官方文件一定不會是您想要的。

SVG 有老牌的 Raphaël, 也有同一個作者開發的 Snap.svg (感覺是 adobe 支持的專案), Snap 的 Getting started 是不錯的開始。

Canvas 的話, KineticJS 是頗為熱門的 framework。

以上。

阿豆皮 ! 我要 Flash/AS3 直接轉 Canvas 的功能 ! (等到鬍渣滿面...)

2013-12-03

JavaScript UI: Gumby Framework

Gumby Framework 整個架構和 Twitter Bootstrap 其實差不多, 算是 Twitter Bootstrap 的另一種選擇。Gumby 的 CSS preprocessor 是使用 SASS。

2013-11-21

給學員做專題時的建議

程式除錯就跟遊戲裡打怪一樣, 怪打得越多, 功力會越強。 請先自己打怪, 打不過再找幫手。
 
 
除蟲守則:

第零條
 不要立刻舉手發問, 先依後續守則測試, 不行再發問。

第一條
 測試時一律使用 Chrome 並開啟「開發人員工具」。

第二條 ( JavaScript )
 看「開發人員工具」右下方有沒有紅色叉叉, 有的話找到出問題的位置並試著自己解決。

第三條 ( PHP )
 出現 PHP 錯誤訊息, 請找出錯誤的行數並試著自己解決。

第四條 ( SQL )
 出現 SQL 錯誤訊息:
 在程式中執行 SQL 的前一行, 用 echo 顯示 SQL 語法, 並以 exit() 結束程式執行。
 將頁面顯示的 SQL 則到 phpMyAdmin 裡執行看看 SQL 有沒有錯誤。

2013-11-12

psr-0 是什麼意思呢?

使用 Composer 時, 在設定檔的 json 常看到 autoload 設定 psr-0。
psr-0 網路上已經有人寫中文說明囉

2013-11-02

網頁分享到 FB 的連結

網頁分享到 FB 的連結, 連到
http://www.facebook.com/sharer/sharer.php?u=網址

例如:
http://www.facebook.com/sharer/sharer.php?u=http://qops.blogspot.tw/

網頁內設定 meta 讓 FB 抓取顯示的資料可以參考:
Optimizing Metadata On Self-Hosted Objects Using Pointers

通常使用下列六個:
    <meta property="fb:app_id" content="{app_id}" />
    <meta property="og:title" content="標題" />
    <meta property="og:type" content="article" />
    <meta property="og:image" content="縮圖的原圖 URL" />
    <meta property="og:url" content="http://qops.blogspot.tw/" />
    <meta property="og:description" content="網頁簡短說明" />

除錯工具:
https://developers.facebook.com/tools/debug


2013-10-08

CSS: pointer-events

在 Flash/AS3 利用下式就可以關閉某個 MovieClip 對滑鼠事件的反應。
mc.mouseEnabled = false;

在 CSS 可以利用 pointer-events, 可惜 IE 連 IE10 都不支援 !
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>What</title>
    <style type="text/css">
    .layer {
        width: 300px;
        height: 300px;
        position: absolute;
        background-color: #F00;
    }
    #a2 {
        pointer-events: none;
    }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <script type="text/javascript">
    $(function() {
        $('#a1').click(function(event) {
            alert('a1');
        });
    });
    </script>
    <div style="position: relative;">
        <div id="a1" class="layer" style="z-index:10;">
        </div>
        <div id="a2" class="layer" style="z-index:11; left:100px; top:100px; background-color: #00F">
        </div>
    </div>
</body>
</html>

IE 的解法: http://stackoverflow.com/questions/9385213/how-to-make-internet-explorer-emulate-pointer-eventsnone

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也是手到擒來的。


目錄

2013-08-04

Yii 在網址列隱藏 index.php

Yii 在網址列隱藏 index.php
參考 http://www.yiiframework.com/wiki/214/url-hide-index-php/

.htaccess 檔的內容使用
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

config/main.php 修改內容
'urlManager'=>array(
    'urlFormat'=>'path',
    'rules'=>array(
      '<controller:\w+>/<id:\d+>'=>'<controller>/view',
      '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
      '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
    ),
    'showScriptName'=>false,
    'caseSensitive'=>false,
),

2013-07-24

Bingo Hits 上架

Bingo Hits 賓果嘻打

Bingo Hits 賓果嘻打Bingo Hits 賓果嘻打

賓果嘻打是一款線上和朋友一起玩的賓果遊戲。透過地理位置偵測,可以讓幾個人一起玩賓果。

至少要有兩個 iOS 裝置才可以一起玩。

1) 首先,先讓一個朋友點選「主持人建立遊戲」,建立遊戲室。
2) 接著,其他朋友點選「加入遊戲」,並選擇遊戲室。
3) 主持人將玩家加入遊戲室,完成後開始遊戲。
希望這個遊戲可以為朋友之間帶來更多樂趣。



FB 留言