まずは、
「ユニット(のベース)」
と、「そのユニットを管理する簡単なシステム」、
そして、「ゲームとしての小さな機構」
を実装したいと思います。
開発環境はVC++2010、言語はC++とDXライブラリで行います。
ユニットは、ゲーム内に登場する”モノ”です。
その”モノ”は、ユニットに限定されないので、
まずは、この”モノ”を定義し、その派生としてユニットを定義します。
//*抽象クラス
class GameEntity
{
//IDがあると便利かも…
int m_ID;
protected:
//座標
Vec2D m_Pos;
public:
GameEntity(Vec2D pos);
virtual ~GameEntity(){}
//更新
virtual void Update() = 0;
//描画
virtual void Render() = 0;
//アクセサ
void SetPos(Vec2D pos){ m_Pos = pos; }
Vec2D Pos()const{ return m_Pos; }
int ID()const{ return m_ID; }
};
そして、2次元の座標をメンバーとしてもちます。
この”モノ”は概念であり、存在しえないので、
抽象クラスとして定義します。
m_Posの型であるVec2Dクラスですが、
これは二次元ベクトルのためのクラスです。
メンバーとしてx, yを持ち、
その他有用なオペレータや関数などを持ちます。
中身は下のスポイラーからどうぞ。
► スポイラーを表示
class Unit :public GameEntity
{
//重量
double m_Mass;
//加速度
Vec2D m_Acceleration;
//速度
Vec2D m_Velocity;
public:
Unit(Vec2D pos)
:GameEntity(pos)
{}
virtual ~Unit(){}
virtual void Update();
virtual void Render();
//アクセサ
double GetMass()const{ return m_Mass; }
};
いわゆるF=maってやつで、質量・加速度・速度をメンバで持ちます。
実装部分を見ればわかると思います。
void Unit::Update()
{
Vec2D Force;
//Force = hoge->GetForce();
m_Acceleration += Force / m_Mass;
m_Velocity += m_Acceleration;
m_Pos += m_Velocity;
}
void Unit::Render()
{
DrawCircle((int)m_Pos.x,
(int)m_Pos.y,
3,
GetColor(0,255,0),
true);
}
この力を与えて、ユニットを動かすことにします。
さて、ユニットの基盤ができたので、これを管理するクラスを作ります。
class UnitManager
{
//IDで管理する
std::map m_Units;
public:
UnitManager();
~UnitManager();
void Update();
void Render();
};
それをキーにしたstd::mapで管理すると便利です。
検索にはO(logN)がかかりますが、
ユニットが1024体いても、O(10)ですので、
ほとんど無視できるオーダー量です。
UnitManager::UnitManager()
{
//ためしに何個か入れてみる
for(int i = 0; i ID(), unit
)
);
}
}
UnitManager::~UnitManager()
{
//一応あとしまつ
std::map::iterator it;
it = m_Units.begin();
while( ! m_Units.empty())
{
Unit* del = m_Units.begin()->second;
it = m_Units.erase(m_Units.begin());
delete del;
}
}
void UnitManager::Update()
{
std::map::iterator it;
it = m_Units.begin();
while(it != m_Units.end())
{
it->second->Update();
++it;
}
}
void UnitManager::Render()
{
std::map::iterator it;
it = m_Units.begin();
while(it != m_Units.end())
{
it->second->Render();
++it;
}
}
ユニットはためしに10体ほど配置してみます。
ユニットを管理する機構ができあがったので、
これらの機構を統括し、ゲーム世界全体を管理するクラスを作ります。
といっても、現状ではユニットマネージャをメンバにもつだけですが。
class World
{
UnitManager* m_UnitManager;
public:
World();
~World();
void Update();
void Render();
};
World::World()
{
m_UnitManager = new UnitManager();
}
World::~World()
{
delete m_UnitManager;
}
void World::Update()
{
m_UnitManager->Update();
}
void World::Render()
{
m_UnitManager->Render();
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(true);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
World* myWorld = new World();
DxLib::SetAlwaysRunFlag(true);
while(ProcessMessage() == 0 && !CheckHitKey(KEY_INPUT_ESCAPE))
{
ClsDrawScreen();
myWorld->Update();
myWorld->Render();
ScreenFlip();
}
DxLib_End();
};
これで、ゲームにユニットを登場させることが出来ました。
次は、ユニットの運動させる「力」を計算するクラスをつくり、
ユニットを操作できるようにするつもりです。