2008年10月アーカイブ

今日はハロウィーンですね。
小学生の時に英会話の塾でハロウィーンパーティーがあって、海賊の仮装をしていたのを思い出しました。

ということで思いつきで作り始めてみたものの、全くダメダメなサンプルになっちゃいましたが、もうハロウィーンになっちゃいましたので公開します。
仕事終わってから数時間で作れるレベルといったらこのくらいになっちゃうかな。。
あちこちから素材集めてこんな感じになりました。。。
6秒毎に動いて、10秒毎に光って、毎時10,20,30,40,50,60分で帽子が降ってきます。
サンプル

今回は全然時計としての用途で使っていませんが、trick7:teraさんのTeraClockを使用させていただきました。

Timer使えよ!というつっこみが入りそうですが、ただ触ってみたかったんです。

で、今回はCastBitmapを使いました。

以下作ったクラス

package myproject{
	import flash.display.BitmapData;
	import jp.progression.casts.*;
	import jp.progression.commands.*;
	import jp.progression.events.*;
	import jp.progression.loader.*;
	import jp.progression.*;
	import jp.progression.scenes.*;
	public class MyCastBitmap extends CastBitmap	{
		/*コンストラクタ*/
		public function MyCastBitmap(bitmapData:BitmapData = null, pixelSnapping:String = "auto", smoothing:Boolean = false, initObject:Object = null) {
			super(bitmapData,pixelSnapping,smoothing,initObject);
		}
		protected override function _onCastAdded():void {
			alpha = 0;
			addCommand(
				// 任意のコマンドを記述してください。
				new DoTweener(this,{alpha:1,time:2})
			);
		}
		protected override function _onCastRemoved():void {
			addCommand(
				// 任意のコマンドを記述してください。
			);
		}
	}
}
使い方はCastSpriteやCastMovieClipと一緒です。_onCastAddedで追加された時の処理を、_onCastRemovedで取り除かれた時の処理を書きます。

以下呼び出し元です。
今回はCastMovieClipの_onCastAddedでビットマップを追加しています。

protected override function _onCastAdded():void {
 	//PumpkinBmdがかぼちゃのビットマップデータ
	_PumpkinBm = new MyCastBitmap(new PumpkinBmd(0,0));
	addCommand(
		// 任意のコマンドを記述してください。
		new Prop(_PumpkinBm, {
			x:_PumpkinBm.width / 2 * ( -1),
			y:_PumpkinBm.height / 2 * ( -1),
			smoothing:true
		}),
		new AddChild(this,_PumpkinBm),
		new Func(function():void {
			_Timer = new Timer(6000);
			_Timer.addEventListener(TimerEvent.TIMER, movePumpkin);
			_Timer.start();
		})
	);
}
通常のビットマップと使い方は全く同じで、ビットマップデータを用意して渡してあげる形になります。

今回のサンプルデータはもっと作りこんでから出します。
ハロウィーンに間に合わせたかったので、中途半端なまま公開となりました。。

flabakaさんのエントリも上がりましたが、Twitterでたまたまyuma_flughafenさんとflabakaさんが北海道出身だという事を知り、東京在住の元北海道民Flasher、ASerで集まりませんかという流れとなったので、早速開催する事となりました。

以下flabakaさんのブログより引用

★参加条件

1. 北海道出身である(必須)
2. 現在、東京近郊にお住まいの方(必須)
3. お仕事or趣味でFlashを使われている方
4. ActionScript好きな方

日時は11月15日(土)夜を予定しております。
参加条件1、2に当てはまる人ならFlashやってなくてもどんどん参加すると良いと思います。(このブログを見ている人は少なくともAcionscriptには興味があると思うので)

参加希望の方はメールでも良いし、Twitterでも良いし、ブログのコメントでも良いので、連絡下さい。
メールはnarayaman(atmark)gmail.comです。

北海道でFLASHerとしてやっていけるのか?ASer向けの勉強会等はあるのか?東京や大坂、名古屋みたいに盛り上げていきたい!等等色々話せるといいなと思っています。


ちなみにこの流れで色々連絡を取り合っていたのですが、yuma_flughafenさんからラーメンサラダは北海道以外ではあまりメニューに載っていないものだという事を初めて知りました。正直驚きました。
大衆居酒屋行ったら必ずあるものだと思ってましたので。

いつぞやの記事で別にフルフラッシュサイトでなくてもProgression使えるよー的な事書きましたが、ちょっとしたサンプル作ってみました。
サンプル

XMLを読み込んで、タイトルを表示し、クリックすると当該URLへジャンプするものです。

後ろの模様は単にperlinNoiseです。
外部からjpgロードして表示しても良いですよね。

一つ一つを別シーンにして一定時間待機させてぐるぐる回してます。ただそれだけ。

今回のポイント?はPropコマンドを使いたいが為にシーンの方でテキスト追加している点ですね。普通はsprite側でテキスト追加するんじゃないかと思います。

var _xmlData:XMLList = new XMLList( this.sceneInfo.data );
var _obj:Object = XMLUtil.xmlToObject( _xmlData );
var _format = new TextFormat();			
_txt = new TextField();
_bannerSprite = new BannerSprite({naviUrl:_obj.naviurl});			
addCommand(
	// 任意のコマンドを記述してください。
	new Prop(_format, {
			size:12,
			color:0xffffff,
			font:"_等幅"
			}),
	new Prop(_txt, {
			mouseEnabled:false,
			text:_obj.title, //タイトルのセット
			wordWrap:true,
			width:230,
			x:10,
			y:10
			}),
	new Func(function():void{_txt.setTextFormat(_format)})
);
このようにソースコードがすっきりします。


もう一つはキャストボタンのhrefプロパティです。これにURL渡すとクリックした際に当該URLに飛ばす事が出来ます。便利!

public function BannerSprite( initObject:Object = null ) {
	super( initObject );			
	_bannerButton = new BannerButton();
	_bannerButton.href = initObject.naviUrl;
			
}
このようにhrefプロパティに値を設定するだけです。


もうひとつあります。
シーン入れ替えの際、前シーンのスプライトの_onCastRemovedと次シーンのスプライトの_onCastAddedを並列動作させたかったのですが、
私は当該スプライトの_onCastRemovedでaddCommandせずに、パラレルリストを作って実行しています。

protected override function _onCastRemoved():void {
	var _pList:ParallelList = new ParallelList();
	_pList.addCommand(
		new DoTweener(this, { alpha:0, time:1 } ),
		new RemoveChild(this,_bannerButton)
	);
	_pList.execute();
}
これで思った通りの動作になります。


前回同様全く屑のようなサンプルですが、プロジェクトファイル一式とりあえずここに置いておきます。
これは徐々にパワーアップさせる予定。

ちなみにこのサンプルは日曜夜10時から絶賛放送中のフララジというラジオ番組を聴きながら作りました。
cellfusion先生のustreamチャンネルで聴く事が出来ます。

みんなも聴くといいと思います。

今回は便利系コマンドシリーズですね。
複数プロパティをいっぺんに指定出来るPropコマンドです。

リファレンスを見れば一発で使い方が分かってしまいますが、あえてエントリ。

私の最初のサンプルの方のソースコードをPropで書き換えてみます。

// ParallelList を作成
var _pList:ParallelList =  new ParallelList();
//ボタンの作成
for ( var i:int = 0; i < numScenes; i++ ) {
	var _xmlData:XMLList = new XMLList( scenes[i].sceneInfo.data );
	var _obj:Object = XMLUtil.xmlToObject( _xmlData );	
	var imageButton:ThumbnailSprite = new ThumbnailSprite();
	imageButton.SetImageUrl = _obj.imageurl;
	imageButton.sceneId = scenes[i].sceneId;
	imageButton.loadImage();
	imageButton.x = ( 110 * i ) + 10;
	imageButton.y = 500;
	_pList.addCommand(
		new AddChild( progression.container, imageButton )
	);
}
最初は以上の様にimageButtonに沢山プロパティを設定していました。

これを以下の様に書き換えます。

var _pList:ParallelList = new ParallelList();
//ボタンの作成
for ( var i:int = 0; i < numScenes; i++ ) {
	var _xmlData:XMLList = new XMLList( scenes[i].sceneInfo.data );
	var _obj:Object = XMLUtil.xmlToObject( _xmlData );				
	var imageButton:ThumbnailSprite = new ThumbnailSprite();		
	var _comProp:Prop = new Prop(imageButton, {
							SetImageUrl:_obj.imageurl,
							x:( 110 * i ) + 10,
							y:500
							});
	_comProp.execute();
	imageButton.sceneId = scenes[i].sceneId;
	imageButton.loadImage();					
	_pList.addCommand(
		new AddChild( progression.container, imageButton )
	);
}

こんな感じになりました。大分すっきりです。
addCommand内で普通に使う場合はnew Prop(~で一発ですみますね。

ここで、ミソなのがボタンのsceneId。
これをPropで設定すると動きませんでした。なので外に出してあります。
何故かはまだ調査していないです。。

initObjectで大量に値を参照したい場合にも使えそうですね。

しかし、このシンタックスハイライター。。アンダーバーが2個目から消えるなあ。。

CastImageLoaderを使ったサンプルファイルアップする宣言を出しておいて出していませんでした。。
前のプロジェクトをいじって変えたものです。

サンプル
(見た目全く同じですが、ちょっと動きが良くなっています)

サンプルのソース

setterの部分をinitObjectから取得するように変えていたりします。
比べてみると、最初のソースはかなり恥ずかしいですね。
今回も恥ずかしい部分は残っていますが。。。(クラス、変数の名前とか酷いです。Traceとかあえて残しちゃっていますし、試行錯誤中のゴミ変数があるかも?)

このサンプル元に色々変えてみたよーという方はご一報いただけるととても嬉しいです。
そういえばプロフィールどころかメールアドレス載せてなかったなあこのブログ。。。

narayaman(atmark)gmail.comです。

少し前の記事で動的なシーンを作成するのに、PRML形式のXMLファイルが必要と書きました。
実はそのPRML形式のXMLファイルを簡単に作れてしまう機能がprogression3には備わっておりました。

それが、主にコンポーネントベース作成時に使用されているシーンエディターです。
実は今までprogression3のシーンエディタを開いた事さえありませんでしたが、ずっと気になっていたので触ってみました。(今更ですが)

するとメニューにこんなのが!
prml_1.jpg

早速以下の様に設定してみます。
prml_2.jpg

そして、名前をつけて保存します。今回はtest_prml.xmlとしました。
prml_3.jpg

すると、以下内容のXMLが出来上がっています。

<?xml version="1.0" encoding="utf-8"?>
<prml version="2.0.0" type="text/prml">
  <scene name="index" cls="myproject.IndexScene" title="index">
    <scene name="image1" cls="myproject.ImageScene" title="index | image1"/>
    <scene name="image2" cls="myproject.ImageScene" title="index | image2"/>
    <scene name="image3" cls="myproject.ImageScene" title="index | image3"/>
  </scene>
</prml>

こんな便利機能があったとは!!
自分の無知さにも程がありますね。

こいつを利用してやればタグ閉じ忘れとか、タイプミスも減りそうです。
ちなみにindexシーンの部分も書き換える事が出来るので、addSceneFromXMLで利用したい時も問題ありません。というかaddSceneFromXMLで利用する用に作られていると思いました。

ちなみにPRMLLoaderで読み込ませたい場合はflabakaというブログを書いていらっしゃるあつのすけさんがPRMLLoaderとaddSceneFromXMLの使い分けという素晴らしいエントリを上げていらっしゃいますので、そちらを参考にすると良いと思います。

2008/10/22追記:
EasyCastingファイルの作成モードだと全く問題ないのですが、PRML作成モードだと、シーンの削除とか、コピーペースト、移動といったメニューが機能しなくなる様です。これはほんのおまけ機能だという理解の方が良さそう。

前エントリーより暫く間が空いてしまいました。。。
今回はCastオブジェクトの中の一つ、CastImageLoaderを使ってみようと思います。

使い方は他のCastオブジェクトと一緒。
今回はCastImageLoaderを継承したサブクラスを作ってみました。
他のと違う所は
_onCastLoadStart、_onCastLoadCompleteで読み込み開始終了の処理が書けるところ

とりあえず以下クラス内容です。

package myproject.loaders 
{
	import jp.progression.casts.*;
	import jp.progression.commands.*;
	import jp.progression.events.*;
	import jp.progression.loader.*;
	import jp.progression.*;
	import jp.progression.scenes.*;
	public class MyLoader extends CastImageLoader 
	{
		//LoaderをAddChildする表示オブジェクト
		private var _container:CastButton;
		//ロード中に表示するCastSprite
		private var _loadImage:LoadImage = new LoadImage();
		/*コンストラクタ*/
		public function MyLoader( initObject:Object = null ) 
		{
			super( initObject );
			_container = initObject.container;
		}
		/*LoaderがRemoveされた時*/
		protected override function _onCastRemoved():void 
		{
			addCommand(
				new RemoveChild(_container, this)
			);
		}
		/*Load開始時*/
		protected override function _onCastLoadStart():void 
		{
			addCommand(
				new AddChild(_container, _loadImage),
				new Func(function ():void{trace("読み込み開始")})
			)
		}
		/*Load完了時*/
		protected override function _onCastLoadComplete():void
		{
			addCommand(
				new RemoveChild(_container, _loadImage),
				new Func(function ():void { trace("読み込み終了") } ),
				new AddChild(_container, this)
			);
		}
	}
}


ポイントは読み込み最中にムービークリップやスプライトを配置したい場合、自身はローダーなので、自分にはロード中表示のSpriteなりをAddChild出来ない点でしょうか?

なので、私はinitObjectで呼び出し元の表示オブジェクト参照してロード中表示のSpriteをAddChildしています。
今回はCastButtonで呼び出したのでソースコードがそのようになっています。
(注:initObjectの話はtrick7さんのブログで拝見し、勉強させていただきました。以前書いたsetterの話はinitObjectでやった方がいいんじゃないかと思います。)

以下呼び出し元(CastButtonの中に書いてます)

public function loadImage():void {
	_ImageLoader = new MyLoader({container:this});
	var _ImageUrlRequest = new URLRequest("thumb/" + _ImageUrl);
	_ImageLoader.load(_ImageUrlRequest);			
}

お気づきの方いらっしゃると思いますが、addEventListenerを一切書いていません。
やっぱり便利だよprogression。
私の以前のサンプルでは結構散在しておりましたが、現在これで書き換えています。書き換え後公開します。たぶん。

正直、フルフラッシュサイトだけでなくて、普通のバナーサイズの案件でも十分使えます。

まだまだ勉強不足ですが、失敗しながらもどんどんやっていこうと思います。

つい最近addSceneFromXMLでXMLからシーン作成というエントリを書いたのですが、早くもprogressionフレームワークの生みの親nium先生から添削が入りました!!すごい!

お忙しい身なのに本当に申し訳ないです。。。

で、添削内容を見てみます。

私の最初のコードはXMLを読み出すのに普通にURLLoaderを使用していたのですが、progressionにLoadURLというコマンドクラスがありまして、そちらを使用されておりました。
LoadURLはファイルを読み込ませるのに使用します。

これを使用する事ですごくスマートな記述が出来るようになります。
添削該当箇所は以下になります。

protected override function _onLoad():void {
	// 実行したいコマンドを登録します。
	addCommand(
		//LoadURLコマンドの登録
		new LoadURL( new URLRequest( "scenedata.xml" ) ),
		function():void {
			// PRML データからシーン構造を作成
			//this.latestDataでLoadURLコマンドで取得したデータを参照
			addSceneFromXML( new XML( this.latestData ) );
			// ParallelList を作成
			var _pList:ParallelList =  new ParallelList();
			//ボタンの作成
			for ( var i:int = 0; i < numScenes; i++ ) {
				var _xmlData:XMLList = new XMLList( scenes[i].sceneInfo.data );
				var _obj:Object = XMLUtil.xmlToObject( _xmlData );	
				var imageButton:ThumbnailSprite = new ThumbnailSprite();
				imageButton.SetImageUrl = _obj.imageurl;
				imageButton.sceneId = scenes[i].sceneId;
				imageButton.loadImage();
				imageButton.x = ( 110 * i ) + 10;
				imageButton.y = 500;
				_pList.addCommand(
					new AddChild( progression.container, imageButton )
				);
			}		
			this.parent.insertCommand(
				_pList,
				new Goto( scenes[0].sceneId )
			);
		}
	);
}

そもそもコマンドクラスのlatestData の存在を知らなかった。。。
リファレンスには

CommandList 上で、自身より前に実行された外部データ読み込み系のコマンドが持っている外部データを取得します。

と書いてあります。

全然把握しきれてませんね私。。。
とりあえずaddEventListenerを使う前にコマンドで出来ないか調べるという事が重要と思いました。

という事で修正後プロジェクトを置いておきます。

Progresson3ですが、本体の他にも便利クラスが搭載されています。
その中でも使用頻度の高そうなのが、XMLListのオブジェクト表現を返してくれるXMLUtilクラスです。

前回エントリのサンプルで使用したXMLを見ていただくと分かるのですが、シーンの情報を記述してある部分はrootノードが無い為、このままXMLとしては扱えません。
なのでXMLListとして扱う事となります。
この辺の違いはXMLListで検索するとザクザク出てきますのでそちらを参考にして下さい。

前回サンプルのシーンの情報XMLLIst

     <caption>imageその1</caption>
     <imageurl>image1.jpg</imageurl>

前回サンプルのIndexScene内のボタンを作成している所で以下の様に使用しています。

//ボタンの作成
for (var i:int = 0; i < this.numScenes; i++) {
     //XMLListとしてシーンの情報を取得
    var _xmlData:XMLList = new XMLList(this.scenes[i].sceneInfo.data);
    //XMLUtil.xmlToObjectを使用
    var _obj:Object = XMLUtil.xmlToObject(_xmlData);	
    var imageButton:ThumbnailSprite = new ThumbnailSprite;
    //imageurlの値を取得
    imageButton.SetImageUrl = _obj.imageurl;
    imageButton.sceneId = this.scenes[i].sceneId;
    imageButton.loadImage();						
    省略				
}

このようにXMLListをオブジェクトとして扱う事が出来ます。

このエントリですが、実は1週間くらい暖めちゃってました。
なんか考えがまとまらないまま忙しくなっちゃいまして。

このままだとどうにもならんなと思ったので勢いでサンプル作って公開します。

とりあえずサンプル見てもらって。。。

デザインは全く考えないで作ったのでそのへんは勘弁してもらうとして、
今回はprogressionフレームワークのaddSceneFromXMLです。

これはXMLファイルからシーン構造を作れてしまうというシロモノで、ギャラリーサイトとかスライドショーとかの作成に大活躍間違い無しの超便利メソッドです。
今回のサンプルはこれで作っています。5シーンあるんですが、自分で作ったクラスファイルは3つです。

まず、用意するXMLですが、
上記サンプルのXMLはこんな感じになってます。

<?xml version="1.0" encoding="UTF-8" ?>
<prml version="2.0.0" type="text/prml">
    <scene name="image1" cls="myproject.ImageScene">
        <caption>imageその1</caption>
        <imageurl>image1.jpg</imageurl>
    </scene>
    <scene name="image2" cls="myproject.ImageScene">
        <caption>imageその2</caption>
        <imageurl>image2.jpg</imageurl>
    </scene>
    <scene name="image3" cls="myproject.ImageScene">
        <caption>imageその3</caption>
        <imageurl>image3.jpg</imageurl>
    </scene>
    <scene name="image4" cls="myproject.ImageScene">
        <caption>imageその4</caption>
        <imageurl>image4.jpg</imageurl>
    </scene>
    <scene name="image5" cls="myproject.ImageScene">
        <caption>imageその5</caption>
        <imageurl>image5.jpg</imageurl>
    </scene>
</prml>

上記のようなprml形式のXMLを用意する事により、動的なシーン作成が可能となります。
sceneタグのnameがシーン名となります。
上記サンプルではclsでクラスを指定していますが、これは自分でシーンのクラスを指定したい時に設定します。
sceneクラスの要素(captionとかimageurl)はシーンオブジェクト.sceneInfo.dataで取得出来ます。

このXMLをシーンを追加したい場面で読み込みます。
今回はいきなりIndexシーンでシーン追加してシーン1に飛ばすという事をしていますのでIndexシーンに以下記述

protected override function _onLoad():void {
    //xml読み込み
    var _XMLLoader:URLLoader = new URLLoader(new URLRequest("scenedata.xml"));			
    _XMLLoader.addEventListener(Event.COMPLETE, xmlLoadComp);
}
private function xmlLoadComp(e:Event):void {
    var _xmlLoader :URLLoader = URLLoader(e.target);
    var _xmlString:XML = new XML(_xmlLoader.data);	
    //シーン構造を作成
    progression.root.addSceneFromXML(_xmlString);
    //サンプルはここでパラレルリスト作ってます
    //ボタンの作成
    for (var i:int = 0; i < this.numScenes; i++) {
    省略
    }
    //最初のシーンへいきなり移動
    progression.goto(this.scenes[0].sceneId);
}

これでOK。
上記サンプルではシーンオブジェクト.numScenesも使用しています。これは当該シーンの子シーンの数を取得する時に使用します。詳細はドキュメント参照して下さい(←逃げ)

実は今回サンプルの場合、progressionインスタンスを丸ごと作成してくれるPRMLLoaderの方を使用した方がスマートなんですが、こっちの方が自分的には実用度が高いので、サンプル作ってみました。

このサンプル作るのに1時間くらいかな(色々ドキュメント読みながらだし)。むしろエントリ書く方が時間がかかるという。。。

サンプルのソースをプロジェクトごと置いておきます。
ロードの処理とか全く書いてないし、そのままでは全く使い物になりませんが、この前エントリしたCastSpriteで包んだCastButtonとか入ってますので色々と参考になれば。。
むしろ添削してもらいたい!!

これでいいのか?っていう書き方も満載ですし。。。
あと無駄にCastLoaderとかも使ってます。。。ロード処理書いてないのに。

このアーカイブについて

このページには、2008年10月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2008年9月です。

次のアーカイブは2008年11月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。