毎回同じ範囲内の数値で行ったり来たりを繰り返します。

スプライトのアニメーション・インデックスと同じような動作をします。実際にスプライトのアニメーションが 16 枚あるという想定で、015 までの数値で循環し続ける処理をビット演算を使って実現します。

サンプルコード

if ステートメントを使うこともできますが、ビット演算を利用できる状況で活用すれば if 処理を省くことができます。

image_index = counter;
var a = 15;
counter = ++counter & a;

インスタンス変数 counter は 015 の間で数字を返します。具体的には

    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;

となります。
&」 は ビット演算(Bitwise)の AND 。これはビット積と呼ばれています。

GML における考え方/ビット積

GML では十進数を二進数化する標準のビルトイン関数はありません。しかし二進数は Power of 2 と組み合わせればかなり覚えやすくなるため一部丸暗記できます。

アニメーションの枚数が 16 というのは二進数を使った処理的には美味しい状況。まず Power of 2 (POW2)を考えて、

1,2,4,8,16,32,,

1 の二進数は「1」(一桁)、
2 の二進数は「10」(二桁)、
4 の二進数は「100」(三桁)、
8 の二進数は「1,000」(四桁)、
16 の二進数は「10,000」(五桁)、15 の二進数は「01,111」。

インスタンス変数 counter は 0 で初期化されましたが常に1が加算されています。

    (counter+1)++counter と同じです。

※ ++counter と counter++ は微妙に違う処理です。

counter と 15 (二進数化された値「01111」)とのビット積を考えます。

counter + 1 の結果が 1 の場合、1 の二進数は「00001」だから

00001 =  1
01111 = 15
-------------
00001 =  1

ビット積の結果はこうなる。じゃあどんどん行きましょう。

00010 =  2
01111 = 15
-------------
00010 =  2
00011 =  3
01111 = 15
-------------
00011 =  3

途中省略、そして最後 ++counter の結果がいよいよ 16 となりました。

10000 = 16
01111 = 15
-------------
00000 =  0

ビット積はビットを 0 でマスク(mask)する時に利用します。マスクとはビットを 0 もしくは 1 に変える処理のことで、ビット積の場合は

  • 各桁のビット単位の比較が 1 で一致した場合 1 を返す

  • ビットが 0 で一致した場合 0 を返す

  • ビットが一致しない場合 0 を返す

するとその結果 16 & 15 == 0 となります。

ビット積を使わない場合

上記コードを if ステートメントで書き直すと以下のようになります。

image_index = counter;
var a = 15;
if (++counter > a) counter = 0;

次のページへ

Leave a Reply

Your email address will not be published. Required fields are marked *