Home > Flash/Flex

Web 酒 肴

«前へ || 1 | 2 | 3 | 4 | 5 | 6 || 次へ»

Flex入門者がアニメーションを基礎から説明してみる #2

第2回からさっそくの放置かよ、と思ったみなさんこんばんわ。 インストールしたFlexBuilderの試用期間が終わる前にちゃんと完結するのか、ご心配のことでしょう。 安心してください。僕も同じように心配しています。

等速直線運動

さて、今回のテーマは「物体の移動」。その中でも最も基本的な「等速直線運動」に取り組みます。 中学生の理科で習ったやつですね。 物体が同じ速度で直線状に移動するというものです。 ああもっと勉強しておけばよかった、というのは全ての大人が感じる感情なので、気にしても仕方ありません。 未来は操作できても過去は操作できないのです。

それと同時に、今後のプログラム作成のベースとなる部分の説明をしますので、第2回として適切な分量になるかと思います。 説明は今後FlexBuilder3を前提にしますので、別の環境で行う方は適宜読み替えてください。

プロジェクトの作成

これから、新たな物を作成するたびにFlexBuilderのプロジェクトを作成するようにします。 今回も以下のようにFlexBuilder上から[新規] → [ActionScriptプロジェクト]とします。

プロジェクト名は何でもいいですが、例として「Animation1」としています。 入力したら「終了」ボタンをクリック。簡単です。

するとAnimation1.asというファイルが開かれるので、これを編集して今回の説明を行います。 この流れは今後も同じになるので憶えておきましょう。 以下が最初の状態。

続きを読む

Flex入門者がアニメーションを基礎から説明してみる #1

ActionScript勉強し始めて1か月、アニメーションの勉強始めて3週間。 どっからどうみても入門者の僕が、入門者だからこそ出来る、かゆい所に手の届く解説記事をみなさんに届ける企画です。

入門者と言ってもJavaやRubyなど、いくつかの言語での開発経験はあるので、対象となる人も同じような人を想定しています。 アニメーションに関する知識は皆無でいいでしょう。 作図が必要な説明はちょっとしんどいので、sin, cosに関する知識は持っていてくれたら嬉しい。 でも知らなくても何とかなるよ。

では始めましょうか。

いい本があります

「ActionScript 3.0 アニメーション」という素晴らしい書籍があります。 ActionScriptで説明しているのですが、アニメーションに対するその考え方は言語を超えてあらゆる場面で役に立つでしょう。 さらにこの著者の、人に教えよう、理解してもらおうという姿勢が随所に見られて、読んでいてとても気持ちがいい。 税込7350円と高価だが買って損はない。むしろ余計な金持ってたらつまらんことに使って、時間と金をダブルで無駄にしていたと思うととっても得した一冊。

「ちぇ、宣伝かよ」 とか思った心の狭い方々へ

僕がこの本のエッセンスを自分なりにかいつまんで、このブログ上で解説しましょう。書籍を買う必要はありません。 少しでも僕を疑った心の狭さを全力で反省しながら、大いにアニメーションを学んでください。

色んな前提条件

  • アニメーションの定義

    主に物理法則に基づいた物の動きのことです。 物が落下したり、ぶつかったりする動きをリアルに再現することを目的としています。 テレビアニメのようなものを想像した人は、ごめんなさい、ここで終了です。

  • 言語と開発環境

    ActionScript3.0です。僕はAdobeのFlex Builder3を使用します。 3万円ほどするソフトですが、60日間の試用版があるので、そちらを使えばいいでしょう。 他にもFlash CS3 IDE(さらに高価)やフリーのコンパイラを使用してコマンドラインで開発することもできます。 また、FlashDevelopというフリーの開発環境もあるみたいです。 安く抑えようとすると、調査すべきこともそれなりに増えます。自分の財布や時間のゆとりと相談しましょう。 Flex Builder3の試用版を導入する人はこの辺が参考になるでしょう。

    Flex/AIRの開発環境Flex Builder 3を使ってみよう

  • 解説する内容

    「ActionScript 3.0 アニメーション」の書籍の内容を僕が解釈して、自分なりに重要だと思えるところ、 それでいて簡単に解説できるところを選択して解説します。 書籍の内容の転載に近いようなことは、もちろん著作権侵害にあたるのでしません。 もっと深い内容が知りたくなった人はぜひ、この書籍を購入してください。

    ここまで読んで「結局、宣伝かよ」と思った人。正解です。

  • 連載回数、連載ペースなど

    どちらも詳しくは未定です。あまり期待しないでください。 だけど、連載回数は10回くらいいけたらいいなと思っています。 あまり長くしても、書いてる方も読んでる方も飽きるし。 連載ペースも本当に未定です。 疲れて途中で投げ出す可能性も否定できません。

ではでは、第1回はここまで (「え~!!!」じゃない!!!)

第2回は「物体の移動」を予定しています。 まだまだ簡単ですよ。 Flex Builderインストールして楽しみにしておきなさい!

Flex3で画像の中心を基準点に回転するには

画像を中心点で回転などしたいときに、Flex3では回転の基準点を設定する方法がないような気がする。 デフォルトでは(0, 0)つまり画像の左上の点を基準に回転してしまう。

色々探してみたが、結局は画像の中心点が左上の点となるような見えないSpriteを作成し、 その上に画像を配置する方法が楽みたい。 後は画像を扱うのではなく、その土台のSpriteを回転などさせる。

つまりこういうこと。

コードはこんな感じ。

myImage = new MyImage(); //自分で用意した埋め込み画像など(回転させる画像)
base = new Sprite();  //回転用のSprite(実際に回転させる対象)

base.addChild(myImage);  //回転させるSpriteに画像を追加
myImage.x = -myImage.bitmapData.width / 2;  //画像の横幅の半分を左に移動
myImage.y = -myImage.bitmapData.height / 2;  //画像の高さの半分を上に移動
addChild(base);

base.rotation = 90;  //90度回転

参考にしたのはこちら。

ActionScript3.0で、中心点を指定して回転させる

他にもフィルタとなるMatrixオブジェクトで移動→回転→移動させる方法などもあるみたいだけど、僕は上の方法が楽だと思うな。

Flex Builder 3でライブラリプロジェクトの作り方

多分基本的なことだけど、少しハマった。

[新規] → [Flexライブラリプロジェクト] で作成。 その中に各プロジェクトで共通して使いたいクラスなんかをいれておくんだけど、忘れてはいけないのが以下。

  1. ライブラリプロジェクトを右クリック
  2. プロパティーを選択
  3. Flexライブラリビルドパスを選択
  4. クラスタブ内で、ライブラリに含めるクラスを指定

これをしないと他のプロジェクトのビルドパスに入れても、その中のクラスを認識しない。

Flexで動的にベクタ画像を表示する方法

Flex3の標準ライブラリでベクタ画像を表示する方法を模索中。 Imageコンポーネントではベクタ画像として唯一SVG形式がサポートされていることをヘルプファイルで発見。 以下のようにhoge.svgを表示しようと試してみるも失敗。

<mx:Image source="hoge.svg"/>

エラーメッセージを読むと、どうやらSVG形式は動的に読み込むことはできず、 最初からSWFファイルに埋め込む形にしなくてはならない。 つまりこのようにする。

<mx:Image source="@Embed('hoge.svg')"/>

こうすると表示できるが、コンパイル時にSWFファイルに埋め込まれる形になる。 つまりユーザの選択に応じて別の画像を表示したりということができない。

ということで、現在の回避策としては以下の方法を取った。

  1. SVGファイルを埋め込んだSWFファイルを必要数用意しておく
  2. そのSWFファイルを動的に読み込むようにする

SVGファイルを埋め込んだSWFファイルの作成

まず、以下のようなMXMLファイルを生成してコンパイル。するとSVGファイルが埋め込まれたhoge.swfができる。 今回は3種類のSVGファイルを用意してhoge1.swf, hoge2.swf, hoge3.swfを作成した。

hoge.mxml

<?xml version="1.   0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()">
    <mx:Image id="imagebox" source="@Embed('hoge.svg')" y="20" x="20"/>
</mx:Application>

用意したSWFファイルを読み込むMXMLファイルを作成

下記のようにImageコンポーネントのsource属性を動的に変更するようにする。 Listコンポーネントのchangeイベントが発生することでImageコンポーネントのsource属性を変更している。

SVGviewer.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()" alpha="1.0" width="271" height="132">
    <mx:HBox x="10" y="10" width="251" height="112">
        <mx:Image id="image" width="100" height="100" source="hoge1.swf"/>
        <mx:VRule height="106" width="1"/>
        <mx:List id="list" width="100" height="81" change="image.source=list.selectedItem.data">
            <mx:Object label="hoge1.swf" data="hoge1.swf"/>
            <mx:Object label="hoge2.swf" data="hoge2.swf"/>
            <mx:Object label="hoge3.swf" data="hoge3.swf"/>
        </mx:List>
    </mx:HBox>
</mx:Application>

用意したSVG画像が単純すぎてわかりにくいかもしれないけど、このようになる。右側のリストからファイル名を選択すると左側の画像が切り替わる。 判別する術はないかもしれないが、ちゃんとSVG形式のベクタ画像だ。

問題点

現状ではこの方法しか思い浮かばないが、もっといい方法があるかもしれない。 ちなみにこの方法では以下の問題点がある。

  1. 画像のファイルサイズが大きくなる

    実際今回のサンプルに使用したSVGファイルのサイズは100バイト程度だ。 しかし、SWFファイルにすると250Kバイト程度となり、実に2千倍以上のサイズになっている。 ただし、SVGファイルが大きくなればなるほど、この差は小さくなると思う。

  2. 画像毎にMXMLファイルを作成した後、SWFファイルにコンパイルしなくてはならない。

    作成するMXMLファイルは定型的なものなので自動化も簡単だが、毎回コンパイルしてファイルを配備する仕組みを作る必要がある。 もちろん、できればそんなことはしたくない。

今回の方法は一つの選択肢ではあるが、引き続き調査は必要だ。

Flex Builder 3を使ってAdobeのチュートリアルを試す #4

Tileコンポーネントの作成

Flickrから取得してきたイメージを表示するためにTileListというコンポーネントを使用する。 HBoxコンポーネントの後、Applicationタグの終了タグの直前に以下の記述を追加しよう。 デザインモードでドラッグ&ドロップした後に編集してもよい。

<mx:TileList width="100%" height="100%"
    dataProvider="{photoFeed}">

</mx:TileList>

以下の部分がポイントだと推測できる。前回のエントリーで述べたように、photoFeed変数にはFlickrから取得した結果が何らかの形で格納されている。それをTileList内にこれまたどのような形かで表示するのだろう。前回も述べたとおり、詳細はよくわかっていない。

dataProvider="{photoFeed}"

分かっているのはphotoFeed変数はArrayCollection型ということだけだ。でもそれで十分かもしれない。 そもそもTileListというのは日本語で言えば「タイルを並べたもの」ということなので、dataProvider(データ提供者)に与えたArrayCollectionの中身を一つずつ取って並べて表示するのだろう。

TileListの中にさらに記述を追加していく。 説明はすっ飛ばしてコードだけ見てみよう。

<mx:TileList width="100%" height="100%"
    dataProvider="{photoFeed}">
    <mx:itemRenderer>
        <mx:Component>
            <mx:VBox width="125" height="125"
                paddingBottom="5"
                paddingLeft="5"
                paddingTop="5">

            </mx:VBox>
        </mx:Component>
    </mx:itemRenderer>
</mx:TileList>

幅や高さ、余白など見た目の部分はVBoxで設定しているようだ。 それ以外のitemRendererやComponentはどういう働きをしているのかよくわからないが、恐らく概念的に必要なのだろう。我ながら都合のいい解釈だ。

そして最後にVBoxの中に実際の画像とテキストを配置する。 全て記述し終えるとこのようになる。

<mx:TileList width="100%" height="100%"
    dataProvider="{photoFeed}">
    <mx:itemRenderer>
        <mx:Component>
            <mx:VBox width="125" height="125"
                paddingBottom="5"
                paddingLeft="5"
                paddingTop="5"
                paddingRight="5">

                <mx:Image width="75" height="75"
                    source="{data.thumbnail.url}"/>

                <mx:Text text="{data.credit}"/>
            </mx:VBox>
        </mx:Component>
    </mx:itemRenderer>
</mx:TileList>

完成!!

セーブしたらメニューより[実行]→[FlickrRIAを実行]を選択し実行してみよう。 うまくいけば、ブラウザが起動するはずだ。検索ワードを入力して検索ボタンを押せばもちろん取得された画像が表示される。 たった54行のソースコードで、しかも一部分はビジュアルエディタで生成したもので、このような見た目も何となく洗練されたアプリケーションができてしまうのだ。 多種多様なコンポーネントを使いこなしたら、相当色んなことができるのではないだろうか。

カスタムコンポーネントを作成し、サムネイル部分を分割する

画像のサムネイル表示部分を別のファイルに分割する。 どうやらカスタムコンポーネントと呼ぶらしい。 そうすることで管理しやすくなる、かどうかは正直わからないが、別のアプリケーションでその部品を再利用できるようになることは確かだ。

メニューより[ファイル]→[新規]→[MXMLコンポーネント]を選択。以下のパラメータで作成する。

  • ファイル名 「FlickrThumbnail」
  • ベース 「VBox」
  • 幅 「125」
  • 高さ 「125」

ひな型が自動生成されるため、その内部に先ほど作成したVBoxの中身の部分をコピーする。

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="125" height="125">

    <mx:Image width="75" height="75"
        source="{data.thumbnail.url}"/>

    <mx:Text text="{data.credit}"/>
</mx:VBox>

次にFlickrRIA.mxml内のitemRenderer以下のコンポーネントをバッサリ削除する。 そしてTileListのitemRenderer属性でFlickrThumnailを指定することでFlickrThumnail.mxmlが使用される。

<mx:TileList wi dth="100%" height="100%"
    dataProvider="{photoFeed}"
    itemRenderer="FlickrThumbnail">

</mx:TileList>

セーブ後、実行して同じように動作すれば成功。 最後にここまでに作成したソースコードを掲載しておく。

FlickrRIA.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
     backgroundGradientColors="[0xFFFFFF,0xAAAAAA]"
     horizontalAlign="left"
     verticalGap="15" horizontalGap="15" >
    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;

            [Bindable]
            private var photoFeed:ArrayCollection;

            private function requestPhotos():void{
                photoService.cancel();
                var params:Object = new Object();
                params.format = 'rss_200_enc';
                params.tags = searchTerms.text;
                photoService.send(params);
            }

            private function photoHandler(event:ResultEvent):void{
                photoFeed = event.result.rss.channel.item as ArrayCollection;
            }
        ]]>
    </mx:Script>
    <mx:HTTPService id="photoService"
        url="http://api.flickr.com/services/feeds/photos_public.gne"
        result="photoHandler(event)"/>
    <mx:HBox width="100%">
        <mx:Label text="Flickrタグ もしくは検索ワード"/>
        <mx:TextInput id="searchTerms"/>
        <mx:Button label="検索" click="requestPhotos()"/>
    </mx:HBox>
    <mx:TileList width="100%" height="100%"
        dataProvider="{photoFeed}"
        itemRenderer="FlickrThumbnail">

    </mx:TileList>
</mx:Application>

FlickrThumbnail.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="125" height="125">

    <mx:Image width="75" height="75"
        source="{data.thumbnail.url}"/>

    <mx:Text text="{data.credit}"/>
</mx:VBox>

お疲れさんっした!!:hahaha:

Flex Builder 3を使ってAdobeのチュートリアルを試す #3

では続けていこう。 今回と次回で完結する予定だ。

HTTPServiceオブジェクトを作成する

「ソース」タブを選択し、ソースコード上のmx:HBoxの上部に以下の記述を追加する。

<mx:HTTPService id="photoService"
    url="http://api.flickr.com/services/feeds/photos_public.gne"
    result="photoHandler(event)"/>

それぞれの属性値に指定したのは以下のような意味があるはずだ。申し訳ないけど、ここは想像でしかない。 後でこれが間違いだとわかったら修正する。

属性名 意味
id このHTTPServiceオブジェクトを保持する変数名
url 接続するURL
result HTTPリクエストの結果を受け取ったときに実行されるメソッドと引数

この時点で画面はこのようになっているはずだ。

ちなみにphotoHandlerというメソッドはまだ作っていないため、この時点では以下のようなエラーがでているが気にしなくていい。 違うエラーメッセージが出ていたら全力で気にするべきだ。

1180: 未定義である可能性が高いメソッド photoHandler の呼び出しです。 FlickrRIA/src FlickrRIA.mxml 行 8

「bindable XML variable in ActionScript 3.0」を作成する

上手い日本語訳が思いつかない。。バインド可能XML変数?組み込みXML変数?まあそんな雰囲気で。

先ほど記述したHTTPServiceコンポーネントの上にもう一つコンポーネントを追加する。 今度はmx:Scriptというもので、どうやらそのコンポーネント内にActionScriptでプログラムを記述するためのものである。 <mx:Script>と打ち込むとコード補完をしてくれて以下のように一気に記述される。

<mx:Script>
    <![CDATA[

    ]]>
</mx:Script>

プログラムは<![CDATA[]]>の間に記述することになる。 これはXMLにおけるコメントを記載するための仕様なのでFlexに限ったことではない。

まずは以下のように必要なクラスを使用できるようにimport宣言を行う。

<mx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.rpc.events.ResultEvent;

    ]]>
</mx:Script>

次に検索結果を格納する(変数名から想像するに)変数を宣言する。 [Bindable]という宣言を行うことで、その後のコンポーネントで使用可能になるということであろうか。 詳しくはわからないが、そんなことを気にしていては先に進めないので、とりあえず納得したことにする。

<mx:Script>
    <![CDATA[
        import mx.binding.utils.BindingUtils;
        import mx.collections.ArrayCollection;
        import mx.rpc.events.ResultEvent;

        [Bindable]
        private var photoFeed:ArrayCollection;

    ]]>
</mx:Script>

ここまで書くとわかるだろうが、どうやらActionScriptでは変数宣言は以下のようになるみたいだ。

var 変数名:変数の型

検索ボタンのハンドラ作成

引き続きソースコードの編集は続く。 mx:HBox内のmx:Buttonの部分を編集していこう。クリック時のイベントを定義するためにclick属性を追加する。

修正前

<mx:Button label="検索"/>

修正後

<mx:Button label="検索" click="requestPhotos()"/>

これで検索ボタンが押された時にはrequestPhotosというメソッドが実行されるわけだが、このメソッドもまだ実装していないためエラーが出る。

Flickr APIにHTTPリクエストでキーワードを送信する処理の実装

次に検索キーワードを入力するテキストボックスである、mx:TextInputを編集する。 単にidをつけるだけだ。

修正前

<mx:TextInput/>

修正後

<mx:TextInput id="searchTerms"/>

デザインを自分なりに変更してテキストボックスの大きさなどをいじった人はwidth="**"のような属性がある場合もある。 もちろんそれはあっても問題ない。

次に先ほどボタンに定義したハンドラ部分を実装しよう。 mx:Script内に以下のように関数宣言をする。

private function requestPhotos():void{
    photoService.cancel();
    var params:Object = new Object();
    params.format = 'rss_200_enc';
    params.tags = searchTerms.text;
    photoService.send(params);
}

photoServiceというのはmx:HTTPServiceタグのIDである。Flickrとの通信を制御するHTTPServiceオブジェクトだ。 ボタンが何度も押されたときの対策として、最初の行で現在の通信をキャンセルしているようだ。 その後はparamsというObject型変数にformatとtagsというパラメータをセットしている。 tagsの方にテキストボックスに入力されたテキストを代入している。 先ほどテキストボックスにsearchTermsというid属性を追加したのを憶えているだろうか。 また、formatやtagsというのはおそらくFlickr APIが定義しているパラメータなので、ここでは深くは掘り下げない。 tagsというパラメータに検索ワードを入れるという決まりがあるのだろう。

HTTPService 結果取得ハンドラの実装

Flickrから結果が返ってきたときに実行される処理を記述する。 先ほど書いたrequestPhotos()の後に書こう。 関数名はphotoHandlerとする。 HTTPServiceの宣言部に以下の記載があるためだ。 これにより、HTTPServiceオブジェクトは通信結果を取得するとただちにphotoHandler関数を実行する。

result="photoHandler(event)"

photoHandlerの内容は以下の通りだ。

private function photoHandler(event:ResultEvent):void{
    photoFeed = event.result.rss.channel.item as ArrayCollection;
}

Flickrから帰ってきた結果がどのようになっているのかわからないが、ResultEvent型のオブジェクトとして引数のeventに代入される。 そこからコレクションの形でphotoFeedに代入しているようだ。 この辺はFlickr APIやResultEventの仕様がわからなければ詳細はわからない。だから今回は気にしないことにしよう。

学習していく上で大切なことは、今自分が何を学ぼうとしているかを忘れないことだ。 自分が学ぶべき内容と本質的に関係ないものであれば、理解しないまま飛ばしても問題はない。 今回はもちろんFlex Builderの使用法、Flashアプリケーションの作成法を大まかに知ることが重要なので、そちらを優先した。 どうせResultEventの仕様はそのうち嫌でも調べなければいけないことになるだろう。

さて、ここまでのFlickrRIA.mxmlの全体を確認しよう。 足りなかった2つの関数も実装したので今ではエラーもないはずだ。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
     backgroundGradientColors="[0xFFFFFF,0xAAAAAA]"
     horizontalAlign="left"
     verticalGap="15" horizontalGap="15" >
    <mx:Script>
        <![CDATA[
            import mx.binding.utils.BindingUtils;
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;

            [Bindable]
            private var photoFeed:ArrayCollection;

            private function requestPhotos():void{
                photoService.cancel();
                var params:Object = new Object();
                params.format = 'rss_200_enc';
                params.tags = searchTerms.text;
                photoService.send(params);
            }

            private function photoHandler(event:ResultEvent):void{
                photoFeed = event.result.rss.channel.item as ArrayCollection;
            }
        ]]>
    </mx:Script>
    <mx:HTTPService id="photoService"
        url="http://api.flickr.com/services/feeds/photos_public.gne"
        result="photoHandler(event)"/>
    <mx:HBox width="100%">
        <mx:Label text="Flickrタグ もしくは検索ワード"/>
        <mx:TextInput id="searchTerms"/>
        <mx:Button label="検索" click="requestPhotos()"/>
    </mx:HBox>
</mx:Application>

次回、いよいよ完成する。

«前へ || 1 | 2 | 3 | 4 | 5 | 6 || 次へ»

Home > Flash/Flex

Search
Feeds

Page Top