Archive for the ‘ActionScript’ Category

switch文内のコメントからimportの整理バグを発動

火曜日, 7月 12th, 2011

とあるソースを改修することになった際に
import文がなぜかメソッドの中にあったり、それを削るとエラーになったりで
意味不明のままずっと謎だった記述の発生原因がわかりました。

簡単に説明するとswitch文の中に/** */ 形式でコメントを記述し
その状態でimport の整理をすると一部のimportが削除される現象が発生します。

実際にサンプルソースで説明します。

まずはswitch文とimportを必要とするクラスを入れたソースを記述
(サンプルは、条件によって描画の色を変更する簡単なクラス)

package
{
  import flash.display.Graphics;
  import flash.display.Sprite;

  public class SwitchTest extends Sprite
  {
    public function SwitchTest()
    {
      var hoge:uint = 0;

      switch (hoge)
      {
        case 0:
          draw(this.graphics, 0xff0000);
          break;
        case 1:
          draw(this.graphics, 0xffff00);
          break;
      }
    }

    private function draw(g:Graphics, color:uint):void
    {
      g.clear();
      g.beginFill(color);
      g.drawRect(0, 0, 100, 100);
      g.endFill();
    }
  }
}

次に上記のswitch文の中に/** */の形式でコメントを記述します。

      switch (hoge)
      {
        /**
         * このコメントは危険です。
         */
        case 0:
          draw(this.graphics, 0xff0000);
          break;

この状態でimportの整理(Ctrl+Shit+O)をすると、、

package
{
  import flash.display.Sprite;

  public class SwitchTest extends Sprite
  {
    public function SwitchTest()
    {
      var hoge:uint = 0;

      switch (hoge)
      {
        /**
         * このコメントは危険です。
         */
        case 0:
          draw(this.graphics, 0xff0000);
          break;
        case 1:
          draw(this.graphics, 0xffff00);
          break;
      }
    }

    private function draw(g:Graphics, color:uint):void
    {
      g.clear();
      g.beginFill(color);
      g.drawRect(0, 0, 100, 100);
      g.endFill();
    }
  }
}

ソースからGraphicsクラスのimportが消えます!

そして、仕方なくこの状態でGraphicsクラスを定義している箇所(g:Graphics)で
コンテンツアシスト(Ctrl+Space)からGraphicsクラスを選択してimportしようとすると

package
{
  import flash.display.Sprite;

  public class SwitchTest extends Sprite
  {
    public function SwitchTest()
    {
      var hoge:uint = 0;

      switch (hoge)
      {
        /**
         * このコメントは危険です。
         */
        case 0:
          draw(this.graphics, 0xff0000);
          break;
        case 1:
          draw(this.graphics, 0xffff00);
          break;
      }
import flash.display.Graphics;

    }

    private function draw(g:Graphics, color:uint):void
    {
      g.clear();
      g.beginFill(color);
      g.drawRect(0, 0, 100, 100);
      g.endFill();
    }
  }
}

今度はGraphicsクラスのimportがメソッドの中に記述されます!!

これを発見したときはかなりの衝撃でした。

今回のサンプルでコンパイルするとエラーになってしまいますが、
エラーにならないこともあるようです。。
(実際自分が触ったソースはコンパイルとおってました。。。)

FlashBuilderのバグと言っていいとは思いますが、
メソッド内ではswitch文に限らず、クラスの説明などで使用する/** */形式での
コメントは避けるべきだと思われます。

ちなみに、
// 形式のコメントや、 /* */ 形式のコメントは問題ありませんでした。

ローカル環境でSWFを動かす時の注意点

金曜日, 12月 10th, 2010

なかなか珍しい案件ですが、
ローカル環境でHTMLを開き、そこにFlashコンテンツを表示させる
案件でハマりました。

まず、navigationURLがデフォルトでは動かないです。
セキュリティサンドボックス侵害エラーがでます。

プロジェクタ形式では問題ないのですが、SWFだと動きません。
納品近くでそのことが判明しかなり冷や汗ものでした。
(事前検証は必須ですね。。)

過去に見聞きした事例をなんとか思い出し、
運よく外部サイトへの遷移がなかったので
コンパイル時に引数で-use-network=falseで回避することができました。

そして、アンカーリンク、クエリーストリングが渡せません。
これは、もうどうしようもなかったです。
実態参照でもダメでしたね。

最後に、FlashからJavaScriptが実行&呼び出しができません。

ローカル環境は、ネットワーク環境に比べて
ものすごくセキュリティが厳しいです。

気持ちは、わからないでもないですが、、もうちょっとなんとかしてほしいです。。

HYPEでFlashコンテンツを透過PNG保存する

木曜日, 1月 28th, 2010

HYPE frameworkの中で最も興味深い機能の一つが
Flashコンテンツを透過PNG形式保存できることではないでしょうか。

JoshaDavisさんが、Flashコンテンツを印刷媒体に使っているのを見て
Flashコンテンツをどうやってベクターデータをキープしてイラレやフォトショにエクスポートするかを
1、2年ぐらい前に、l00oo.oo00lさんと何度か議論したことがあり
結局、fladdictさんがやっているようなSVGエクスポートしかないのかなぁと
その時は思っていました。

しかし、このHYPE frameworkではPNG保存ができるということをアナウンスしていたので
早速試してみました。

チュートリアルで一通りチェックをした感じだとすごい簡単に出来そうでした。

ContextSavePNG from Joshua Davis on Vimeo.

サンプルコードをHYPEのサイトから適当にもってきて試します。
(自分は01_objectpoolを少し改造して試します。)

まずは、ContextSavePNGクラスをインポートします。

	import hype.extended.util.ContextSavePNG;

後は、BitmapCanvasクラスのインスタンスをつくり、
setupLargeCanvas()メソッドに保存倍率を指定し、
ContextSavePNGをインスタンス化するだけで準備は完了です。

			// PNGエンコードの際の倍率を指定
			clipCanvas.setupLargeCanvas(10);
			// PNG保存のコンテキストを登録
			var savePNG:ContextSavePNG = new ContextSavePNG(clipCanvas);

ものすごくシンプルです!!

では実際に、Flashコンテンツをキャプチャしてみます。

※ 描画用の背景は透明で、描画領域は縦横300pxです。

まずはFlashコンテンツを実行し、感性に任せて程好いところで右クリック。
すると、コンテキストメニューに[ Encode PNG ] と表示されるのでそこでクリック。
プログレスバーが表示されPNGへのエンコードを行います。
プログレスバーが消えたら再度右クリック。
すると、今度はコンテキストメニューに[ Save PNG... ] と表示されるのでそこでクリック。
ダイアログが表示されるのでお好みの場所に保存で完了です。

早速、フォトショで確認してみます。

ちゃんと、透過できて取り込めています。
そして、気になる解像度も、300px * 300px の10倍でPNG保存したので
3000px * 3000px になっています。

これであれば、たとえば解像度300にしても
254mm サイズの印刷に劣化せず対応できるということになります。

これは、とても便利です!
間単に自作のジェネレーティブアートが印刷できるようになりました!!

ベクターデータではないので、
Joshuaさんの実際の作品用エクスポートだったり、fladdictさんがやっているようなアプローチとは
ちょっと違うとは思いますが、これでも、十分可能性を秘めていると思います。
検証の価値ありです。

ますます、Flashが楽くなりますね。

HYPE frameworkの勉強(4)

水曜日, 1月 27th, 2010

初回はこちら
第2回はこちら
第3回はこちら
前回までのソースはこちら

※ 注意 ※
自分はFlexBuilder3を使用して試していますので
CS4を使ったやり方は実際のチュートリアルを参照ください。

オブジェクトをビットマップでキャプチャする

今までは、オブジェクトを移動させていただけですが、
今度は動きをビットマップでキャプチャをしていきます。

まずは、BitmapCanvasクラスをインポートします。

	import hype.framework.display.BitmapCanvas;

ビットマップキャプチャ用のキャンバスを作成します。

		// ビットマップキャプチャ用キャンバス
		private var clipCanvas:BitmapCanvas;

コンストラクタにステージの領域でインスタンスを作成。
※一部抜粋

			// シェイプを非表示
			exitShape.visible = false;

			// ビットマップキャプチャ用キャンバスを作成します
			// 第1引数には、キャンバスの横幅
			// 第2引数には、キャンバスの高さ
			clipCanvas = new BitmapCanvas(myWidth, myHeight);
			addChild(clipCanvas);

コンストラクタの最後にキャプチャを開始する処理を記述します。
はじめはstartCaptureメソッドの第2引数をtrueにします。

※一部抜粋

			// キャプチャを開始します。
			// 第1引数には、対象オブジェクト
			// 第2引数には、キャプチャを繰り返すかどうか
			clipCanvas.startCapture(clipContainer, true);

			addEventListener(Event.ADDED_TO_STAGE, onAddToStage);

実行してみると、オブジェクトが動くたびにキャンバスに転写され
足跡みたいな描画になります。

別ウインドウで表示

描画されている箇所をよく見ると、BitmapCanvasのコンストラクタで設定したとおり
ステージ領域だけ足跡が描画されていることがわかります。
つまり、Graphicクラスのclear()メソッドを呼ばないで描画している状態と同じです。

そこで、ステージ領域だけを描画するようにコンストラクタに記述していた
コンテナ(clipConteiner)の追加処理を削除します。
※一部抜粋

			// コンテナを作成
			clipContainer = new Sprite();
// 削除		addChild(clipContainer);

これでBitmapCanvasのキャプチャ部分だけを表示するようできました。

別ウインドウで表示

ステージへ入る前、出た後は表示されず、ステージ上では正しく表示されています。
何よりもDisplayObjectを描画しているわけではなく、Bitmapに転写したものを描画しているので
パフォーマンスもかなり期待できます。

ここで、はじめに設定したstartCaptureメソッドの第2引数をfalseにして実行してみます。

別ウインドウで表示

画面がスッキリしました。そして、スムーズに動きます。

オブジェクトにいろいろな動作をつけてみる

初回で、DIrectionalVibrationクラスで下から上に動きをつけましたが、
その他の動きもつけてみます。

まず、FixedVibrationクラスをインポートします。

	import hype.extended.behavior.FixedVibration;

はじめに角度をつけます。
FixedVibrationのインスタンスをpool.onRequestObjectの関数内に記述します。

				// オブジェクトを指定した角度に振動させます。
				// 第1引数には、対象オブジェクト
				// 第2引数には、対象プロパティ
				// 第3引数には、弾力値?
				// 第4引数には、加減速値?
				// 第5引数には、振動幅の最小値
				// 第6引数には、振動幅の最大値
				// 第7引数には、現在の値を維持するかどうか
				var rVibration:FixedVibration = new FixedVibration(clip, "rotation", 0.9, 0.1, -13, 13, false);

				// 振動を実行させます。
				rVibration.start();

-13度から13度の間で動きます。

別ウインドウで表示

次に、第7引数がどのような影響をあたえるか、X座標を動かすことで確認します。
角度を少し抑え(min:-2、max:2)
X座標用のFixedVibrationのインスタンスをpool.onRequestObjectの関数内に記述します。
第7引数はとりあえずfalseに設定します。

				// オブジェクトを指定した座標に振動させます。
				// 第1引数には、対象オブジェクト
				// 第2引数には、対象プロパティ
				// 第3引数には、弾力値?
				// 第4引数には、加減速値?
				// 第5引数には、振動幅の最小値
				// 第6引数には、振動幅の最大値
				// 第7引数には、現在の値を維持するかどうか
				var xVibration:FixedVibration = new FixedVibration(clip, "x", 0.9, 0.1, 10, 40, false);

				// 振動を実行させます。
				xVibration.start();

実行すると、左側にオブジェクトが寄ってしまいます。

別ウインドウで表示

これは、第7引数の現在の値、つまり現在のX座標を維持するかどうかで、false=しないに設定しているので
常に10pxから40pxの間を行き来することになります。

動きがわかるように振動幅を大きくし(min:-40、max:40)、第7引数をtrueにして実行してみます。

別ウインドウで表示

現在のX座標を維持し相対で動くことが確認できました。

最後に角度、X座標ともに程よい振動幅(min:-4、max:4)に設定し実行してみます。

別ウインドウで表示

3ヶ月遅れのハロウィンですが、、これで出来上がりです!!

気づいたら第4回まで続いてしまい
つたない文章と、わかりずらいコードの説明が散見していたと思いますので
出来上がりのソースをおいて置きます。

個人的に解釈して記述している箇所もあるので
是非、Joshuaさんのチュートリアルを閲覧されることをお勧めいたします。

チュートリアルを見て試しているだけで、ActionScriptのテクニックが物凄い詰まっていることがわかります。
コードも直感的でわかりやすいし、引数のパラメータをいじるだけでいろいろな動きがつけられるので
コードを書くのがが苦手な方や、AS初心者にはとてもなじみ易いと思います。
メモリ管理もしっかり考慮されていてASになれている方にも興味深いフレームワークだと思いました。

指摘等ございましたら以下までご連絡いただけると幸いです。
otayori[at]awk2.net

HYPE frameworkの勉強(3)

火曜日, 1月 26th, 2010

初回はこちら
第2回はこちら
前回までのソースはこちら

※ 注意 ※
自分はFlexBuilder3を使用して試していますので
CS4を使ったやり方は実際のチュートリアルを参照ください。

オブジェクトのステージアウトを検知する

ステージと同じ領域にしたシェイプから
オブジェクトが外れたかどうかをチェックすることで
ステージアウトしたかを判断します。

ExitShapeTriggerクラスをインポートします。

	import hype.extended.trigger.ExitShapeTrigger;

ステージ領域のシェイプを作成します。

メンバー変数を定義します。

※一部抜粋

		// ステージ領域のシェイプ
		private var exitShape:Shape;

コンストラクタでインスタンスを作成し、
ステージ領域で塗りつぶします。

※一部抜粋

			var myWidth:Number = stage.stageWidth;
			var myHeight:Number = stage.stageHeight;

			// ステージ領域のシェイプを作成します
			exitShape = new Shape();
			exitShape.graphics.beginFill(0x333333);
			exitShape.graphics.drawRect(0, 0, myWidth, myHeight);
			exitShape.graphics.endFill();
			addChild(exitShape);

次に、オブジェクトがステージ領域から外れたら呼ばれる関数に
プールからの解放と表示リストからの削除をする処理を記述します。

		/**
		 * ExitShapeTriggerクラスのコンストラクタに設定するコールバック関数
		 * リファレンスには詳しく書かれていないですが第1引数は対象オブジェクトのようです。
		 */
		private function onExitShape(clip):void
		{
			// 対象オブジェクトをプールから解放します
			pool.release(clip);
			// クリップコンテナから対象オブジェクトを削除します
			clipContainer.removeChild(clip);
		}

最後に、オブジェクトがステージ領域から外れたかどうかをチェックする処理を、
pool.onRequestObjectの関数内に記述します。

※一部抜粋

				// 振動を実行させます。
				yVibration.start();

				// シェイプから外れたかどうかをチェックします
				// 第1引数には、対象オブジェクトがシェイプから外れた場合に呼ばれるメソッド
				// 第2引数には、対象オブジェクト
				// 第3引数には、検知するシェイプ
				// 第4引数には、対象オブジェクトの実際のピクセルで比較するか境界ポックスで比較するかどうか(hitTestPointメソッドの第3引数と同じ意味)
				// 第5引数には、対象オブジェクトを一度シェイプに入れる必要があるかどうか
				var exitTrigger:ExitShapeTrigger = new ExitShapeTrigger(onExitShape, clip, exitShape, false, false);

				// チェックを開始します。
				exitTrigger.start();

				clipContainer.addChild(clip);

ステージ領域から外れたオブジェクトが消えることが確認できます。
しかも、外れたオブジェクトが新たに作成されることも確認できました。
※ステージサイズが550px×400pxで、SWFの表示サイズを600px×480pxにして確認しています。

別ウインドウで表示

これは、前回の『ランダムにムービークリップを表示する』で記述したSimpleRhythmクラスのメソッドが
一定時間動いてるからです。

次に、ExitShapeTriggerコンストラクタの第5引数について仕組みを考察してみます。

第5引数をfalseに設定してみるとオブジェクトが上に動くことなく、点滅したようになります。

別ウインドウで表示

これは第5引数で、オブジェクトが既にシェイプに入っていると設定しているので
SimpleRhythmクラスのメソッドによって作成された瞬間に
シェイプから外れたと判断され削除の処理が実行されます。
さらにSimpleRhythmクラスのメソッドによって再度作成されるので
ステージを横断することなく点滅してしまいます。

では、第5引数をfalseの状態のまま
オブジェクトが作成した際に既にシェイプに入っている状態になるように
ステージ領域のシェイプを広げてみます。

※一部抜粋

			exitShape.graphics.drawRect(0, -myHeight*0.25, myWidth, myHeight*1.5);

※ステージサイズが550px×600pxで、SWFの表示サイズを600px×720pxにして確認しています。

別ウインドウで表示

正常に動くことが確認できました。

再度、第5引数をtrueの状態に変更します。
そこで今度はステージ領域のシェイプの横幅を半分ぐらい短く設定してみます。
※一部抜粋

			exitShape.graphics.drawRect(0, 0, myWidth*0.6, myHeight);

※ステージサイズが330px×400pxで、SWFの表示サイズを600px×480pxにして確認しています。

別ウインドウで表示

シェイプに入ったオブジェクトだけ、シェイプから外れた瞬間に消えることが確認できました。

最後に、これまでの内容を踏まえコンテンツを次のように調整します。
・第5引数をfalseの状態に変更
・シェイプの横幅をステージ領域に戻し、高さをオブジェクトの生成/削除されるタイミングが
 ステージ上で見えないように調整
・シェイプを非表示に設定(非表示にしても検知可能です。)
・オブジェクトの数を増加(200個)

別ウインドウで表示

段々と形になってきました!

今回は、チュートリアルの26分ぐらいから39分ぐらいまでのお話でした。

調べれば調べるほど興味深いです。
ちゃんと、メモリ管理も考慮して作られています。

指摘等ございましたらご連絡いただけると幸いです。

HYPE frameworkの勉強(2)

火曜日, 1月 26th, 2010

初回はこちら
初回までのソースはこちら

※ 注意 ※
自分はFlexBuilder3を使用して試していますので
CS4を使ったやり方は実際のチュートリアルを参照ください。

色をランダムに変えてみる

ColorPoolクラスをインポートします。

	import hype.extended.color.ColorPool;

コンストラクタに、ColorPoolクラスのインスタンスを作成し
addColorで色情報を追加していきます。

※一部抜粋

			// コンテナを作成
			clipContainer = new Sprite();
			addChild(clipContainer);

			// カラープールを作成
			ghostColor = new ColorPool();
			// カラープールに色を追加します
			// カウントが多いとその色が出る確率が高くなります
			// 第1引数には、プールさせる色
			// 第2引数には、追加する数
			ghostColor.addColor(0xFFFFFF, 3);
			ghostColor.addColor(0xF7F7F7, 3);
			ghostColor.addColor(0xECECEC, 3);
			ghostColor.addColor(0xCCCCCC, 3);
			ghostColor.addColor(0x999999, 3);
			ghostColor.addColor(0x666666, 3);
			ghostColor.addColor(0xFF3300);
			ghostColor.addColor(0xFF6600);

			// スクリーンアセットを作成かつプールし管理させます
			// 第1引数には、作成するクラス
			// 第2引数には、作成するインスタンス数
			pool = new ObjectPool(MyGhost, 50);

第2引数に追加する数をセットしていますが、

ghostColor.addColor(0xFFFFFF, 3);

これは、0xFFFFFFを3回追加したことと同じ意味になります。

ghostColor.addColor(0xFFFFFF);
ghostColor.addColor(0xFFFFFF);
ghostColor.addColor(0xFFFFFF);

つまり、ここでは追加する数が多いほど
後でランダムに色を塗る際の、その色がでる確率が高くなります。

次に、実際に色をつける処理を、pool.onRequestObjectの関数内に記述します。

※一部抜粋

				// 大きさをランダムに変える
				clip.scaleX = clip.scaleY = (Math.random() * 1.25) + 0.75;

				// 指定したオブジェクトの子DisplayObjectに色をつけます。
				ghostColor.colorChildren(clip);

				// オブジェクトを指定した方向に振動させます。

実行してみたところ、、色が全くつきません。。

別ウインドウで表示

frameworkのソースを見たところどうやら、自作したMovieClipに問題が
あるようでした。
そこで、次のように、

ColorPoolを使用した塗りを適用させたい箇所を入れ子のInteractiveObjectの子クラスにしてやると
ちゃんと色がつきました。

別ウインドウで表示

よくよくチュートリアルを見直すとJoshuaさんが最初のほうで
言ってます。完全にスルーしていました。。

本日は、チュートリアルの19分ぐらいから26分ぐらいまでのお話でした。

もう少し進める予定でしたが、サンプルの準備が厄介なので
次回に持ち越します。

指摘等ございましたらご連絡いただけると幸いです。

HYPE frameworkの勉強

日曜日, 1月 24th, 2010

JoshuaDavisさん、BrandenHallさんのプロジェクト『HYPE framework』のver1.1.1が
2010年1月17日にリリースされたということなので早速勉強を始めました。

個人的に、JoshuaDavisさんのプロジェクトには常に感銘を受けおり、
あのJoshuaDavisさんのプロセスがライブラリとして提供されるということは
とても刺激的なことです。

HYPE frameworkとは何か?

英語が読めないので正しく伝えられないですが、
翻訳機能を駆使しながら読んだ感じだと、
Flash、AS3初心者でも創造的な表現などを学ぶことのできる
アニメーションのフレームワークという位置づけみたいです。

また、HYPE frameworkを始めるには、
基本的なプログラミング知識(変数、条件、ループ、関数)と
サンプルを見ればよいですよとのことです。

HYPE frameworkのチュートリアルを見ながら触ってみる

まずは感覚をつかむため、HYPE frameworkのブログに
Joshuaさんがポストしているチュートリアルを基に触ってみます。

HYPE ghosts October 2009 from Joshua Davis on Vimeo.

※ 注意 ※
 基本的にサンプルはFlashCS4で作られていますが、自分はもっていないので
 FlexBuilder3にframeworkのソースを入れて試しています。
 また、自分が試しているHYPE frameworkのバージョンは1.1.1になります。
 framework内のクラスを覗いたところ、Vectorクラスが使われているので、
 FlashPlayer10以上の動作環境が必要になります。

そもそもこのフレームワークの読み方は?
Joshuaさんの発音を聞く限り、「ハイプ」で良いみたいです。

ムービークリップの作成
サンプルでは既にありそうなんですが、CS4をもっていないので
サンプルファイルが開けません。
そこで、適当なMyGhostムービークリップを作成します。
追記(10.01.26):
適当に作ると、ColorPoolクラスを使った処理がうまく動きません。。
詳しい説明は次の回を参照ください。

ランダムにムービークリップを表示する

次のコードで、
ムービークリップの作成、ステージへのランダム配置を
100ミリ秒間隔で50回実行することができます。

package
{
	import flash.display.MovieClip;
	import flash.display.Sprite;

	import hype.framework.core.ObjectPool;
	import hype.framework.core.TimeType;
	import hype.framework.rhythm.SimpleRhythm;

	[SWF(backgroundColor=0, frameRate=25, width="550", height="400")]
	public class Hype01 extends Sprite
	{
		// クリップコンテナ
		private var clipContainer:Sprite;

		// オブジェクトプール
		private var pool:ObjectPool;

		/**
		 * コンストラクタ
		 */
		public function Hype01()
		{
			var myWidth:Number = stage.stageWidth;
			var myHeight:Number = stage.stageHeight;

			// コンテナを作成
			clipContainer = new Sprite();
			addChild(clipContainer);

			// スクリーンアセットを作成かつプールし管理させます
			// 第1引数には、MyGhostのインスタンス
			// 第2引数には、作成するインスタンス数
			pool = new ObjectPool(MyGhost, 50);

			// 任意の関数を一定間隔で実行させます
			// 第1引数には、実行させたい関数
			var rhythem:SimpleRhythm = new SimpleRhythm(addNextClip);

			// 実行
			// 第1引数には、実行タイプ(デフォルトはEnterFrame)
			// 第2引数には、間隔
			rhythem.start(TimeType.TIME, 100);

			// 新しいオブジェクトを作成(pool.request())した後に呼ばれる関数を設定します
			// 第1引数には、作成されたオブジェクトを設定
			pool.onRequestObject = function(clip:MovieClip):void{
				clip.x = Math.random() * myWidth;
				clip.y = 100;

				clipContainer.addChild(clip);
			}

		}

		/**
		 * SimpleRhythmクラスのコンストラクタに設定するコールバック関数
		 * リファレンスには詳しく書かれていないですが第1引数は設定するSimpleRhythmクラスのようです。
		 */
		private function addNextClip(myRhythem:SimpleRhythm):void
		{
			// 新しいオブジェクトを作成します
			// 新しいオブジェクトがない場合はnullを返します
			pool.request();
		}

	}
}

早速、パブリッシュを行ったところ、コンパイルエラーが発生しました。。
自分の環境だけかもしれませんが、
RhythmManagerクラスに2箇所エラーが出ます。

いきなりつまずいたのですが、、何とかしても動かしてみたかったので
とりあえず、エラーが出ている箇所118行目、187行目に
Event.EXIT_FRAMEと定義しているところをEvent.ENTER_FRAMEと修正。
これでとりあえずは(後々問題になるかもしれませんが・・)コンパイルできました。

追記(10.01.25):
当初FlashPlayer9のコンパイル環境で試していたのが原因でした。FlashPlayer10のコンパイル環境であればエラーは出ません。

別ウインドウで表示

とりあえず、ステージに表示するところまでできました。

大きさもランダムに変えてみる

pool.onRequestObjectの関数内に
スケール値をランダム関数を使って変更する処理を追加します。

※一部抜粋

			// 新しいオブジェクトを作成(pool.request())した後に呼ばれる関数を設定します
			// 第1引数には、作成されたオブジェクトを設定
			pool.onRequestObject = function(clip:MovieClip):void{
				clip.x = Math.random() * myWidth;
				clip.y = 100;
				// 大きさをランダムに変える
				clip.scaleX = clip.scaleY = (Math.random() * 1.25) + 0.75;

				clipContainer.addChild(clip);
			}

別ウインドウで表示

大きさも問題なくランダムに変更できました。
ここまでは、自分で作成するのとあまり労力はかわらないかもしれません。

スクリーン上のMyGhostインスタンスを動かしてみる

まず、DirectionalVibrationをインポートします。

import hype.extended.behavior.DirectionalVibration

次にpool.onRequestObjectの関数内に
DirectionalVibrationクラスのインスタンスを作成し、
Y座標で移動するような設定をし、実行します。
Y座標の初期値もステージから出るようにします。

※一部抜粋

			// 新しいオブジェクトを作成(pool.request())した後に呼ばれる関数を設定します
			// 第1引数には、作成されたオブジェクトを設定
			pool.onRequestObject = function(clip:MovieClip):void{
				clip.x = Math.random() * myWidth;
				clip.y = 450;
				// 大きさをランダムに変える
				clip.scaleX = clip.scaleY = (Math.random() * 1.25) + 0.75;

				// オブジェクトを指定した方向に振動させます。
				// 第1引数には、対象オブジェクト
				// 第2引数には、対象プロパティ
				// 第3引数には、弾力値?
				// 第4引数には、加減速値?
				// 第5引数には、振動幅の最小値
				// 第6引数には、振動幅の最大値
				var yVibration:DirectionalVibration = new DirectionalVibration(clip, "y", 0.9, 0.02, -20, -30);

				// Y座標への振動を実行させます。
				yVibration.start();

				clipContainer.addChild(clip);
			}

別ウインドウで表示

クラス名がVibrationとついているので前後に動くものを想定していましたが
引数の指定次第で、単純な動きになるようです。

実際に引数をちょっと変えただけで面白い動きをするので色々と試す価値がありそうです。

次のような引数にすると、、

var yVibration:DirectionalVibration = new DirectionalVibration(clip, "y", 1, 0.1, -20, 20);

別ウインドウで表示

振動する動きがより鮮明になりました!

想像以上にエントリが長くなったのでとりあえず一旦ここまで。

これまで(チュートリアルビデオでいうと約19分ぐらいですが)Hype frameworkを使った
単純な動きの勉強をしてきましたが、
次からはさらにHYPE frameworkの興味深い機能などを勉強していきたいと思います。

調べながら書いてはいますが、誤った情報があった場合は
指摘していただけると助かります。

追記(10.01.24):
現在コメントが投稿できないようです。原因調査中です。
l00oo.oo00lさん報告ありがとうございました!
取り急ぎ何かありましたら以下までお願いいたします↓
otayori[アット]awk2.net

分割処理というより敷き詰め処理

金曜日, 10月 23rd, 2009

最近、自分の親しい周りで分割処理をチャレンジしているので
自分もやってみました。

ただ、同じことをしてもなんとなくテンションがあがらないので
アプローチを変えてチャレンジです。

やり方は、単純でテトリスみたいに隙間を埋めていく方法です。

描画する正方形の最小サイズを1行と考え、

1. 最初の行は、適当に隙間を敷き詰め。
2. 次の行に移り、空いている隙間を見つける。
3. 空いている隙間に入る大きさの正方形を敷き詰める。
4. 最後の行まで2、3の繰り返し。

結果はこうなりました。(追記091023:以下はランダムに出るようにちょっと処理を加えています。)

(クリックで再描画)

思ったより処理も速くキレイにできました。
応用すれば、長方形もできそうです。

切り捨て処理は、キャストかビット演算で

水曜日, 10月 7th, 2009

yd_nikuさんのwonderflのソースを眺めていたら

flash on 2009-10-5 – wonderfl build flash online

見たことない処理を発見。

>>0

0ビット移動して何しているんだろうと思い、
色々実験してみたところ
どうやら切り捨て処理をしているみたい。

trace(10.1 >> 0); // 10

ビット演算が速いのはなんとなく知っていたのですが、
今までこういう使い方は知らなかったのでかなり斬新でした。

で、実際どれぐらい速いのかと思い
テストしてみました。

サンプルは次の3つで
・Mathクラスのfloorメソッド
・キャスト
・ビット演算
単純な10,000,000回の処理でどれが速いかをテスト。

まずは、Mathクラスのfloorメソッド

var d:int = getTimer();

for (var i:uint=0; i < 10000000; i++)
{
	var n:uint = Math.floor(10.1);
}

trace(getTimer() - d + "ms");

1回目 390ms
2回目 392ms
3回目 389ms
4回目 395ms
5回目 391ms

次は、キャスト

var d:int = getTimer();

for (var i:uint=0; i < 10000000; i++)
{
	var n:uint = uint(10.1);
}

trace(getTimer() - d + "ms");

1回目 2324ms
2回目 2388ms
3回目 2366ms
4回目 2350ms
5回目 2337ms

最後は、ビット演算

var d:int = getTimer();

for (var i:uint=0; i < 10000000; i++)
{
	var n:uint = 10.1 >> 0;
}

trace(getTimer() - d + "ms");

1回目 403ms
2回目 413ms
3回目 407ms
4回目 420ms
5回目 459ms

予想通り、Math.floorは重いですが、
キャストとビット演算だとキャストの方が若干速い!

ということで、
自分はキャストをいままで通り使うことにします。

しかし、wonderflはいろんな人のコードが見れて
とても勉強になりますね。

pv3dでポリゴンの順序がずれる

火曜日, 7月 28th, 2009

Papervison3Dで蛇腹のモーションを作っていたら、
どうもポリゴンの順序がずれることが判明。

色々調べたところFlash3Dブログさんに興味深い記事が。

このアルゴリズムの欠点は、奥行きを判定するのがポリゴン単位なため、交差しているポリゴンの奥行きを正しく描画できないことです。Papervision3Dでモデルを表示した際、ポリゴンが欠けて見える事があるのはこのためです。
Flash3Dブログ: Papervision3Dの仕組みについて

なるほど、蛇腹は交差はしてないものの
隣接する2つのオブジェクトが同じ座標を見ているので判定が難しいのかもしれません。

ちなみに自分が試したところ、10度までの接近ならポリゴンが正常に描画されました。

隣接するオブジェクトの角度が9度の場合

隣接するオブジェクトの角度が10度の場合