RTS製作日記。その2

アバター
MNS
記事: 35
登録日時: 15年前

RTS製作日記。その2

投稿記事 by MNS » 14年前

さて、やっとですが開発に入ります。

まずは、
「ユニット(のベース)」
と、「そのユニットを管理する簡単なシステム」、
そして、「ゲームとしての小さな機構」
を実装したいと思います。

開発環境はVC++2010、言語はC++とDXライブラリで行います。


ユニットは、ゲーム内に登場する”モノ”です。
その”モノ”は、ユニットに限定されないので、
まずは、この”モノ”を定義し、その派生としてユニットを定義します。

CODE:

//*抽象クラス
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; }
};
このクラスは、”モノ”を識別するためのID、
そして、2次元の座標をメンバーとしてもちます。
この”モノ”は概念であり、存在しえないので、
抽象クラスとして定義します。

m_Posの型であるVec2Dクラスですが、
これは二次元ベクトルのためのクラスです。
メンバーとしてx, yを持ち、
その他有用なオペレータや関数などを持ちます。
中身は下のスポイラーからどうぞ。
► スポイラーを表示
次に、ユニットの定義です。

CODE:

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ってやつで、質量・加速度・速度をメンバで持ちます。
実装部分を見ればわかると思います。

CODE:

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);
}
現状では、力(Force)を得る手段は用意してませんが、
この力を与えて、ユニットを動かすことにします。


さて、ユニットの基盤ができたので、これを管理するクラスを作ります。

CODE:

class	UnitManager
{
	//IDで管理する
	std::map	m_Units;


public:

	UnitManager();

	~UnitManager();



	void	Update();

	void	Render();
};
ユニットは個別にIDをもつので、
それをキーにしたstd::mapで管理すると便利です。
検索にはO(logN)がかかりますが、
ユニットが1024体いても、O(10)ですので、
ほとんど無視できるオーダー量です。

CODE:

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体ほど配置してみます。

ユニットを管理する機構ができあがったので、
これらの機構を統括し、ゲーム世界全体を管理するクラスを作ります。
といっても、現状ではユニットマネージャをメンバにもつだけですが。

CODE:

class	World
{
	UnitManager*	m_UnitManager;

public:

	World();

	~World();


	void	Update();

	void	Render();
};

CODE:

World::World()
{
	m_UnitManager = new UnitManager();
}


World::~World()
{
	delete m_UnitManager;
}


void	World::Update()
{
	m_UnitManager->Update();
}


void	World::Render()
{
	m_UnitManager->Render();
}
最後に、main.cppを定義します。

CODE:

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();

};
実行結果:
sono1.png
sono1.png (28.72 KiB) 閲覧数: 130 回
緑の●がユニットです。

これで、ゲームにユニットを登場させることが出来ました。
次は、ユニットの運動させる「力」を計算するクラスをつくり、
ユニットを操作できるようにするつもりです。

ああ
記事: 49
登録日時: 14年前

Re: RTS製作日記。その2

投稿記事 by ああ » 14年前

今後が楽しみです!!

アバター
ナムアニクラウド
記事: 16
登録日時: 14年前

Re: RTS製作日記。その2

投稿記事 by ナムアニクラウド » 14年前

 がっつり物理法則とかを考慮しててレベルが高いですね。面白そう!
自分もツリー構造の勉強しようかしらん。

アバター
MNS
記事: 35
登録日時: 15年前

Re: RTS製作日記。その2

投稿記事 by MNS » 14年前

>NNKさん
ありがとうございます。
形になるよう頑張ろうと思います。

>ナムアニクラウドさん
どうもです。
ユニットの移動モデルは物理法則に見立ててますが、
実際というか、現実の「物理」とは全く関係ないので、
レベルが高いとか、そんなことはないですよ(-o-)~
ツリー構造ですか、
地形の実装にグラフを用いるとしたら、私もしなければいけないかも・・・