9 月 07 2008
PV3Dでレースゲーム制作 14 - 色情報を操る
前回の続きです。
周回カウントの判定自体は前回のエントリの内容をそのままコードにすれば良かったので問題なくできました。
実は難しかったのは、コースデータ画像にグラベルとか壁という「地形情報」と、周回判定用の「チェックポイントエリア」、この2つを両方記録して、しかもプログラムは別々に処理できるようにしないといけない点。(前回はサラッと流してたけど。)
データ画像と変換した巨大配列を2つず作ってもできるけど、何とか工夫して1セットで、しかも効率よく実装できないものか…?色情報の扱い方がカギとなりました。
*データ画像→巨大配列で判定する話はこちらのエントリ。
いろいろ考えた末、色情報を R/G/B 別々に扱えばできそう、という結論に。
どういうことかというと、地形情報は Blue の値で表し、チェックポイントは Green の値で表すというわけです。(Red は未使用。そのうち別のデータに使うかも。)
データ画像はこんな風になりました。
| 色情報 | 地形情報 | チェックポイント |
|---|---|---|
| 0x****ff | ターマック | - |
| 0x****99 | グリーン | - |
| 0x****66 | サンド | - |
| 0x****00 | コース外 | - |
| 0x**ff** | - | 判定用エリア1 |
| 0x**cc** | - | 判定用エリア2 |
| 0x**99** | - | 判定用エリア3 |
| 0x**66** | - | 判定用エリア4 |
| 0x**00** | - | エリア外 |
色はこの2つの組み合わせで決まります。たとえば、「判定用エリア1の砂地部分」は「0×00ff66」で塗られます。
Photoshop のレイヤー合成で「スクリーン」を使えば、「000000」+「000066」+「00ff00」→「00ff66」となり、別々のレイヤーに青・緑それぞれ作っておいても重なれば自動的に期待どおりの色になってくれます。
これなら画像作るのが楽チン!
RGB16進数の色分解
今度はプログラムのお話。
RGBのデータから、必要な部分の単色の値だけを抜き出す方法です。
複数の情報(地形/チェックポイント)を格納しないといけないので、エリア判定用の巨大配列には、getPixel で取得した16進数の uint 値をそのまま代入していきました。データを取り出すときに、地形情報が欲しいときは Blue の値を取得、チェックポイント判定の時は Green を取得するようにすればOK。
//コースデータの作成
groundData = new Array();
var groundBitmapData:BitmapData = groundBitmap.bitmapData;
for (var i:int = 0; i < 560; i++)
{
groundData[i] = new Array();
for (var j:int = 0; j < 420; j++)
{
groundData[i][j] = groundBitmapData.getPixel(i, j);
}
}
たとえば、(100, 200)マス目の情報を参照するには、以下のようになります。
var color:uint = groundData[100][200]; var colB:uint = color & 0xff; //Blueの値(地形情報)を取得 var colG:uint = (color >> 8) & 0xff; //Greenの値(チェックエリア情報)を取得
参考サイト:flair4 blog - AS3.0 16進数の色分解ではまった事
「&」はAND演算子、「>>」はビットシフトです。何をしているかは、参考サイトの記事下の方にとても分かりやすい解説があるので、気になるかたは参照してください。
今までビット演算ってどんなとき使うんだろ、、とか思っていたけど、こういう使い方もあるんですね。
あとはGreen取得値を元に前回の周回カウントアルゴリズムを実行するだけ。ちょっと遠回りしましたが、ようやく周回のカウントが実現できました。
次回、タイムアタック付きのデモ公開、…できるといいな。
