2013年02月09日 15:00

Haxe + NME 4回目 ハチの巣にしてやられる

 映画やら漫画やらで、「ハチの巣にしてやるぜ」的なセリフを時々見かける。多数の銃弾を頼りに、相手に対して「穴だらけにしてやる」という意味で使われるこのセリフだが、たいていは言った人がその場あるいはその後に命を落としているような気がする。ってことは、基本的に悪役の吐くべきセリフなのだろうか。

 さて、先のヘクスマップだが、確かに形状はハチの巣になっているものの、多数の銃弾的な物で穴を開けたわけではなく、どちらかというと丁寧に上から順に六角形の3辺を描画している感じである。しかも、わざわざShapeにハチの巣をひと通り描画して、それをBitmapDataに写し取っている。

 どうせShapeに描画してからBitmapDataに転送するなら、1ヘクス分だけShapeに描画しといて、それを座標を変えつつBitmapDataにコピーしてった方がアルゴリズム的にもすっきりするんじゃなかろうか…と、ふと思いついた。つまり、六角形の3辺と中心円、そして青マスの部分を単体で描画したShapeを用意して、青マスの単位で縦横にずらして複写すればいい。1個分のShapeを銃弾に見立てて、形容としても文字通りの意味でも「ハチの巣にしてやるぜ」的な指向で「ハチの巣」を描画しようという寸法である。

 この方法の長所は、境界線や中心円を描く、描かないのオプションが発生した時にif文が発生する回数が少なくなる事。例えば100×100ヘクスを描画するとして、それぞれ10,000回の繰り返しの中にif文を入れて描くか描かないかを判断するというのは、それなりに演算時間を食うはずである。これを、あらかじめ描画したShapeのコピーで処理すれば、たったの1回で済むというわけだ。うん、何だかお得な気がしてきた。

 では…とやってみた。
 …はまった…。
 結論から言う。NMEのBitmap.draw()は、かなりのクセモノだ。いや、HTML5への出力時にSpriteからのDrawが出来ないバグは前から知っていたが、それ以外にも環境によって動作が違うっぽい。

 具体的には、HTML5への出力だとdrawするShapeの位置は「Shape.x Shape.y」によって動く。Flashへの出力だとBitmap.drawの第二引数にMatrixを指定して描画位置を決めるため、Matrixが無いと「Shape.x Shape.y」の値に関わらずBitmapの原点に描画される。そして、再度HTML5に戻ると、このMatrixでの位置指定はなぜか無視されてしまい、Matrixで位置を指定してもBitmapの原点に描画される。

 NMEは基本的にActionScript3のラッパーであると思われる。故に、Flash側での動作が正しいような気がしなくもない。が…何はともあれ、同じソースなのに環境によって差があるというのは困った物である。

 ん〜。どうしよう…。

 待てよ。
  • 「Flashの時はMatrixのみ使用される」
  • 「HTML5の時はShape.x Shape.yのみ使用される」
ということは…。

 なんだ、両方書いときゃいいんじゃん。つまり、こんな感じ。

// 出来上がったShapeを、位置をずらして描画
// Matrixを指定しないと、Flashで位置が動かない!!
// Shape.xとShape.yを指定しないと、HTML5で位置が動かない!!
var m:Matrix = new Matrix();
for (y in 0 ... mapMax) {
shape.y = y * ySize;
m.ty = shape.y;
for (x in 0 ... mapMax) {
if ((x + y) % 2 == 0) {
shape.x = x * xSize;
m.tx = shape.x;
target.draw(shape, m);
}
}
}


 というわけで、今回のNMEでの注意点。

nme.display.Bitmap.draw(Shape, Matrix)を使う時、
  • HTML5に出力する時は、Shapeの x y で位置が決まる
  • Flashに出力する時は Matrix で位置が決まる。
  • 両者の環境で同じ描画をするときには、 x y を入れた上で、同じ値を Matrix に入れておくと何とかなる。
あぁ…我ながらなんて馬鹿な実装してるんだろうなぁ、と思いつつも…プログラムなんて物は、最終的に正しく動けば勝利なのです。うん。

 しかし…何だかこう…「ハチの巣にしてやるぜ」とほざいた物の、いつの間にか倒されて「どうしてこんな…」とか思っている悪役の気分である。
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。