「ゲームプログラミング」の版間の差分

削除された内容 追加された内容
→‎特殊イベントのフラグの作り方: 三値ビット的なイベント管理手法の是非
597 行
== 特殊イベントのフラグの作り方 ==
==== フラグとは ====
RPGなど、ゲーム中で1回しかおきない特殊なイベントとかを作りたい場合があるでしょう。RPG以外でも、シミュレーションゲームなどで特殊イベントを実装したいこともあります。たとえば、もし日本の中世の戦国時代シミュレーションゲームで「桶狭間の戦い」が3回も起きたりしたら困ります。
 
RPGの場合、1人しかいない中ボス敵(生物)を倒して殺すイベントは、1回しか起きなくては困ります。そして、たとえば中ボスを殺すと、大ボスの居城に行けるようになるストーリーだとしましょう。
618 行
 
 
==== 備考 ====
こういった、ゲームのフラグ処理には、あまり上手い方法はありません。
 
==== フラグ変数は2値か3値か4値か? ====
また、あまり凝った特殊フラグ処理のシステムを実装(?)すると、デバッグがとても大変になります。
 
一般にIT産業では「フラグ」と言った場合、状態 on または off の意味で、数値「1」か「0」の二つのいずれかの使います。
なので、初心者は、あまり凝りすぎない、フラグ管理システムにしましょう。
 
このような2個の数値で管理する方式を、数学の記号論理学の用語を使って「2値論理」と言います。
 
特に、特殊イベント処理のデバッグには、ゲーム全体を最初からエンディングまでプレイする「通しプレイ」によるデバッグが必要になることもありますので、あまり凝りすぎないようにしましょう。
 
ですが、ゲームでは数学とは異なり、イベント状態 の「未発動」または「イベント発動中だがイベント未クリア」または「イベントクリア済み」 の3種類の状態を使うこともあります。
 
つまり、2000年代以降のゲーム制作において、イベント処理の実装とデバッグは、じつはゲーム開発上のボトルネック( 制約(せいやく)になりうる要因 )です。
 
(デバッグ作業の問題ではなく)動画の画質の向上などハード面の問題なら、解決には単に、ゲーム機のハードウェアにメモリ基盤などを増やすというハード的な方法で対処できます。しかし、ゲーム内の特殊イベントのデバッグは、人間の感性をもった人員が必要なので、これはメモリをいくら増やそうがCPUを増やそうが、ハードだけではデバッグは解決しません。
 
まず、イベント処理にかぎらず、デバッグ作業は基本的に ITソフトウェア開発のボトルネックです。
 
そしてゲーム開発において、特殊イベント処理のデバッグは、そのデバッグ作業のなかでも、かなり手間のかかる部分です(通しプレイなどが必要なので)。
 
 
 
==== ON/OFF以外のフラグが必要な場合 ====
たとえばゲーム中では、「ある用事を頼まれたけど、まだその用事を解決していない」のような場合もあります。
 
648 ⟶ 637行目:
という3段階の区別が必要なのに、ON/OFFの2通りだけでは区別できないからです。
 
なので、必要に応じて、3段階のフラグも作りましょう。
 
必要に応じて、3段階のフラグも作りましょう。
 
とりあえず、
657 ⟶ 645行目:
とでも、数値の意味を設定しておけば大丈夫でしょう。
 
 
このようにゲームでは、情報科学の伝統的な理論とは異なり、イベント変数としてのフラグ変数を「2」または「1」または「0」の三つのうちのいずれかを使って記述する場合もあります。
 
 
C言語でゲームを作るなら、配列を使って、0/1/2の三値のフラグ変数を管理すると、ラクに管理できるでしょう。
 
 
なお、数学でいう「3値論理」とは、上述イベント変数のような手法とは、本来は意味が異なる。1950~1970年ごろ、かつて三値論理学が大学などで研究された事もあったが、現代では滅多に使わないので、気にしなくていい。
 
なお、情報科学にはビット列という概念がありますが(たとえば 1011 0010 みたいな数値列)、
 
ビット列は、ゲームのフラグ管理では、あまり実用的ではないです。通常の二値ビットだけでなく、もし三値ビット(2202みたいなの)でイベント処理をしても、よくあるミスで、ビット列が1個ズレるバグで、となりの桁のイベントがズレてしまうバグがあります。
 
たとえば、
:1120
という三値ビットを
 
:4個目のイベントは発動中で未クリア、
:3個目のイベントはクリア済み、
:2個目のイベントは発動中で未クリア、
:1個目のイベントは未発動、
という意味だとしましょう。
 
 
これをもし、現在未発動である1個目のイベントをこれから発動させようとして、本来なら0001を足して三値ビット列を本来なら「1121」にすればいいのですが、
もしケタをひとつ間違えて、0010 を足してしまうと
 
1121
+ 0010
-----
1201
 
というふうに、プラス1をミス入力した2ケタ目だけでなく、さらに繰り上がりにより、ひとつ上の3ケタ目もプラス1してしまい、バグが連鎖的に波及してしまいます。
 
 
他にも、よくあるミスとして、クリア済み(変数=2)のイベントのクリアを本来1回しかクリア発動していけないのに2回発動してしまい、三進数では 2+1=10 なのでケタが繰り上がってしまい、隣のイベント変数も変化してしまうバグがあります。
 
 
三値ビットではなく二値ビットでも同様にケタ間違いが波及しやすいので、なるべくビット列は避けるほうが安全です。
 
 
もしかしたらファミコン時代の古いゲームなら、メモリの節約のためビット列で処理する事もあったかもしれませんが、現代なら配列でイベント管理するほうが安全でしょう。(ファミコン時代のRPGによくあるバグで、メモリのオーバーフローを起こしてイベントフラグのズレるバグが幾つかある。)
 
なお、3値論理ではなく4値論理なら比較的に実装しやすいですが(2値ビットを2ケタ使用すれば4値論理が実装できるので)、また余った最大値3はバグ波及を防ぐ余白にも使えるのですが、しかしC言語なら配列で充分にイベント管理は代用できますので、わざわざ4値論理を実装する必要も乏しいでしょう。
 
 
ただし、C言語を使えない、ゲーム制作ツールを使ってゲームを作る場合、ビット列で代用せざるを得ない場合があり、4値論理的なビット列を使って代用する場合もあります。その場合、上述のビット列バグのようなバグが発生しやすいので、あまり重要なイベントにはビット列を使わないようにするとか工夫するとよいでしょう。
 
 
==== 備考 ====
こういった、ゲームのフラグ処理には、あまり上手い方法はありません。
 
また、あまり凝った特殊フラグ処理のシステムを実装(?)すると、デバッグがとても大変になります。
 
なので、初心者は、あまり凝りすぎない、フラグ管理システムにしましょう。
 
 
特に、特殊イベント処理のデバッグには、ゲーム全体を最初からエンディングまでプレイする「通しプレイ」によるデバッグが必要になることもありますので、あまり凝りすぎないようにしましょう。
 
 
つまり、2000年代以降のゲーム制作において、イベント処理の実装とデバッグは、じつはゲーム開発上のボトルネック( 制約(せいやく)になりうる要因 )です。
 
(デバッグ作業の問題ではなく)動画の画質の向上などハード面の問題なら、解決には単に、ゲーム機のハードウェアにメモリ基盤などを増やすというハード的な方法で対処できます。しかし、ゲーム内の特殊イベントのデバッグは、人間の感性をもった人員が必要なので、これはメモリをいくら増やそうがCPUを増やそうが、ハードだけではデバッグは解決しません。
 
まず、イベント処理にかぎらず、デバッグ作業は基本的に ITソフトウェア開発のボトルネックです。
 
そしてゲーム開発において、特殊イベント処理のデバッグは、そのデバッグ作業のなかでも、かなり手間のかかる部分です(通しプレイなどが必要なので)。