クラスの設計に関して私はあまり精通していない為
最近少し興味を持っていたのですが、
面白そうなので少し考えてみました。
諸所おかしなところがありますが、基本的には
その人の好みの問題でもあると思うので
細かいところは自分変えて見てください。
今回は多重継承を使っていますが、
オブジェクトの関係はあまり考えていません。
使えればいいって感じでこうしたほうが良い
ってのもあると思いますが。。。
#短くする為に多少見難くなっています
#全角スペースは半角かタブに変換してください。
一番のミソはvectorに抽象クラスを登録させる
ところです。(C++では基本かも。)
これにより、その基本クラスを継承するクラスは
このリストに登録できるようになり、
さらに、純粋仮想関数での実装をオーバーライド
させ分けるようにしています。
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
//配置オブジェクト
class ObjectPointBase
{
int m_nPointX;
int m_nPointY;
public:
int m_nDistance;
ObjectPointBase() : m_nDistance(0), m_nPointX(0), m_nPointY(0){}
virtual ~ObjectPointBase(){}
//整数未満切捨ての距離
int CalcDistance( ObjectPointBase & Player ){
m_nDistance = sqrt((m_nPointX-Player.m_nPointX)*(m_nPointX-Player.m_nPointX))+sqrt((m_nPointY-Player.m_nPointY)*(m_nPointY-Player.m_nPointY));
printf( "Distance = %d\n", m_nDistance );
return m_nDistance;
}
void SetPoint( int X, int Y ){ m_nPointX = X; m_nPointY = Y; }
private:
// コピーコンストラクタ/代入演算子は無効
ObjectPointBase(const ObjectPointBase& other);
ObjectPointBase& operator=(const ObjectPointBase& other);
};
// 距離ソート用の大小比較関数
bool LessDistance( const ObjectPointBase* lhs, const ObjectPointBase* rhs )
{
return lhs->m_nDistance < rhs->m_nDistance;
}
//敵オブジェクト基本クラス
class EnemyObjectBase : public ObjectPointBase
{
int m_nMaxHP;
int m_nNowHP;
int m_nItemID;
public:
EnemyObjectBase(){}
virtual ~EnemyObjectBase(){}
virtual void Shot() = 0;
private:
// コピーコンストラクタ/代入演算子は無効
EnemyObjectBase(const EnemyObjectBase& other);
EnemyObjectBase& operator=(const EnemyObjectBase& other);
};
//障害物オブジェクト基本クラス
class ItemObjectBase : public ObjectPointBase
{
int m_ItemID;
int m_Count;
int m_Break;
public:
ItemObjectBase(){}
virtual ~ItemObjectBase(){}
virtual void test() = 0;
private:
// コピーコンストラクタ/代入演算子は無効
ItemObjectBase(const ItemObjectBase& other);
ItemObjectBase& operator=(const ItemObjectBase& other);
};
//プレイヤオブジェクト
class PlayerObject : public ObjectPointBase
{
public:
PlayerObject(){}
virtual ~PlayerObject(){}
};
//Enemy1の動作を決定する派生クラス
class Enemy1 : public EnemyObjectBase
{
int m_nColor;
int m_nGraphicHandle;
public:
Enemy1(){}
virtual ~Enemy1(){}
void Shot(){ printf( "Enemy1のShot!\n" ); }
};
//Enemy2の動作を決定する派生クラス
class Enemy2 : public EnemyObjectBase
{
int m_nColor;
int m_nGraphicHandle;
public:
Enemy2(){}
virtual ~Enemy2(){}
void Shot(){ printf( "Enemy2のShot!\n" ); }
};
//item3の動作を決定する派生クラス
class Item3 : public ItemObjectBase
{
int m_nColor;
int m_nGraphicHandle;
public:
Item3(){}
virtual ~Item3(){}
void test(){ printf( "Item3のtest\n" ); }
};
//item4の動作を決定する派生クラス
class Item4 : public ItemObjectBase
{
int m_nColor;
int m_nGraphicHandle;
public:
Item4(){}
virtual ~Item4(){}
void test(){ printf( "Item4のtest\n" ); }
};
//配置オブジェクトを管理する配列型
typedef std::vector<ObjectPointBase*> StageObjectList;
typedef std::vector<ObjectPointBase*>::iterator Object;
//障害物、アイテムを管理する配列型
typedef std::vector<ItemObjectBase*> ItemObjectList;
typedef std::vector<ItemObjectBase*>::iterator Item;
//敵パターンを管理する配列型
typedef std::vector<EnemyObjectBase*> EnemyObjectList;
typedef std::vector<EnemyObjectBase*>::iterator Enemy;
static StageObjectList ObjectList;
static EnemyObjectList EnemyList;
static ItemObjectList ItemList;
int main( void )
{
int i;
Object itObject;
PlayerObject Player;
Enemy itEnemy;
Enemy1 enemy1, enemy2;
Enemy2 enemy3;
Item3 item1;
Item4 item2;
//配置位置決定
enemy1.SetPoint( 200, 100 );
enemy2.SetPoint( 600, 500 );
enemy3.SetPoint( 400, 50 );
item1.SetPoint( 300, 500 );
item2.SetPoint( 550, 640 );
//敵を登録
EnemyList.push_back(&enemy1);
EnemyList.push_back(&enemy2);
EnemyList.push_back(&enemy3);
//アイテム・障害物を登録
ItemList.push_back(&item1);
ItemList.push_back(&item2);
//配置オブジェクトに登録
ObjectList.push_back(&enemy1);
ObjectList.push_back(&enemy2);
ObjectList.push_back(&enemy3);
ObjectList.push_back(&item1);
ObjectList.push_back(&item2);
//プレイヤに対する配置オブジェクトすべての距離を計算する
Player.SetPoint( 10, 20 );
for ( itObject = ObjectList.begin(); itObject!=ObjectList.end(); itObject++ ){
(*itObject)->CalcDistance( Player );
}
//距離について近い順にソートを行う
std::sort( ObjectList.begin(), ObjectList.end(), LessDistance );
for ( i = 0; i < 10 ; i++ ){
//プレイヤまでの距離を計算する為位置を更新する
Player.SetPoint( 100 + (i*40), 200 + (i*40));
//敵に関連する処理を呼び出し距離を計算させる
for( itEnemy = EnemyList.begin(); itEnemy != EnemyList.end(); itEnemy++ ){
(*itEnemy)->CalcDistance( Player );
}
//距離について近い順にソートを行う
std::sort( EnemyList.begin(), EnemyList.end(), LessDistance );
//ソートした結果から近い順になっているはずなのでショットの処理を実行する
for( itEnemy = EnemyList.begin(); itEnemy != EnemyList.end(); itEnemy++ ){
printf( "プレイヤまでの距離:%d(500未満で攻撃する)\n", (*itEnemy)->m_nDistance );
if ( (*itEnemy)->m_nDistance < 500 ){
(*itEnemy)->Shot();
}
}
}
return 0;
}