そろそろ、ゲームにおけるマップを作りたいと思います。
その第一歩として、壁を定義し、配置します。
class Wall
{
Vec2D m_From;
Vec2D m_To;
public:
Wall(Vec2D from, Vec2D to)
:m_From(from), m_To(to)
{}
void Render();
Vec2D From(){ return m_From; }
Vec2D To(){ return m_To; }
};
Render関数ではそれを結ぶ線を描くだけなので、
省略します。
次に、この壁を管理するクラスを作ります。
例によってこれもシングルトンで実装します。
class WallManager
{
std::list m_WallList;
//シングルトン
WallManager();
public:
static WallManager& Instance()
{
static WallManager wm;
return wm;
}
void Render();
//与えられた線分ABが壁と交差していないか返す
bool IntersectWalls(Vec2D A, Vec2D B);
//Getter
std::list& GetWallList(){ return m_WallList; }
};
壁との衝突を判定する関数が備わっています。
あらゆる局面においても、壁との衝突判定は、
線分を用いて行われることが多いです。
というか、行うようにします。
bool WallManager::IntersectWalls(Vec2D A, Vec2D B)
{
std::list::iterator it;
for(it = m_WallList.begin();
it != m_WallList.end();
++it)
{
if(Line_Collision(A, B, it->From(), it->To()))
return true;
}
return false;
}
理論的な知識は持ち合わせていないので、
単なる模倣に過ぎません。
理論的に理解したいという人には、
http://marupeke296.com/COL_2D_No10_Segm ... gment.html
などのページが参考になると思います。
► スポイラーを表示
WallManager::WallManager()
{
//画面を囲うように壁を配置
m_WallList.push_back( Wall(Vec2D(000.0, 000.0) , Vec2D(000.0, 480.0)) );
m_WallList.push_back( Wall(Vec2D(000.0, 000.0) , Vec2D(640.0, 000.0)) );
m_WallList.push_back( Wall(Vec2D(640.0, 000.0) , Vec2D(640.0, 480.0)) );
m_WallList.push_back( Wall(Vec2D(000.0, 480.0) , Vec2D(640.0, 480.0)) );
m_WallList.push_back( Wall(Vec2D(100.0, 100.0) , Vec2D(100.0, 200.0)) );
m_WallList.push_back( Wall(Vec2D(100.0, 100.0) , Vec2D(500.0, 100.0)) );
m_WallList.push_back( Wall(Vec2D(100.0, 200.0) , Vec2D(400.0, 200.0)) );
m_WallList.push_back( Wall(Vec2D(400.0, 200.0) , Vec2D(400.0, 400.0)) );
m_WallList.push_back( Wall(Vec2D(400.0, 400.0) , Vec2D(500.0, 400.0)) );
m_WallList.push_back( Wall(Vec2D(500.0, 100.0) , Vec2D(500.0, 400.0)) );
}
なぜなら、将来、壁を回避する機能を実装したときに、
ユニットの座標を直接弄ることなしに、
ユニットが画面外(もしくはマップ外)へ出ることを防げるからです。