読者です 読者をやめる 読者になる 読者になる

スクリプト仕様の再設計5

フリーゲーム作製


# ひたすらチラシの裏
# 何か,中学時代にノートの端に↓こんなのをビッチリ書いてたような気がするなぁ...
# これ書いてて,ゲーム作製って慢性的な中2病だよなぁ,と思った(今更).


# リファクタリングするにあたって,まず現行スクリプト仕様を書きなぐって,
# で,おかしいなと思った所を修正してみる.
# 基本的にはリファクタリングが大目的なので,スクリプト仕様はそこまで変化しません.
# ので,「シューティング用スクリプト2」で晒しているスクリプトが多少参考になるかもしれません.


# オブジェクトについて

■ オブジェクトの種類

「シーンオブジェクト」
「プレイヤーオブジェクト」
「カメラオブジェクト」
「背景オブジェクト」
「ショットオブジェクト」
「編隊オブジェクト」
「敵オブジェクト」
「弾オブジェクト」
「パーティクルオブジェクト」
「背景パーティクルオブジェクト」
「プリミティブパーティクルオブジェクト」
「文字列パーティクルオブジェクト」
の13種類.オブジェクトは当り判定の方法によって分類する.
「ショット」→「敵」,「弾」→「自機」の当り判定しか行わない.
当り判定の必要が無いオブジェクトを全て「パーティクル」と呼ぶ事にする.
「背景パーティクル」は,背景オブジェクトの回転変換の影響を受ける.
「プリミティブパーティクル」は,直描きの四角ポリゴン飛沫.
「文字列パーティクル」は,文字列を扱う.

■ オブジェクトについて

オブジェクトは,メンバ変数で設定されたパラメータに従って,単純な運動のみを行う.
オブジェクトのメンバ変数が,ファイバによって書きかえらる事で,オブジェクトが動く.


また「オブジェクト生成」コマンドによって,オブジェクトがオブジェクトを発生させる.
例えば,
「ステージシーン」が「編隊」を発生させたり,
「編隊」が「敵」を発生させたり,
「敵」が「弾」を発生させたり,
「敵」が「敵」を発生させたり,「弾」が「弾」を発生させたり,
「プレイヤー」が「ショット」を発生させたり,
「パーティクル」が「ショット」を発生させたり(支援機),
「背景」が「パーティクル」を発生させたり.
各ステージは,「ステージシーンオブジェクト」が唯一のルートオブジェクトとなる.
オブジェクト生成コマンドによって,子オブジェクトを生成する事で,ステージが進行する.


このオブジェクトの生成により,オブジェクトには「親子関係」が生まれる.
子オブジェクトは,親オブジェクトのポインタを保持しておき,
親→子の破棄,子→親のメンバ変数参照,が行えるようにする.
これにより,親オブジェクトの"dest:"で子を破棄する事で,親に連動して子が自爆.
親の変数レジスタをチェックして,子オブジェクトが親変数に連動した行動を取る.
といった行動が可能となる.


また,オブジェクトは「ターゲットオブジェクト」のポインタを保持する.
敵オブジェクトのターゲットはデフォルトで自機(変更可).
ターゲットに向かって突進,ターゲットに向かって子オブジェクト生成(弾発射),
ターゲットから引力を受ける,ターゲットに向かって旋回,などの動きに用いる.


オブジェクトは,"const:","dest:","esc:","main:" の4種のスクリプトルーチンを
定義できる.

  const:
    〜 生成時,1Frame内の処理を書く(wait, waitif は書けない)
  dest:
    〜 破壊された時,1Frame内の処理を書く(wait, waitif は書けない)
  esc: 
    〜 画面外に退避した時/自爆した時,1Frame内の処理を書く(wait, waitif は書けない)
  main:
    〜 生成された次のフレームからの処理を書く

プログラム内で,これらが書かれている中間コードの位置を記憶しておいて,
それぞれのタイミングでファイバを生成,記憶した中間コード位置からスクリプトを実行する.

// オブジェクト定義クラス
//(「オブジェクト」は意味が広いので,内部的には「Actor」と呼ぶ)
class CActorClass
{
public:
    // アクターに結び付けられたモデル/ビットマップ
    GL::CSolidModel*    m_pModel;
    GL::CTexture*       m_pBitmap;
    
    // 実行するスクリプトの Entry Pointer
    CCommand* m_pConstPointer;  // "const:" 位置
    CCommand* m_pDestPointer;   // "dest:" 位置
    CCommand* m_pEscPointer;    // "esc:" 位置
    CCommand* m_pMainPointer;   // "main:" 位置

    // 管理するアクターの種類
    ACTOR_TYPE          m_enType;
};

■ シーンオブジェクト

シーンは全部で,
「初期化」「タイトル」「キャラセレ」「ステージ1-6」「エンディング」「リプレイ」
の11種.これらは,描画の違いによって分類.
コンフィグメニュー,ランキング表示は「タイトル」,
ステージスタートデモからクリアリザルト表示,ゲームオーバー表示は「ステージ」,
の中に含む(背景を替えずに表示するため).
シーンオブジェクトは,プレイヤーをのぞく全てのオブジェクトのルートとなる.
各シーンに一つだけ存在していて,シーンの切り替わりのタイミングで生成/破棄が行われる.
各ステージのオブジェクトは全てシーンオブジェクトから生成される.

■ プレイヤーオブジェクト

キャラクタセレクト後に生成され,被弾/復活のたびに,生成/破棄が行われる.
速度メンバ変数はプログラム内でパッド入力に合わせて自動的に書きかえられる.
また,ショットを生成するサブルーチンを作成して,プレイヤ生成時に登録する.
登録したショット生成サブルーチンは,ショット専用ファイバによって実行され,
プログラム内でボタン入力に合わせて自動的に差し替えられる.

■ カメラオブジェクト

カメラオブジェクトは,ターゲットオブジェクトのポインタを保持して,
カメラからターゲットに向かって視線を投げる.

■ 背景オブジェクト

背景オブジェクトは,1つだけ存在し,シーンオブジェクトから生成される.
モデル,Bitmap の両方を設定する必要があり,
モデルは背景として,Bitmapは天球に張りつけられる絵として描画される.
一つ一つの背景モデルをタイルと呼び,タイルは8*8のマップ上に敷き詰められる.
マップは上下左右が繋がっており,無限繰り返しで描画される.
実際に描画するマップ範囲は,スクリプトで変更する.
マップ上のタイルはスクリプトによって差し替えが可能で,このモデル差し替えによって,
背景の変化を表現する.

■ ショットオブジェクト

「ショット」は「敵」と当り判定を待つ.

■ 編隊オブジェクト

描画と当り判定を行わない「敵オブジェクト」.つまり透明な敵.
編隊オブジェクトは,自分が生成した敵/編隊オブジェクトが全て破棄されるまで破棄されない.
自分が生成した敵/編隊が全てショットによって破壊された場合,編隊は破壊扱いとなる.
自分が生成した敵/編隊の内一つでも画面外に退避した場合,編隊は退避扱いとなる.

■ 敵オブジェクト

「敵」は「ショット」と当り判定を待つ.当った場合,
CEnemy::m_fLife -= CShot::m_fAttackPoint * CEnemy::m_fDiffencePoint
が計算され,m_fLife < 0 で,「破壊」扱いとなる.
また,オブジェクト内のメンバ変数として移動可能範囲が設定されており,
この範囲を超えた場合,「退避」扱いとなる.

■ 弾オブジェクト

「弾」は「プレイヤ」と当り判定を待つ.喰弾範囲内と判定された場合,
CBullet::m_fLife -= CBullet::m_velocity.Length() / (CPlayer::m_fEatRange + CBullet::m_fEatResistance)
が計算され,m_fLife < 0 で,「破壊(喰弾)」扱いとなる.
また,被弾と判定された場合,プレイヤオブジェクトが破壊扱いとなる.

■ パーティクルオブジェクト

当り判定を持たない飾り.スクリプトに従い動く.

■ 背景パーティクルオブジェクト

当り判定を持たない飾り.スクリプトに従い動く.
背景オブジェクトの回転行列とz座標の影響を受ける.

■ プリミティブパーティクルオブジェクト

着弾飛沫は,四角形ポリゴンの直描きによって描画する.ファイバを持つ事は出来ない.
初速度,初加速度,色,透明度,ライフを指定して生成する.

■ オブジェクト定義命令

DefScene      [SceneID]       // シーン定義
DefPlayer     [PlayerNo]      // プレイヤー定義
DefCamera     [ActorID]       // カメラ定義
DefBackGround [ActorID]       // 背景定義
DefShot       [ActorID]       // ショット定義
DefGroup      [ActorID]       // 編隊定義
DefEmeny      [ActorID]       // 敵機定義
DefBullet     [ActorID]       // 敵弾定義
DefBGParticle [ActorID]       // 背景パーティクル定義
DefParticle   [ActorID]       // パーティクル定義

SetBitmap     [BitmapID]      // Bitmap 設定(BackGround/Shot/Bullet/Particle)
SetModel      [ModelID]       // Model 設定(BackGround/Player/Enemy/Particle)

const:   // 生成時 1Frame で呼び出される処理の開始位置
dest:    // 破壊された場合 1Frame で呼び出される処理の開始位置
esc:     // 退避/寿命の場合 1Frame で呼び出される処理の開始位置
main:    // 動きの定義開始位置

■ オブジェクト定義構文

DefEmeny     [ObjectID]
  SetModel   [ModelID]
  const:
    〜
  dest:
    〜
  esc: 
    〜
  main:
    〜


(つづく)