ゲームプログラムTips

投稿者: | 2012年12月1日

■これは何?

ゲームプログラムしていて、気が付いたことを書き留めておくものです。

■当たり判定

▼当たり判定は「円」で充分

「円」による判定は、汎用的で、直感的に分りやすいためバグも出にくく、コストパフォーマンスが高いです。なにか特別な理由がある(地形との当たり判定とかニードル(縦長の弾)など)以外は、「円」で判定を行ったほうが良いみたいです。

▼衝突応答は、複数回に分けて判定を行うとうまくいく

例えば、地形にぶつかった場合押し戻す、という処理を実装する場合、XY方向の判定をまとめて行うのではなく、

  1. X方向に移動、ぶつかってたら押し戻し
  2. Y方向に移動、ぶつかってたら押し戻し

というように、2回に分けて判定を行うと、うまくいきます。

▼移動速度が速くて、通り抜けが起こる場合

以下のどちらかの方法を取ります。

  • 通り抜けが起きない移動量になるよう、制限をかける
  • 通り抜けが起きない移動量になるように、移動量を分割して判定を行う

例えば、シューティングの自機のショットはたいてい高速なので、2回以上に分けて当たり判定を行います。

▼敵のバランス

プレイヤーに不利益となる判定(ex.プレイヤーへの衝突)の場合、敵のサイズを小さくし、プレイヤーに利益となる判定(ex.プレイヤーの弾の衝突)の場合、敵のサイズを大きくします。

つまり、敵は2つのサイズを持つことになります。

▼リプレイ実装の副産物

リプレイを実装すると、プレイヤーが楽しめるだけではなく、

  1. バグの再現
  2. レベルデザインの修正

が可能になります。

1は、何らかのバグが発生した場合、リプレイを再生することで、バグの手順を再現できるということです。

2については、自分が理想とするプレイを再現できるため、その通過ポイントにアイテムを配置することで、プレイヤーを「理想のプレイスタイルに誘導」することが可能になります。

■数学

▼一定のフレームでAからBに移動させる
  1. 一定のフレームをTとする。
  2. Bまでの方向ベクトル(v)を「B-A」で求める。
  3. |v|でその距離(L)を求める。
  4. 「L/T」で1フレームの移動距離(l)が求められる。
  5. vの単位ベクトルにlをかけると1フレームの移動ベクトル(v1)が求められる。
  6. 「A+v1」により、そのフレームの移動後の座標が求められる。

これを使うと、

  • テキトーに動かした敵をある位置まで自動的に戻す
  • 誘導弾
  • 任意の位置にいるプレイヤー座標から開始したエフェクトを特定の位置への線形移動(例えば、メッセージウィンドウなど)

といった処理を行うことができます。

■物理

▼物理は複雑

物理計算をして移動量を決定すると、複雑な軌道をシミュレートすることが可能になります。

しかし、それはしばしばゲームの不安定要素となるため、テーブルと移動開始時間からのタイマーにより移動量を決定すると、移動量が安定します。

■AI

▼AIの使い道

AIは複雑なルールを持つゲームにおいて、敵やNPCの思考ルーチン構築の負担を減らすものであり、通常は必要ないです。

確実に使えるものとしては、用途の明確な、

  • LOS追跡アルゴリズム(追いかける)
  • LOS迎撃アルゴリズム(先読み弾)
  • 有限状態機械
  • A*による経路探索

ぐらいです。

逆に、

  • ニューラルネットワーク
  • 遺伝的アルゴリズム

は、とっても使いどころが難しいです。

■リファクタリング

リファクタリングとは、

  • 外部から要求される動きを変えずに、ソースを読みやすくする

手法です。

リファクタリングの手法については、例えば、

  • 重複する処理の共通関数化
  • 長すぎるメソッドのサブルーチン化
  • 巨大なクラスの分割

などがあります。

これらの手法をカタログ・パターン化したのがリファクタリングです。

「まあ、動けばいいじゃん」という思想は、とても正しく、健全です。

リファクタリングをしても、進捗率は1%も増加しません。

ただ、リファクタリングには、機能拡張・修正を容易にし、未知のバグを検出するなどのメリットがあることを忘れてはいけません。

■トークンの選択・追加

ゲームを面白くするのは、トークンの増加です。

ただ、トークンを単純に増やすだけではダメで、

  • メリット(追加することにより、どんな効果が得られるのか?)
  • デメリット(追加することにより、どんなゲーム性が失われるのか?)

をしっかり考察し、自分が重視する価値観を満たすトークンのみを選択・追加する必要があります。

しかしこの考察・選択は、作り手のスキルに依存する部分でもあります。いざ、追加してみたら予測のできなかった問題が発生した、というのは、良くあることです。

そこで、実際にゲームに使うかどうかを「保留」できる仕組みを、前もって作っておくことで、このリスクを回避することができます。

その仕組みとは、トークンの生成ロジックをプログラムから切り離してしまうことです。

具体的には、

  • 外部スクリプト化
  • 外部マップデータ化

により、トークン生成の定義を外部で行えるようにします。

■トークン生成の定義の副産物

トークン生成の定義を外部で行えるようにするようにすると、生成するための入り口が簡易化されます。

それにより、「敵トークン」の破壊により、「爆発トークン」を生成するというような、トークン間の「連鎖反応」を実装しやすくなります。

他にも、「ボストークン」が「雑魚トークン」を生成するという連携や、「エフェクト1トークン」消滅すると「エフェクト2トークン」を生成するという連携の実装も容易になります。

■飽和点を認識する

ゲームを作っていると、時々、些細なことが非常に気になったりします。例えば、このエフェクトをあと1フレーム伸ばすべきか?などと。おそらく、その問題を解決したところで得られるものは少ないです。

その問題を解決したい気持ちをグッとこらえて次のステップに進むことが大切です。

このことは、素材作成などについてもいえます。

絵の下手な人が何時間も必死でドット絵を描いても、絵のうまい人が鼻歌交じりで数分で描いた絵には勝てません。作曲の知識のない人がメロディーを必死に考えても、一定のレベル以上の曲は作れません。

飽和点を認識することで、無駄な作業を避けるようにしましょう。(注:頑張ることは悪いことではないです。でも成果の出やすい方法を選んだほうが結果としていいものが出来上がることが多いです)

■ミニマップ

ミニマップはスクロールが存在するゲームでの指針となります。

しかし、ミニマップを透明化できない場合(情報がごちゃごちゃある場合など)、フィールドの視界を妨げます。

その場合は、思い切って、上から下まで伸びた枠にしてしまうと、

視界を妨げることがなくなります。

■バージョン管理

大きな修正を加える場合、万が一にとバックアップ・コピーを続けると、コピーファイルだらけになってしまい、なんだかよくわからなくなってしまいます。

個人開発では大げさかもしれないですが、バージョン管理システムを使うことにより、

  • ソース管理の簡易化
  • コメントの付加
  • コピーを取る手間の削減

などの効果を得ることができます。

Subversion

バージョン管理システムの主流となりつつあるのが、Subversion (TortoiseSVN)です。

このあたりを参考にインストール、設定をします。