「えぐぜりにゃ〜」ソース解説

色々と勉強になった「えぐぜりにゃ〜」のソースをkenmoなりに解説してみます。
 

シーンの状態遷移

まずはシーンの遷移について解説します。
 
34行目〜41行目の定数に注目します。

	// 遷移状態ステート
	#define STATE_TITLE_INIT    0
	#define STATE_TITLE         1
	#define STATE_GAME_INIT     2
	#define STATE_GAME          3
	#define STATE_OVER_INIT     4
	#define STATE_OVER          5
	#define STATE_QUIT          99

これらはシーンを切り替える状態遷移の定数です。
変数「state」にいずれかの値が入り、各状態に応じて処理を分岐していきます。
 
遷移図としては、以下のようになります。

 
エントリポイントは、177行目の

	state = STATE_TITLE_INIT

ですね。
 
以降、*mainloopにジャンプし、

	repeat
		・
		・
		・
		// メインルーチン
		if (state == STATE_TITLE_INIT) :gosub *statetitleinit
		if (state == STATE_TITLE)      :gosub *statetitle
		if (state == STATE_GAME_INIT)  :gosub *stategameinit
		if (state == STATE_GAME)       :gosub *stategame
		if (state == STATE_OVER_INIT)  :gosub *stateoverinit
		if (state == STATE_OVER)       :gosub *stateover
		if (state == STATE_QUIT)       :break
		・
		・
		・
	loop

該当する処理(サブルーチン)を呼び出し、少しの処理を行い、
何らかの変化があった場合に、状態(state)を遷移させていきます。
 
例えば、stateがSTATE_TITLE_INITであった場合、
ラベル*statetitleinitを呼び出し、「タイトル画面の初期化」をして、
またこのループに帰ってきます。
 
 
さて、この状態遷移の方法を知らない人にとっては、
「なんだか面倒なことをしているなー」
という印象があるかもしれません。
 
では、なぜこのような面倒なことをするのかというと、

  • シーンの区切りがハッキリする
  • シーンの追加・削除がカンタン!

というメリットがあるからです。
 
例えば、ゲームオーバー時に「ハイスコアを記録・表示するシーン」を追加するとします。
 
その場合は、

  1. stateがSTATE_OVERのときの遷移先を「ハイスコアを記録・表示するシーン」にする
  2. そのシーンの遷移先をSTATE_TITLE_INITにする

という手順を踏むことで実現できます。
 
このように「遷移先の付け替え」がカンタンになる、
というのが、この方法の利点です。
 
 
他の部分でも、この方法は使われています。
それは96〜110行目にはアンカーの状態遷移定数で、変数「anchor_state」に代入されます。

	// アンカー遷移状態
	#define ANCHOR_STATE_STANDBY   1
	#define ANCHOR_STATE_THROW     2
	#define ANCHOR_STATE_GRAB      3
	#define ANCHOR_STATE_RETURN    4

 
 

ゲームオブジェクト

ゲームオブジェクトには、以下のものがあります。

変数名 オブジェクト 配列
mychar プレイヤー ×
anchor アンカー ×
enemy
grabenemy 掴んだ敵 ×
threnemy 投げられた敵
effect エフェクト

画面上に複数表示する必要のあるものは、配列になっています。
 
各オブジェクトが持つ値の一覧です。
(※ソース上の変数名は「オブジェクト変数名」+「_」+「値の変数名」になります)

変数名 意味 mychar anchor enemy grabenemy threnemy effect
x X座標
y Y座標
sx X移動量 ×
sy Y移動量 ×
ssx X慣性 × × × × ×
ssy Y慣性 × × × × ×
size 大きさ × × × × ×
rotate 回転角度 × ×
gr_rotate 画像の回転角度 × × × × ×
anc_rotate アンカーの回転角度 × × × × ×
timer タイマー × × × ×
dam_timer ダメージタイマー × × × × ×
life 体力 × ×
type 種類 × × ×
state 状態 × × × × ×
flag フラグ × × × × ×

 
それぞれの値については、ほとんど「意味」のままなのですが、
すこしだけ詳細を解説します。
 
「x,y」は中心座標です。
そして、「sx,sy」は移動量です。
それぞれの移動関数で「x,y」に足しこまれます。
(※移動関数については次の項で解説します)
 
「ssx,ssy」はプレイヤーを操作したときに少しだけ発生する慣性です。
操作したときに、フワッとするのは、この変数があるためです。
 
「timer」というは、敵が持っているカウンターのようなもので、移動関数を呼ぶたびにカウントされます。
この数値が一定の値になるたびに、攻撃方法や移動パターンが変化します。
 
dam_timer」というのは、連続でダメージを食らって秒殺されないようにするための変数です。
ダメージを受けたときに、このタイマーがセットされ、移動関数を呼ぶたびに減少します。
これが1以上の場合は、敵にぶつかっても体力が減らないようになっています。
 
最後の「flag」は牛乳とプリンの行動パターン格納するフラグです。
これにより、4wayやにんじんショットを切り替えたりしています。
 
 

ゲームオブジェクトの移動関数

とりあえず、ざっくりと解説します。
 
sx,syを持っているオブジェクト(grabenemy以外)は、それぞれ移動関数を持っています。
「moveXXXX」とついているラベルがそれです。
 
これは、「各オブジェクトに関連する処理」を実行する関数です。
移動関数は主に以下の処理を行います。

  • オブジェクトの移動
  • 他のオブジェクトとの当たり判定
  • 状態遷移

 

オブジェクトの移動

オブジェクトの移動では、主に、

  • 「中心座標」に「移動量」を足しこむ
  • 「移動量」の減衰
  • 「キー入力」に対応する移動

を行っています。
 

他のオブジェクトとの当たり判定

以下のような関係があります。
(※横から見ていき、○で当たり判定を行っています)

  mychar anchor enemy threnemy grabenemy
mychar
anchor
enemy
threnemy
grabenemy

 

状態遷移

プレイヤーの状態遷移は特にありません。
 
アンカーについては、定数で宣言されているように4種類の状態遷移があります。

これはゲームクリエーターズバイブルにのっている状態遷移の書き方です。
四角が「状態」で、丸が「外部からの入力」になります。
 
例えば、「待機」状態においてボタン1の押下があった場合、
赤い線を辿って「射出」状態になる、といった感じです。
 
敵は「enemy」「threnemy」「grabenemy」という別オブジェクト扱いになっていますが、

  • 通常状態
  • 掴まれ状態
  • 投げられ状態

という3つの状態があるものとして考えます。(説明上、、、(´∀`;

 
とりあえず今日はここまでですー。