2013年02月03日

ヘクスマップ

 コンピュータでシミュレーションゲーム的な物を作ろうとか考えた時に、最初に立ちふさがる壁の一つと言えばヘクスマップとか呼ばれる物ではなかろうか。二次元マップの癖に、移動方向がデジタル計算しやすい4でも8でもなく6方向だし、座標系が変なずれ方をしているからマップの配列での管理も面倒くさいし。ゲームの中身がどうこうではなく、「ヘクスマップ」という実装をしようとするだけで膨大なインターフェースだのライブラリだのを作らないといけない雰囲気がある。というか、あの六角形をどう扱ったらいいかわららないという、それだけの理由で挫折してしまうケースの方がぶっちゃけ多かろうと思われる。

 とはいえ、ふとそれっぽい物をちょっと作ってみたいなと思い立ってしまったので、少し考えてみようか。

 まず、座標系。プログラム内では「縦横」の二次元配列で考えるのが基本かと思われる。というか、それ以外で考えるのはちょっと小生にはムリ。というのも、プログラム内部での配列なんて物は、そもそも画面に出てこない。故に、頭のなかでイメージをしっかり持てるものでないとヤバイ事になる。だから管理用の配列を無理矢理六角形に合わせるくらいなら、画面に出てくる六角形の方を縦横系に無理矢理直す方がイメージしやすいはず。うまく理屈に出来ないけど、何だか小生のカンと経験がそう言っている。

 カンと経験はともかくとして。とりあえず自力でもいくつか表現方法を考えてみる。2〜3種類、もやもやしたイメージを持つ事は出来たけど、なんとなくどれも長所と短所がちょっとずつ見えて、判断つかず。

 じゃぁ…といって、ヘクスマップを普通の座標系に変換する方法をGoogle先生に色々相談してみる。小生が思いついた以外のスマートなアルゴリズムってないかしら。出来れば、楽に、スマートに実装できる物。要は楽していい思いがしたいわけであるが…そこまではムリかな。

 色々検索していると、何やら「お、これ使えるかな?」と思ったものを発見。小生がもやもやと考えていた物の一つが、ある程度まとまった形で載っているサイトがあった。ははは。似たようなことを考える人ってのは世の中に居るわけで、しかもそういう人ってのは小生なんかよりずっと先に進んでるわけなんだなぁ。

 というわけで、その見つけた方法を採用。考え方はそんなに難しくない。段違いになっている部分を無理矢理1行と数える考え方を放棄して、段違いは別の行とする。で、段違い故にモノが無い場所は「使わない座標」と考える方法である。

HexAlgo01.png

 赤線の六角形に対して、青線のようにマス目を入れる。内部管理はこのマス目に従えば、管理的にはすごく楽である。まぁ、メモリ的には半数が無駄になるわけだが、内部的には使わない部分を左詰めでもしてやれば良い。その辺は後でどうにでも出来る気がするので気にしない。

 で、こうすると、青のマス目の中心にヘックスの中心「○」がある物と、ヘックスの境界線「―」がある物の二種類が、市松模様で並んでいることがわかる。市松模様ということは、X座標とY座標を足して偶数(あるいは奇数)だとか、排他的論理和を取って末尾1ビットが0(あるいは1)だとか、そういう方法で「○」か「―」かが簡単に検出出来る事を意味する。あとは、マウスカーソルが乗った時などは「―」のマスだったら、上半分か下半分かを調べて上側なり下側なりのマスを指すようにしてやれば良い。

 距離の測り方についてはどうだろう。青マスの座標系でX方向、Y方向のそれぞれの絶対値(以下dX、dYとする)を取っておいて、dX≧dYならば単純にdXが距離になるし、そうでなければ ( dX + dY ) / 2 が移動距離になる。

 射撃時の射角のように、向きと範囲が絡む場合はどうなるか。具体的には、ある方向を向いている時に、その正面60度の範囲内に目標があるかどうかの判断である。これについても、上向きと下向きはdX≦dYの判断で出来そうだ。また、それ以外の4方向は青マス座標系での右上、左上、右下、左下で判断が出来る。境界線を含めるか含めないかは、不等号を「≦」にするか「<」にするかで対応出来よう。

 射線上の障害物などを判断するために、直線を引いた時の通過ヘクスを扱うならどうするか。これはちょっと悩んだが、青マス座標系で通過するマスを特定して、「―」のマスだけ無視すれば良さそうに思える。青マスでの通過部分はというと、二次元系ならいくらでもアルゴリズムが探せるだろう。

 移動についてはどうだろう。例えばダイクストラ法…要は起点から1マスずつしらみ潰しで最短距離を探して行く方法)を使う場合、普通の二次元座標であれば1マスについて縦横4マス、八方向移動が出来るなら8マス分の「隣接する」経路を考えるわけだ。ヘックスでの上下の隣は、青マス座標系で見ると2マス上下である故、ダイクストラ法を2次元系に特化したようなアルゴリズムはそのままでは使えない。とはいえ、「上下左右」ではなく、「2マス上、2マス下、右上、右下、左上、左下」の6マス分の経路を入れてやれば基本的な部分はそのままでも済みそうな予感がする。

 ふむ。何とかなりそうな気がしてきた。もうちょっと掘り下げて、Haxe + NME で何かつくってみようかな。

 余談ながら、ここでヘクスマップのアルゴリズムの参考としたサイトでは、小生の表記と比較すると90度回転した物となっていた。つまり、無視すべきマスは「―」ではなく「|」であり、ここで「縦方向」と称した物はそのサイトでは「横方向」であった。が、昔ながらのボードゲーム系ヘクスマップでは、参考サイトを90度横にした形の物が多かったと記憶している故、これを横にして焼き直してみた感じである。
posted by 管理人 at 13:43| Comment(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2012年10月24日

これでいいのかな?

 プログラムの開発環境という物は、案外たくさんあると言える気がする。とはいえ、各言語で使用出来る…というか使用に耐えうる開発環境は、と問うと案外少ない。まぁ、愛用するエディタとコマンドラインベースのコンパイラで全てが完結するのであれば、それで十分と言えば十分なのだとも思う。とはいえ、各言語の専用開発環境という物は、昨今ではコード補完の機能がとても充実しているわけで…そっちを使ったほうが楽なのも事実である。

 で、専用エディタに乗り換えて、設定等を完全にお任せでやってしまうと、それはそれで時々困ったことが起きる。特に小生のように、自宅PCで、職場PCで、そしてそれ以外の場所にてノートPCで、といった具合に複数の環境、OSを使用する場合に色々と困ったことが起きるわけだ。

 一例として、Windowsの64bit環境だと、他のWindowsにおける「Program Files」が一部「Program Fils (x86)」というフォルダ名になっていたりする。故に、「デフォルトの設定で」インストールした同じアプリを立ち上げるにしても、呼び出し方が違ってしまう。

 小生、FlashやAdobe AIRの開発に「Flash Develop」を愛用しているわけだが、この問題が発生してしまった。32bit系で作ったプロジェクトでAIRアプリの開発していて、64bit系でプレビューをしようとした時に、エラーで弾かれるのだ。内容を見ると、flexsdkのツールが見つからないとのこと。

 結論から言うと、まずFlash Developは(x86)にインストールされる。で、件のプロジェクト内にあるパスの指定を見ると(x86)がない。だが、このプロジェクトは32bitでも64bitでもいじるので、どっちか一つに絞る事はできない。

 で…結果。SetupSDK.batの中身で、

set FLEX_SDK=C:\Program Files\FlashDevelop\Tools\flexsdk

とある物を、

set FLEX_SDK=C:\Program Files (x86)\FlashDevelop\Tools\flexsdk
if exist "C:\Program Files (x86)\FlashDevelop\Tools\flexsdk\*.*" set FLEX_SDK=C:\Program Files (x86)\FlashDevelop\Tools\flexsdk

という形に、下に1行置いてみた。早い話、(x86)があるなら、そっち用に環境変数を上書きしろというバッチのコマンドである。とりあえず、こんな程度の改変で動いているっぽい。

 まぁ、備忘録というか、万が一同じ状況で困っている御仁のためというか、そんな感じで…。
posted by 管理人 at 00:00| Comment(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

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