何を見てもアルゴリズムを考えてしまうのがプログラマの職業病といったところです。
私は結構ゲーム好きなんですが、ついついアルゴリズムを考えてしまうんですね。
バグを発見したときなどは楽しくてたまりません。
そのほつれからプログラムのコードが透けて見えるのです。
本日のターゲットは2001年、匠から発売されたアーケードゲーム「ナイトレイド」です。
ジャンルはシューティングなのですが、変なシステムを採用した、あまり見栄えのしないゲームでした。
このゲーム、非常にマイナーです。多分、名前を聞いて分かる人の方が少数派ですね。
ちなみにプレイステーションに移植されています。
アーケード版公式ページ
PS版公式ページ
このゲームには非常に致命的なバグがあり一部界隈では有名です。
自機を画面左上に移動させると敵が弾を撃たなくなるのです!
なぜこんなことが起こるのでしょうか?
矩形の衝突判定
ところで矩形(ようするに四角形のこと。プログラム用語。「くけい」と読む)同士の衝突判定はどうやるか分かりますか?
図のようにA,Bふたつの矩形があるとします。
Aの左上角の座標から見て右下にBの右下角があり(図の黒矢印)、
Aの右下角の座標から見て左上にBの左上角がある(図の赤矢印)場合にふたつの矩形は重なっているのです。
// 矩形Aの座標
// (ax1, ay1)───────────┐
// └───────────(ax2, ay2)
// 矩形Bの座標
// (bx1, by1)───────────┐
// └───────────(bx2, by2)
if (((ax1 < bx2) && (ay1 < by2))
&& ((ax2 > bx1) && (ay2 > by1))){
// 衝突!
}
シューティングゲームでは敵に近くから弾を撃たれて即死しないように配慮して、
敵が自機に近い場合は弾を撃たないようにしているものがあります(ゲーマー用語で弾封じといいます)。
このナイトレイドでは自機と敵が重なってもミスとはならない仕様なのですが、
重なった状態から弾を撃たれると理不尽だろうという配慮でしょうか、
この弾封じの判定が実装されているわけです。
そして、あろうことか、弾封じのための矩形の衝突判定で条件式の"<"と">"を
間違えるというコーディングミスをしてしまったのです!
// 矩形Aの座標
// (ax1, ay1)───────────┐
// └───────────(ax2, ay2)
// 矩形Bの座標
// (bx1, by1)───────────┐
// └───────────(bx2, by2)
if (((ax1 < bx2) && (ay1 < by2))
&& ((ax2 < bx1) && (ay2 < by1))){
// 衝突?
}
そして、誰もこのことに気づかないままゲームは出荷されたのでした。境界値テストは重要ですね。
投稿日時 : 2007年8月5日 18:28