Macromedia Flash非公式テクニカルノート ActionScriptとその基本概念について
Platform: All
本稿では、ActionScriptとその背景にあるプログラミングや仕様上の基本概念について解説します。基本とはいえ、概念説明ですので、必ずしも初心者向けの内容ではありません。スクリプトについての基礎知識が前提とされます。その中でも中級者向けと思われる節には、【Advanced】と付記してあります。基本用語は「Word」という項目で、囲み記事としました。また、中級者以上向けのトピックも、「Advanced Topic」という囲み記事にしています。ご興味や知識レベルに応じて、ご参照ください。 ●01 ECMAScriptとしてのActionScript
JavaScriptは、Netscape Communications社(1998年に現AOL Time Warner社に買収)とSun Microsystems社が共同開発したスクリプト言語です。それに対抗したMicrosoft社が自社技術を追加・拡張して、JScriptを開発しました。NetscapeとMicrosoftの仕様は細部で異なっていたため、両社も参加して、ECMAがECMAScriptとして標準化しました。 こうした経緯ですので、JavaScriptもJScpritも、厳密にはECMA-262と一致していない部分があります。これはActionScriptでも同様で、ECMA-262に完全に準拠している訳ではありません。 ●02 スクリプトとは【Advanced】 もっとも、このように説明すると、プログラムすべてが含まれてしまいそうです。もともとは、小規模の処理手順をすばやく作成することがおもな目的とされる、簡易プログラムが「スクリプト」と呼ばれました。一般のプログラミング言語に比べて機能は少ないものの、習得しやすく文法も簡便なことが特徴です。 しかし、スクリプト言語も改訂が進み、機能が拡張されていきます。すると、必ずしも容易とも簡便ともいえなくなってきました。そこでプログラミング言語のなかでも、とくに「インタプリタ形式」で実行されるものが、一般に「スクリプト」と呼ばれます。
interpreterというのは、「通訳」のことです。プログラミング言語のインタプリタは、記述されたプログラム(「ソースコード」といいます)をコンピュータが理解・実行できる形式いわゆる機械(マシン)語(「オブジェクトコード」または「ネイティブコード」)に翻訳します。インタプリタ形式のプログラミング言語は、実行時にこのインタプリタを介して処理を実行します。 インタプリタ形式に対するプログラムの実行形態は、「コンパイル形式」です。compileというのは、「まとめる」という意味です。具体的には、これも機械(マシン)語に翻訳する処理を指します。しかし、インタプリタと異なるのは、実際の処理を行う前にこの翻訳を終えて、実行ファイルを作成してしまうということです。つまり、実行ファイルは、オブジェクトコードで直接処理を行います。 インタプリタ形式がその場で通訳を介してコンピュータとやり取りするのに対して、コンパイル形式ではネイティブスピーカーの代役を立ててしまうということです。あるいは映画なら、吹替えをすると考えればよいでしょう。 インタプリタ形式の方が、手軽にプログラムが試せます。また、MacintoshとWindowsそれぞれの通訳を雇うだけで、複数のオペレーティングシステムに対応できます。Flash(SWF)ムービーに対して通訳の役割を担うのは、Flash Playerです。MacintoshでもWindowsでも、対応するFlash Playerがインストールされていれば、同じSWFムービーを再生することができます。 コンパイル形式は、準備に手間がかかります。しかし、吹替えされた映画は、観客にリアルタイムでストーリーが伝わります。つまり、実行時の処理が、最適化されるのです。そのため、処理スピードが問題とされるような大規模開発には、コンパイル形式の言語が用いられます。コンパイル型言語の代表として、CやC++が挙げられます。 もっとも、FlashのActionScriptは、記述したスクリプトをそのまま直ちに実行できる訳ではありません。一旦SWFに書出す必要があります。このとき、ActionScriptはソースコードのまま書出されるのでなく、「バイトコード」と呼ばれるFlash Player向けの命令に変換されます。その命令は、MacintoshやWindowsといったプラットフォームを問わず共通のSWFファイル形式で、Flash Playerの通訳を必要とします。バイトコードは、ソースコードとネイティブコードのいわば中間言語にあたります。
ActionScriptでは、FlashムービーをSWFに書出すことを、「コンパイル」ということがあります。ソースコードを、Flash Player上で実行するのに適した形式に変換するからです。しかし、コンパイル形式の言語のように、機械(マシン)語の実行ファイルに変換する訳ではありません。バイトコードを解釈してそのコンピュータのネイティブコードに変換するFlash Playerを必要とします。 つまり、ActionScriptは、インタプリタ型とコンパイル型の中間のプログラミング言語ということになりそうです。とはいえ、仕様はECMAScriptに準拠しています。また、ネット上で実行されるというFlash Playerの性質から、そのプログラムサイズには大きな制約があります。少なくとも現在の段階では、おもに小規模のプログラムを目的とするということができます。したがって、ActionScriptは「スクリプト」であるとして、差支えはないでしょう。 ●03 クラス(オブジェクト)について たとえば、Flashムービーの中で、ムービークリップシンボルのインスタンスは重要な役割を果たします。「ActionScriptリファレンスガイド」を見ると、MovieClipというクラスが存在し、さまざまなプロパティやメソッドが定義されています。ムービークリップインスタンスは、ActionScriptの世界では、MovieClipクラスのインスタンスとして捉えられます。 図001■ステージに配置されたムービークリップシンボルのインスタンス 図002■「ActionScriptリファレンスガイド」の「MovieClipクラス」の項 そこで筆者は、ムービークリップインスタンスを、ActionScript上の存在としてMovieClipインスタンス(あるいは単にMovieClip)と表記しています。同じように、ボタンインスタンスはButtonインスタンス(またはButton)、テキストフィールドはTextFieldインスタンス(またはTextField)と表現します(ただし、[静止テキスト]は、ActionScript上の存在とはいえません)。 ActionScriptは他にも、サウンドをコントロールするSoundクラスや、ムービークリップインスタンスのカラーを変更するColorクラス、外部テキストやXMLドキュメントをロードしたり解析するためのLoadVarsやXMLなどといった、目に見えないクラスも数多く扱います。 Flashのアニメーションでは、シンボルを活用することがひとつのポイントです。タイムラインには[ライブラリ]からシンボルのインスタンスをいくつでも配置でき、インスタンスはそれぞれ個別に設定を変えたり、アニメーションさせることが可能です。 ActionScriptでは、クラスがシンボルと似た重要な役割を果たします。つまり、クラスもインスタンスを作成します。クラスから作成されたインスタンスを、一般に「オブジェクトインスタンス」あるいは単に「インスタンス」と呼びます(MovieClipインスタンスも、ActionScript上はMovieClipクラスのインスタンスです)。そして、それらのインスタンスをActionScriptがコントロールして、インタラクティブなインターフェイスやナビゲーションをつくりあげるのです。 シンボルはインスタンスに対して、タイムラインやビジュアル(視覚)的なデータを提供します。シンボルは、いわばインスタンスのひな形(テンプレート)になる訳です。他方クラスは、そのインスタンスに対してプロパティとメソッドを提供します。クラスもやはり、オブジェクトインスタンスのひな形ということができます。
●04 オブジェクト・クラス・インスタンス【Advanced】 前項03では、「クラス」はFlashムービーのシンボルのようなもので、その内容をもとに「インスタンス」を作成するとご説明しました。これで、何となくイメージはできると思います。しかし、もう少し具体的に、ふたつの関係を考えてみます。 「クラス」は概念的・抽象的なもので、「インスタンス」はクラスを実体化・具体化したものだと説明されることがあります。実際、英語のinstanceには「実例」という意味があります。また、「クラス」は、「インスタンス」をつくり出す存在だともいわれます。「クラス」は設計図で、「インスタンス」が製品だと例えられたりもします。 これらの説明の中では、設計図と製品の例えが比較的わかりやすいでしょうか。しかし、まだ身近な感じがしませんので、例えを変えましょう。「クラス」は、料理の「レシピ」です。そのレシピにしたがって、実際につくられるひと皿ひと皿の「料理」が「インスタンス」になります。あたりまえのことですが、「レシピ」は食べられません。料理の素材・味つけ・調理方法を、「定義」したものだからです。これが概念的・抽象的だということの意味です。レシピからつくった具体的な「料理」が、「実体」として口にできるものなのです。 では初めに戻って、「オブジェクト」とは何でしょう。多くの場合、「インスタンス」を指す用語として使われているようです。しかし、「MovieClipオブジェクトには、水平座標のプロパティとして_xがある」というように、個々のインスタンスでなく一般的な説明をする場合には、むしろ「クラス」を意味していると捉えられることも少なくありません。Flash MX以前の「ActionScript辞書」で、「MovieClip(オブジェクト)」というのは、明かに「クラス」を表しています。 考えてみれば、「料理」という言葉も、「オブジェクト」に似たところがあります。テーブルに運ばれてくるひと皿ひと皿が「料理」です。しかし、「フランス料理」や「イタリア料理」という場合には、器に盛られた料理のことではなく、それぞれの国の伝統的な「レシピ」による料理のスタイルという意味になります。 「オブジェクト」という用語も、具体的には文脈から判断すべきことになります。大切なのは、用語に惑わされることなく、「クラス」と「インスタンス」とを理解し、区別することです。 ●05 メソッドとプロパティ クラスからインスタンスを作成すると、定義されたプロパティに値を設定したり、メソッドで操作をすることが可能です。つまり、インスタンスには、そのクラスのプロパティやメソッド一式が自動的にパッケージされてついてくるのです。これが、オブジェクト指向プログラミング言語の特徴です。 すると、クラス(オブジェクト)の種類によって、設定できるプロパティや実行できるメソッドが決まってくることになります。MovieClipインスタンスの水平座標は、_xプロパティによって設定することが可能です。他方、ButtonインスタンスやTextFieldインスタンスの水平座標も、_xプロパティで変えられます。しかし、Flash 5では、ButtonやTextFieldの位置をActionScriptで制御することができませんでした。これは、Flash 5には、ButtonやTextFieldというクラス(オブジェクト)が定義されていないからです。クラスがなければ、当然プロパティも存在しません。ですから、制御は不可能だということになるのです。 「ActionScriptリファレンスガイド」にはMovieClip._xプロパティが存在し、その解説があります。同様に、Flash MX以降では、Button._xやTextField._xプロパティも掲載されています。つまり、たまたま(というよりわざわざ)同じ名前の_xというプロパティが定義されているものの、それぞれは異なるクラスの別個のプロパティだということです。 ActionScriptは、基本的にインスタンスを操作して、ムービーをコントロールします。オブジェクトインスタンスの代表は、もちろんMovieClipです。その他、ButtonやTextFieldなどステージ上に表示されているものから、SoundやXMLなどの目に見えないインスタンスも存在します。インスタンスは、プロパティとメソッドによって操作します。 ですから、ActionScriptでムービーをコントロールするには、まず操作の対象となるオブジェクト(クラスとそのインスタンス)を特定します。つぎに、そのクラスのプロパティやメソッドを探します。そして、そのインスタンスに対して、目的に応じたプロパティあるいはメソッドを操作します。 表001■ActionScriptでムービーを操作するには
クラスとかプロパティやメソッドというと、抽象的でピンとこないかもしれません。そういう人は、身の周りにある家電やAV機器で考えてみるとよいでしょう。たとえば、TVがオブジェクトです。プロパティには、選択されたチャンネルやボリューム、画面の明るさやコントラスト、色合いといった設定があります。TVのリモコンやコントロールパネルにあるボタンで、それらの設定を変更することができます。ですから、これらのボタンが、メソッドに当ります(正確には、ボタンで操作される電気回路といった方がよいでしょう)。 TVをつけるには、リモコンを取って「電源」とか「Power」という表示のあるボタンを押します。すると、なぜかビデオデッキの電源が入ってしまったという経験はありませんか? リモコンを取違えたということです。電源ボタンはどのリモコンにもありますが、TVを見たいのであれば、TVのリモコンを手にしないといけません。つまり、まず操作対象の家電を特定し、そのリモコンを手に取ります。つぎに、操作すべき手段となるメソッドつまり電源のボタンを探します。そして、リモコンをその家電に向けてボタンを押すという操作を実行すれば、晴れてTVが映るということです。 ActionScriptのほとんどの操作の基本単位は、クラスとインスンタンスです。ですから、「ActionScriptリファレンスガイド」も、クラスごとにプロパティとインスタンスの説明をまとめています。したがって、スクリプトを書くには、どのオブジェクト(インスタンス)を操作するのかということからスタートする必要があるのです。 ●06 ActionScript 2.0とFlash Player 7【Advanced】 ActionScript 2.0の仕様も、やはりECMA-262によって定められています。ただし、ActionScript 1.0がECMA-262第3版に準拠するのに対して、ActionScript 2.0は第4版にもとづきます。
ECMA-262第4版に準拠するActionScript 2.0は、厳密な型指定とクラスをベースとしたプログラミングスタイルに大きな特徴があります。ActionScript 2.0について詳しくは、「ActionScript 2.0を使ったクラスの作成概要」および本サイトのActionScript 2.0に関するノートをご参照ください。。
ActionScript 2.0を使用した場合、Flash Player 7はもちろん、Flash Player 6でパブリッシュすることも可能です。これは、Flash MX 2004の現状では、後述(「07 ActionScript 1.0 vs 2.0」)のとおり書出されるバイトコードが1.0と基本的には異ならないからです。ActionScript 2.0を使ったFlash Player 6書出しについては、「ActionScript 2.0と1.0の継承について」の「3. ActionScript 2.0の継承をFlash Player 6で書出した場合」をご参照ください。 ActionScript 2.0の採用とは別に、Flash Player 7ではECMA-262への準拠を強めています。そのため、Flash Player 6以前と仕様が一部変わりました。これは、ActionScript 1.0でスクリプトを記述したとしても、Flash Player 7でパブリッシュを行った場合、バージョン6以前とは動作が違ってしまう可能性のあることを意味します。とくに、旧バージョンで作成したムービーをFlash MX 2004で修正・変更して、Flash Player 7で書出す場合に注意が必要です。パブリッシュで、Flash Player 7を指定するか、それより前のバージョンを選択するかによって、動作が異なる部分はつぎの表002のとおりです。 表002■Flash Player 7と6以前のバージョンとの違い
[1] 大文字小文字の区別
Flash Player 6以前の形式では、大文字と小文字が区別されません。しかし、同一の名前(識別子)を表記するのに、大文字小文字を統一して使用しないと、プログラムのミスを招きやすくなります。ですから、Flash Playerのバージョンにかかわらず、大文字と小文字は区別して使うべきでしょう。 [2] 未定義値undefinedを数値として評価したとき
スクリプト002■Flash Player 6以前でundefinedに数値を加算
上記のスクリプトを繰返し実行すれば、整数値が加算されていきました。しかし、Flash Player 7からは、未定義値undefinedを数値演算の対象とすると、NaNに変換されます(スクリプト003)。 スクリプト003■Flash Player 7でundefinedに数値を加算
NaNに対しては、どのような数値演算を行っても、結果はNaNのままです。したがって、Flash Player 7でこのスクリプトを繰返し実行しても、結果はつねにNaNになります。
[3] 未定義値undefinedをストリングとして扱ったとき
しかし、Flash Player 7からは、未定義値undefinedがストリングの"undefined"に変換されます。したがって、同じスクリプトの結果が、つぎのように変わります(スクリプト005)。 スクリプト005■Flash Player 7でundefinedに文字列を連結
[2][3]の未定義値undefinedの処理を、バージョンにかかわらず統一的に扱えるようにするためには、変数には必ず初期値を与えるのがよいでしょう(スクリプト007および008)。変数を宣言するvarステートメントを用いると、変数の初期値を設定していることが明確になります(var宣言をしなくても、処理結果は同じになります。varステートメントについては、「ActionScriptリファレンスガイド」をご参照ください)。 スクリプト007■変数を宣言して数値の初期値を与える
スクリプト008■変数を宣言して文字列の初期値を与える
[4] ストリングをプール(論理)値として評価したとき Flash Player 6の処理は、少し変わっています。ストリングは、まず数値として評価され、その結果0以外の数値ならtrueとして扱われます。そして、それ以外の場合つまり、数値0と評価されるか、数値として扱えない(NaNの)場合をfalseとします。
[5] 配列に対する値の設定と配列の長さ ところが、Flash 5およびMXでは、数値ではじまるプロパティ名や数値の前に半角スペースを加えたプロパティを設定しても、その数値を元にArray.lengthプロパティの値が更新されてしまいました(表003)。 表003■数値ではじまる配列エレメントと配列の長さ
配列のArrayクラスは、Flash 5から実装されたもので、それより前のバージョンとの整合性が問題になることはありません。また、配列の長さが変わっているにもかかわらず、配列そのものをtrace()アクションで出力したとき、配列エレメントとしては扱われていない(my_array.lengthが5で、出力が「,1,,,」となっている)ことから考えても、Flash Player 6以前の結果は整合性を欠くといわざるをえません。 この仕様変更は、バグ修正と見るべきでしょう(ただし、過去のコンテンツの動作を変えないという意味で、上位互換性が保たれています)。
●07 ActionScript 1.0 vs 2.0 他方、比較的小規模で、スクリプティングとデザインとを明確に分けないプロジェクトもあります。こうしたコンテンツでは、従来のFlashと同じフレームやMovieClipインスタンスなどのタイムライン(MovieClip)に記述するスクリプトの方が、小回りも利いて便利な面も少なくないでしょう。おそらくコンテンツの数でいえば大多数を占めると思われるこのような小規模のムービーでは、引続きActionScript 1.0を使用して問題ありません。 実際、型指定をしなければ、(クラス定義をしない)通常のフレームアクションやMovieClipアクションでは、ActionScript 2.0と1.0の違いはありません。そして、Flash MX 2004のスクリプティングにおいても、型指定は必須という訳ではないのです。むしろクラス定義以外では、型指定をあえてすべき場合は多くはないでしょう。 また、型指定はFlashがコンパイル(SWF書出し)するときのみのチェックです。つまり、書出されたSWFには、型指定の情報が残りません。その意味では、一種のシンタックスチェックにすぎないと見ることもできます。さらに、ActionScript 2.0でスクリプトを記述しても、SWFに書出されるバイトコードは、Flash MX 2004ではActionScript 1.0とほとんど異なるところがありません(将来のバージョンで、ActionScript 2.0に最適化された実装がなされる可能性はあります)。 _____ 作成者: 野中文雄 Copyright © 2001-2006 Fumio Nonaka. All rights reserved. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||