QuickBox2Dの衝突判定とビット単位の論理積

今更ながら周りの影響で、QucikBox2Dをいじってます。@alumican_net さんが書かれたブログがわかりやすいので拝見してますが、『 QuickBox2DやBox2DFlashAS3での衝突判定をグループ分け 』という記事で以下のような記述がありました。
自分と何かが衝突するかどうかは、自分のmaskBitsと相手のcategoryBitsの論理積をとって計算できる。結果が0なら衝突しない、0以外なら衝突する。
普段あまり使わないので「論理積ってなに?」って状態だったんで調べてみると、大重美幸さんのActionScript3.0入門ノートにわかりやすい解説がありました。
ビット単位の論理和では値を2進数に換算して各ビットごとに比較し、どちらかが1ならば1にします。たとえば、6(2進数で110)と5(2進数で101)のビット単位の論理和は7(111)になります。同様にビット単位の論理積では両方が1のときに1にし一方が0ならば0にします。6と5のビット単位の論理積は4(100)になります。
2進数における桁のシフトは2のn階乗で変化します。次のサンプルで使われているrgbToHex()はRGBの各色の値から0xFFFFFFの形式の16進数に変換する関数です。

なるほど!ということで、実際に計算してみました。


maskBits:0x0007(0111) &  categoryBits:0x0004(0100) >> 4(0100):衝突する

maskBits:0x0007(0111) &  categoryBits:0x0008(1000) >> 0(0000):衝突しない

maskBits:0x0007(0111) &  categoryBits:0x0002(0010) >> 2(0010):衝突する

maskBits:0x0007(0111) &  categoryBits: 0x00020010) >> 2(0010):衝突する


maskBits:0x0007(0111) &  categoryBits:0x0008(1000) >> 0(0000):衝突しない

maskBits:0x0007(0111) &  categoryBits: 0x00040100) >> 4(0100):衝突する

・■

maskBits:0x0001(0001) &  categoryBits: 0x00020010) >> 00000):衝突しない



maskBits: 0x00010001) &  categoryBits: 0x00040100) >> 0(0000):衝突しない

maskBits: 0x00010001) &  categoryBits: 0x00081000 >> 0(0000):衝突しない

ふむふむ。確かに先の引用通り「結果(論理積)が0なら衝突しない、0以外なら衝突する。」になっています。

そこでを categoryBits:0x0001, maskBits:0x0003 に変更してみました。すると・・・

maskBits:0x0003(0011) &  categoryBits:0x0004(0100) >> 0(0000):衝突しない


maskBits:0x0007(0111) &  categoryBits: 0x00010001) >> 1(0001):衝突する


と、基準を変えて計算すると違う結果になってしましました。
そこで色々調べてみたら、QucikBox2Dのユーザーマニュアルに次のように書いてありました。

Here is the rule for a collision to occur:

uint16 catA = fixtureA.filter.categoryBits;

uint16 maskA = fixtureA.filter.maskBits;

uint16 catB = fixtureB.filter.categoryBits;

uint16 maskB = fixtureB.filter.maskBits;

 

if ((catA & maskB) != 0 && (catB & maskA) != 0)

{

  // fixtures can collide

}

つまりAとBを比較する時に「それぞれを基準に計算した結果が、どちらも0でない場合に衝突する」ということなんんですね。上に書いたの場合とも合致しますね。納得。
以下のサイトを参考にしました。感謝。

NetStreamで使用するflvの相対位置

NetStreamを使ってるswfをHTMLと別階層に配置することになって、flvが読めなくなって混乱。改めてヘルプを見ると、flvHTMLでなくswfからの相対パスになるってことなのね。以下引用。

ローカルファイルの再生

メディアファイルの場所。引数には、String、URLRequest.url プロパティ、またはこのどちらかを参照する変数を使用できます。アプリケーションセキュリティサンドボックス外にある Flash Player および AIR コンテンツの場合、SWF ファイルまたはサブディレクトリと同じディレクトリに保存されているローカルビデオファイルを再生できます。ただし、上位レベルのディレクトリに移動することはできません。

アプリケーションセキュリティサンドボックス内の AIR コンテンツの場合、メディアファイルに指定するパスは、SWF ファイルのディレクトリに相対します。ただし、SWF ファイルのディレクトリより上位に移動することはできません。AIR でパスを相対パスとして処理するため、完全なパスは指定しないでください。

「参照するパスの起点はHTML」って考えが染みついていると、普段HTMLとswfは同階層に置くことが多いので、ちょっと混乱しました(笑)。ヘルプの該当箇所はこちらから。

iTunesのデータ移行

そろそろiTunes用に使ってたPowerBook G4 の容量がやばくなっていたのと、春にMacBook Pro(2011)を導入したので、それまでメインで使っていたMacBook Por(2008)にiTinesのデータを移行しました。

毎回移行を行う際に色々調べることになるんで、自分用にメモ。開発そのものとは直接関係ないんですが、まあiPhone/iPad開発で必ず使うことになるので。
  • 移行元:PowerBook G4 OSX10.5.8,iTunes10.4.1,音楽データは外付けHDDに保存。
  • 移行先;MacBook Por(2008) OSX10.6.8,iTunes10.4.1
  1. 移行元のiTunesでファイルライブラリライブラリを整理…を開き、ファイルを統合にチェックを入れてOKボタンを押す。
  2. ユーザ/ミュージック/iTunesフォルダを移行先マシンの同じ場所にコピー(上書き)
  3. 移行元のiTunesで、Storeこのコンピュータの認証を解除…を実行。
  4. 移行元のiTunesを終了。
  5. 外付けHDDを移行先マシンに接続。
  6. 移行先でiTunesを起動。
  7. ここで「iTunes Library.itlが最新でない」とアラートが出てしまったため、一度iTunesを終了して、移行元のユーザ/ミュージック/iTunesフォルダからiTunes Library.itlを移行先マシンの同じ場所にコピー(上書き)。直前まで移行元のiTunesを使っていたため、情報がずれてしまったらしい(汗。
  8. 移行先のiTunesを起動。iTunesがGuniusの情報を作り直してるらしく、それが終わると移行完了。
で、問題なく使えています。移行元データは音楽は外付けHDDに入っていたものの、何故かアプリは内蔵HDDにあって、これは次に移行の時にまた面倒だな〜と思って調べていたら、ありました。アプリも外付けHDDに移動する方法が。
  1. iTunesでファイルライブラリライブラリを整理…を開き、“iTunes”フォルダ内のファイルを整理し直す にチェックを入れてOKボタンを押す。
  2. iTunesでファイルライブラリライブラリを整理…を開き、ファイルを統合にチェックを入れてOKボタンを押す。
これでアプリのデータも全て、外付けHDDに移動しました。内蔵HDDにはオリジナルファイルが残るので、これを全て消して作業完了。最初に気づいていれば、移行元マシンで先にやっておけば、ネットワーク越しのデータコピー分の時間が無駄にならなかったのに…( ´ ▽ ` )ノ。
これで今後はよりカンタンにデータ移行ができそうです。外付けHDDは、Finderで見ると59.32/137.29GBなので、しばらくは余裕でしょう。
※実際の移行作業は、自己責任でお願いします。

東京ひよこの会(第2回勉強会)みんなで共有ファイルのDL

先日開催した東京ひよこの第二回勉強会。遅くなりましたが、みんなで持ち寄ったファイルのDLの準備ができました。ここからダウンロードできます。ひろゆきさん(@ProjectNya)さんの作ってくださったみんなのレポートページとと合わせてご覧ください。


参加者は勿論、惜しくも参加できなかった方も「どんな会だったのか」を感じていただけるといいかもです。

みなさん続々とブログ等に感想、解説など書いて下さってます。是非、Twitterでハッシュタグ#tokyopiyoをチェック!

iPhoneでGoogle Maps を表示する

iPhoneでGPS関連を調べる必要があってググっていたら、Google codeでGoogle Maps APIを使ってiPhoneに表示させるための解説ページを見つけました。
ただこのサンプル、使ってあるURLが404になってしまいます(笑)。そのURL部分はこちらに書き換えれば大丈夫。問題なく動作しました(Xcode 3.2.6/OSX10.6.8)。

一応、メモとして。

東京ひよこの会(第2回勉強会)

7/9に東京ひよこの第二回勉強会を開催しました。内容については、@kenji_clown5さんの力作レポがあるので、そちらをご覧いただくとして、運営面から書いてみます。
時間は13:30〜18:00の設定で、参加者15名。5名発表毎に15分休憩挟んでの3セット。前回より人数も少ないし、時間通りにいけるかな・・・と思ったら、終了が18:40で40押しでした。
参加全員が発表することと、ネタによってはそこから話が膨らんでいくので、単純に時間を計れない難しさもあります。その点はひろゆきさんからも「全員発表でなくてもいいのでは?そうすれば、更に議論を深める時間も取れる」という意見があったんですが、私個人としては、参加=発表というラインは堅持したいなあと・・・。単に聞くだけならセミナーもたくさんあるし、発表自体が勉強且つ事前準備という意味合いもあるし。
今回もおやつの呼びかけに、みなさん持参していただき、たくさんのおやつを会場協力いただいた会社さんにお礼として置いていくことができました。ありがとうございます。ただ進行としてしゃべっていると、ゆっくり食べられないのが個人的に残念です(T_T)。
で、19:00から懇親会。遅めの設定だったのですが、幹事のみ遅刻(笑)。座敷だったんですが、ちょっと狭かったので席の移動がままならない感じで、それぞれが全員と話して回るってことができなかったのが残念でした。この辺はなかなか難しいですね。広くても仕切りがなくてうるさいのも困るし、椅子席の方が移動しやすいのかな〜と思ったり。
フリーランスになって以降、宴席の機会が激減しているので(笑)、その辺は経験豊富な宴会幹事さんにご教授いただきたいところですね。
・・・と、ざっと全体の雑感です。今回も盛況でつつがなく終了してほっとしました。運営面や懇親会、次回のお題など、参加した方、これから参加してみたい方も含めて、いろいろご意見いただけるとウレシイです。
ではみなさま、次は第三回目で!
[追記]どなたかがいってましたけど、持参ノートのMac率がとても高かったです(笑)。

XMLから取り出したエレメントの親への参照

XMLをいじっていて不思議な現象が。下記のようなXMLを定義します。

var xml:XML =
<itemlist>
<itemGroup name=”X”>
<itemGroup name=”XX”>
<itemGroup name=”XXX”>
<item name=”XXX001″ />
<item name=”XXX002″ />
<item name=”XXX003″ />
<item name=”XXX004″ />
<item name=”XXX005″ />
</itemGroup>
</itemGroup>
<item name=”X-001″ />
<item name=”X-002″ />
</itemGroup>
</itemlist>;
この中のitemエレメントで@name=”XX001″のデータの親を参照すると、下記のようになります。これは問題なし。
trace(xml..item.(@name==”XXX001″).parent());
—-
<itemGroup name=”XXX”>
  <item name=”XXX001″/>
  <item name=”XXX002″/>
  <item name=”XXX003″/>
  <item name=”XXX004″/>
  <item name=”XXX005″/>
</itemGroup>
次に同じ条件でitemエレメントを検索して、それを別XMLの子として追加します。
var xmlList:XMLList = xml..item.(@name==”XXX001″);
var xml2:XML = new XML(“<top></top>”)
for each (var item:XML in xmlList) {
xml2.appendChild(item);
}

xml2に対して、itemエレメントで@name=”XX001″のデータの親を参照すると、下記のようになります。これも問題なし。

trace(xml2..item.(@name==”XXX001″).parent());
—-
<top>
  <item name=”XXX001″/>
</top>

この後に、元々のXML(xml)に対して、同じく親を参照すると・・・

trace(xml..item.(@name==”XXX001″).parent());
—-
<top>
  <item name=”XXX001″/>
</top>
と、別XMLの親を参照してしまいます。該当エレメントを別XMLに追加してしまうと、元XMLの該当エレメントの参照も変わってしまうようなのです。
これってどういうことなんでしょうね???もっとも別XMLにしたいなら、XML.copy()で複製を作れって話ではあるんですけけど、ちょっと納得いかない感じです。

外部ファイル読み込みでswf/flvのファイルパスの違い

某所から「flvが再生できないので見て欲しい」と連絡があって(私が作ったものではない)、flaファイルを見たらコンポーネントにflvをリンクしているだけ。
いろいろ調べてみたら、flvのファイルパスの起点は、swfが貼ってあるHTMLではなく、swfになるらしい。いつのバージョンからだったか、外部読み込みのパスがswfからHTMLになったのは覚えていたけど、flvのパスがまた別だとは知らなかった。
※ちなみにコンポーネントのスキンはswfなのでHTML起点だけど、パブリッシュ設定でswfの出力先をサブフォルダにすると同じ場所に書き出されてしまう。この辺りは「ちょっとなあ」と思う。
フツーにHTMLとswfが同階層にあれば何もする必要はないし、サーバ絡みのコンテンツだとflv自体が別サーバだったりすることもあるからか、今まで問題に遭遇したことがなかったです。
う〜ん、わかっているようで気づいてないことがいろいろあるなあ。
下記サイトのお世話になりました。感謝。

親エレメント名を一括で取得

文字通り、特定のエレメントから遡って、全ての親エレメント名を取得するための関数を書きました。XMLは下層に向かっての処理はいろいろあるけど、上層に向かっての処理は少ない気がする。前提として、XMLは上から下に向かって使うものなのか? いや、そんなことないよね。単に階層化されたデータな訳だから。

//—————————
// 親ノード名取得(再帰)
//—————————
function getParentName_xml(xml:XML,array:Array):void
{
if (xml.parent() != undefined)
{
array.unshift(xml.parent().name());
getParentName_xml(xml.parent(),array);
}
}
前回の件みたいに単なる見落としの可能性もあるので、もっと簡便な方法を知ってる方は教えてください。

XMLから特定のエレメントを抽出(文字列で指定)

XMLをいじってて、XMLオブジェクトのすべての子孫(子、孫、ひ孫など)から特定のエレメントを抽出するには、descendant accessor(..)を使って
 
var resultList:XMLList = xml..aa;
 

と出来るのですが、このaaが文字列の場合にはどうすればいいか?

 
何かメソッドがあるはずだと探しまくって発見したのが、XML.descendants()でした。

var resultList:XMLList = xml.descendants(“aa”);

 

しかし散々探したあげく、見つけた場所がdescendant accessor(..)のヘルプにある関連項目からのリンクだったという・・・。灯台下暗しというけれど、ヘルプの見方に問題がありありです。うう…(T_T)。
 
 

AS,Objective-C,Javascript,その他諸々の備忘録