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

投稿者: | 2012年5月22日

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

シーンの状態遷移

まずはシーンの遷移について解説します。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」とついているラベルがそれです。これは、「各オブジェクトに関連する処理」を実行する関数です。

移動関数は主に以下の処理を行います。

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

 

オブジェクトの移動

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

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

を行っています。

 

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

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

&nbsp mychar anchor enemy threnemy grabenemy
mychar
anchor
enemy
threnemy
grabenemy

 

状態遷移

プレイヤーの状態遷移は特にありません。

 

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

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

敵は「enemy」「threnemy」「grabenemy」という別オブジェクト扱いになっていますが、

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

という3つの状態があるものとして考えます。そうすると、

このように関係図が描けることとなります。