Progression 4.0.1 Public Beta 1.3でのPRMLLoader

僕はProgression3からPRMLLoaderを使ってシーン構成を生成することが多いいのですが、Progression4になって仕様が変わり、こちらのブログを参考にさせて頂いて使っていたのですが、Public Beta 1.3になってどうもディープリンクが上手く作動していないことに気付く。Public Beta 1.2までは大丈夫だったとにと思い、twitterでつぶやいてみると、nium先生からご教示が!!

結論から言うと、PRMLLoaderには、autoGotoというプロパティーがあって、デフォルトでtrueとなっているので、PRMLLoaderで読んだprml.xmlに自動的に移動する→そのあとディープリンクのシーンに移動するという処理になるようで、IndexSceneのatSceneDescend()を通らずに、自動遷移するatSceneInit()を通るとのこと。今までの認識で書いて2重に書いていたみたい。

_prml.autoGoto = false;

としたら無事直りました。nium先生ありがとうございます。
とりいそぎcreateFromXMLを使ってシーン構成を生成したんやけど、PRMLLoader、createFromXML、addSceneFromXMLの使い分けがまだよくわかっておらず。flabakaさんの「PRMLLoaderとaddSceneFromXMLの使い分け」に書かれているように、「一気に全シーンを作成したい場合はPRMLLoader。任意の(シーンの)子シーンを作成したい場合は、addSceneFromXMLを使うのかな? と個人的に思っています。」ということみたいですけど。そうなるとcreateFromXMLはどうなんでしょ?すごい人誰か教えてくださいw。
あっコメントは最近スパムが多くなったので切っちゃったのでtwitterなりなんなりで出来たらお願いします(__)いいかげんこのブログもデザインしなければと思いつつ。。。

僕はProgression4でもPRMLLoaderを使っていこうかと思っているのですが、せっかくcreateFromXMLも使ってみたので、汚いソースですが晒しておきます。正しい使い方かどうかもわかりませぬが;

package michinoko {
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import jp.progression.Progression;

	import jp.progression.casts.*;
	import jp.progression.commands.display.*;
	import jp.progression.commands.lists.*;
	import jp.progression.commands.net.*;
	import jp.progression.commands.tweens.*;
	import jp.progression.commands.*;
	import jp.progression.config.*;
	import jp.progression.data.*;
	import jp.progression.debug.*;
	import jp.progression.events.*;
	import jp.progression.scenes.*;

	import michinoko.scenes.*;

	/**
	 * ...
	 * @author michinoko
	 * @see http://blog.inasiantime.com/
	 * @email michinoko[a]inasiantime.com
	 * @version 1.0.0
	 * @date created 2010.01.29
	 *	createFromXMLを用いてシーン構造を読み込む
	*/
	public class Index extends CastDocument {
		//PRMLで使うシーンクラスを宣言
		IndexScene;
        TestScene;

		private var _xmlLoader:URLLoader;
		public function Index() {
			// 自動的に作成される Progression インスタンスの初期設定を行います。
			// 生成されたインスタンスにアクセスする場合には manager プロパティを参照してください。
			super( null, null, new WebConfig() );
		}

		/**
		 * SWF ファイルの読み込みが完了し、stage 及び loaderInfo にアクセス可能になった場合に送出されます。
		 */
		override protected function atReady():void {
        	//PRML形式のxmlを読み込む
			_xmlLoader = new URLLoader();
			_xmlLoader.addEventListener(Event.COMPLETE, onXMLloaded);
			var urlReq:URLRequest = new URLRequest("xml/myscene.xml");
			_xmlLoader.load(urlReq);
		}
		//xmlを読み込んだらcreateFromXMLを使いシーン構造を生成して遷移
		private function onXMLloaded(e:Event):void {
			var xmlObj:XML = new XML(_xmlLoader.data);
			var manager:Progression = Progression.createFromXML(stage, xmlObj);
			manager.sync = true;
			manager.goto(manager.syncedSceneId);

		}
	}
}

getResourceByIdとgetResourcesByGroup

progression4もPublic Beta 1.3になって、またBeta 1.2でokやったのが、NGになってたり色々と仕様が変わりつつあるけど、とりあえずprogression4の新機能Resourceを使ってみました。カヤックさんの「Progression4の新機能Resourceを試してみる」などを参考に。

ついでにPreloadSWFも試してみたかったので、ロード処理はPreloader.asに書く。

//Preloader.asのatCastLoadStart()内、ex外部画像(img/gaibu1.png~img/gaibu5.png)の5枚を読み込む場合
var _loadCmd:LoadCommand;
for (var i:int = 1; i <= 5; i++) {
	_loadCmd = new LoadBitmapData(new URLRequest("img/gaibu" + i.toString() + ".png"), { cacheAsResource:true, context:new LoaderContext(true), group:"myGroup", id:"myId"+i.toString() } ),
	_preLoaderList.addCommand(_loadCmd);	//これは全体のLoaderList
}

これを、IndexSceneで呼び出す。

//IndexScene.asのatSceneLoad()内
trace("読み込んだ画像をidで呼び出す:", getResourceById("myId1"));
trace("読み込んだ画像をグループごと呼び出す:", getResourcesByGroup("myGroup"));

すると、どちらも読み込めない。getResourceById("img/gaibu1.png")とすると読めるので、設定が出来てない模様。

よくよくドキュメントをみると、呼び出しは、getResourceById、getResourcesByGroupやけど、設定するときは、resId、resGroupで設定とする。というわけで、

//Preloader.asのatCastLoadStart()内、ex外部画像(img/gaibu1.png~img/gaibu5.png)の5枚を読み込む場合
var _loadCmd:LoadCommand;
for (var i:int = 1; i <= 5; i++) {
	_loadCmd = new LoadBitmapData(new URLRequest("img/gaibu" + i.toString() + ".png"), { cacheAsResource:true, context:new LoaderContext(true), resGroup:"myGroup", resId:"myId"+i.toString() } ),
	_preLoaderList.addCommand(_loadCmd);	//これは全体のLoaderList
}

で、めでたしめでたしと。

HAPPY2010とFlashDevelopでの宣言

今年もよろしくお願いいたします。
って、もう1月もあと10日で終わりですが、なかなか更新してなくてスミマセン。

前に書いたつもりでいて書き忘れていたので、自分用にもすぐ忘れてしまうので、メモ。
FlashDevelopを僕は使っているのですが、NewClassを追加すると、

package  {

	/**
	 * ...
	 * @author michinoko
	 */
	public class NewClass {

		public function NewClass() {

		}

	}

}

みたいになりますよね?僕もしばらくそのまま使っていたのですが、バージョン管理や日付なども必要だなと思っていたらやはりありました。Custom Arguments。詳しくはflabakaさんのエントリーに書いているのですが、FlashDevelopのToolからCustomArgumentsで設定ができます。ただここはあくまで定数を入れるので、日付は別途テンプレートに直で書きます。

同じく、ToolsからApplicationFiles…を選ぶとエクスプローラが立ち上がります。そこで、Templatesから設定したいテンプレートファイルへアクセス。僕の場合だと、「C:\Users\michinoko\AppData\Local\FlashDevelop\Templates\ProjectFiles\AS3Project/Class.as.fdt」(win vista 64bit)です。このファイルをダブルクリックで、

package $(Package) $(CSLB){

	/**
	$(CBI)* ...
	$(CBI)* @author $(DefaultUser)
	$(CBI)* @see $(See)
	$(CBI)* @email $(EMail)
	$(CBI)* @version $(Version)
	$(CBI)* @date created $$(#DateTime#=yyyy.MM.dd)
	$(CBI)*
	*/
	public class $(FileName) $(CSLB){

		public function $(FileName)() $(CSLB){
			$(EntryPoint)
		}

	}

}

のようにすると、

package  {

	/**
	 * ...
	 * @author michinoko
	 * @see http://blog.inasiantime.com/
	 * @email michinoko[a]inasiantime.com
	 * @version 1.0.0
	 * @date created 2010.01.21
	 *
	*/
	public class NewClass {

		public function NewClass() {

		}

	}

}

のようになります。もちろんセットしたい項目をCustomArgumentsで設定するのが先です。ついでに、Stardustのテンプレートも入れておこう。まだ試してないけど。

progression4 タイムライン上のroot

やっとこさprogression4を触りだし、来週くらいには会社HPの実績に作ったprogression4のサイトがアップされるはず。。。触った感触としては3よりも全然早い!

で、へなちょこFlasherの僕としてはタイムライン上にmcなどを置いて確認したり、各シーンからアクセスしたりもするんやけど、progression3のときCastDocument.root.instanceNameでアクセスしていたような気がするけどprogression4では使えない。。。んー?とちょっと詰まるも結論から言えば、MovieClip(CastDocument.root).instanceNameでアクセスできる。

そういや、parentを使うときも、parent.gotoAndPlay();でなく、MovieClip(parent).gotoAndPlay();とするなぁと納得。

ちなみに今回のは、PRMLLoaderを使って動的にシーンを作成して、各シーンは子swfをprogressionでなく普通のflaファイルで作成してみました。いつもprogression3でやっていたカタチがprogression4でもできたので、ひとまず上出来かなと。
LoadSWF関連はoshige先生の「さらにLoadSWF()が続く」を参考にさせていただきました。本当にいつもお世話になってます(__)。

あれprogression3のときって、_mc = MovieClip( MovieClip( CastDocument.root ).getChildByName( “instanceName” ) );でアクセスしていたような気もする。。。テストやモック以外ではタイムライン上のmcにアクセスすることがなくなっているのであやしめ。

>>2010.02.03追記
通常の場合は、MovieClip( CastDocument.root )でよいみたいやけど、SceneLoaderを使っている場合は、CastDocumentが変わるので、MovieClip(container)のほうが無難ぽい。

「Spark67 Deep Edge ActionScript Libraries」メモ

先週ですが、「Spark67 Deep Edge ActionScript Libraries」で勉強してきました。

とりあえずメモのまとめ。ちゅうかめちゃめちゃ丁寧なフォローアップメールが来たのでそこからも一部抜粋。さすがお金を払っているだけはある。セミナー聞くだけでも十分もとはとった感じやねんけど。。。
■Session1:JavaScript なんて怖くねぇぜ!SWFWheel から紐解く Flasher のための JS の歩き方(HIGEさん
>>FlasherがJavaScriptを歩くために
・asとjsとのやりとり、、、
→navigateToURL:とりあえず手軽、ローカルでテストできる。
→ExternalInterface:色々使えるけど、セキュリティサンドボックスとの戦い。ローカルでは動かない。
→ExternalInterface.available:ExternalInterfaceがサポートされているかチェックするけど、セキュリティサンドボックスまでは加味しません。
→ExternalInterface.objectID:IEならobject属性、それ以外ならembedタグのname属性を返すが、objectタグであってもname属性を返してしまう。
・ちなみにallowScriptAccessは、asからjsを呼ぶときの設定なので、jsからasには関係ない。
→jsで設定する。
・Security.allowDomainがjsからasを呼ぶときの設定。Security.allowInsecureDomainでドメインを指定する。アスタリスクも使えるけど、全て許可しちゃうので注意。
→asで設定する。
・無駄に徹夜しないために
→id属性には”external~”を決め打ちする。
→動きが怪しい時は非同期処理にしてみる。(setTimeoutやsetInterval)
>>SWFWheelから得たノウハウ
・ブラウザはどのobjectタグを見るか?
→SafariやIEは外側のobjectタグ、Gecko系は内側のobjectタグ
→つまりは、、、外側にはid, name、内側にはname属性。
・JavaScriptを埋め込むと挙動が変わる
→Gecko系のブラウザ保護機能が働く、XPCNativeWrapperなオブジェクトが出てくる。

■Session2:BetweenAS3 にみるライブラリ設計と最適化(新藤さん
>>設計編
・”小さなクラス” 重要
・クラスの責務 (役割, 責任を負う範囲) をできるだけ絞る
・他のクラスもできるだけ知らなくて良いようにする
・良いライブラリは簡単に使える
・きちんとした名前をつける(何をするものかすぐ分かる/副作用が分かる/一般的な命名規則に沿っている/組み合わせで使うものが分かる/true を返すときが何を表すのか分かる (isPlaying, contains))
・よい設計のために(コードを読む, デザインパターンを知っておく)
>>最適化について
・必ず読んでおくGSkinner先生(http://gskinner.com/talks/
・厳密に型指定することによりハッシュ検索がなくなる
→具体的に言うと、

objA:MyClass;	//早い
objB:Object;	//遅い
objC:*;			//遅い
objD;			//遅い

ということ。
・ループの最適化

do {
	obj.update();
}while((obj=obj.next)!=null) {
	obj.update();
}

のほうがforより早いとか。まだ試してない。。。
・不要なイベントは発行しない。
・ビットフラグで、1文字16進数で管理する。
→新藤さんのブログで勉強しよう。

所感としてはDeepとつくだけあってめちゃめちゃふかーい話。jsの話とかクリティカルなとこもあったので、めちゃ参考。ライブラリの設計はしたことがないけど、oreoreライブラリとかの上で最適化とか勉強になりました。とりあえずビット演算とかはもっかいちゃんと勉強しないとぱっと実用できそうもない。

いやー楽しかった。HIGEさん、新藤さん、そして67WSの加茂雄亮さんありがとうございました(__)
あーあとはこれは試しておきたい。
■URLOpener
http://www.libspark.org/wiki/ikekou/URLOpener

twitter api

以前にTwitterのrssをフィードするという、普通のrssをphpで読むエントリーを書いたんやけど、今回は会社のサイトにtwitter apiを反映してみました。

まずやりたいこととして、
1.つぶやきの中のURLはやっぱりそのままリンクさせたい。
2.何件かデフォルト表示させて、moreボタンでそのあと何件か表示。
3.フォローしてくれている人の一覧を見せたい。
4.可能ならばそのままフォローできるようにしたい。

結論からいうと、4はペンディング。出来ないことはなさそうやけど、エンドユーザーがログイン中?ログインしてるなら、フォローしている人?してない人?などと、ちょっと大がかりになりそう。ログインしていない人には、ログインして下さいってしなきゃいかんだろうし。。。apiもどんどん進化しているっぽいので、そんときにまた考えるとします。

で、
1.→つぶやきのリンク付きってどっかにありそうなんに探しきれずなんで、rssでも同じ処理すればいけるやん!って言われそうやけど、今回はつぶやきの文字列を取ってきて正規表現を用いてURLを置き換えることに。ただURLはいくつ入ってくるかわからないので、その分無くなるまでループが必要。

2.→最初の10件までとその後の10件とでわけてあげて、単純にjQueryでアニメーション表示。

3.→つぶやきは、「user_timeline」のapiから取ってきたんやけど、こっちは「friends」のapiから取得して並べるだけ。

概要はこんな感じですかね。ソースは晒すほどというか、参考サイトがぎょうさんあるのでそちらでお願いします(整理/解説するのが面倒なだけ)。見たいヒトは言ってもらえればw
ほかにもサイトから投稿できたり、自分のfriendの発言とか自分に対する返信だけとかmentionsとか色々できそうなので、お試しあれ。僕は次はやっぱりFLASH案件で使いたいすねw
ちなみに今日現在(2009.11.19)のtwitter apiの日本語訳最新版はコチラ

「F-site 20091031」行ってきました

ご無沙汰してます。
もう2か月以上ぶりなブログ更新。ちょっとしたメモでもこれから書いていこうかとこそっと心で誓う。

最近はセミナーにもほとんど行けなかったんですが、久々にF-siteに行ってきました。そのメモ。
■demo1「ActionScriptでつくるActionScriptエディター」吉川佳一氏
何を説明するよりも、この2つ。
「 F-siteで紹介したエディタを無理やりWonderflに突っ込んでみた」
「マルチユーザ対応のASエディタ」
もうこれらを見てくれればどんだけ楽しかったか分かって頂けるかなと。

AS変態トークだけでなく、ちゃんとLocalConnectionとかSingletonとかFileReferenceとかの話しも軽くしてたけど、そんなんよりもとても笑わせて頂きました。
エディタについては、AIR化しようかなんて話もしてたんで、macユーザーにとってはかなり重宝するんではないでしょうか。

例えば1000文字の2つの文字列を比較するならば、2の累乗の近い数、1000なら512をビットシフトさせながら一致かどうかをチェックしてって、、、とすると軽い処理で2つの文字列の違いを探せれるなんて話もしてましたが、ほとんど上記リンクの2つのインパクトが強すぎて飛んでしまったw

■demo2「フレームワーク”の”作り方」阿倍貴弘氏
フレームワーク”の”、、、”の”に騙された?ヒトも多かったのでは。Progression4の使い方ではなく作り方の参考のようなdemo。

・フレームワークを作るには
→自分がほしいキモチ
→調子にのせてもらえるカンキョー
→他人に使われるキキカン
→維持をするセキニンカン
が必要。

などなど、ちょっと難しい話w
僕が一番気になったのは、「Progression4のプロジェクトパネルには、自分の普段使っているライブラリなどをパッケージ化できるようになっている。」というとこ。いつもプロジェクトごとに俺俺ライブラリとかコピペしてたので、Progressionファイルを生成するときに一緒にそれもパッケージ化させてプロジェクトを作れるのは素晴らしい!!

■demo3「サイトを作るツールを作るでござる、の巻。」Saqoosha氏
こちらは、さくーしゃさん自らブログでまとめて頂いているので、
「F-site で話したやつのまとめみたいな。」
を見ればすべて。

このあと、nagggさんも「ParameterController と離婚」とクラスを晒してくれているw

久々のセミナーやったけど、やっぱりテンションは上がる!!最近新しいことが全然できてなく、ぼちぼち触っていかないと完全に流れから遅れてしまうキキカン!それにしても今回はめちゃめちゃヒトが多かった。確か300名?二次会も100人超えとったもんなぁ。全然知りあいと話したりできひんかった。相変わらずじゃんけんは勝てずorz。。。

>>2009.11.09追記
F-siteのレポートがアップされてました。

Slidesライブラリにボタンを追加

本来プレゼン用に使うのに非常に便利なSlidesライブラリですが、今回普通のwebページにも使ってみようということで、キーボード操作と同様の動きをボタンを使ってやろうとしてつまづいたメモ。

基本的には、uranodai.slides.sceneにあるMainScene.asとListScene.asに、ボタンを追加してキーボード操作と同じアクションをセットすればええんやけど、実行してみると、途中でSceneIdのエラーになってしまう。

解決法として、ボタンやサムネイルモードになるときの背景(デフォルトでグレイの)をaddChildでなく、addChildAtを使ってaddしてあげれば直った。どうやら、色々動的に足したせいかもしれんけど、なんかかぶってしまうみたい。それで、それぞれのインデックス位置を指定してあげることで解決。

まぁ、僕のへなちょこコードにしか起こらない現象かもしれないけど、一応メモ。

6度目の会社員

今回もFLASHネタでないです;

私事のお知らせですが、このたび8月から6度目の会社員になります。日本社会復帰です。
MONSTER DIVEという会社にお世話になることになりました。
cafegrooveを飛び出して早7ヶ月。色々なとこへ行き、見えてきたものや見えなくなってきたものなど色々あったのですが、そろそろもっかい日本社会に戻らねばと思っていた矢先、
元上司がタイミングよくこの不況下に会社を設立しお声をかけて頂きました。本当に感謝です。

仕事内容は、どベンチャーなだけにFLASHだけとはいかず、前の会社みたく色々やるかと思いますが、まぁそれも経験。ほっとかれるとFLASHしか触らない僕にはそれもアリかなと;FLASHがあくまでメインというとこだけぶれないようにはしないとやけど。そのぶんこのブログにも色々なジャンルのことも書いていけたらと思います。まぁ、基本はFLASHがメインなのは変わらずですが。

そんなわけで、今後もよろしくお願い致します。

Twitterのrssをフィードする

ご無沙汰してます。
エジプト行ったり諸々してたら前回のエントリーより1か月も経ってた;
月日が流れるの早っ!予定では自分のサイトを発表する予定が、デザインだけやりつつもそっから手つかずorz何故かやたらと忙しかった。まぁ気を取り直して、またしても自分のメモ兼用ブログなので、ぼちぼち書いて行けたらええなぁと。

というわけで、作ったけどお蔵入りしたrssを読むphpで引っかかったところ。twitterで、発言ページの右下にある「michinokoのつぶやきのRSSフィード」をphpで読みたかった。

躓いたところは2つ。
・文字化け問題
・タグの重複

めちゃ基本的なとこで躓く。解決として文字化けは、

xml_parser_set_option($parser,XML_OPTION_TARGET_ENCODING,"UTF-8");

を記述。タグ問題は、phpのパーサ関数では子要素のタグも親要素のタグも同じに扱ってしまったので(日付のcreated_atとリンク先のlink)、単純に2回に1回(奇数回のときだけ)表示するようにする。例えば、$data['created_at'][$j*2-1]感じで呼び出してあげる。リンクはtrimをしてhttp://twitter.com/michinoko/statuses/をつけるのも忘れずに。

全然大した事のないコードですが、自分用ということで晒しておきます;余計なとこは無視してください。ちなみに「michinokoのつぶやきのRSSフィード」をクリックすると.rssのページに飛ぶけどそれを.xmlにするとスタイルが関連づけられてない単純なxmlが見えます。

mb_internal_encoding("UTF-8");
function CharacterHandler($parser,$text)
{
	global $buffer;
	$buffer.=$text;
}
function StartHandler($parser,$name,$attrib)
{
	global $itemcnt,$idFlag;
	if($name=="status"){$itemcnt++;}
}
function EndHandler($parser, $name)
{
	global $buffer,$itemcnt,$data,$idNum,$created_atNum;
	mb_detect_encoding($buffer, "UTF-8");
	switch($name){
    case "created_at":
			$created_atNum++;
			$data['created_at'][$created_atNum]=$buffer;
			break;
    case "text":$data['text'][$itemcnt]=$buffer;break;
    case "id":
			$idNum++;
			$data['link'][$idNum]="http://twitter.com/michinoko/statuses/".trim($buffer);
			break;
    default :
      	break;
	}
  	$buffer="";
}
$parser=xml_parser_create();
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,false);
xml_parser_set_option($parser,XML_OPTION_TARGET_ENCODING,"UTF-8");
xml_set_element_handler($parser,"StartHandler","EndHandler");
xml_set_character_data_handler($parser,"CharacterHandler");
$fp = fopen("http://twitter.com/statuses/user_timeline/16305324.xml",'r');
while($strbuf=fread($fp,3000)){
	xml_parse($parser,$strbuf,feof($fp));
}
fclose($fp);
xml_parser_free($parser);
for($j=1;$j<=$itemcnt;$j++){
	echo "<hr>{$data['created_at'][$j*2-1]}<br>";
	echo "<hr>{$data['text'][$j]}<br>";
	echo "<hr>{$data['link'][$j*2-1]}<br><br>";
}

次回こそFLASHネタを書くか。