タスクシステム4

タスク同士の当たり判定

ここが超重要です。はいはいテストに出ますよー(何のテストじゃ)
 
例えば、ブロック崩し(こればっかですね)において、
以下のタスクがぶつかった場合、何らかのやり取りを考えなければなりません。

  1. ボールvs壁
  2. ボールvsパドル
  3. ボールvsブロック

1,2の場合は、ボール自身が跳ね返るだけですが、
3の場合、ブロックを破壊する必要があります。
 
ただ、全ての場合において、

  • どれにぶつかったのか?
  • どれと跳ね返るのか?
  • どれを破壊するのか?

ということを調べる必要がありますよね。
 
ということで、これを解決するためには、
タスクに「グループ属性」を追加します。

// グループ列挙
enum GROUP
{
	PADOL = 0x01,
	BALL  = 0x02,
	BLOCK = 0x04,
	WALL  = 0x08,
};

struct TCB
{
	・
	・
	GROUP group; // グループ属性
	・
	・
};

これにより、チェックしたいタスクを

IsHit(ball->rect, (GROUP)(PADOL | BLOCK | WALL));

として渡し、

void IsHit(RECT rect, GROUP group)
{
	// タスクリストを全チェック
	while(taskList->next != NULL)
	{
		・
		・
		// パドルとぶつかっているか?
		if(taskList->group == (group & PADOL))
		{
			// ぶつかっていたら、ボールの移動量を反転する
		}
		・
		・
	}
}

というようにチェックを行うことができます。
 
最適化の方針として、タスクリストを、
グループごとに分けるという方法があります。
 
例えば、シューティングゲームなら、

  • 自弾タスクリスト
  • 敵機タスクリスト
  • 敵弾タスクリスト

といった感じです。
 
これで、呼び出すタスクリストを節約できるので、
高速化が計れるわけです。

描画関数の扱いについて

これも結構重要です。
 
たとえば、実行関数ポインタの中で描画を行うものとします。
と、これはこれで楽なのですが、以下の問題があります。

  • Zバッファ
  • 描画の処理落ち

Zバッファというのは、「描画順」のことです。
例えば、シューティングゲームでは、
自機→自弾→敵機→敵弾
の順番で描画を行う必要があります
(実装により多少順番が変わるかもしれませんが…(∀`;
 
というのも最近の弾避けシューティングで、
自機や自弾の下に敵弾が隠れてしまったら、
間違いなくシューターから暴動が起こります(きっと)
 
ということで、「描画順」はとっても重要なのですが、
現在のタスクにはそういった指定はないですよね。
 
そこで、実行関数ポインタから描画関数を分離して、
「グループ」別に描画を行うようにすることで、
Zバッファの問題を回避します。
 
あと、描画の処理落ちということですが、
重い処理を行う場合には、描画の処理を省略して、
処理を軽くしたいというときがあります。
あるはずです。あるにちがいありません。
きっと、、、。
 
そういう場合に、描画関数を分離しておくと、
描画処理を省略できるわけです。
 

その他の機能

タスクの優先順位

タスクを実行する優先順位を属性に持たせます。
例えば、、、。
 

親子タスク

これです。
これが優先順位に関係あります。
 
と、その前に親子タスクの説明。
 
「親子タスク」とは、例えばシューティングにおける、
ボスの本体と手足です。
本体がやられると、手足も爆発します。
 
この場合、本体が「親」、手足が「子」になります。
 
この様なつながりを「親子タスク」といいます。

で、優先順位の話に戻ると、
あるフレームで、本体を破壊しました。
そして通常、そのフレーム内で手足も破壊されます。
 
しかし、手足タスクを先に実行してしまったとします。
そうすると、手足タスクが爆発するのは次フレームになってしまいます。
 
これは不自然ですよね。
 
ということで、本体タスクの優先順位を高くする必要があるわけです。
 
これが優先順位の必要性です。
 

全タスクの削除

これはあると便利ですね。
例えば、達人ボム発動時とか、ステージクリア時に使えますね。
 
(つづく)