<< Flash ActionScript2.0 実践講座3:Flash OOP詳細 | top | Flash ActionScript2.0 実践講座5:YouTube APIをFlashから使う >>
FlashOOP詳細(4):アプリケーションフレームワーク、XMLデータの読み込み
本日の予定
本日も引き続き、FlashOOPの基本を学んでいきます。
まずはじめに、今後、複数のクラスを複雑に組合せてひとつのアプリケーションを構築していく場合を想定して、より整理されたアプリケーション構築のためのフレームワークの作り方を学んでいきます。クラスファイルの名前やメソッド名の重複などがないように多数のクラスを共存させるためにはどうするのか、ソースファイルとWebサイト側のイメージをどのように一致させていくのか、などについて学びます。
後半は、ActionScript2のXMLオブジェクトを活用して、Flashに読み込むファイルの管理やパラメータの読み込みの方法をサンプルを通して学んでいきます。サンプルとして簡単な画像スライドショーを作成します。これが今後のマッシュアップアプリの基礎となっていくので、順を追ってじっくりと学んでいきましょう。
本日のスライド
サンプルファイル
目次
- Flash応用講座(4)
- OOPアプリケーションフレームワーク
- ディレクトリ構造の標準化
- 現在のディレクトリ構造
- フラッシュ書類(.flaファイル)
- フラッシュ書類(.flaファイル)
- クラス
- クラスファイルの構造的な配置
- ディレクトリ構造
- FLAファイルからメインのA.asクラスをインスタンス化する
- A.asクラス
- B.asクラス
- XMLデータの活用
- XML(Extensible Markup Language)
- FlashとXML
- XMLを用いたスライドショーを作成してみる
- ディレクトリ構造を整理する
- 画像データの整理
- アプリケーションの設計
- クラスの相関図(UMLクラス図)
- XMLファイルの作成
- XMLファイルの構造
- クラス”Slideshow”のインスタンス化
- クラスの作成
- Slideshowクラス
- SlideshowXml?クラス
- 最終的なUMLクラス図
- 応用:Livedoor Weather Web Systemを利用してみる
Flash応用講座(4)
今日の内容
- OOPアプリケーションフレームワーク:
- 複数のクラスを仕様したFlashプロジェクトのファイル配置をもう少し整理してみる
- XMLファイルを読み込んで、Flashムービーのデータにする
- 次回扱う、「マッシュアップ」の導入的な内容
- コンポーネントの利用
- GUIコンポーネントを利用してみる
OOPアプリケーションフレームワーク
ディレクトリ構造の標準化
- アプリケーションの名前をつけたメインディレクトリを生成する(ex: AppName?) メインディレクトリ内(Appname/)に、”deploy”というサブディレクトリを生成。ここにはWebサーバーにアップロードされる内容が入る。(.swfファイル、データ類)
- メインディレクトリ内(Appname/)に、”source”というサブディレクトリを生成。ここにはすべてのクラスファイル(.as)とFlash書類(.fla)が入る
現在のディレクトリ構造
- AppName/
- deploy/
- source/
フラッシュ書類(.flaファイル)
- 全てのFlashアプリには必ず、1つ以上のフラッシュ書類が必要。そこからFlashムービー(.swfファイル)がエクスポートされ、FlashPlayeを利用してブラウザ上やスタンドアローンで表示される
- 複数のFlash書類に分割して開発することもある
- Flash書類はパブリッシュ設定で自動的に../deploy/以下にパブリッシュされるよう設定しておく
フラッシュ書類(.flaファイル)
- パブリッシュ設定

クラス
- より純粋なOOPアプリケーションを作成するために、複数のクラスを配置する際の構造をきちんとルール付けする
- クラスファイルを構造的に配置する
- 偶然同じ名前のクラスを仕様してしまう可能性の排除
- 役割ごとに整理することができる
- 複数人での開発にも向いている
クラスファイルの構造的な配置
- 例えばドメイン名で整理してみる
- “somedomain.com”というドメイン名の開発者が作成したクラスだった場合
- クラスファイルを下記にまとめる
- AppName/source/com/somedomain/
- 順番がドメインと逆になっている部分に注意!
- 2つのクラスを順番に読みこむサンプルを作成してみる
- A.as
- B.as
ディレクトリ構造
- AppName/
- deploy/
- AppName.swf
- AppName.html
- source/
- AppName.fla
- com/
- somedomain/
- A.as
- B.as
FLAファイルからメインのA.asクラスをインスタンス化する
- フレームアクションとして以下の命令を実行
- import:特定階層にあるクラスファイルにアクセスしている
import com.somedomain.A; A.main();
A.asクラス
- A.asクラスから同じ階層にあるB.asクラスをインスタンス化する
- import、クラス名に注意!
import com.somedomain.B;
class com.somedomain.A {
private static var bInstance:B;
public function A () {
// コンストラクタは未使用
}
public static function main ():Void {
trace("Starting application.");
bInstance = new B();
}
}
B.asクラス
- B.asクラスから同じ階層にあるA.asクラスをインスタンス化する
class com.somedomain.B {
public function B () {
trace("クラスBのインスタンス化");
}
}
XMLデータの活用
XML(Extensible Markup Language)
- 文書やデータの意味や構造を記述するためのマークアップ言語の一つ
- Extensible Markup Language (エクステンシブルマークアップランゲージ、XML、拡張可能なマーク付け言語、JIS X 4159:2002) は、データを記述するマークアップ言語を定義するためのメタ言語である。W3C (World Wide Web Consortium) により1998年2月にXML1.0の勧告が公開された。 2005年現在、W3C勧告の最新バージョンはXML1.1である。(wikipediaより)
FlashとXML
- ActionScript2.0には、XML形式のデータを扱うためのクラスが充実していて、外部データとの連携の際にとても便利
- XMLファイルを外部データ群の記述に用いて、一括して管理することができる
- ローカルのデータ
- ネットワーク上のデータ
XMLを用いたスライドショーを作成してみる
- ローカルファイルとして扱っている画像ファイルを順番に読み込んで、説明を表示するFlashアプリケーション
- 画像ファイルと説明のテキストは全てXMLドキュメントで管理されている
- GUIコンポーネントの活用
ディレクトリ構造を整理する
- xml_slideshow/
- deploy/
- xml_slideshow.swf
- xml_slideshow.html
- source/
- xml_slideshow.fla
- org/
- yoppa/
- slideshow/
- (クラスファイル群)
画像データの整理
- スライドに読みこむための画像ファイルを、”deploy/images”以下に配置する
- このサンプルでは、image1.jpg〜image5.jpgという名前の画像ファイルを使用している
- xml_slideshow/
- deploy/
- xml_slideshow.swf
- xml_slideshow.html
- images/
- (画像ファイル群)
アプリケーションの設計

クラスの相関図(UMLクラス図)

XMLファイルの作成
- XMLファイルの形式
- 画像ファイルのURL
- 画像の説明
- deployディレクトリ以下に”slides.xml”という名前で保存
XMLファイルの構造

クラス”Slideshow”のインスタンス化
- 下記のアクションをxml_slideshow.flaファイルのフレームアクションとして実行して、メインとなるクラス”Slideshow”をインスタンス化する
クラスの作成
- あとは、UML図を参考にしながらクラスを作成していく
- クラスの属性(プロパティ)を変数に
- クラスの動作(メソッド)を関数に
- クラスの種類
- Slideshow.as
- SlideshowXml.as
Slideshowクラス
//GUIコンポーネントのクラスパス
import mx.controls.*;
//Slideshowのクラスパス
import org.yoppa.slideshow.SlideshowXml;
class org.yoppa.slideshow.Slideshow {
//このオブジェクト
private var thisSlide:Slideshow;
//このオブジェクトへのXMLローダーのオブジェクト
private var thisXml:SlideshowXml;
//このオブジェクトのターゲットパス
private var target_mc:MovieClip;
//XMLより読み込まれるスライドのリスト(URLとスライドの名前)
private var slideList:Array;
//現在表示しているスライド番号
private var currentSlideNum:Number;
//スライドの写真を貼り付けるムービークリップ
private var photo_mc:MovieClip;
//スライドのタイトルを表示するテキストエリア
private var slideText:TextArea;
//「前の写真」ボタンと「次の写真」ボタン
private var prevButton:Button, nextButton:Button;
//コンストラクタ
public function Slideshow(target:MovieClip) {
target_mc = target;
//現在のスライド番号を初期化
currentSlideNum = 0;
//GUI(ボタン、テキストフィールド)の生成
createGui();
//XMLファイルを読みこむためのクラスをインスタンス化
thisXml = new SlideshowXml();
//XMLファイルを読みこんで、makeSlide関数をコールバック
thisXml.loadXML("/media/1/xml_slideshow/slides.xml", makeSlide, this);
}
//GUIコンポーネントを利用して、インタフェイスを生成
private function createGui():Void {
var thisSlide:Slideshow = this;
slideText = target_mc.createClassObject(mx.controls.TextArea,
"slideText",
target_mc.getNextHighestDepth());
slideText.move(10, 120);
slideText.setSize(144, 24);
prevButton = target_mc.createClassObject(mx.controls.Button,
"prevButton",
target_mc.getNextHighestDepth(),
{label:"前の写真"});
prevButton.setSize(70, 24);
prevButton.enabled = false;
prevButton.move(10, 150);
prevButton.clickHandler = function(e:Object):Void {
thisSlide.showPrevSlide();
};
nextButton = target_mc.createClassObject(mx.controls.Button,
"nextButton",
target_mc.getNextHighestDepth(),
{label:"次の写真"});
nextButton.setSize(70, 24);
nextButton.move(prevButton._x+prevButton.width+5, prevButton._y);
nextButton.clickHandler = function(e:Object):Void {
thisSlide.showNextSlide();
};
}
//スライドを初期生成
public function makeSlide(list:Array, target:MovieClip):Void {
slideList = list;
photo_mc = target_mc.createEmptyMovieClip("photo_mc",
target_mc.getNextHighestDepth());
photo_mc._x = 10;
photo_mc._y = 10;
viewSlide();
}
//番号に合わせた写真とテキストを表示
private function viewSlide():Void {
loadMovie(slideList[currentSlideNum].jpegURL, "photo_mc");
slideText.text = slideList[currentSlideNum].slideText;
}
//次のスライドを表示
private function showNextSlide():Void {
prevButton.enabled = true;
currentSlideNum++;
viewSlide();
if (currentSlideNum>=slideList.length-1) {
nextButton.enabled = false;
}
}
//前のスライドを表示
private function showPrevSlide():Void {
nextButton.enabled = true;
currentSlideNum--;
viewSlide();
if (currentSlideNum<=1) {
prevButton.enabled = false;
}
}
}
SlideshowXmlクラス
import org.yoppa.slideshow.*;
class org.yoppa.slideshow.SlideshowXml {
private var slidexml:XML;
//XMLデータを外部ファイルから読み込む
public function loadXML(url:String, callFunc:Function, callObj:Object):Void {
//XMLオブジェクトを作る
var slidexml:XML = new XML();
//空白行を無視する
slidexml.ignoreWhite = true;
//読み込み完了のイベントハンドラ
slidexml.onLoad = function(success:Boolean) {
if (success) {
// Slideのリスト
var slideList = new Array();
// XMLの解析(parse)
var rootNode = this.firstChild;
//スライドの数だけ繰り返し
for (var aNode = rootNode.firstChild;
aNode != null;
aNode=aNode.nextSibling) {
var slideObj = new Object();
//画像のURLを取得
slideObj.jpegURL = aNode.attributes["jpegURL"];
//スライドのタイトルを取得
slideObj.slideText = aNode.firstChild.nodeValue;
//slideListへの追加
slideList.push(slideObj);
}
//解析完了をコールバックする
callFunc.call(callObj, slideList);
} else {
//XMLの取得に失敗
//エラー処理を行う場合はここから呼び出す
}
};
//(ローカルの)XMLファイルの読み込みを実行する
slidexml.load(url);
}
}
最終的なUMLクラス図

応用:Livedoor Weather Web Systemを利用してみる
お天気Webサービス(Livedoor Weather Web Service / LWWS)

- Livedoorが提供している、XMLで全国の天気概況を取得できるAPI
- 全国142カ所の今日・明日・あさっての天気予報・予想気温と都道府県の天気概況情報を提供
Lwwsクラス
//GUIコンポーネントのクラスパス
import mx.controls.*;
//Slideshowのクラスパス
import org.yoppa.lwws.*;
class org.yoppa.lwws.Lwws {
//LivedoorWebサービス、XML取得URL
private var url:String
= "http://weather.livedoor.com/forecast/webservice/rest/v1?city=63&day=tomorrow";
//このオブジェクト
private var thisLwws:Lwws;
//このオブジェクトへのXMLローダーのオブジェクト
private var thisXml;
//このオブジェクトのターゲットパス
private var target_mc:MovieClip;
//GUI要素
private var titleLabel:Label;
private var telopLabel:Label;l
private var temperatureLabel:Label;
private var descriptionText:TextArea;
private var icon_mc:MovieClip;
//コンストラクタ
public function Lwws(target:MovieClip) {
target_mc = target;
//GUI(ボタン、テキストフィールド)の生成
createGui();
//XMLファイルを読みこむためのクラスをインスタンス化
thisXml = new LwwsXml();
//XMLファイルを読みこんで、makeSlide関数をコールバック
thisXml.loadXML(url, showWeather, this);
}
//GUIコンポーネントを利用して、インタフェイスを生成
private function createGui():Void {
//メインタイトル(ラベル)
titleLabel = target_mc.createClassObject(mx.controls.Label,
"titleLabel",
target_mc.getNextHighestDepth());
titleLabel.setSize(300, 24);
titleLabel.move(10, 10);
titleLabel.setStyle("fontSize", 18);
//お天気アイコン(画像表示用のMovieClip)
icon_mc = target_mc.createEmptyMovieClip("icon_mc",
target_mc.getNextHighestDepth());
icon_mc._x = titleLabel._x;
icon_mc._y = titleLabel._y+titleLabel.height+10;
//天気名(ラベル)
telopLabel = target_mc.createClassObject(mx.controls.Label,
"telopLabel",
target_mc.getNextHighestDepth());
telopLabel.setSize(60, 20);
telopLabel.move(icon_mc._x, icon_mc._y+32);
//気温(ラベル)
temperatureLabel = target_mc.createClassObject(mx.controls.Label,
"temperatureLabel",
target_mc.getNextHighestDepth());
temperatureLabel.setSize(300, 80);
temperatureLabel.move(telopLabel._x+telopLabel.width+5, telopLabel._y);
//気象概況とピンポイント天気(テキストエリア)
descriptionText = target_mc.createClassObject(mx.controls.TextArea,
"descriptionText",
target_mc.getNextHighestDepth());
descriptionText.setSize(460, 240);
descriptionText.move(telopLabel._x, telopLabel._y+telopLabel.height+10);
descriptionText.html = true;
descriptionText.wordWrap = true;
descriptionText.editable = false;
descriptionText.vScrollPolicy = "on";
}
private function showWeather(weatherObj:Object):Void {
//メインタイトルのテキストを設定
titleLabel.text = weatherObj.title;
//天気名のテキストを設定
telopLabel.text = weatherObj.telop;
//お天気アイコンの画像をロード
loadMovie(weatherObj.imageUrl, "icon_mc");
//最高気温と最低気温をまとめて表示
temperatureLabel.text
= "最低気温:"
+weatherObj.temperatureMin
+"℃ 最高気温:"+weatherObj.temperatureMax+"℃\n";
//気象概況を表示
descriptionText.text
= "気象概況:\n"+weatherObj.description+"\n\n";
//ピンポイント天気予報の表示
descriptionText.text
+= "ピンポイント天気予報:\n";
for (var i:Number = 0; i<weatherObj.pinpointTitleList.length; i++) {
//ピンポイントの数だけ地域名を表示、ピンポイント予報のリンクを付加
descriptionText.text
+= "<font color=\"#0000ff\"><a href=\""
+weatherObj.pinpointUrlList[i]+"\">"
+weatherObj.pinpointTitleList[i]+"</a></font>";
}
}
}
LwwsXmlクラス
// ライブドアお天気Webサービス(REST)XML解析
// お天気Webサービス仕様
// http://weather.livedoor.com/weather_hacks/webservice.html
// ---
class org.yoppa.lwws.LwwsXml {
private var lwwsXml:XML;
//XMLデータを外部ファイルから読み込む
public function loadXML(url:String, callFunc:Function, callObj:Object):Void {
//XMLオブジェクトを作る
var lwwsXml:XML = new XML();
//空白行を無視する
lwwsXml.ignoreWhite = true;
//読み込み完了のイベントハンドラ
lwwsXml.onLoad = function(success:Boolean) {
if (success) {
// 読み込みに成功 → XMLの解析開始
//コールバック用オブジェクトの初期化
var weatherObj = new Object();
//ルートノードの定義
var rootNode = this.firstChild;
//ルートノード以下の子ノードが存在する限り解析を続ける
for (var aNode = rootNode.firstChild;
aNode != null;
aNode=aNode.nextSibling) {
//ノードの名前をキーにして、必要な値を抽出し、
//オブジェクトweatherObjのプロパティーとして追加する
switch (aNode.nodeName) {
case "title" :
//メインタイトル
weatherObj.title = aNode.firstChild.nodeValue;
case "telop" :
//天気名
weatherObj.telop = aNode.firstChild.nodeValue;
case "description" :
//気象概況
weatherObj.description = aNode.firstChild.nodeValue;
case "image" :
//imageノードのさらに下の階層のノードを解析
for (var aaNode = aNode.firstChild;
aaNode != null;
aaNode=aaNode.nextSibling) {
switch (aaNode.nodeName) {
case "url" :
//お天気アイコンの画像ファイルのURL
weatherObj.imageUrl = aaNode.firstChild.nodeValue;
}
}
case "temperature" :
//temperatureノードのさらに下の階層のノードを解析
for (var aaNode = aNode.firstChild;
aaNode != null;
aaNode=aaNode.nextSibling) {
switch (aaNode.nodeName) {
case "max" :
//最高気温
weatherObj.temperatureMax
= aaNode.firstChild.firstChild.nodeValue;
case "min" :
//最低気温
weatherObj.temperatureMin
= aaNode.firstChild.firstChild.nodeValue;
}
}
case "pinpoint" :
//pinpointノードのさらに下の階層のノードを解析
//ピンポイント天気の地名とURLのリストを準備
var pinpointTitleList:Array = new Array();
var pinpointUrlList:Array = new Array();
//ピンポイント地域の数だけ、リストに追加していく
for (var aaNode = aNode.firstChild;
aaNode != null;
aaNode=aaNode.nextSibling) {
switch (aaNode.firstChild.nodeName) {
case "title" :
//ピンポイント予報、地名(リストに追加)
pinpointTitleList.push(aaNode.firstChild.firstChild.nodeValue);
case "link" :
//ピンポイント予報、URL(リストに追加)
pinpointUrlList.push(aaNode.childNodes[1].firstChild.nodeValue);
}
}
//地名とURLのリストをオブジェクトweatherObjに追加
weatherObj.pinpointTitleList = pinpointTitleList;
weatherObj.pinpointUrlList = pinpointUrlList;
}
}
//解析完了後、解析結果weatherObjをコールバックする
callFunc.call(callObj, weatherObj);
} else {
//XMLの取得に失敗
//エラー処理を行う場合はここから呼び出す
}
};
//(ローカルの)XMLファイルの読み込みを実行する
lwwsXml.load(url);
}
}
<< Flash ActionScript2.0 実践講座3:Flash OOP詳細 | top | Flash ActionScript2.0 実践講座5:YouTube APIをFlashから使う >>


Comments
コメントはありません
Add Comment
トップページに戻る