<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>きんくまデザイン</title>
	<atom:link href="http://119.245.215.115/feed" rel="self" type="application/rss+xml" />
	<link>http://119.245.215.115</link>
	<description>クライアント系プログラムとイラスト制作</description>
	<lastBuildDate>Wed, 03 Mar 2010 14:23:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>[AIR] NativeWindowを仮想デスクトップ一杯に表示しようとしたらタスクバーの上に重なった件</title>
		<link>http://119.245.215.115/blog/2010-03-03/1645</link>
		<comments>http://119.245.215.115/blog/2010-03-03/1645#comments</comments>
		<pubDate>Wed, 03 Mar 2010 14:23:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-Flash]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-アプリケーション]]></category>
		<category><![CDATA[1-日記]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1645</guid>
		<description><![CDATA[こんにちは。きんくまです。
またAIRメモです。
NativeWindowを仮想デスクトップ一杯にして、そのステージ上をキャラが動きまわれるようにしたかったんです。
それで、デュアルモニターなんかを考慮した仮想デスクトッ [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。<br />
またAIRメモです。</p>
<p>NativeWindowを仮想デスクトップ一杯にして、そのステージ上をキャラが動きまわれるようにしたかったんです。<br />
それで、デュアルモニターなんかを考慮した仮想デスクトップの計算方法が書いてあり、そこまでは大喜び！</p>
<p><a href="http://www.adobe.com/jp/devnet/air/flash/quickstart/screens_virtual_desktop.html" target="_blank">> 仮想デスクトップのサイズ計算</a></p>
<p>これすごいですよ。あるモニタ（Screen）の横にさらにモニタがあるかどうかの判定方法なんかも書いてあっておお！みたいな。<br />
まあ、そこまではいいです。<br />
問題は、これを参考に</p>
<pre class="brush:as3">
		private function setStageSettings():void
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			var virtualRect:Rectangle = computeVirtualBounds(Screen.screens);
			stage.nativeWindow.width = virtualRect.width;
			stage.nativeWindow.height = virtualRect.height;
			stage.nativeWindow.x = 0;
			stage.nativeWindow.y = 0;
		}

		private function computeVirtualBounds(screens:Array):Rectangle{
			var bounds:Rectangle = new Rectangle();
			for each (var screen:Screen in screens){
				if(bounds.left > screen.bounds.left){bounds.left = screen.bounds.left;}
				if(bounds.right < screen.bounds.right){bounds.right = screen.bounds.right;}
				if(bounds.top > screen.bounds.top){bounds.top = screen.bounds.top;}
				if(bounds.bottom < screen.bounds.bottom){bounds.bottom = screen.bounds.bottom;}
			}
			return bounds;
		}
</pre>
<p>とかやってみたんですよ。そしたらWin7のOSのタスクバー（アプリきりかえられる部分）の上にNativeWindowがのっかる！！！<br />
通常はAIRに限らずどんなアプリでもタスクバーの下というか裏側にくるんですが、それがなぜか表側にきちゃって<br />
操作ができなくなっちゃうんですよ！</p>
<p>それでですね、ネットとか公式サイトとか説明書とか探したんだけど結局わからず、<br />
自分で地道に調べた結果やっとわかった結論としては<br />
・ある一定の大きさ以上の幅・高さである（少なくとも１画面分以上）<br />
・nativeWindowのx=0,y=0である<br />
っていう２つの条件がそろうとダメっぽい。なんだそりゃ、そんなのわかんないよー。</p>
<p>なので、幅と高さを仮想デスクトップからそれぞれ2pxずつひいて、<br />
x=1,y=1とかやったら大丈夫になりました。</p>
<p>この挙動すごーくあやしいので、ひょっとしたら私の端末だけかもしれないです。<br />
一応書いておくと Win7 64bit proffesional です。<br />
特にGPUを使うとかそういうことはしてません。なんなんだろー。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-03-03/1645/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[AIR] ファイルの非同期読み取りメモ</title>
		<link>http://119.245.215.115/blog/2010-03-02/1640</link>
		<comments>http://119.245.215.115/blog/2010-03-02/1640#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:47:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-ActionScript3]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-プログラミング]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1640</guid>
		<description><![CDATA[表題の件です。
同期処理の方の読み取りは比較的スムーズにできたのですが、
非同期処理で同じようにしようと思ったら全くできなかったのでメモです。

>> 読み取りバッファと FileStream オブジェクトの bytes [...]]]></description>
			<content:encoded><![CDATA[<p>表題の件です。</p>
<p>同期処理の方の読み取りは比較的スムーズにできたのですが、<br />
非同期処理で同じようにしようと思ったら全くできなかったのでメモです。</p>
<p><a href="http://help.adobe.com/ja_JP/AIR/1.1/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7dac.html" target="_blank"><br />
>> 読み取りバッファと FileStream オブジェクトの bytesAvailable プロパティ </a></p>
<p>なんか、まとめると<br />
・同期処理中はファイルのすべてのバイトが読み取り可能<br />
・非同期処理中はprogress イベント中に全バイトの一部のみが可能。progressイベントがすすむと一度たくわえられたバイトは削除されて、次の範囲のバイト列を読み取れるようになる。</p>
<p>って感じでしょうかね。<br />
今調べてるのは、短いテキストファイルの読み書きをしようと思ってるだけなので、今回は同期処理でやってしまおうと思いますけど、重いデータとか扱うときは非同期処理になると思うので面倒くさそうだなー。</p>
<h3>Win7のFile.applicationStorageDirectoryのありか</h3>
<p>Macは調べてないです。すみません。<br />
C:\Users\{ ユーザー名 }\AppData\Roaming\com.adobe.example.Hoge\Local Store<br />
みたいなところ。</p>
<p>AIRのいけないところはアンインストールしてもここのデータは残りっぱなしだってことかな。</p>
<p>あと、絶対にインストーラー通さないとアプリとして実行できないところ。<br />
Flashってお遊びアプリみたいの作るのと相性がいいから、絶対にインストーラー通さないといけないのって<br />
ツラいところだと思う。お手軽感がないっていうか。</p>
<p>例えば、スロットアプリを作ったとしても、それを落としてわざわざインストーラー通してまでやりたいかって<br />
いうとそうじゃない気がしてる。こういう小ぶりなのって試して気に入ったら遊ぶけど、そんなでもなければすぐ消しちゃうだろうし。</p>
<p>Cとかで作られてるフリーアプリとかってレジストリとかいじらない気軽なものが多いし。<br />
セキュリティの関係でなんかあると一気にアドビに裁判で賠償請求とか出されちゃうのを懸念してなのかな？<br />
そんなこと本当に起こるのかな。どうなんでしょ。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-03-02/1640/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>オリンピック見た。ビフォー・アフターは水戸黄門</title>
		<link>http://119.245.215.115/blog/2010-03-02/1631</link>
		<comments>http://119.245.215.115/blog/2010-03-02/1631#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:21:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-日記]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1631</guid>
		<description><![CDATA[こんにちは。きんくまです。
テレビネタです。
オリンピック
仕事の合間にちょろちょろと見てました。
オリンピックは４年に一度だからドラマがあると思いました。あれ、毎年開催してたら全然別物でしたよね。
ありがたみも全然違う [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。<br />
テレビネタです。</p>
<h3>オリンピック</h3>
<p>仕事の合間にちょろちょろと見てました。</p>
<p>オリンピックは４年に一度だからドラマがあると思いました。あれ、毎年開催してたら全然別物でしたよね。<br />
ありがたみも全然違うっていうか、４年間貯めに貯めたパワーをうわっ！と出すっていうか。<br />
スポーツ選手の現役時代ってすごく短くて、だいたい３０代ぐらいまでだと思うので、<br />
オリンピックに出られる回数も本当に少ないんだと思います。<br />
なんで４年に１度にしたんだろ？そういやワールドカップも４年に１度だし。なんかあるのかな？<br />
うるう年？？？？？謎です。</p>
<p>フィギアも面白かったです。で、やっぱりトップ２の戦いは本当にすごくて、いろいろ肩にかかってくる<br />
ものもあったと思ったのですが、それにおしつぶされずに力を出せたのはすごいと思いました。</p>
<p>浅田さんは、ちと出し切れない部分もあったかもしれないですけど、あれは周りとのプレッシャーじゃなくて<br />
自分とのプレッシャーの中でのことのような気がしています。違うかもしれんけど。</p>
<p>それと、どうでもいいんですけど、国際スケート連盟会長の名前が<br />
<a href="http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%83%E3%82%BF%E3%83%93%E3%82%AA%E3%83%BB%E3%83%81%E3%83%B3%E3%82%AF%E3%82%A2%E3%83%B3%E3%82%BF" target="_blank">オッタビオ・チンクアンタ</a>会長<br />
だってことを知ったことが一番の収穫です。なんかマンガに出てきそうな名前ですよね。<br />
すみません。本当どうでもいいですね。<br />
前のサマランチ会長とかもいい名前だったし。あ、会長の名前はもういいですね。</p>
<h3>ビフォー・アフター</h3>
<p>テレ朝系のリフォーム番組です。</p>
<p>あれ、いつも思うんですけど、基礎は必ず残すんですよね。どんなにへばってても。補強して再利用。<br />
やっぱり基礎を壊してさら地にするのは番組的にダメなんですかね。<br />
絶対にリフォームじゃないとダメなのかな。<br />
それとも基礎って結構高いのかな。</p>
<p>あと、気になるところは、どこまで依頼者と匠の間で施工前に打ち合わせが行われているかということ。<br />
依頼者が最後リフォーム完了後に、普通に驚いているところを見ると、</p>
<p>・依頼者と匠の間で何度か打ち合わせ、リフォームの方向性を確認<br />
・子ネタ（組みあわせ箱系）などは教えない<br />
・細かい設計図や仕様は見せない。（ここが微妙なところで基本設計図までは見ている気がする）<br />
・基本、施工中の建物の見学はしない（中には見に来る場合もアリ）</p>
<p>ってところでしょうかね。金額が金額なだけに、番組とはいえども後からトラブルにならないように<br />
することを考えると、やっぱり設計図までは見せているのかもなあ。</p>
<p>で、人気の秘密なんですが、コンセプトは「水戸黄門」なんだと思うんです。</p>
<p>・住まいのことで困っている家族がいる。<br />
・匠登場<br />
・匠の技術やアイデアを使い、見事に住まいが再生<br />
・家族大喜び<br />
・一件落着。めでたしめでたし</p>
<p>水戸黄門と同じように、毎回必ず最後は困っていた家族が「ありがとうございます！」と笑顔で匠に感謝した後、<br />
新しい住まいで新しい日々を迎える。という安心感。<br />
匠側にたつ人からみると、家族から感謝され「やったー」<br />
家族側にたつ人からみると、新しい住まいで新しい生活「やったー」<br />
みたいな。大いなるマンネリ（決して悪い意味じゃないです）安心感。</p>
<p>それで、ここも重要なんですけど、一般の人が人生のうちで家を建てたりリフォームすることなんてほんの数回あるかないか。だからこそ、希少価値があります。<br />
で、そんな他人のリフォームなんかを、ビタ一文払わず（ここ重要！）に娯楽として楽しめる。<br />
ってところが良いんでしょうかね。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-03-02/1631/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>フリーランス3年目の壁</title>
		<link>http://119.245.215.115/blog/2010-02-24/1624</link>
		<comments>http://119.245.215.115/blog/2010-02-24/1624#comments</comments>
		<pubDate>Wed, 24 Feb 2010 08:49:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-日記]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1624</guid>
		<description><![CDATA[こんにちは。きんくまです。
なんと、来週から３月ですね。期末ですね。
なんとか、期末のお仕事をいくつかいただいて、慣れないながらもいろいろとやらせてもらってます。
仕様書書いたり、AIRについて調べたり。
仕様書は実装前 [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。<br />
なんと、来週から３月ですね。期末ですね。<br />
なんとか、期末のお仕事をいくつかいただいて、慣れないながらもいろいろとやらせてもらってます。<br />
仕様書書いたり、AIRについて調べたり。<br />
仕様書は実装前に、頭の中で流れをシュミレートしながら書いていくので難しいですね。<br />
本当慣れないです。</p>
<p>さて、今回はフリーランス３年目の壁というお話です。<br />
私は独立してからおかげさまで今月で２年２ヶ月となりました。なので、ちょうど３年目にあたります。<br />
独立したばかりのころ、以前お世話になった専門の先生（教科書とか幼児向け雑誌なんかのイラストを書かれていて、スタッフを3人ほど雇い、その道うん十年という方）とお話することがありまして。<br />
話をまとめると</p>
<p>・フリーランスとして独立してきた人を何人も見てきた（業界的に多いですよね）<br />
・だけど、3年もつ人は少ない<br />
・3年もてばあとはなんとかなる（たぶん基盤みたいなものができるんでしょう）<br />
・1年目２年目は勢いがあるので、仕事は意外ととれる。だけどその後が続かない。<br />
・儲かると思ってそっちの方ばかり目を向けていると、儲かる仕事はそれっきりなことが多い<br />
・だから儲からない仕事も大事にした方がよい。終わったように見えても、意外と続いていくことが多い<br />
・短期でキツいけどお金のサイクルが早い仕事と、長期でゆるやかだけどお金のサイクルが長い仕事。この２つをバランスよくしよう<br />
・忙しいといって今の仕事だけに目を向けていると、その仕事が終わったときに次の仕事がないことがある。<br />
・だから今の仕事は、ある意味「終わった仕事」として次の３ヶ月を乗り切る仕事にも目を向けておこう</p>
<p>てな感じでした。それまで私は制作しかしたことがなく、営業やお金まわりのことをほとんどやったことがありませんでした。なので、当初はいまいち実感がわきませんで、「そういうもんかなー？」と思っていました。<br />
自分で当初ポツポツと売り込み営業をしたりしながら、今までやってきたのですが、やっぱり新規の営業はすごく大変です。なんていうか、いったいどこから芽がでてくるのかわからないのに、種をまいている感じ？</p>
<p>で、商売の基本はやっぱり「お得意さま」。つまりリピーターですよね。<br />
リピーターっていうのは、自分の技術を買ってくれている部分もあると思うのですが、<br />
もっというと「信頼」を買ってくれてるのかもなー。とも思ったりします。<br />
とあるところに書いてあったのですが、会社にとって一番の財産は「お金」でもなく「人（従業員）」でもなく「信頼」のようです。お金は使えばおしまい。人も変わっていきます。けれど、信頼さえあればまた新たな仕事が発生するので、またお金と人がまわりだす。みたいな。<br />
信頼はある意味ブランドともいえるような。<br />
「この人だったら、きっとうまくやってくれるだろう」みたいにお客様に思ってもらえたら、たぶんそれがその人のブランドなんでしょう。</p>
<p>なんだかまとまりがなくなっちゃいましたね。<br />
毎日こういうことばっかり考えているわけじゃないんですが、仕事がうまくいったり、意外とキツイ仕事だったりだとか、そういうときにチラリと頭の片隅で考えることはあります。</p>
<p>でまあ、最初に書きましたとおり、私は今３年目なので何とか来年のお正月を無事に迎えたいなーと思ってる次第です。<br />
ではでは。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-02-24/1624/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FlashとAfterEffectsでアルファチャンネルつき動画をやりとりする</title>
		<link>http://119.245.215.115/blog/2010-02-17/1618</link>
		<comments>http://119.245.215.115/blog/2010-02-17/1618#comments</comments>
		<pubDate>Wed, 17 Feb 2010 11:33:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-Flash]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-アプリケーション]]></category>
		<category><![CDATA[AfterEffects]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[アルファチャンネル]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1618</guid>
		<description><![CDATA[こんにちは。きんくまです。
アルファチャンネルつき動画のやりとりメモです。
■AfterEffects→普通の動画形式に書き出し
形式 > Video For WIndows　か　QuickTimeムービー
出力モジュー [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。</p>
<p>アルファチャンネルつき動画のやりとりメモです。</p>
<p>■AfterEffects→普通の動画形式に書き出し<br />
形式 > Video For WIndows　か　QuickTimeムービー<br />
出力モジュール設定 > ビデオ出力 > チャンネル > RGB + アルファ</p>
<p>これで書き出した動画をAfterEffectsとかPremireで、またアルファチャンネルつきでよみこめます。<br />
Media Encoderでも読み込めるのでそこからflvに落としてもよいかと。</p>
<p>■AfterEffectsから直接flv書き出し<br />
形式 > Adobe Flash Video<br />
ビデオ出力 > 形式オプション > タブ　ビデオ > 基本ビデオ設定 > アルファチャンネルをエンコードにチェック</p>
<p>&#8212;-<br />
flvにできたらあとはFlashでどうにもできるので大丈夫だと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-02-17/1618/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[AS3] BetweenAS3のThread</title>
		<link>http://119.245.215.115/blog/2010-02-17/1613</link>
		<comments>http://119.245.215.115/blog/2010-02-17/1613#comments</comments>
		<pubDate>Wed, 17 Feb 2010 11:20:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-ActionScript3]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[BetweenAS3]]></category>
		<category><![CDATA[Thread]]></category>
		<category><![CDATA[そうめん]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1613</guid>
		<description><![CDATA[こんにちは。きんくまです。
期末ですね。もうすぐ３月ですね。みなさま、いかがお過ごしですか。
オリンピックはじまりましたね。
さてThread（そうめん）を、再度勉強しているところです。
Threadは、非同期処理が結構 [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。<br />
期末ですね。もうすぐ３月ですね。みなさま、いかがお過ごしですか。<br />
オリンピックはじまりましたね。</p>
<p>さて<a href="http://www.libspark.org/wiki/Thread" target="_blank">Thread（そうめん）</a>を、再度勉強しているところです。</p>
<p>Threadは、非同期処理が結構柔軟にかけると思いました。<br />
非同期処理の手続きを開始したあとは、その非同期処理を中止するか、終わるのをひたすら待つかのどちらかなのですが、Threadは非同期処理中の動作を細かく設定できるんですね。だから、ゲームやサーバーと頻繁にデータの出し入れなんかするときに結構役に立つと思います。</p>
<p>で、BetweenAS3です。<br />
これはTweenerと同じ、アニメーション用のライブラリです。<br />
一見複雑そうに見えたのですが、基本はBetweenAS3.toさえ使えればTweenerの代わりにすぐ使えるようになりました。</p>
<p>それで、Thread用にBetweenAS3Threadを作りました。</p>
<pre class="brush:as3">
package
{
	import fl.motion.ITween;
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.core.easing.IEasing;
	import org.libspark.betweenas3.tweens.IObjectTween;
	import org.libspark.thread.IMonitor;
	import org.libspark.thread.Monitor;
	import org.libspark.thread.Thread;

	public class BetweenThread extends Thread
	{
		private var _target:Object;
		private var _to:Object;
		private var _time:Number;
		private var _easing:IEasing;
		private var _delay:Number;
		private var _monitor:IMonitor;
		private var _tween:IObjectTween;

		public function BetweenThread(target:Object, to:Object, time:Number = 1.0, easing:IEasing = null, delay:Number = 0)
		{
			_target = target;
			_to = to;
			_time = time;
			_easing = easing;
			_delay = delay;
			_monitor = new Monitor();
		}

		override protected function run():void
		{
			_monitor.wait();
			interrupted(interruptedHandler);
			_tween = BetweenAS3.to(_target, _to, _time, _easing);
			if (_delay != 0) {
				BetweenAS3.delay(_tween, _delay);
			}
			_tween.onComplete = completeHandler;
			_tween.play();
		}

		public function cancel():void
		{
			interrupt();
		}

		private function completeHandler():void
		{
			_monitor.notifyAll();
		}

		private function interruptedHandler():void
		{
			if (_tween != null &#038;&#038; _tween.isPlaying) {
				_tween.stop();
			}
		}
	}

}
</pre>
<p>TweenerThreadを参考にしながら作りました。<br />
ところが、さっき検索かけたらすでにさくーしゃさんがBetweenAS3Threadを作られていました。</p>
<p><a href="http://saqoosha.net/en/2009/05/13/1745/" target="_blank">>> BetweenAS3Thread</a></p>
<p>それで気がつきました。そうだよなー。コンストラクタの引数をITweenにしておけばBetweenAS3.toに固定しなくてすむもんなー。頭いいなー。と<br />
BetweenAS3はパラレル・シリアルの複数トゥイーンを制御するグループ機能があるので、そっちの方が使い勝手がよいと思いました。<br />
なのでさくーしゃさん方式で今後はいきたいと思いました。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-02-17/1613/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[AS3] シーケンス遷移（ページ遷移）を自作する3　（swfaddressを試す）</title>
		<link>http://119.245.215.115/blog/2010-02-09/1604</link>
		<comments>http://119.245.215.115/blog/2010-02-09/1604#comments</comments>
		<pubDate>Mon, 08 Feb 2010 16:05:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-ActionScript3]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-プログラミング]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[SWFAddress]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1604</guid>
		<description><![CDATA[こんにちは。きんくまです。
F-siteのセミナーに行ってきました。
今回からスタッフとして参加です。
内容はケータイFlash。
つまりFlash Liteの話を中心に、技術的な話だけでなく、仕事の進め方なども交えて講 [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。</p>
<p><a href="http://f-site.org/" target="_blank">F-site</a>のセミナーに行ってきました。<br />
今回からスタッフとして参加です。<br />
内容はケータイFlash。<br />
つまりFlash Liteの話を中心に、技術的な話だけでなく、仕事の進め方なども交えて講義がありました。<br />
<a href="http://www.au.kddi.com/lismo/index.html" target="_blank">LISMO</a>や<a href="http://www.mext.go.jp/wonder/shinkai.html" target="_blank">深海ワンダー</a>などの実例も紹介されました。なかなかこういう機会はないと思うので、とても面白かったです。<br />
ケータイの面白いところは、リアルタイム性にあるみたいです。<br />
<a href="http://hi-posi.jp/" target="_blank">岡田さん</a>の講義中に、デモ用のケータイサイトからボタンを押すとプレゼンの画面にニコニコ動画のように「へぇー」やコメントがたくさん流れたりしてました。<br />
岡田さんはサービス精神旺盛な方なようでした。<br />
講義の最後に「TBS系のオールスター感謝祭」と同じようなゲームが出てきて、それを使ってご自分の本のプレゼント大会をしてました。これには驚きました。「アンサーチェック！」とかいうと、リアルタイムにケータイからの投票状況がランキングされてプレゼン画面に出ていたので。演出も本物そっくりで、すごかったです。</p>
<p>さてさてswfaddressです。</p>
<p><a href="http://www.kuma-de.com/flash/samples/004_swfaddress/" target="_blank"><br />
>>画像クリックで別ウインドウがひらきます。<br />
<img src="http://119.245.215.115/wp/wp-content/uploads/2010/02/swfaddress1.gif" alt="swfaddress1" title="swfaddress1" width="526" height="380" class="alignnone size-full wp-image-1606" /><br />
</a></p>
<p><a href="http://www.kuma-de.com/flash/samples/004_swfaddress/swfaddress_test.zip">>> 今回のソース一式</a></p>
<p><a href="http://www.asual.com/swfaddress/" target="_blank">swfaddress</a>はJavaScriptとFlashを連携させて、ディープリンクを実現するライブラリです。<br />
ディープリンクというのは、通常Flashだけだと内部にURLを直接そのままだと貼ることができないのですが、ページ内リンク（#ではじまるやつです）を使うことによって実現しようというやつです。</p>
<p>で、今まで試したことがなかったんですが今回やってみました。<br />
そしたら意外と基本は難しくなくて素朴な仕組みでした。</p>
<p>１．ASで、SWFAddressのイベントをリスナー登録しておく<br />
２．ASで、SWFAddress.setValue(&#8217;設定したいURL&#8217;);をする<br />
３．SWFAddressがJSと連携プレー。ブラウザのURLを変更する。SWFAddressがASのイベントをdispatch<br />
４．ASでイベント登録していた関数がよばれる。<br />
５．関数の中でSWFAddress.getValue();をすると現在のURLが読み込めるので、switchやif文で分岐</p>
<p>が基本の流れです。他にもいろいろと機能はあるみたいですが、基本はこれで十分かと。<br />
feb19.jpさんのブログ記事が詳しいです。<br />
<a href="http://feb19.jp/blog/archives/000181.php" target="_blank">>> AS3 で SWFAddress 2.4 を使う ( Flash でブラウザの戻るボタン、パーマリンクに対応する )</a></p>
<p>もう少し、簡単に知りたい！という方は、<a href="http://www.asual.com/swfaddress/resources/" target="_blank">本家のチュートリアル集</a>からこのページがおすすめ<br />
<a href="http://code.radiesel.com/examples/SWFAddress_AS3/" target="_blank">>>SWFAddress ActionScript 3 sample for Flash</a></p>
<p>で、ここまでできたのですが、２階層目以降の場合は結構難しそうですね。<br />
URLを判別して再帰処理をして画面を積み上げていくのかな？と今考えていますけど、いろいろ試してみないとなんともですね。</p>
<p>今回のメインのソースです。<br />
<span id="more-1604"></span></p>
<pre class="brush:as3">
package
{
	import flash.display.MovieClip;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.MouseEvent;
	import org.libspark.next.*;
	import swfaddress.SWFAddress;
	import swfaddress.SWFAddressEvent;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class Main extends MovieClip
	{
		private var _childPage:BasePage;
		public var btn1:MovieClip;
		public var btn2:MovieClip;

		public function Main()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			SWFAddress.addEventListener(SWFAddressEvent.INIT, initHD);
		}

		private function initHD(e:SWFAddressEvent):void
		{
			SWFAddress.removeEventListener(SWFAddressEvent.INIT, initHD);
			SWFAddress.addEventListener(SWFAddressEvent.CHANGE, addressChangeHD);
			btn1.addEventListener(MouseEvent.CLICK, btn1ClickHD);
			btn2.addEventListener(MouseEvent.CLICK, btn2ClickHD);
		}

		private function btn2ClickHD(e:MouseEvent):void
		{
			SWFAddress.setValue("/2");
		}

		private function btn1ClickHD(e:MouseEvent):void
		{
			SWFAddress.setValue("/1");
		}

		private function addressChangeHD(e:SWFAddressEvent):void
		{
			var self:Main = this;
			N.push(stopPage).func(function() {
				self.stopPageCompleteHD();
			}).start();
		}

		private function stopPageCompleteHD():void
		{
			var self:Main = this;
			switch(SWFAddress.getValue()) {
				case "/":
				SWFAddress.setTitle("トップページ");
				break;
				case "/1":
				_childPage = new Page1();
				SWFAddress.setTitle("1ページ目");
				break;
				case "/2":
				_childPage = new Page2();
				SWFAddress.setTitle("2ページ目");
				break;
			}

			if (_childPage != null) {
				addChild(_childPage);
				N.push(self._childPage.startPage)
				.func(function() {
				}).start();
			}
		}

		private function stopPage():ITrigger
		{
			var tri:Trigger = new Trigger();
			var self:Main = this;
			if (_childPage == null) {
				tri.call();
			}else{
				N.push(_childPage.stopPage)
				.func(function() {
					self.removeChild(self._childPage);
					self._childPage = null;
					tri.call();
				}).start();
			}
			return tri;
		}
	}

}
</pre>
<p>あとページ共通の親クラス</p>
<pre class="brush:as3">
package
{
	import flash.display.MovieClip;
	import kinkuma.BAS3Trigger;
	import org.libspark.betweenas3.easing.*;
	import org.libspark.next.*;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class BasePage extends MovieClip
	{

		public function BasePage()
		{

		}

		public function startPage():ITrigger
		{
			var tri:Trigger = new Trigger();
			alpha = 0;
			N.push(BAS3Trigger, this, {	alpha:1 }, 0.5, Quad.easeIn)
			.func(function() {
				tri.call();
			}).start();
			return tri;
		}

		public function stopPage():ITrigger
		{
			var tri:Trigger = new Trigger();
			N.push(BAS3Trigger, this, {	alpha:0 }, 0.5, Quad.easeIn)
			.func(function() {
				tri.call();
			}).start();
			return tri;
		}
	}

}
</pre>
<p>ではでは。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-02-09/1604/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[AS3] シーケンス遷移（ページ遷移）を自作する2　（非同期処理を組み込む）</title>
		<link>http://119.245.215.115/blog/2010-02-05/1587</link>
		<comments>http://119.245.215.115/blog/2010-02-05/1587#comments</comments>
		<pubDate>Fri, 05 Feb 2010 10:53:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-ActionScript3]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[シーケンス遷移]]></category>
		<category><![CDATA[シーン制御]]></category>
		<category><![CDATA[ページ遷移]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1587</guid>
		<description><![CDATA[こんにちは。きんくまです。
先日の節分の日に、家族で豆まきをしました。
私が鬼役だったので、外で家族が豆をまいてくれるのを「出待ち」してたんです。そしたら、その日は雪がちょろっとふってきていて、すごく寒かったです。
早く [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。<br />
先日の節分の日に、家族で豆まきをしました。<br />
私が鬼役だったので、外で家族が豆をまいてくれるのを「出待ち」してたんです。そしたら、その日は雪がちょろっとふってきていて、すごく寒かったです。<br />
早く出てきて豆まいてほしかったです。</p>
<p>さて、<a href="/blog/2010-02-03/1561">前回</a>のシーケンス遷移の続きです。<br />
今回は前回のものに、非同期処理を加えてみました。<br />
シーンのイベント処理は<a href="http://progression.jp/ja/" target="_blank">Progression</a>を参考にしました。</p>
<p><a href="/wp/wp-content/uploads/2010/02/PageTrangision2.zip">>> ファイル一式</a></p>
<p><script type="text/javascript">
//<![CDATA[
swfobject.embedSWF("/wp/wp-content/uploads/2010/02/page_transition2.swf", "page_transition2", "400", "300", "9.0.0");
//]]&gt;
</script></p>
<div class="border_area" style="width: 400px; height:300px">
<div id="page_transition2"></div>
</div>
<p><span id="more-1587"></span></p>
<p>非同期処理にはNextを使います。<br />
<a href="http://www.libspark.org/wiki/hidachinoiro/Next" target="_blank">>> Next は非同期処理を簡素に記述するために作られたライブラリです。</a> </p>
<p>やり方にはちょっとクセがあるのですが、JavaScriptでjQueryをさわったことがある人だったらすぐに慣れると思います。<br />
非同期処理には、他にもたくさんあります。<br />
<a href="http://www.libspark.org/#async-as3" target="_blank">>> 非同期処理 (AS3) （Spark project）</a><br />
このほかにもProgressionのCommandやfladdictさんのCommandもありますね。<br />
<a href="http://fladdict.net/blog/2008/01/as3commands.html" target="_blank">>> AS3で非同期処理を行う為のcommandsライブラリ</a></p>
<p>で、Nextは非同期処理をクラスを個別につくらなくても、関数単位でも組み込むことができるお手軽さがウリだと思います。<br />
ソースを書く量が減らせて、面倒くさがりな私にはぴったりです。</p>
<p>それで、今回はシーン移動のときの非同期処理に使いました。<br />
すべてのシーンのベースとなるSceneBase は前回と比べてinit関数はやめてstartSceneとstopSceneのみにしました。</p>
<pre class="brush:as3">
package test.base
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import org.libspark.next.*;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class SceneBase extends MovieClip
	{
		protected var _nextScene:SceneBase;
		protected var _trigger:Trigger;

		public function getNextScene():SceneBase
		{
			return _nextScene;
		}

		public function SceneBase()
		{

		}

		public function startScene():ITrigger
		{
			_trigger = new Trigger();
			_trigger.call();
			return _trigger;
		}

		public function stopScene():ITrigger
		{
			_trigger = new Trigger();
			_trigger.call();
			return _trigger;
		}

		protected function dispatchCompleteEvent():void
		{
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}

}
</pre>
<p>メインはこんな感じ</p>
<pre class="brush:as3">
package  test
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import org.libspark.next.*;
	import test.base.SceneBase;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class Main extends MovieClip
	{
		private var _childScene:SceneBase;

		//シングルトン
		private static var _instance:Main;
		public static function getInstance():Main
		{
			return _instance;
		}

		public function Main()
		{
			if (_instance == null) {
				_instance = this;
				init();
			}else{
				throw new Error('Error. This is singleton class.');
			}
		}

		private function init():void
		{
			_childScene = new TopScene();
			_childScene.addEventListener(Event.COMPLETE, childSceneCompleteHD);
			_childScene.startScene();
			addChild(_childScene);
		}

		private function childSceneCompleteHD(e:Event):void
		{
			_childScene.removeEventListener(Event.COMPLETE, childSceneCompleteHD);
			var tempScene:SceneBase = _childScene.getNextScene(); //一時保存
			var self:Main = this;

			//マウス無効
			setMouseEventEnable(false);

			//終了処理
			N.push(_childScene.stopScene)
			.func(function(){;
				self.removeChild(self._childScene);
				self._childScene = null;
				self._childScene = tempScene;
				self.startChildScene();
			}).start();
		}

		//新シーン処理
		private function startChildScene():void
		{
			var self:Main = this;
			N.push(self._childScene.startScene)
			.func(function() {
				self._childScene.addEventListener(Event.COMPLETE, self.childSceneCompleteHD);
				self.setMouseEventEnable(true);
			}).start();
			addChild(_childScene);
		}

		//マウスイベントをとるか
		public function setMouseEventEnable(isPossible:Boolean):void
		{
			this.mouseChildren = this.mouseEnabled = isPossible;
		}
	}

}
</pre>
<p>ここで、マウスイベントをとるかとらないかという関数をつくってあります</p>
<pre class="brush: as3">
		//マウスイベントをとるか
		public function setMouseEventEnable(isPossible:Boolean):void
		{
			this.mouseChildren = this.mouseEnabled = isPossible;
		}
</pre>
<p>これはどういうものかというと、非同期処理の最中にボタンを押されるといろいろと面倒なことになるので、それを防ぐためにつけてあります。</p>
<p>ルート以下につるしてあるすべてのマウスイベントを一時的にオン・オフすることができるというものです。作成するアイデアとなったのは、下のページです。<br />
どうもです。<br />
<a href="http://blog.flair4.jp/2009/10/as3-mouse-event-tips.html" target="_blank">>> AS3.0 マウスイベントの伝播の理解とTIPS ( flair4 blog )</a></p>
<p>オプションページはこんな感じ</p>
<pre class="brush:as3">
package test
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import kinkuma.BAS3Trigger;
	import org.libspark.betweenas3.easing.*;
	import org.libspark.next.*;
	import test.base.SceneBase;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class OptionScene extends SceneBase
	{
		public var titleBtn:MovieClip;
		public var startBtn:MovieClip;

		public function OptionScene()
		{

		}

		override public function startScene():ITrigger
		{
			var self:OptionScene = this;
			var tr:Trigger = new Trigger();
			alpha = 0;
			N.push(BAS3Trigger, this, { alpha:1 }, 0.6, Quad.easeIn)
			.func(function(){
				self.startBtn.addEventListener(MouseEvent.CLICK, startClickHD);
				self.titleBtn.addEventListener(MouseEvent.CLICK, titleClickHD);
				tr.call();
			}).start();
			return tr;
		}

		private function startClickHD(e:MouseEvent):void
		{
			_nextScene = new GameScene();
			dispatchCompleteEvent();
		}

		private function titleClickHD(e:MouseEvent):void
		{
			_nextScene = new TopScene();
			dispatchCompleteEvent();
		}

		override public function stopScene():ITrigger
		{
			startBtn.removeEventListener(MouseEvent.CLICK, startClickHD);
			titleBtn.removeEventListener(MouseEvent.CLICK, titleClickHD);
			var tr:Trigger = new Trigger();
			N.push(BAS3Trigger, this, { alpha:0 }, 0.4, Quad.easeIn)
			.func(function() {
				tr.call();
			}).start();
			return tr;
		}
	}

}
</pre>
<p>ここで、BAS3Triggerというクラスがでてきました。<br />
今回トゥイーンエンジンはBetweenAS3を使っているので、それ用のTriggerクラスを作っています。</p>
<pre class="brush:as3">
package kinkuma
{
	import flash.display.DisplayObject;
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.core.easing.IEasing;
	import org.libspark.betweenas3.events.TweenEvent;
	import org.libspark.betweenas3.tweens.ITween;
	import org.libspark.next.*;

	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class BAS3Trigger extends Trigger
	{
		private var _tw:ITween;

		public function BAS3Trigger(target:Object, params:Object, time:Number, easing:IEasing, delay:Number = 0)
		{
			_tw = BetweenAS3.to(target, params, time, easing);
			_tw = BetweenAS3.delay(_tw, delay);
			_tw.addEventListener(TweenEvent.COMPLETE, tweenCompHD);
			_tw.play();
		}

		override public function halt(... args:Array):void
		{
			_tw.removeEventListener(TweenEvent.COMPLETE, tweenCompHD);
			_tw.stop();
		}

		private function tweenCompHD(e:TweenEvent):void
		{
			_tw.removeEventListener(TweenEvent.COMPLETE, tweenCompHD);
			call();
		}

	}

}
</pre>
<p>あと、節となるゲームシーン</p>
<pre class="brush:as3">
package test
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import test.base.GameSceneBase;
	import test.base.SceneBase;
	import kinkuma.BAS3Trigger;
	import org.libspark.betweenas3.easing.*;
	import org.libspark.next.*;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class GameScene extends SceneBase
	{
		public var popupBtn:MovieClip;
		public var titleBtn:MovieClip;
		private var _childScene:SceneBase;

		public function GameScene()
		{

		}

		override public function startScene():ITrigger
		{
			var self:GameScene = this;
			var tr:Trigger = new Trigger();
			alpha = 0;
			N.push(BAS3Trigger, this, { alpha:1 }, 0.6, Quad.easeIn)
			.func(function() {
				self.popupBtn.addEventListener(MouseEvent.CLICK, self.popupClickHD);
				self.titleBtn.addEventListener(MouseEvent.CLICK, self.titleClickHD);
				tr.call();
			}).start();
			return tr;
		}

		private function popupClickHD(e:MouseEvent):void
		{
			_childScene = new PopupScene();
			addChild(_childScene);
			var self:GameScene = this;
			Main.getInstance().setMouseEventEnable(false);
			N.push(_childScene.startScene)
			.func(function() {
				self._childScene.addEventListener(Event.COMPLETE, self.childSceneCompleteHD);
				Main.getInstance().setMouseEventEnable(true);
			}).start();
		}

		private function childSceneCompleteHD(e:Event):void
		{
			_childScene.removeEventListener(Event.COMPLETE, childSceneCompleteHD);

			Main.getInstance().setMouseEventEnable(false);

			var self:GameScene = this;
			N.push(_childScene.stopScene)
			.func(function() {
				self.childSceneTransitionCompleteHD();
				Main.getInstance().setMouseEventEnable(true);
			}).start();
		}

		private function childSceneTransitionCompleteHD():void
		{
			removeChild(_childScene);

			_nextScene = _childScene.getNextScene();

			//何もしない
			if (_nextScene == null) {

			//GameSceneの子シーンになれるんだったら
			}else if (_nextScene is GameSceneBase) {
				/*
				 * 子シーンを追加してchildSceneCompleteHDを登録する処理
				 * 今回は別の子シーンがないので何もしない
				 */

			//子シーンでない場合は親に通達する
			}else {
				dispatchCompleteEvent();
			}
		}

		private function titleClickHD(e:MouseEvent):void
		{
			_nextScene = new TopScene();
			dispatchCompleteEvent();
		}

		override public function stopScene():ITrigger
		{
			popupBtn.removeEventListener(MouseEvent.CLICK, popupClickHD);
			titleBtn.removeEventListener(MouseEvent.CLICK, titleClickHD);
			var tr:Trigger = new Trigger();
			N.push(BAS3Trigger, this, { alpha:0 }, 0.4, Quad.easeIn)
			.func(function() {
				tr.call();
			}).start();
			return tr;
		}
	}

}
</pre>
<p>なんか長々となってしまいました。興味がある方はソースを見てみてください。<br />
これにswfaddressを組み込めれば、簡易自作ページ遷移システムになると思います。でもこれがすごく厄介そうだなー。</p>
<p>ではー。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-02-05/1587/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[AS3] シーケンス遷移（ページ遷移）を自作する1</title>
		<link>http://119.245.215.115/blog/2010-02-03/1561</link>
		<comments>http://119.245.215.115/blog/2010-02-03/1561#comments</comments>
		<pubDate>Tue, 02 Feb 2010 16:38:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-ActionScript3]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-プログラミング]]></category>
		<category><![CDATA[シーケンス遷移]]></category>
		<category><![CDATA[シーン制御]]></category>
		<category><![CDATA[ページ遷移]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1561</guid>
		<description><![CDATA[こんにちは。きんくまです。
東京や千葉では昨夜、雪が降りました。
すぐに溶けてしまったのですが、子供は物心ついて初めて見た雪なので喜んでいました。
２年前にも見たのですが、あのときは1歳ちょっとだったから。
さて、今回は [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちは。きんくまです。<br />
東京や千葉では昨夜、雪が降りました。<br />
すぐに溶けてしまったのですが、子供は物心ついて初めて見た雪なので喜んでいました。<br />
２年前にも見たのですが、あのときは1歳ちょっとだったから。</p>
<p>さて、今回はシーケンス遷移を自作してみようと思います。<br />
シーケンス遷移は、ゲーム業界で使われている用語のようです。<br />
普通にいうとページ遷移です。<br />
なんでゲーム業界のことなんか出てくるんだ？といいますと、今回は下の本を参考に作ったからなのです。</p>
<p><a href="http://www.amazon.co.jp/dp/4798021180" target="_blank">>> ゲームプログラマになる前に覚えておきたい技術</a></p>
<p>これはセガの中の人が書いた本です。C++の本なのですが、考え方は別の言語でも<br />
使えるということでAS3で拝借しました。<br />
この本の中でシーケンス遷移は２章割かれていまして、簡単なのと難しいのがあります。<br />
今回は難しい方をやってみようと思います。<br />
もっとも、難しいといってもオブジェクト指向やデザインパターンなどを熟知している人からしたらすごく簡単だと思います。<br />
私には難しかったです。</p>
<p>さて、今回のデモ</p>
<p><a href="/wp/wp-content/uploads/2010/02/PageTrangision1.zip">>> ファイル一式</a></p>
<p><script type="text/javascript">
//<![CDATA[
swfobject.embedSWF("/wp/wp-content/uploads/2010/02/page_transition1.swf", "page_transition1", "400", "300", "9.0.0");
//]]&gt;
</script></p>
<div class="border_area" style="width: 400px; height:300px">
<div id="page_transition1"></div>
</div>
<p>　<br />
シーケンスやページという呼び方でもいいんですが、今回はProgressionに習って<br />
シーンという呼び方にします。<br />
シーン構成はこんな感じ。</p>
<p>Main（シーンなしこれを基底とする）<br />
　┣　タイトルシーン<br />
　┣　オプションシーン<br />
　┣　ゲームシーン<br />
　　　　┣　ポップアップシーン</p>
<p>Main直下に、タイトル・オプション・ゲームが並んでいて、<br />
ゲームにポップアップがぶら下がっている形。<br />
ゲームが表示されている上にポップアップが出ていることに注目してください。</p>
<p><span id="more-1561"></span></p>
<p>各シーンはSceneBaseを継承しています。</p>
<pre class="brush: as3;">
package test.base
{
	import flash.display.MovieClip;
	import flash.events.Event;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class SceneBase extends MovieClip
	{
		protected var _nextScene:SceneBase;

		public function getNextScene():SceneBase
		{
			return _nextScene;
		}

		public function SceneBase()
		{

		}

		public function init():void
		{

		}

		public function startScene():void
		{

		}

		public function stopScene():void
		{

		}

		protected function dispatchCompleteEvent():void
		{
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}

}
</pre>
<p>ポップアップだけがSceneBaseを継承したGameSceneBaseをさらに継承しています。</p>
<pre class="brush: as3;">
package test.base
{
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class GameSceneBase extends SceneBase
	{

		public function GameSceneBase()
		{

		}

	}

}
</pre>
<p>それで、親と子の同階層間移動の基本方針は以下のようになります。</p>
<p>１）一番最新の子（画面手前）が自分の次のシーンを決めてnewする<br />
２）親は子供からEvent.Completeを受け取ったあと、子供から次のシーンの情報をもらう。<br />
３）親は現在の子供をstopSceneして、次のシーンをinitし、startSceneする。<br />
４）親は次のシーンにaddEventLitener(Event.Complete)して待機<br />
１）に戻る</p>
<p>ここで、全てのシーンはSceneBaseを継承しているので、親は子供が言ってきた次のシーンが何であるかわからないまま進めることができます。<br />
Mainの初期化のときだけ最初のシーンを決めますが、あとは子供の言うとおり「はいはい、次はそのシーンね」みたいな感じですすめられます。</p>
<p>さきほどのセガの参考書の簡単な方の章では、別のやり方をしています。<br />
１）子供の中でnewするのではなくて、子供が次のシーンの番号だけを保持しておく<br />
２）親は子供の番号を見て次のシーンを分岐、親がnewする</p>
<p>ここで、今回のやり方との違いは親と子供の仕事の分担です。<br />
親がnewする場合は、次に行くシーンの数だけif文が親の中に並ぶことになります。<br />
それだと、シーンの数が増えた場合に可読性が下がるので、子供の方で分岐を分割してあげようというのが今回の方針です。<br />
たとえば次の行き先が全部で10あったとしても、一人の子供が示す次の行き先は2～3である場合があるからです。</p>
<p>ちなみに、本の方ではC++を使っているので、newした参照ではなくポインタを渡していました。newした参照とポインタって同じもんだと思ってるんですけど、ちょっと違うんでしょうかね？？このあたりよくわかりません。</p>
<p>Mainのソース</p>
<pre class="brush: as3;">
package  test
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import test.base.SceneBase;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class Main extends MovieClip
	{
		private var _childScene:SceneBase;

		public function Main()
		{
			init();
		}

		private function init():void
		{
			_childScene = new TopScene();
			_childScene.init();
			addChild(_childScene);
			_childScene.startScene();
			_childScene.addEventListener(Event.COMPLETE, childSceneCompleteHD);
		}

		private function childSceneCompleteHD(e:Event):void
		{
			_childScene.removeEventListener(Event.COMPLETE, childSceneCompleteHD);
			var tempScene:SceneBase = _childScene.getNextScene(); //一時保存

			//終了処理
			_childScene.stopScene();
			removeChild(_childScene);
			_childScene = null;

			//新シーン処理
			_childScene = tempScene;
			_childScene.init();
			addChild(_childScene);
			_childScene.startScene();
			_childScene.addEventListener(Event.COMPLETE, childSceneCompleteHD);
		}
	}

}
</pre>
<p>タイトル画面 TopScene</p>
<pre class="brush: as3;">
package test
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import test.base.SceneBase;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class TopScene extends SceneBase
	{
		public var startBtn:MovieClip;
		public var optionBtn:MovieClip

		public function TopScene()
		{

		}

		override public function init():void
		{
			super.init();
		}

		override public function startScene():void
		{
			startBtn.addEventListener(MouseEvent.CLICK, startClickHD);
			optionBtn.addEventListener(MouseEvent.CLICK, optionClickHD);
			super.startScene();
		}

		private function optionClickHD(e:MouseEvent):void
		{
			_nextScene = new OptionScene();
			dispatchCompleteEvent();
		}

		private function startClickHD(e:MouseEvent):void
		{
			_nextScene = new GameScene();
			dispatchCompleteEvent();
		}

		override public function stopScene():void
		{
			startBtn.removeEventListener(MouseEvent.CLICK, startClickHD);
			optionBtn.removeEventListener(MouseEvent.CLICK, optionClickHD);
			super.stopScene();
		}
	}

}
</pre>
<p>オプションシーンはタイトルシーンとほぼ同じなので省略。<br />
親と子供を両方もち、処理が複雑になるゲームシーンについて。</p>
<p>今回、ゲームからポップアップを開いたあとに、ゲームシーンから見て、ポップアップをただ閉じるだけという場合と、自分を飛び越えて自分の兄弟であるタイトル画面へ行くという仕様にしました。</p>
<p>ゲームシーンの子シーンは全てGameSceneBaseを継承するようにします。<br />
そうしたときに、<br />
if(次のシーン is GameSceneBase)<br />
と型判定をすると自分にまだ関係があるかどうかわかります。<br />
もし自分にもう関係ないや、ということであれば自分の親、つまりこの場合はMainに判定してもらおう。という仕組みです。<br />
その場合、自分にはもう関係ないのでゲームシーンがイベントを発行して親にひろってもらいます。</p>
<p>GameScene</p>
<pre class="brush: as3;">
package test
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import test.base.GameSceneBase;
	import test.base.SceneBase;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class GameScene extends SceneBase
	{
		public var popupBtn:MovieClip;
		public var titleBtn:MovieClip;
		private var _childScene:SceneBase;

		public function GameScene()
		{

		}

		override public function init():void
		{
			super.init();
		}

		override public function startScene():void
		{
			popupBtn.addEventListener(MouseEvent.CLICK, popupClickHD);
			titleBtn.addEventListener(MouseEvent.CLICK, titleClickHD);
			super.startScene();
		}

		private function popupClickHD(e:MouseEvent):void
		{
			_childScene = new PopupScene();
			_childScene.init();
			addChild(_childScene);
			_childScene.startScene();
			_childScene.addEventListener(Event.COMPLETE, childSceneCompleteHD);
		}

		private function childSceneCompleteHD(e:Event):void
		{
			_childScene.removeEventListener(Event.COMPLETE, childSceneCompleteHD);
			_childScene.stopScene();
			removeChild(_childScene);

			_nextScene = _childScene.getNextScene();

			//何もしない
			if (_nextScene == null) {

			//GameSceneの子シーンになれるんだったら
			}else if (_nextScene is GameSceneBase) {
				/*
				 * 子シーンを追加してchildSceneCompleteHDを登録する処理
				 * 今回は別の子シーンがないので何もしない
				 */

			//子シーンでない場合は親に通達する
			}else {
				dispatchCompleteEvent();
			}
		}

		private function titleClickHD(e:MouseEvent):void
		{
			_nextScene = new TopScene();
			dispatchCompleteEvent();
		}

		override public function stopScene():void
		{
			popupBtn.removeEventListener(MouseEvent.CLICK, popupClickHD);
			titleBtn.removeEventListener(MouseEvent.CLICK, titleClickHD);
			super.stopScene();
		}
	}

}
</pre>
<pre class="brush: as3;">
package test
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import test.base.GameSceneBase;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class PopupScene extends GameSceneBase
	{
		public var titleBtn:MovieClip;
		public var closeBtn:MovieClip;

		public function PopupScene()
		{

		}

		override public function init():void
		{
			super.init();
		}

		override public function startScene():void
		{
			closeBtn.addEventListener(MouseEvent.CLICK, closeClickHD);
			titleBtn.addEventListener(MouseEvent.CLICK, titleClickHD);
			super.startScene();
		}

		private function closeClickHD(e:MouseEvent):void
		{
			_nextScene = null; //画面を閉じたあと兄弟シーンにいくわけでないのでnull
			dispatchCompleteEvent();
		}

		private function titleClickHD(e:MouseEvent):void
		{
			_nextScene = new TopScene();
			dispatchCompleteEvent();
		}

		override public function stopScene():void
		{
			closeBtn.removeEventListener(MouseEvent.CLICK, closeClickHD);
			titleBtn.removeEventListener(MouseEvent.CLICK, titleClickHD);
			super.stopScene();
		}
	}

}
</pre>
<p>SceneBaseにinit, startScene, stopSceneがありますが、本の方ではそういう風な関数はまったくありません。あと本は、こういったイベント駆動の方式ではなくて、毎フレーム次のシーンを返してreturn nextScene;みたいにして、親の方で判定する方式です。<br />
なので、今回のはAS3向けにアレンジしてますので、ちゃんとしたやつが見たい方は本の方を見てください。</p>
<p>次回はこれに非同期処理を加えたいと思います。<br />
非同期処理はいろいろあるのですが、前から愛用している<a href="http://www.libspark.org/wiki/hidachinoiro/Next" target="_blank">Next</a>を使ってみようと思っています。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-02-03/1561/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[AS3] 自分メモ　静的に配置したサウンドの取り扱い</title>
		<link>http://119.245.215.115/blog/2010-01-31/1554</link>
		<comments>http://119.245.215.115/blog/2010-01-31/1554#comments</comments>
		<pubDate>Sun, 31 Jan 2010 14:29:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[1-ActionScript3]]></category>
		<category><![CDATA[1-blog]]></category>
		<category><![CDATA[1-プログラミング]]></category>

		<guid isPermaLink="false">http://119.245.215.115/?p=1554</guid>
		<description><![CDATA[自分メモです。
タイムライン上に配置したストリーミングサウンドは、MovieClip自体を停止しないと
ストリーミングが永久に続く。

特に注意しなければいけないのが、タイムラインにストリーミングサウンドを貼り付けたMC [...]]]></description>
			<content:encoded><![CDATA[<p>自分メモです。</p>
<p>タイムライン上に配置したストリーミングサウンドは、MovieClip自体を停止しないと<br />
ストリーミングが永久に続く。</p>
<p><img src="http://119.245.215.115/wp/wp-content/uploads/2010/01/streming_sound.gif" alt="streming_sound" title="streming_sound" width="246" height="34" class="alignnone size-full wp-image-1555" /></p>
<p>特に注意しなければいけないのが、タイムラインにストリーミングサウンドを貼り付けたMCが入っているswfを<br />
外部ファイルとしてloaderで読み込んだとき。<br />
loader.unloadをやっても、何をやってもそのままだとストリーミングサウンドがなり続ける。<br />
解決策としては、unloadする前にMCをstopしてあげること。</p>
<p>タイムラインに貼り付けるのが「ストリーミング」ではなく「スタート」であれば、unloadするだけで音は消える。</p>
<p>本当はSoundChannelをstopできればよいのだが、タイムライン上でなっているサウンドのSoundChannnelが<br />
どうやって取得できるのかがわからないためこうする。</p>
<p>タイムライン上の音量はmc.soundTransformで変更できる。クラスファイル内ではthis.soundTransformで。<br />
全体の音量調整はSoundMixer.soundTransformで変更できる。<br />
ただ、SoundMixerは個別の音量調整ができない。</p>
]]></content:encoded>
			<wfw:commentRss>http://119.245.215.115/blog/2010-01-31/1554/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
