あたり判定を管理

書き忘れましたが、私は当たり判定は矩形で管理するのが好きなので、矩形でやることにしますよ。
さて、とりあえず、1個のプレイヤーにN個の敵が接触したかを判定したいとします。そんな時は、敵キャラを動かす処理のところで矩形を登録しておき、プレイヤを動かす処理の部分で判定してやるのが一つの手です。

MainLoop
{
  敵判定リスト.reflesh(); // 判定を空にする

  // 敵を動かす
  foreach( 敵キャラ )
  {
     敵キャラ.Update();
     敵判定リスト.SetHantei(敵キャラの判定);
  }

  // 自機を動かす
  {
    自機.Update();
    if( 敵判定リスト.IsAtari(自機の判定)
    {
      //やられたー
    }
  }

  // 敵の表示
  敵キャラ.Draw();
  
  // 自機の表示
  自機.Draw();
}

こんな感じすか。判定を登録するリストは、リスト的なものを適当に実装してやればOKです。が、登録はケツだけでOK、挿入削除無しってことなので、固定長配列に入れてしまうのが楽でしょう。

/* ただのRECT構造体ですが、後に拡張したいので、敢えて定義しておく
typedef struct _tagAtariRect
{
  int left;
  int top;
  int right;
  int bottom;
}AtariRect;

class CHanteiList
{
public:
  void SetHantei(AtariRect* pRect);
  int  IsAtari(AtariRect* pRect);
  void Reflesh();

private:
  AtariRect mRect[1024];  // 1024個くらいでいいか?
  int pos;  // 登録位置
};

こんな感じのクラスでいいですかね。つうことで実装。先ずはリストを空にするところから。

void CHanteiList::Reflesh()
{
  pos = 0;
}

実体をクリアしなくても、論理長を0にすればジューブン。続いて、判定の登録。

void CHanteiList::SetHantei(AtariRect* pRect)
{
  memcpy( &(mRect[pos]), pRect, sizeof(AtariRect) );
  pos++;
}

バッファにコピーするだけー。スタックの実装みたいな感じですね。で、最後に判定

void CHanteiList::IsAtari(AtariRect* pRect)
{
  int len = pos;
  for( int idx=0; idx<len; idx++ )
  {
    AtariRect* pTarget = &(mRect[idx]);

    if(   (pRect->left < pTarget->right)
       && (pRect->top  < pTarget->bottom)
       && (pRect->right > pTarget->left)
       && (pRect->bottom > pTarget->top)  )
    {
      return 1;
    }
  }

  return 0;
}

ループで回すだけっすね。登録されている敵の判定を順番に一巡り、自機の判定と比較して結果を出すってわけですね。

ってなわけで、次回はN個:N個の判定をやると思いたい