メイン

2014年11月29日

Tween24のバグ見つけたのと対処法について

トゥイーンによるアニメーション制御をメソッドチェーンでがんがん書けることで有名なTween24ですが、なんか
アニメがズレるなあと思ってテストコード書いてみたら途中でマニュアルモードが勝手に解除されてた件。

続きを読む "Tween24のバグ見つけたのと対処法について" »

2008年07月02日

フラグ駆動ライブラリ Flagment

フラグ(変数値)によってメソッドを呼び出すためのライブラリを SparkProject にコミットしました。

Flagment


そうめんに触発されて以前作ったChainライブラリに手を入れようかなと思ったんですが、非同期処理ってどうもソースコードが汚くなりがちなのでもっと単純にすべきなのではと考えた挙句、フラグ駆動に落ち着きました。

まあぶっちゃけこれだけで非同期処理やろうとしても、かえってフラグ管理が大変になるのでオススメできないのですが、依存度の低いクラスの中で判定のためだけにインスタンス参照持ちまわすとかアホくさいことしなくても済みます。
他に有用なケースはないか探してみますが、いい使い方あったら教えてください。


使いたい時にちょっとだけ入れてみる、それだけで使えます。
インスタンス作る必要もありません。


以下サンプルコード


Flagment.register("a", 1 ); // フラグaを登録(初期値:1)
Flagment.register("b", true ); // フラグbを登録(初期値:true)

Flagment.bind("a", 10, age ); // フラグaの値が10になったら関数ageを呼ぶ
Flagment.bind("a", 10, sage ); // フラグaの値が10になったら関数sageを呼ぶ
Flagment.bind("a", 20, hoge ); // フラグaの値が20になったら関数hogeを呼ぶ
Flagment.bind("b", false, ahoge, true ); // フラグbの値がfalseになったら一度だけ関数ahogeを呼ぶ

Flagment.update("a", 10 ); // フラグaの値を10に更新(ageとsageが呼ばれる)
Flagment.update("b", false ); // フラグbの値をfalseに更新(ahogeが呼ばれる)

Flagment.unbind("a", 10 ); // フラグaの値が10になった時の駆動メソッドを全て解放
Flagment.unbind("a"); // フラグaの駆動メソッドを全て解放

Flagment.unregister("a"); //フラグaを解放
Flagment.unregister("b"); //フラグbを解放


複数フラグのAND対応もしています。
第一引数はフラグ名ではなく識別用ラベルなので、どういう駆動なのか説明するラベルを推奨


Flagment.bindAnd("a5_and_!b", { a:5, b:false }, toge ); // フラグaの値が5かつフラグbの値がfalseになったら関数togeを呼ぶ
Flagment.update("a", 5 ); // フラグaの値を5に更新
Flagment.update("b", false ); // フラグbの値をfalseに更新(togeが呼ばれます)
Flagment.unbindAnd("a5_and_!b"); // 上記の駆動を解除


一元管理しているので、全く異なるクラス内で呼んでもOKです。
というか、元々そういう目的で作っています。
分散している処理の終了時にそれぞれフラグを立てて、全てが終了したらメソッドを呼ぶといった用途に使えると思いますが、それはそれで面倒かも?

優先度とか比較演算子の定義まで入れられたらと思うのですが、ちょっと冗長な気もするのでひとまず使ってみてから判断します。
複雑な条件を定義できるようにすべきかどうかも。

2008年02月25日

こくばん.in β版リリース

先日のコリン・ムック迎撃イベントの発表資料で小ネタとして用いた黒板手書きエフェクトをサービスとして昇華リリースしました。


こくばん.in


見ての通り、黒板です。

チョークは6色のみ。
学校の先生もそれでやりくりしてるわけで、不便なんて言わせません。
一応マウスホイールor上下カーソルでチョークのサイズを変えられますが、エッジを使って細く書いたりするのを代用してるつもりで。

この手のサービスにありがちな、一手戻るだとか初期化とかも一切ありません。
リアルの黒板にそんな機能ないですよね。
ミスっても黒板消しで地道に消しましょう。
意外と楽しいかもしれないですよ?


β版ということで最低限の機能しかありませんが、ユーザ登録やコメントなどできれば追加していきたいなと思います。

2008年02月16日

バレンタインネタゲームのソース公開

すっかり忘れていたんですが、先日のバレンタインゲームのソース公開します。

valentine.zip

ああいう突貫で作ったネタゲームなんかは技術抱え込んでもしょうがないというか大したことやってないので、as3初心者が勉強する取っ掛かりにはいいかなと思います。
コード自体は全部asファイルに書いてあります。
FlashCS3 がないとパブリッシュできないのであしからず。


ごくごく簡単な説明。
今回ほとんどのオブジェクトが画面の右から左へスクロールするので、一定速度の移動を制御する Movable クラスを作って各々継承。
クラス生成時に速度渡せば勝手にスクロールしていきます。
ものによっては衝突判定が入ってくるので、必要に応じて移動処理をオーバーライド。
そのへんの追加処理を抽象メソッドにしておいてもよかったけど、適当なのでパスパス。
効果音再生や衝突判定はイベント駆動させるのが面倒くさかったので、各クラスにドキュメントクラスへの参照を持たせておいて必要時に直接メソッド呼ぶようにしてます。
手抜きプログラミング万歳。


衝突判定を領域分割するとか破片をビットマップに描画するとか最適化の余地はいくらでもあるんですが、実際そういうこと一切やってなくて超富豪プログラミング。
Flashゲーム作る時は何よりもまず遊べるようにするところに注力すべきです。
最適化なんて完成してからでいいじゃない。

こういうミニゲームを仕様書くだけで簡単に構築できるライブラリは作ってみたいですなあ。

2008年02月14日

バレンタインネタゲーム作ってみた

クリスマスネタゲーム作ってみたに引き続き、ネタゲームです。
見ての通り、ほとんど使い回しです。

バレンタインの惨劇!?


カップルをスナイプしたり、チョコレートをスナイプで弾き飛ばしたり、弾き飛ばされたチョコレートをスナイプで破壊したり。
クリスマスと違って、バレンタインにはテーマ曲らしいテーマ曲がないので無音の中もくもくとスナイプする地味なゲームになってしまいました。

例のごとくクリアやゲームオーバーなど全くありませんが、バレンタインなんてなくなればいいと思ってるそこの貴方、思う存分スナイプしませう。

2008年02月13日

アイコンファイルのデコーダクラス作った

flash で favicon.ico を直接読み込みたいなと思ったので作りました。


ICODecoder


マスクデータとかRLE圧縮とか全部対応してますが、クロスドメイン制約のせいでURLを直接指定して読み込むのはほとんど無理という罠。
実際に読み込むにあたっては面倒ですがサーバ介しましょう。
サーバサイドで画像変換しちゃえばいいじゃないかという本末転倒な解決策はこの際無視です。


以下サンプルコード。
デコード結果が配列なのは、ICOファイルに複数のアイコンデータが格納されているため。


var decoder:ICODecoder = new ICODecoder();
var arr:Array = decoder.decode( bytes );

for ( var i:int = 0; i < arr.length; i++ ) {
var data:ICOImageData = arr[i] as ICOImageData;

if ( ( data.info.width == 16 ) && ( data.info.height == 16 ) ) {
// 16x16だったら
addChild( new Bitmap( data.image ) );
}
}

関連エントリ:
外部BMPファイルを読み込むためのデコーダクラス作った
PSDParser リリース

2008年01月29日

as3の非同期処理を行うお手軽ライブラリを作った

CommandだとかThreadだとかChainだとか、as3の非同期処理クラスを見ていて思うのはとにかく小回りがきかないこと。

実装はどれも素晴らしいんですが、ちょっとだけ使いたい時でもひたすら型を書かなきゃならなかったりと微妙に不便なので手軽に使える非同期処理クラスを作りました。
ASDeferred(JSDeferred) をベースにしています。


Chain ライブラリ


・・・激しく名前かぶってますorz
だって後から知ったんだもの。

コンセプトは以下の3つ。
・やってることが一目で分かる
・必要なコード量を極力減らす
・取得データを参照しやすい仕組み

続きを読む "as3の非同期処理を行うお手軽ライブラリを作った" »

2008年01月25日

非同期処理クラス ASDeferred を作ってみた

JSDeferred の実装に感銘を受けて、思わず ASDeferred として移植してみました。

SparkProject にコミット。
ASDeferred

といっても ActionScript3.0 のクラスなので function を書くたびに返り値の型をしっかり記述しなければならず、はっきりいって使い勝手は激悪ですwww
それでも移植せずにはいられなかったというやつです、はい。

それと parallel が直列で繋げないのがどうにも腑に落ちなかったので、直列に繋ぐための挿入コードを追加してみました(一応コメントアウト)
テストコードの方も同様にコメントアウトしています。
クラスメソッドを呼ぶかインスタンスメソッドを呼ぶかの違いだけとはいえ、どうも混乱しそうなので使いやすい方を選ぶべきなのかなと思いますが、このあたり JSDeferred の中の人にも聞いてみたいなと思います。

テストが不完全なところがあるかもしれないので、おかしな挙動があったらコメントください。

2008年01月01日

煩悩の鐘

あけましておめでとうございます。
今年もどうぞよろしくお願いします。


年明け直前に思い立って作ったネタ、さすがに間に合わなかったため年明け後に Twitter でこっそり投下するだけにとどめたのですが、1年後まで公開を見送ってもしょうがないので公開してしまいます。


煩悩の鐘

名前を入力して、鐘をクリックするだけ。
108個の煩悩が吹っ飛びます。
除夜の鐘で浄化できなかった貴方の煩悩、なんて位置付けはどうだろうw


脳内メーカーもどきなのは重々承知、というか明らかに劣化版ですね。
文字とかアイコンを大量に吹っ飛ばす実験作のひとつ、ということで;

2007年12月27日

ぴたごらったー

クリスマスの惨劇!?に引き続き、Box2DFlashAS3の習作第二弾です。

ぴたごらったー

Twitterにログインしている状態でアクセスすると、友達のアイコンが山のように降ってきます。
最終発言時刻に応じてアイコンの大きさが変わるので、アクティブユーザがなんとなく分かる感じ。

ステージをドラッグするとラインを描画、シフトキーを押しながらだと円を描画できます。ツールボタン群を用意しました。
パチンコっぽいものを作ったり、特定のアイコンを閉じ込めたり。
配置しなおしたい時は、オブジェクトをクリックで消し消し。

隠し機能的ですが、マウスホイールでFPS調整ができるのでスローモードでもお楽しみいただけます。
どうもFirefoxでは機能してないみたいなので、IE推奨ということで(IEの方がそもそも動作軽いし)

スピードメータを追加しました。クリックで変えられるのでお好みの速度でお楽しみください。

将来的にはオブジェクトごとに摩擦係数やはねかえり係数を設定できるようにする予定。
アイコンの色とかユーザの発言内容を反映させるのもありかなと。

2007年12月24日

クリスマスネタゲーム作ってみた

クリスマスツリーとばしに触発されて、ネタゲームを作ってみた。
クリスマスではしゃいでるカップルなんて死ねばいいのにとか思ってる人は是非!?

クリスマスの惨劇!?


物理演算は Box2DFlashAS3 を使用しました。
マウスを押す時間に応じてプレゼント箱が大きくなるので、ゴロゴロ転がしていきましょう。

このままでも面白いんだけど、ゲームオーバーをどうしようか悩み中。


[追記]
エントリファイル名ミスった…もう何件かブクマされてるのでこのままでー

2007年12月15日

Twitter弾幕シューティング「Bulletter」作った

Twitterの発言を弾幕生成器としてあれこれしてみました。

Bulletter


やりすぎ感は否めません。
東方風に仕上げたので、操作周りもなんとなく踏襲。
カーソルキーで移動、Zで攻撃、Shiftで低速移動ができます。
やられても特にペナルティなし。


時間が確保できず、年内公開が危ぶまれたので完成度5割ながら公開することにしました。
生成パターンが少ないのは仕様ですが、ちょっとずつ増やしていきます。
理想としてはスペルカード名が発言に含まれていると……あくまで理想です。
ボムだとかスコアだとかそういうのは余裕ができたらつけると思います。


たまに緋蜂みたいなひどいのがくるので環境によっては激重になりますが、as3をもってしてもこの辺がflashの限界ラインかなと思います。

2007年11月08日

初音ミクが3dでティウンティウン

まーなんというか、百聞は一見に如かず。

ティウンティウン3d

クリックでティウンティウン、その後は弾幕レボリューションと同じです。
一定時間で復活するのでエンドレスでティウンティウンできます。
他にもいろいろギミック考えてたんですが、なんかグダグダになりそうなのでさっさと公開。


3dデータはnote.xで配布されているものをお借りしました。ありがとうございます。

2007年10月24日

弾幕レボリューション

すっかり弾幕が板についてしまったので、もうひとつ新機軸かもしれない作品を公開。

弾幕レボリューション

なんの変哲もない3D弾幕ですが、表示されている弾幕全てに当たり判定があります。
3Dなのに2D。

ただそれだけだとなかなか避けられるものではないので、画面ドラッグで任意に空間を回転させられるようにしました。
回転中は時間が停止するとともに、無敵状態になります。
これにより、安全地帯を確保するための空間回転という避け方ができます。

この能力を敵が使ってきても面白いかもしれないですね、東方とかで。
余裕で避けられる弾幕が空間回転によって豹変するような。


ひたすらドラッグを繰り返しているとほぼ無敵なのでゲージ作ろうと思ったのですが、そこまでするほど弾幕の方を作り込んでいないので、まずは雰囲気を味わってもらおうと敢えてゲーム性を封印しました。


6年ほど前に適当に作ったループサウンドをはめてみたら割といい感じになったので、そのまま公開しています。
初音ミクでDTMブームが再燃してるので、また機材引っ張り出そうか・・・


スペック依存な作りなので、重いと感じたらブラウザのサイズを小さくしてください。
全画面でもお楽しみいただけます。

2007年10月21日

PSDParser リリース

FlashPlayer 上で PSD ファイルを展開することができる PSDParserSpark Project の Snippets にコミットしました。


レイヤー別にドラッグできるサンプル(読み込んだPSDファイル







もともとはJavaで書かれたコードを移植したものなのですが、 PSD のフォーマットと若干違う部分があったりバイトコード読み飛ばしてる部分が多かったりと気持ち悪かったので、ずいぶん手を加えてしまいました。
ひとまずレイヤーの有無に関わらず(背景のみであっても)画像を表示できるようにしましたが、一部どうやっても実現できないブレンドモードがあるので完全対応ではありません。
また、ドロップシャドウなどのレイヤー効果についてもフォーマットが不明なので未対応です。

このあたりはオンラインフォトショップを見据えているためか Adobe が公開を控えているので、バイトコードとにらめっこしながらひとつずつ調べていくしかないようです。
Photoshop 3.0.4 Software Development Kit の PDF しか手元にないので、なにか詳しいこと知ってる人がいたら教えてください。


関連エントリ:
外部BMPファイルを読み込むためのデコーダクラス作った
アイコンファイルのデコーダクラス作った

2007年10月15日

弾幕時計ブログパーツ改良

目がチカチカすることで巷で評判(?)の弾幕時計ですが、このたび窓の杜に紹介されました。
ただ、現状ではブログパーツとして使うにはあまりに目立ちすぎるので、設置者によって色をカスタマイズできるようにと改良を施してみました。

色を変更するにはFlash貼り付け時に、以下のようにFlashVarsパラメータを付加します。

h=RRGGBB&m=RRGGBB&s=RRGGBB&f=RRGGBB,RRGGBB,RRGGBB,RRGGBB

h:時針
m:分針
s:秒針
f:枠を構成する交差弾の色をカンマ区切りで(数は自由)


設定サンプル


<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="160" height="240" id="bulletclock" align="middle">
<param name="movie" value="http://www.voidelement.com/bulletclock/blogparts.swf" />
<param name="bgcolor" value="#000000" />
<param name="wmode" value="opaque" />
<param name="FlashVars" value="h=cccc00&m=00cc99&s=ffffff&f=666666,cc0000,9933cc,cc66cc" />
<embed src="http://www.voidelement.com/bulletclock/blogparts.swf" FlashVars="h=cccc00&m=00cc99&s=ffffff&f=666666,cc0000,9933cc,cc66cc" bgcolor="#000000" width="160" height="240" name="bulletclock" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

2007年10月10日

ハーフトーンカメラにブラーかけてみた

それっぽくなった。
配信に使うならこっちの方がいいかな。
ドットドットしてる方もアレはアレで味があるので、そこらへんは好みの問題で。















ちなみにそれぞれ、画像処理部分に以下のコードを追加しただけ。

effect_bd.applyFilter( effect_bd, rect, zero, new BlurFilter( 2, 2, 1 ) );

2007年10月08日

ハーフトーンカメラ(カラー)

前回のエントリに引き続きハーフトーンカメラ処理、今度はカラー版です。
RGBそれぞれに対してハーフトーン処理を行うと、8色に減色できるようなのでこちらも作ってみました。








大部分はモノクロ版と同じですが、最後の変換を paletteMap で一括変換しています。
こちらも全ピクセルをなめる必要なし。
画像処理様様ですね。


ソースは以下。

続きを読む "ハーフトーンカメラ(カラー)" »

ハーフトーンカメラ(モノクロ)

Flash上でwebカメラにエフェクトかけて仮想カメラでキャプチャすれば、ustreamに加工映像を流せるようになるのでいろいろ試してみることにしました。

たとえばかまいたちフィルタ(PastClips参照)
http://ustream.tv/channel/munegons-show


他にどんなことができるかなと探していたらハーフトーン処理(ディザ法)なるものがあったので参考に作ってみました。








もちろん全ピクセルをひとつずつ見るようなことはせず、画像処理で一括変換してます。
これでustream配信しても面白そう。
こないだ衝動的に bitmapdata.jp のドメインを取ってしまったのもあるので、この手のエフェクトを集めてみるところから始めてみようかなと考えています。


ソースは以下。

続きを読む "ハーフトーンカメラ(モノクロ)" »

2007年10月04日

弾幕時計 -BULLET CLOCK-

多分こういうのは今までなかったと思うので作ってみた。

弾幕時計 -BULLET CLOCK-

秒針は加速弾。
分針と時針は何の変哲もない低速弾。
針はそれぞれ角度が切り替わるたびにはじけます。

時計の枠をあしらっているのは交差弾。
他にも扇状弾とか趣向凝らそうと思ったんですが、くどくなるのでやめました。
残念ながら避け要素はありません。


ついでなのでスクリーンセーバーも作ってみました。
ディスプレイ解像度によって秒針の長さが激しく変わってしまいますがご愛嬌。


[追記]
ブログパーツも作りました
弾幕時計ブログパーツ
弾幕時計ブログパーツ改良

2007年10月03日

ActionScript 3.0 でラベリング (改)を勝手に添削

超絶技巧発表会の資料を参照しておきながら、てっく煮ブログ:ActionScript 3.0 でラベリング (改)でラベリング時にピクセル全走査やってるのが気になってしょうがなかったので添削エントリ書かせてもらいます(笑)

いきなり改良版ソースコード

function labeling2(src:BitmapData):BitmapData {
var dst:BitmapData = src.clone(); // ソースの複製を作る
var lno:int = 0;
var rect:Rectangle = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );

while ( !rect.isEmpty() ){
for ( var x:int = rect.left; x< rect.right; x++) {
if ( dst.getPixel( x, rect.top ) == 0xffffff ){
dst.floodFill( x, rect.top, ++lno );
rect = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );
}
}
}
return dst;
}


BitmapData.getColorBoundsRectメソッドは引数で指定した色が含まれる領域を返してくれるので、最初から検索範囲を絞ることができます。
また、ラベリングの floodFill によって自動的に領域がごっそり消えるので再度メソッドを呼べばさらに検索範囲を絞られる、この繰り返しでさらに高速化を図ることができます。

うちの環境では4~5倍改善されましたが、ラベリング対象が複雑に絡み合った形状をしていると逆に遅くなる可能性があるので、検証する余地はありそうです。


ちなみに横方向走査まで getColorBoundsRect でやってみたら若干重くなりました。
やりすぎイクナイ!

書き方が悪かっただけでした・・・これで一切getPixelなしでいける上に速くなります。

というわけで、さらに改良版ソースコード。

function labeling2(src:BitmapData):BitmapData {
var dst:BitmapData = src.clone(); // ソースの複製を作る
var temp:BitmapData = new BitmapData( dst.width, 1, false, 0x000000 );
var lno:int = 0;
var zero:Point = new Point();
var rect:Rectangle = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );
var area:Rectangle = new Rectangle( 0, 0, dst.width, 1 );

while ( !rect.isEmpty() ){
area.y = rect.top;
temp.copyPixels( dst, area, zero );
rect = temp.getColorBoundsRect( 0xffffff, 0xffffff, true );
dst.floodFill( rect.x, area.y, ++lno );
rect = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );
}

return dst;
}

2007年10月01日

ドキッ!変態だらけのActionScript的超絶技巧発表会

超絶技巧+発表必須というシビアな参加条件の「ActionScript的超絶技巧発表会」に参加してきました。
どんな感じだったのかはてっく煮ブログのエントリにまとめられているので、そちらをご覧ください。

まーみんな変態というか「こんなのにまじになっちゃってどーすんの」と言わんばかりのハックぶりでポカーンとしたりさせたり発表してる自分まで危うくポカーンとしかねない勉強会でしたが、何よりも刺激受けまくりでこれだからやめられないぜ!と再確認。

で、何を発表したかというと以前公開したフィールドマップジェネレータでさりげなく使っているアルゴリズムの説明。
ピクセル走査を一切行わず、画像処理だけで全部やっちゃうという無茶っぷりを晒してみましたが、あの説明と資料でその場で理解できた人がどれくらいいたのか正直気になるところ。


発表資料をそのまま公開しても全く理解できないこと請け合いなので、口頭で説明した部分を追記しました。

発表資料
(左右カーソルキーでページ送り)

ソースはもうしばらくお待ちください。
分からないところがあったらコメントやTwitterでどしどし受け付けます。

2007年09月28日

BitmapDataの範囲拡張&収縮

てっく煮ブログ:BitmapDataの範囲拡張をするなら・・・では全ピクセルをチェックしていますが、それよりも圧倒的に軽く処理できる方法があるので紹介しておきます。






マウスで適当に線を描いて、上下キーで拡張・収縮できます。
別段難しいことをしているわけではなく、コンボリューションフィルタ使った結果をdrawしてるだけなのですが、ちょっと手抜きしたので拡張があまり綺麗じゃない・・・
もう少し作り込めば収縮と同じような感じで拡張を行えるはずですが、いずれにせよこの手の処理はビットマップのメソッドだけでやれることが多いのでアルゴリズムを考えてみると楽しいと思います。

(ブラーフィルタかけてからスレッショルドで削ることでマシになりました。ソースも微修正)


ソースは以下。

続きを読む "BitmapDataの範囲拡張&収縮" »

2007年09月26日

as3版かまいたちの夜カメラ

特に習作というわけでもないのだけれど、前に作ったかまいたちの夜カメラをas3で書いてみた。






クリックすると映像を固定。
以後、差分がいわゆるかまいたち。
上下キーでスレッショルド調整ができるけど、おまけ程度。

ほんとこれが ustream 配信できれば面白いのにな。
仮想カメラデバイスなソフトを作るスキルなんてないので残念。


あまり美しくないけど、ソースは以下。
よくよく考えたら今までソース丸ごと公開したことなかった気がする。

続きを読む "as3版かまいたちの夜カメラ" »

2007年09月15日

爆発連鎖ゲーム「CHAIN DETONATION」

AS3でゲーム作っている方々に挙がっているゲームのあまりの少なさにビックリしていたところに、ActionScript3.0がゲーム開発者に広がらないというABAさんのエントリを読んで「こりゃ作っていかないとどうにもならないな」と一念発起、ゲームを作ろうぜブームが爆発して広がって欲しいなと願いを込めてちょっくら作ってみました。

 
CHAIN DETONATION

基本的には爆発連鎖ゲーで、そこにちょっとだけマインスイーパの要素を含めてみた感じです。
一応 ActionScript3.0 で作ってはみたものの、プロトタイプは ActionScript1.0 で作っていたのと処理負荷が描画にほとんど持ってかれちゃってるのとで、ActionScript3.0で作る必要性があまり感じられない作品になっちゃいました。
というかこの手のミニゲームはルール作りが全てだと思います。

もう少し工夫すれば描画負荷は下げられそうですが、とにかく早く遊べるものにしてしまいたかったので自分的には完成度5割です。
詰め問題モードやらリアルタイム連鎖モードなど、いろいろ考えてはいるのでこれからの展開にご期待ください。


ところで今頃になって1年半前に作ったゲーム「桜吹雪」を一度もブログで紹介していなかったことに気付く。
もう少し陽の目を浴びてもいいだろうとは思ってたけど迂闊・・・せっかくなのでバージョンアップしよう。

2007年08月27日

ブログパーツ TwitterConsole を作った

3年前に作った遺産、ダイアリーマトリックスを何かに使えないかと思ってTwitterのログを流し込んでみたらカオスなことになったので、せっかくだからブログパーツにしました。








そのまんまだとアレなので、papervision3dでパースかけてみたり色んな意味で実験作。
Twitterの発言って横文字がどうしても多くなるので縦スクロールを省いた結果、ニコニコ動画っぽくなったのをパースをかけてごまかしたという説もあります。
単調にならないよう角度をある程度ランダムに振っていますが、ステージの四隅に欠けが出ないようにしつつビットマップのサイズを抑えるのがめちゃくちゃ苦労したという裏話も。

デバイスフォントをビットマップ化したりフェードアウト仕込んだりパースかけたりでめちゃくちゃ重くなってるので、このままじゃちょっと配布するのは忍びないかなといったところです。
もう少し軽くできるとは思うので、最適化が終わったら正式に配布しまっす。

2007年08月26日

外部BMPファイルを読み込むためのデコーダクラス作った

外部BMPファイルをFlashPlayerで表示するためのデコーダクラス BMPDecoder を作成しました。
RLE圧縮にも対応。

Spark projectSnippetsにコミットしました。
怪しいところがあればいくらでもご報告ください。

 
当初は BMPLoader として読み込みから表示までサポートするクラスとして作ろうと考えていたのですが、Loader を拡張すると load をオーバーロードできない、URLLoader を拡張するとインスタンスを直接子として配置できない、しょうがないから Sprite を拡張しようとしたらデコードしたビットマップデータをわざわざ子として配置するために Bitmap インスタンスまで持たなきゃいけなくなる。
じゃあもう Bitmap を拡張すればいいじゃないか。

……読み込みから表示まで行うクラスのベースクラスが Bitmap ってなんだか気持ちが悪い。

自分が使う分にはいいのですが、オープンソースプロジェクトにコミットするにあたってどうもこの気持ち悪さが拭えなかったので、デコーダだけでいいかなと。
こんなクラス使う人はそもそもこなれてるはずだから、読み込みから全部サポートしなくてもいいかなと。
データの読み込み後、すぐにデコードを行うかどうかも使う人に任せられるのできっとこの方がいいかなと。

 
最終的には拡張子を気にすることなく読み込みを行う ImageLoader クラスといった感じで作り込めれば最強なんですが、どれだけ対応しなきゃならないんだと。
こういうのは複数人で開発した方がよさそうですね。

関連エントリ:
PSDParser リリース
アイコンファイルのデコーダクラス作った

2007年07月28日

深度管理クラス DepthManager 作ったよ

AS1MovieClipクラスを作った時に必要に迫られて中途半端に実装していた深度管理を、ヘルパークラスとして切り離して作り直しました。

niumさんのところでFlexibleChildIndexerクラスというのがすでに公開されていますが、あちらはあくまでインデックス管理の拡張といった感じなので敢えて差別化を図りました。
あくまで深度、同じ深度に対する追加は上書きになるなど従来の手法に準じています。

せっかくなのでSparkProjectSnippetsにコミット。


DepthManager


詳細はリンク先あるいはソースを見てください。
途中で勝手に直接子を追加した場合などの厳密なエラーチェックが不足している感は否めませんが、そういうの自動検出するためにわざわざイベントリスナ登録した方がいいのかちょっと悩んでます。
助言求ム。

それ以外のごく普通の使い方で不都合やエラーが出る場合はご一報ください。

2007年07月23日

配置済みインスタンスの宣言文を名前空間で分かりやすくする

FlashCS3 と Flex2(あるいはas3の外部エディタ)を併用しているとよくあるのが

「あれ、この MovieClip 宣言されてるメンバって FlashCS3 で配置してあるインスタンスのことだっけ?」

 
ステージに配置済みのインスタンスについては変数宣言で public としておかなければならないため、インスタンス名で区別するしかないかなと思ってましたが名前空間を利用してしまう手もあるので紹介してみます。

 
メインタイムラインにムービークリップ(インスタンス名:mc) とボタン(インスタンス名: btn)が配置されているとして、ドキュメントクラスの宣言文に以下のように記述します。

public namespace added = public;

added mc:MovieClip;
added btn:SimpleButton;

初期状態でADDされてるインスタンスという意味合いを持たせるために added という名前空間を定義し、実体は public としておきます。
public ではなく added として宣言することで、視認性を上げようという話です。


役に立つのか微妙な気もしますが、こういうやり方もあるよーってことで。

2007年06月16日

ガーベジコレクション発動!?

いつのまに追加されていたのか気付かなかったんですが、おそらく上条さんのブログで公開されている playerglobal.swc の最新版を入れてからか、とんでもないものがFlexBuilder2のコードヒントに現れました。

flash.system.System.gc()

GC任意発動ktkr
定義だけかと思ったら、ちゃんと動いてるー

メモリリークに悩まされてきた ASer にはかなり朗報なんじゃないでしょうか。

2007年06月15日

AIRのドラッグ&ドロップ起動について調べてみた

任意のファイルをAIRアプリのアイコン上にドラッグ&ドロップして起動した時に、そのドロップされたファイル情報を取得する方法について調べてみました。


AIRアプリの起動情報に関しては flash.system.Shell クラスが把握していますが、プロパティとして直接参照はできません。
その代わりに flash.events.InvokeEvent から参照することができます。

どのタイミングでもいいようですが、起動時に必要になることが多いため applicationComplete に設定したメソッド内に以下のように記述しておくことにします。

Shell.shell.addEventListener( InvokeEvent.INVOKE, onInvoke );


そしてイベントハンドラを以下のように記述します。

private function onInvoke( e:InvokeEvent ):void {
for ( var i:uint = 0; i < e.arguments.length; ++i ){
var file:File = new File( e.arguments[ i ] );
}
var currentDir:File = e.currentDirectory;
}


InvokeEvent の arguments プロパティは、起動時に渡されたファイルのフルパスを格納した配列引数の配列です。
コマンドラインからの実行により任意の引数を渡すことができますが、デフォルトでは何も指定されていないためファイルをドロップした場合はファイルのフルパスのみが格納されます。

たとえばショートカットの設定に /a というコマンドを自前でつけてしまうと、arguments の先頭要素が /a という文字列になり、その後にドラッグ&ドロップ起動時のドロップしたファイルのフルパスが続くことになります。

このフルパスはあくまで文字列なので、実際にファイルを読むためには File インスタンスをパス情報から自前で生成する必要がありますが、コマンドラインから実行された時のことを考慮して有効なパスかどうか念のため確認した方がよさそうです。
ディレクトリをドロップした場合はディレクトリのフルパスのみが渡され、ディレクトリ内の全ファイルが配列に格納されるわけではありません。


currentDirectory プロパティは、起動パス情報を持つ File インスタンスです。
設定ファイルなど AIR アプリの格納ディレクトリ下に置く場合には、ここから参照すればよさそうですが、たまに正確な情報を返さないことがあるようなのでもう少し探ってみます。


ドロップ起動に対応するアプリが作れるなら、やれることが大幅に増えますね。

----追記----
arguments プロパティの説明について若干誤りがあったので書き直しました。
ドラッグ&ドロップ起動だけでなく、隠しコマンド起動をつけられるということですね。

2007年06月13日

AIRにドラッグ&ドロップできるものについて調べてみた

AIRアプリにドラッグ&ドロップするためには、NativeDragEvent.NATIVE_DRAG_DROP についてイベントリスナ登録する必要があります。
そこで登録したイベントハンドラが呼ばれる際に引数として渡される NativeDragEvent インスタンスに transferable というプロパティ(TransferableDataインスタンス)があり、そこにドラッグしたデータの情報が全て格納されています。


せっかくなのでどういったものをドラッグすると、どういったデータが AIR に渡されるか調べてみました。

■Firefoxで表示した Web ページのリンクテキストをドラッグした場合

1.TransferableFormats.URL_FORMAT
 リンク先URL

2.TransferableFormats.TEXT_FORMAT
 リンク先URL+テキスト


■Firefoxで表示した Web ページの画像(リンクなし)をドラッグした場合

1.TransferableFormats.URL_FORMAT
 画像URL

2.TransferableFormats.BITMAP_FORMAT
 画像をビットマップデータ化したもの

3.TransferableFormats.FILE_LIST_FORMAT
 おそらくビットマップ化する際に格納したらしき画像ファイル
 格納先 C:\Documents and Settings\{username}\Local Settings\Temp

4.TransferableFormats.TEXT_FORMAT
 画像URL+代替テキスト


■Firefoxで表示した Web ページの画像(リンクあり)をドラッグした場合

1.TransferableFormats.URL_FORMAT
 リンク先URL

2.TransferableFormats.BITMAP_FORMAT
 画像をビットマップデータ化したもの

3.TransferableFormats.FILE_LIST_FORMAT
 おそらくビットマップ化する際に格納したらしき画像ファイル
 格納先 C:\Documents and Settings\{username}\Local Settings\Temp

4.TransferableFormats.TEXT_FORMAT
 リンク先URL+代替テキスト


■PC上のファイルとディレクトリをまとめてドラッグした場合

1.TransferableFormats.FILE_LIST_FORMAT
 ファイルとディレクトリそれぞれのFileインスタンスを格納した配列


■Flashオーサリング環境のステージに配置されているムービークリップをドラッグした場合

1.TransferableFormats.BITMAP_FORMAT
 ムービークリップをビットマップデータ化したもの


■Flashオーサリング環境のステージに配置されているテキストをドラッグした場合

1.TransferableFormats.BITMAP_FORMAT
 テキストをビットマップデータ化したもの


WebページについてはFirefoxで確認しましたが、IEではリンクをドラッグできなかったため割愛しました。
Win版Safariでも若干挙動が異なるようです。

Flashオーサリング環境の配置シンボルについては複数まとめてドラッグすると多少縮小されてしまうのがよく分からない仕様ですが、ビットマップ化された状態とはいえ何か面白いものが作れそうです。

2007年06月12日

PrintScreenした画像をAIRで表示させてみる

前回のエントリではクリップボードの文字列データを問題なく拾えることが分かったので、次は PrintScreen でキャプチャしたデスクトップの画像を AIR アプリ内に表示できるかどうか試してみました。

前回言及したクリップボードアクセス用クロージャ内に以下のように記述することでビットマップデータが拾えます。
サンプルなのでエラーチェックとかそういうのは省略。

var data:TransferableData = ClipboardManager.data;

if ( data.formats[0] == TransferableFormats.BITMAP_FORMAT ){
var bd:BitmapData = data.dataForFormat( TransferableFormats.BITMAP_FORMAT ) as BitmapData;
}

で、実行したら

air_printscreen.png

あれ?
.icoしか拾ってなかったりする?
どういう構造になってんだろ。。。某ウイルスもどきが作られないように対策でもしたのかなと勘ぐってみました。
キャプチャ画像をクリップボードから直接あれこれするアプリは今のところは作れないようです、残念!

2007年06月11日

クリップボードのデータを拾ってみる

Adobe Apollo が正式名称 AIR として公開されました。
同時に FlexBuilder3 のパブリックベータ版も公開されたので、追加された機能をふんだんに使った AIR アプリが続々と出てくると思います。


今回新たに追加された機能の中で特に注目すべきはデータベースモジュールでしょう。
flash.data パッケージ以下に SQL 関連クラスがごっそり入っていますが、ざっと目を通しただけでもかなり充実している模様。
このタイミングで入ってくるとは思っていなかったのですが、先日公開された Google Gears でローカルデータベースの機運が高まりつつあるので、それに合わせてきた感じがしないでもありません。

とにかく弄ってみたい機能が目白押し。
前々から気になっていたドラッグアンドドロップやクリップボード管理のドキュメントを真っ先にチェックしてみました。
たとえばクリップボードのデータを拾うには以下のように書きます。


ClipboardManager.accessClipboard( onAccessClipboard );


private function onAccessClipboard():void {
var data:TransferableData = ClipboardManager.data;
var text:String = data.dataForFormat( TransferableFormats.TEXT_FORMAT ) as String;
}

いつでもクリップボードのデータにアクセスできるわけではなく、処理を記述したクロージャメソッドを引数として ClipboardManager.accessClipboard メソッドを実行することで初めてアクセスできるようになります。

データは TransferableData 型としてClipboardManager.data に格納されていますが、中身がテキストだったり画像データだったりするので dataForFormat メソッドによってフォーマット指定する必要があります。


また、逆にクリップボードに文字列データをペーストする場合は上記のクロージャ内に


var data:TransferableData = new TransferableData();
data.addData("hoge", TransferableFormats.TEXT_FORMAT );
ClipboardManager.data = data;

といった処理を記述します。


ヘルプにわざわざクロージャと書かれているのが気になったのですが、任意の文字列をクリップボードにペーストしようとする際に ClipboardManager.accessClipboard の引数に直接指定ができないので、下記のようなクロージャ生成メソッドを用意してねという意味なんだと思います。

ClipboardManager.accessClipboard( pasteString("hoge") );
private function pasteString( str:String ):Function {
	return function():void {
		var data:TransferableData = new TransferableData();
		data.addData( str, TransferableFormats.TEXT_FORMAT );
		ClipboardManager.data = data;
	}
}

2007年06月10日

うっかり限界突破

一瞬はまりかけたので備忘録も兼ねて。

int や uint 型の変数に Number.POSITIVE_INFINITY を代入すると 0 扱いになります。
あたかも初代スーパーマリオの無限1UPで128突破すると死んだら突然ゲームオーバーみたいな(ちょっと違う
なお、以下の4種は強制的に0になります。

・Number.POSITIVE_INFINITY
・Number.NEGATIVE_INFINITY
・Number.MAX_VALUE
・Number.MIN_VALUE

Number に定義された定数なんだから Number 型変数にしか正しく代入できません。
そりゃそーだ。

でも逆に int.MAX_VALUE はちゃんと Number 型変数に代入できる。
そりゃそーだ。

せめて最大値(最小値)に丸めてくれたらいいのになーと思った日曜の昼下がりでした。
とはいえ、丸められてたらこのことに気付かないままだったかと思うとなんだかなー

~ せっかくなので試しにイロイロやってみた ~

new Array( uint.MAX_VALUE + 1 ); // ランタイムにお叱りを受けた

var arr:Array = new Array( uint.MAX_VALUE );
arr.push( 0 );
trace( arr.length ); // 0になったよー

stage.frameRate = Number.POSITIVE_INFINITY;
trace( stage.frameRate ); // どうやら1000で打ち止めらしい

2007年05月31日

パラメータのプロパティ渡しについて考察

Life is beautiful で興味深いエントリがあがっていたので反応してみたいと思います。


引数に数字が並ぶと何がなんだか分からなくなるのは確かにそうなのですが、開発環境によってはメソッド定義先でどういう変数名で受け取っているのか、は何なのか、デフォルト引数は設定されているのかがコーディング時に全て分かります。
これをプロパティ渡しでやってしまうと、変数名はまだ分かるのですが型やデフォルト引数がわからなくなってしまうというデメリットが生じます。
型については識別可能なように変数名を付ければ問題ありませんが、デフォルト引数についてはコメントで補足しないとどうしようもありません。

下記みたいにプロパティ渡しでもデフォルト引数が渡せれば最強なんですが、サポートされてないのでどうしようもないですね。


function hoge({a:String="aaa",b:uint=0xffffff}:Object):void {
// ほげほげ
}


それから引数に関して前々から気になっているのが、定数とデフォルト引数について。
コーディングしている時にオートコンプリートでデフォルト引数値が表示されるのはとても便利なのですが、このデフォルト引数値に数値や文字列ではなく定数を設定していると生真面目に定数名を表示してくれるおかげでたまに面倒なことがあります。
constで宣言されている場合には値も表示してくれればどんだけー


プロパティ渡しについては実は2年前にやっていたブログで書いたことがあったので、ちょっと切ない気持ちになりましたw
でもあれから環境も変わり、上記のような開発環境によるメリットデメリットを改めて考察することができたのでいい機会になったと思います。

2007年05月24日

2880pxよりも大きい画像を読み込む方法を発見したよ

FlashPlayerでは2880pxを超えるサイズの画像を読み込んでも、2880pxのところでカットされてしまうという悲しい仕様がありますが、ActionScript3.0限定でこれを打開できる方法を見つけました。


バイナリで読み込んで、Loader.loadBytesで再生成するだけ。


要するに前回のエントリで紹介した方法と全く同じです。
このやり方だと上限がなくなるのかどうかまでは未検証ですが、誰かエロい人がやってくれるでしょう。


ちなみにバイナリ経由だと外部ドメインの画像に対するサンドボックスも無視できるため draw し放題。
ただし外部リソースの読み込み自体にセキュリティ制限があるため、crossdomain.xmlによって開放されている必要があります。


あたかも最初から埋め込まれているリソースとして扱えるようになるということですね。
こうなってくると、バイナリで読み込むところにものすごい可能性が秘められているような気がしてきます。

2007年05月19日

AS3では外部swfを複製できる!

as1やas2では、loadMovieで読み込んだ外部swfをduplicateMovieClipで複製することができませんでしたが、as3ではバイナリを利用すれば複製することができます。


Loaderで読み込む代わりにURLLoaderでバイナリとして読み込んだ後、dataプロパティに格納されているバイナリデータからLoader.loadBytesメソッドを利用してLoaderを再構築します。
これを繰り返せば、その場で複製が可能となります。



private function loadMovie( url:String ):void {
var loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener( Event.COMPLETE, onCompleteLoad );
loader.load( new URLRequest( url ) );
}

private function onCompleteLoad( e:Event ):void {
var bytes:ByteArray = URLLoader( e.target ).data;

// 複製その1
var loader1:Loader = new Loader();
loader1.loadBytes( bytes );
addChild( loader1 );

// 複製その2
var loader2:Loader = new Loader();
loader2.loadBytes( bytes );
loader2.x = 100;
addChild( loader2 );
}


バイナリデータを保持しておけばいつでも複製可能になりますが、あくまで読み込んだ直後の状態すなわち外部swfの初期状態からの複製となるので注意が必要です。

もちろんswfだけではなくjpgやpngなどの画像データにも適用ができます。
今のところはBitmapDataとして保持しておいた方が使い勝手がよさそうなので、バイナリで画像データを弄るライブラリが出揃うのを待つといった感じですね。
そっち方面はまだまだ未開拓なので、@flaな人たちに期待。


で、この機能を持ったloadMovieとduplicateMovieClipをAS1MovieClipに盛り込んだら便利そうなので実装してみたいと思います。

2007年05月16日

Twitterで盛り上がったAS3フレームワーク談義のログまとめ

すごく楽しかった Flash 談義のログをまとめてみたよに引き続き、TwitterでまたひとつAS3についての話が1~2時間ほど盛り上がったのでログをまとめてみました。

話の方向別にグループ分けしつつ、それぞれの時系列は保持してあります。
全体の構成など勝手ながらてっく煮のエントリを参考にさせていただきましたが、ログの読み方などはそちらを参照してもらえればと思います。




■ AS3のメンテ性と再利用性

fladdict: AS3ウザスに追記した http://tinyurl.com/2gqfdk 微妙に釣り風味

psyark: @fladdict メンテは無くても再利用はあるよー!と、釣られてみました

beinteractive: @fladdict 俺みたいな人が差を埋める努力をしなきゃいけないと勝手に思ってます

munegon: @psyark 確実に再利用できるクラスならいいけど、絶妙な仕様変更で案件ごとに違うファイルができあがったりしてw

fladdict: @beinteractive そんなこと言われると超期待しちゃう

psyark: @munegon そうならない努力を俺がしたい(有言不実行w)

beinteractive: @fladdict ASerとFLASHerの両方の気持ちがわかる人はなかなかいないと思うので。。

beinteractive: @fladdict FLASHerな人を応援したい!


■ フレームワークの認知度について

munegon: @fladdict フレームワークとかそういった他人が作ったものを平気で組み込んで使う人って FLASHer には少ない気がしてならない。なんとなくだけど。

fladdict: @munegon 現状そうだけど、AS3になるとそれじゃあかなり辛いんじゃないかなぁと。

trickstar_os: @munegon それは今までのAS1,2の再利用性が著しく悪かったからだよ。

fladdict: 一番大変なのは、これからFlashを憶えようとするデザイン系の人はどうなるのか?ということ

fladdict: 変数って?みたいな人にAS3を最初に教えるのは辛い

beinteractive: @munegon フレームワークとかswcとかそういう概念自体よくわからない人が多いのでは。

Saqoosha: @munegon おいらの周りのFlasherをみてるとそもそもそういうものの存在をしらにゃいかったりする。

mainyaa: @fladdict 最初はMX2004とか使って教えるほうがいいかもしれないですねぇ

fladdict: かといって、まずAS2教えたら、もうAS3は絶対やらなそう

cellfusion: @Saqoosha たしかに存在自体を知らない人って意外と多いですね。

beinteractive: @trickstar_os 確かに。再利用という風潮が超薄かった。

whitebase: @fladdict AS3だからこそコピペ&インポートが楽になるのでは?

Saqoosha: @cellfusion フレームワークはフレームワークで学習コストがかかるしね。


■ 国内では配布物を利用する人が少ない?

nium: Flash自体を拡張できるmxpですら流行ってないので、ASパッケージとか存在を探そうとする人いなそう・・・

mainyaa: @nium ですねぇ。。。

whitebase: @nium mxpがはやんないのは日本語ドキュメントがあんまないからかね

nium: @whitebase 作るのは敷居が高いから分かるんですけど、使うだけの人も増えなかったな~と

psyark: @munegon 再利用性もそうだしそもそも配布物のクオリティがゴニョゴニョ<今まで

munegon: @nium 国内でオープンな風潮が生まれない限りは難しそうですね(結局そこにいきつくのか)

psyark: navigateToURLを自前getURLでラップするのは簡単にできる。逆は大変。今まではキャンプファイヤーしかできなかった。今後はどちらもできる。

mnr: 8の時のスクリプトアシスト復活が全てを物語ってたような気がしてたんやけどなぁ・・・


■ Adobeの展望

trickstar_os: @fla Adobeはプログラマとデザイナの住み分けをはっきりさせて、デザイナがコーディングしなくてもいい方向に持っていこうとしてると思う

munegon: @trickstar_os デザインとプログラム兼業してる人にとっては、あまり分離しすぎるのもってのがあるかも…ボタンアクション然り。 やっぱ大規模案件向き。

trickstar_os: @munegon Adobeが見てるのは人ではなく企業ってのは間違いない。

beinteractive: デザイナー向けのはずのFlashからシンタックスシュガー的なものが減ったのは痛い。


■ ライブラリ作例集の必要性

fladdict: ようはライブラリ使えば速いしすげーって感じの作例が色々でればいいのかな

psyark: @fladdict そして粒度小さい方の恩恵も誰か分かりやすく見せられると良いですね。俺か!w

nium: @fladdict 見た目から入る人は、ライブラリの説明見せるより「コレを使えばアレが簡単にできるんだ!」のが早いですね。

nium: ライブラリ×実績&作例のリンク集は、Sparkでも色々話してたとこですね

munegon: @nium Progression も Flex2 勉強会のプレゼンで初めて知った&興味持った人が多いでしょうしね。

nium: @munegon あれだと、ほとんどの人が3Dプレゼンツールと思われたっぽいですね(汗

fladdict: progressionは次、小~中規模のAS3仕事あったら使ってみたい

nium: @fladdict 横に座って手取り足取りレクチャーしますよっ!

munegon: @nium 確かに(汗 でも認知されないことにはどうしようもないので、いっそのことプレゼンツールとして前面に押し出すのもありですよw

nium: @munegon コンテンツの複雑さとProgressionの威力は反比例するので、簡単なものを作ると冗長になる・・・

nium: @munegon プレゼン資料のようなリニアな構造だと遷移制御には微妙ですねwブラウザ連動が便利なくらいかな

munegon: @nium サイト全体を制御するものを導入すると小回りが利かなくなるんじゃないかという不安から導入をためらう人が出てくるので、そういうのをサンプルでどこまでフォローできるかですね。

fladdict: まぁパーマリンク作れるんだぜいいぇーい大量生産されれば、なにかしらのフレームワークはみんな導入せざるを得なくなってくる気が


■ まとめ

これだけ中身のある話してるのに、@flaつけて発言してる人がほとんどいなかったのが印象深かったですw
とにかくフレームワークにせよ単体クラスにせよ、誰かが先頭に立って作成&テストしながら作例集をガンガン作っていかないことにはオープンな土壌が育たないのではと思います。
公開するメリットがあまりないというような意見もよく耳にしますが、まわりに人が集まるということが何よりもメリットではないでしょうか?

AS3は難しいというイメージをなんとか払拭していきたい、そう強く思った一日でした。

2007年05月09日

煩雑だからこそ簡潔にしたくなる

お互いトラバ合戦になりかねないですが

で、結局 FLASHer 的に AS3.0 って・・・
AS3 は FLASHer には使いにくい?

などで言われているように、ActionScript3.0になって煩わしくなったのがやはり何をするにもコード量が増えてしまったことです。
getURLのようなほんとに些細な処理でも手続きが煩雑になってしまいました。


ですが、逆に考えてみます。


今までは面倒なことを全部 FlashPlayer がやってくれてただけだと。
本来は複数のクラスを組み合わせてやらなければいけなかったことを、単一メソッドで済むように便宜を図ってくれていただけだと。
そのせいで選択の余地がなく、自由度が低かったのだと。
あるべき形に戻っただけなのだと。

ここにきて継承か委譲か、なんていう多言語ではよく目にする話題も出始めました。
ああでもないこうでもないと思考を巡らせ、自作ライブラリを公開してメリット・デメリットについて意見交換をする。
その中で蓄積されたノウハウを元にケースバイケースでクラスを取捨選択するという形に昇華していくのでしょう。

以前からFlash業界ではノウハウを共有しようという動きが幾つもありましたが、特に国内ではそういった動きが活性化することなく自然消滅していました。
共有するまでもなく、各自のとれる手法が限られていたというのもあります。
しかし、ActionScript3.0ではその膨大(というほどでもないがそれなりに大量)なクラスの数に圧倒されるため、知識を共有する流れに乗っていかないと勉強が追いつきません。

手前味噌ではありますが AS1MovieClip のような、似非ではあるけれど従来の手法に近い形でコーディングするためのクラスを作ることは比較的簡単にできます。
これからもどんどん便利なクラスライブラリが多くの人によって生み出されていくと思いますが、それはひとえに AS3 が煩雑になったからだと言えそうです。


少しでも楽ができるように工夫するのが人間ですからw
今までぬるま湯に浸かっていた FLASHer に対する挑戦なんだと受け止めて、みんなで工夫しようぜ!といったところですね。

2007年05月06日

AS1MovieClipクラスの問題点

前回のエントリに引き続いて、AS1MovieClipクラスについて。

as1な手軽さで書けるようにと onEnterFrame などのイベントハンドラを setter で処理したのはいいものの、イベントハンドラを解除する時の以下の記述

delete mc.onEnterFrame;

を setter で自動検出できないのが痛い!
とTwitterでぼやいていたら、BeInteractiveの人に「setterがある時点で、dynamicなプロパティとしては扱われていない(と思う)ので、deleteは出来ない気がします。」と言われた。
そりゃそーだ。
でも、deleteできるできないに関わらず、Proxyクラスを継承しない限りは自動検出する術がなさそう。

もちろん、以下の方法だとちゃんと解除できる。

mc.onEnterFrame = null;

多重継承ができれば解決するんだけどな。
ENTER_FRAME でチェックするにしてもタイミングのズレで思わぬバグが発生しかねないので、とりあえず delete は禁止の方向で。


もうひとつ、as1では親がボタン化すると子のボタンが無効化するという仕様があるのですが、これをas3で再現するのがめちゃくちゃ難しい!
イベントはデフォルトではバブリング段階で処理されるので、stopPropagationで親に伝播するのを止めることはできても、子に伝播するのを親が止めることはできない。
それならキャプチャ段階で監視すればいいかというと、そうは問屋が卸さない。
キャプチャを有効にしてリスナ登録すると、キャプチャフェーズだけでイベント伝播が終了してしまうためターゲットにまでイベントがこない。

さて、どうしたものか…親がボタン化しているのかどうかわざわざ問い合わせるメソッド用意しなきゃいけないのかなあ。
処理的に美しくないので避けたいところだけど、他に方法がなければそうするしかないかな。

2007年05月03日

AS1MovieClipクラスを作ってみた

fladdict.net blog : processingライクにくめるAS3が欲しいに触発されて、as1記法でMovieClipのメソッドを扱える AS1MovieClip クラスを作ってみました。

ソース

まだ全メソッドを登録していませんが、MovieClipクラスを継承しているので特に不自由なく使えると思います。

以下、使用例。


インポート文はこれ

import com.voidelement.display.AS1MovieClip;


んで、as1ライクな記述がこれ


class Hoge extends AS1MovieClip {
public function Hoge() {
var mc1:AS1MovieClip = createEmptyMovieClip("mc1", 1 );
mc1.a = 0;
mc1.b = 0;
mc1.onEnterFrame = function():void {
this.a += 1;
this.b += this.a;
}
mc1.onMouseUp = function():void {
this.onEnterFrame = null;
trace( this.a, this.b );
}

var mc2:AS1MovieClip = mc1.createEmptyMovieClip("mc2", 1 );
mc2.moveTo( 100, 100 );
mc2.lineTo( 200, 200 );
}
}

深度管理についてはas1を踏襲しているため、すでにインスタンスが配置されている深度に createEmptyMovieClip などで配置しようとすると上書きにより消えてしまいます。
これを実現するにあたって、深度概念が交錯しないように addChildAt メソッドを使用禁止にしました。
あくまでas1の深度ベースでサンプルを組み上げるためのクラスなので、その他のas3クラスとの親和性は多少犠牲にしています。
また、深度管理の都合上 removeMovieClip や swapDepths などの自身を対象とするメソッドについては親が AS1MovieClip かその派生クラスでないと機能しないように制限してあります。

ちなみに _xscale や _yscale などのアンダースコアなプロパティも定義してみました。
as1では0~100ベースだったのに、as3で0~1になったのでよく間違えるorz


それと深度管理するにあたって、Dictionaryクラスがやたらと役に立ちました。
インスタンスと深度値を相互参照することで、インスタンスに直接深度プロパティを持たせずに済んでいます。
他にも便利な使い方があると思うのでそのうちまとめてみる予定。


果たして需要があるのか否や。
突貫で作ったのでコメントぶっ飛ばし状態…後から追加しますが、そもそもこんなクラスをわざわざ使うような人は、as1のメソッドなんてほとんど暗記してるんじゃないかと勝手に予想。
なんだか無駄に張り切りすぎた感があるので、深度関係のところだけ抽出して DepthManager クラスとして作り直した方がいい気もしてきたけど、まだまだ作りかけだしツッコミ大歓迎。

2006年08月03日

人生いろいろバグもいろいろ

AS3.0の勉強をしている過程において発見したバグを紹介してみます。

Event.REMOVED をイベントリスナ登録しておくと、そのオブジェクトが removeChild などで削除された時にコールバックメソッドが呼ばれるのですが、そこで削除したオブジェクトの子オブジェクトを削除しようとするとFlashPlayerが落ちます、少なくともうちの環境では100%確実に。
これはバグというか仕様に近い気もするけれど。

また、この Event.REMOVED はあくまでスクリプトによる直接削除のみでしか発生せず、MovieClip.nextFrame() などでフレームを切り替えることによるシンボル削除については一切発生しません。
つまりこの場合のイベントリスナ解除はわざわざ自前で入れなきゃいけないとか結構ふざけてますね。
Flasherイジメとしか思えない。

Event.ACTIVATE や Event.DEACTIVATE をイベントリスナ登録しておくと、それぞれ FlashPlayer にフォーカスが戻った時や外れた時にイベントが通知されるのですが、デバッグプレイヤーのみなぜかプレイヤー本体とステージでそれぞれイベントが発生します。
フォーカスを戻す際にプレイヤーの枠をクリックすると Event.ACTIVATE が発生しますが、そこでさらにステージ内をクリックすると Event.DEACTIVATE と Event.ACTIVATE が連続で発生。
その状態でフォーカスを外すと今度は Event.DEACTIVATE → Event.ACTIVATE → Event.DEACTIVATE の順でイベントが多重発生します。
どう考えてもデバッグプレイヤーが余計なことしてるっぽいです。

2006年07月26日

Arrayの追加メソッド

Flashはヘルプが充実していて下手な参考書よりも役に立つことがしばしばあるのですが、バージョンアップ時に追加されたメソッドがこっそり書かれているため、チェックは欠かせません。
ActionScript3.0でも既存のビルトインクラスにメソッドが幾つか追加されていますが、特にArrayにはたくさん追加されています。
コールバックメソッドを指定するものがほとんどなので、まとめて覚えてしまうのがよさげです。


Array.indexOf
Array.lastIndexOf
これは今まではprototypeで強引に追加定義したりしたものですが。やっとこさ実装されました。
引数で指定した要素が配列のどこにあるか探すメソッドです。

Array.forEach
配列の全ての要素について特定の処理を施したい時に使います。
for each 文とほとんど変わりませんが、同じ処理が何度も使いまわされるような場合に向いています。

Array.every
これは配列の全ての要素について、ある条件を満たしているかどうかをチェックするために使います。
条件自体は引数で指定するコールバックメソッド内に記述します。

Array.some
これはArray.everyと似ているのですが、ある条件を満たす要素が配列内に存在するかどうかをチェックするために使います。
こちらも条件自体は引数で指定するコールバックメソッド内に記述します。

Array.map
これはPerlでよく使いますね。
配列の全ての要素に一定の処理を施した値を要素とする新しい配列が欲しい時に使います。
コールバックメソッドの返り値が、新しい配列の要素となります。

Array.filter
こちらもPerlで頻出のgrep関数と同じで、要素のフィルタリングを行います。
コールバックメソッド内に記述する条件を満たす要素のみから構成される新たな配列を返します。


処理速度的には for each で回すのがもちろん一番速いのですが、処理が高速化されているActionScript3.0では些細なレベルっぽいです。
ただでさえイベントだらけのコールバックメソッドだらけになるので、この際コールバックメソッドで固めてしまうもよし、やらなくても済むところは徹底的に省くもよし、開発者のソース管理能力とセンスが問われるところでしょうか。

2006年07月18日

イベントフロー図解

前回のエントリで ActionScript3.0 におけるイベントフローを軽く説明してみたのだけれど、文字だけでは限界があると思ったので flash でサンプルを作ってみました。
なお、これ自体は ActionScript3.0 で組んだものではありません。







これはインスタンスの親子関係をビジュアル化したもので、mc3 の親が mc2、mc2 の親が mc1 となります。
マウスポインタの指し示す最前面のインスタンスがマウスイベントのターゲットとなるため、この図解ではクリックしたインスタンスがターゲットとなります。
イベントはキャプチャフェーズ、ターゲットフェーズ、バブリングフェーズの順に伝わりますが、キャプチャフェーズはイベントリスナ登録時に明示的に設定しない限りはイベントを受け取りません。

各種インスタンスはイベントに応じてメソッドを呼びますが、引数として渡されるイベントの target プロパティの参照先は共通で上記のターゲットとなります。

これを理解した上で覚悟しなければならないことがあります。
それはボタンに対するマウスイベントの発生過程において、ボタンを内包する全てのインスタンスにイベントが通知されるということです。
サンプルを見ての通り、mc2 と mc3 のどちらをクリックしても mc1 のメソッドが呼ばれますが、イベントの主体は target プロパティを確認しないと分かりません。
このような全ての階層に渡ってイベントリスナ登録をすること自体稀かもしれませんが、かなり気を使わないと思わぬところで全く無関係のメソッドが呼ばれる可能性があるということを意識しておく必要があると思います。

2006年07月16日

ボタン作成のためのイベントフロー制御

従来のボタンの挙動をActionScript3.0で再現するためには、リスナー登録まわりでひと工夫する必要があります。
fladdict.net blog の【AS3メモ MouseEventについて】で言及されているように、マウスイベントはそのインスタンス上でしか発生しないため releaseOutside を実現するためには stage にリスナー登録する必要が出てきます。
また releasereleaseOutside の判別にロールオーバー中かどうかのフラグで対応できるのと同様、rollOverdragOver の判別や rollOutdragOut の判別についてもマウス押下中かどうかのフラグで対応できます。

ところでマウスイベントがインスタンス上でしか発生しないという事実は、言い換えるとマウスカーソル下の全てのインスタンスに対して必ずマウスイベントが発生してしまうマウスカーソル下の最前面に配置されているインスタンスとそれを包括する全ての親インスタンスに対して一部を除く全てのマウスイベントが発生してしまうということです。
ボタンの releaseOutside を実現するためにボタン領域外で MouseEvent.MOUSE_UP を発生させると、そこがたまたま別のボタン上であった場合にそのボタンの release も同時に処理されてしまうことになります。
もっと単純に、ボタンをクリックするとそのボタンが配置されている Sprite をはじめ、ボタンのパスに含まれる全インスタンスにイベントが発生します。

もちろんこれは望ましくないのですが、簡単に制御することができます。

続きを読む "ボタン作成のためのイベントフロー制御" »

2006年07月15日

マウス入力とキーボード入力

ActionScript3.0ではキーボード入力の検出に枷が嵌められています。
それは検出を行うインスタンスがフォーカス状態でなければいけないということです。

キー押下を検出するには、適当なインスタンス(ドキュメントルートでも可)にイベントリスナを登録してさらにフォーカスさせておく必要があります。

stage.focus = this;
addEventListener( KeyboardEvent.KEY_DOWN, onKeyDownHandler );


ここまではまだいいのですが実はこのフォーカス、ボタン押下時に奪われます。
たとえばシンボルの移動にキーボードを割り当てて、あるキーを押している間だけ動き続けるようにします。
これは Keyboard.KEY_DOWN と Keyboard.KEY_UP のそれぞれについてリスナー登録すれば実現できます。

このとき画質変更ボタンを画面に配置していたりなんかすると、ボタンを押した瞬間フォーカスがそのボタンに移るのでキーボード入力が検出できなくなります。
さらにひどいことに、キー押下だけならまだしもキー押上まで拾えなくなるため、キー押下中にボタンを押してしまうとシンボルの移動が止まらないなんてことに!!

これを解決するにはフォーカス移動を強制的にキャンセルすることです。
ボタン btn が押下された瞬間に、フォーカスをキーボード入力検出用インスタンスに戻すためには

public コンストラクタ() {
 stage.focus = this;
 addEventListener( KeyboardEvent.KEY_DOWN, onKeyDownHandler );
 addEventListener( KeyboardEvent.KEY_UP, onKeyUpHandler );
 btn.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDownHandler );
}

private function onKeyDownHandler( e:KeyboardEvent ):void {
 // 移動開始処理
}
private function onKeyUpHandler( e:KeyboardEvent ):void {
 // 移動終了処理
}
private function onMouseDownHandler ( e:MouseEvent ):void {
 stage.focus = this;
}

といった具合に、ボタンに対して MouseEvent.MOUSE_DOWN のイベントリスナを登録して、メソッドでフォーカスを戻す処理を記述しておきます。
これで一応はキーボード入力が奪われずに済みます。

が、これが本当に正しいやり方なのかは試行錯誤中なのでよく分からず・・・
もっと賢いやり方があれば誰か教えてください。

あわせて読みたい