継承元のクラスのインスタンス化について
Posted: 2012年11月19日(月) 14:22
継承元(親)のクラスでインスタンス化した物を子クラス同士でも同じものを共有できませんか?
StageBase.h (ステージ基底)
今作っているゲームで、ゲームのメインループ(Stageというクラス)を
StageTitle、StageGame、StageClear、StageGameOverという4つのクラスにわけ、メインループではswitch文でゲームの流れを見やすくしようとしています。
Stage、StageTitle、StageGame、StageClear、StageGameOverはそれぞれStageBaseを継承していて、
Stageのなかでは下のようなコードにしたいのです。
Stage.cpp
インスタンス化したクラス(これを共有したい)
どのクラスで共有したいのかといいますと、Stage、StageTitle、StageGame、StageClear、StageGameOverの5つのクラスで、
なにを共有したいかといいますと、StageBaseでインスタンス化しているクラスを共有したいのです。
ですが、どのようにすればこの5つのクラスで同じ物を共有できるのかわかりません。
プログラムは組んでみたのですが、継承したクラスではそれぞれがコピーをとって違うものを持っているようで、うまく共有ができません。
組んでみたプログラム
Stage.h
Stage.cpp
すごく醜いコードですみません。
上に書いた共有したい部分をうまく共有できていないため、Stageで値が変わった変数が、
StageGameの方では変わってなかったので、共有して同時に値が変わるようにしたいです。
出来れば関数(game.updateのように)の引数に渡したりせずに、継承したクラスでは共有したい部分を共通で使えるようにはできませんか?
うまく説明できていなくてすみません。
StageBase.h (ステージ基底)
class StageBase
{
public:
Map map; //!< マップインスタンス化
Bouei bouei; //!< 防衛インスタンス化
Back back; //!< 背景インスタンス化
Player player; //!< プレイヤーインスタンス化
Special special; //!< 必殺技インスタンス化
HitManager hit; //!< ヒット管理インスタンス化
Recode recode; //!< タイム、スコアインスタンス化
EnemyBase* gpEnemy[ENEMY_COUNT_MAX]; // 敵配列
public:
ofTrueTypeFont myFont_64; //!< フォントクラスインスタンス化
StageBase(void);
virtual ~StageBase(void);
virtual void init(); //!< 初期化
virtual void update(); //!< 更新
virtual void draw(); //!< 描画
};
StageTitle、StageGame、StageClear、StageGameOverという4つのクラスにわけ、メインループではswitch文でゲームの流れを見やすくしようとしています。
Stage、StageTitle、StageGame、StageClear、StageGameOverはそれぞれStageBaseを継承していて、
Stageのなかでは下のようなコードにしたいのです。
Stage.cpp
void Stage::init()
{
StageBaseでインスタンス化したクラスのinit
}
void Stage::update()
{
switch(ステージの状態){
case Title: // タイトル画面
StageTitleのupdate();
break;
case Game: // ゲーム状態
StageGameのupdate();
break;
case Clear: // ゲームクリア状態
StageClearのupdate();
break;
case GameOver: // ゲームオーバー状態
StageGameOverのupdate();
break;
}
}
void Stage::draw()
{
switch(ステージの状態){
case Title: // タイトル画面
StageTitleのdraw();
break;
case Game: // ゲーム状態
StageGameのdraw();
break;
case Clear: // ゲームクリア状態
StageClearのdraw();
break;
case GameOver: // ゲームオーバー状態
StageGameOverのdraw();
break;
}
}
Map map; //!< マップインスタンス化
Bouei bouei; //!< 防衛インスタンス化
Back back; //!< 背景インスタンス化
Player player; //!< プレイヤーインスタンス化
Special special; //!< 必殺技インスタンス化
HitManager hit; //!< ヒット管理インスタンス化
Recode recode; //!< タイム、スコアインスタンス化
EnemyBase* gpEnemy[ENEMY_COUNT_MAX]; // 敵配列
なにを共有したいかといいますと、StageBaseでインスタンス化しているクラスを共有したいのです。
ですが、どのようにすればこの5つのクラスで同じ物を共有できるのかわかりません。
プログラムは組んでみたのですが、継承したクラスではそれぞれがコピーをとって違うものを持っているようで、うまく共有ができません。
組んでみたプログラム
Stage.h
class Stage : public StageBase, public ofBaseApp
{
public:
// インスタンス化一覧
StageTitle title;
StageGame game;
StageClear clear;
StageOver over;
// ステージ切り替え用列挙体
enum STAGE_MODE{
STAGE_TITLE,
STAGE_GAME,
STAGE_GAMEOVER,
STAGE_CLEAR,
};
public:
Stage(void); //!< コンストラクタ
virtual~Stage(void); //!< デストラクタ
bool addEnemy(EnemyBase* p);
virtual void init(); //!< 初期化
virtual void update(); //!< 更新
virtual void draw(); //!< 描画
void start_draw(); //!< タイトル画面描画
bool clear_flag;
void mouseMoved(int x, int y );
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
private:
STAGE_MODE stage_mode;
};
//==============================================================
//! @file Stage.cpp
//! @breif ステージの流れ
//! @author YukiIshigaki
//==============================================================
#pragma once
#include"../../HeaderMain.h"
//EnemyBase* gpEnemy[ENEMY_COUNT_MAX]; // 敵配列
//--------------------------------------------------------------
//! 敵配列に追加する
//!@param [in] p 追加する敵クラス
//!@param true 成功
//!@param false 失敗(満杯)
//--------------------------------------------------------------
bool Stage::addEnemy(EnemyBase* p)
{
for( int i = 0; i < ENEMY_COUNT_MAX; i++){
if( gpEnemy[i] != NULL ) continue;
//---- find
gpEnemy[i] = p;
return true;
}
return false;
}
// コンストラクタ
Stage::Stage(void)
{
ofSetFrameRate(60); // フレーム数を固定
//==========================================================
// スタート、ゲームオーバー等の初期化
//==========================================================
//myFont_64.loadFont("font_data/cooperBlack.ttf",64); // フォントデータ読み込み
//==========================================================
// マップ初期化
//==========================================================
map.init();
//==========================================================
// 背景初期化
//==========================================================
back.setup();
//==========================================================
// プレイヤー初期化
//==========================================================
//==========================================================
// 防衛初期化
//==========================================================
bouei.setup();
//==========================================================
// 敵初期化
//==========================================================
for( int i=0; i<10; i++){
EnemyBase* p = new Crow;
if( addEnemy(p) == false){
delete p;
}
}
for( int i=0; i<10; i++){
EnemyBase* p = new Ghost_Big;
if( addEnemy(p) == false){
delete p;
}
}
for( int i=0; i<10; i++){
EnemyBase* p = new Ghost_Mini;
if( addEnemy(p) == false){
delete p;
}
}
//==========================================================
// タイム、スコア初期化
//==========================================================
recode.init();
clear_flag = false;
clear.init();
stage_mode = STAGE_TITLE; // ステージモード初期化
}
// デストラクタ
Stage::~Stage(void)
{
delete [] * gpEnemy;
}
// 初期化
void Stage::init()
{
// コンストラクタと同じ
}
// 更新処理
void Stage::update()
{
switch( stage_mode )
{
case STAGE_TITLE:
{
title.update();
if(GetKeyState(VK_RETURN)& 0x8000){ // エンターキーを押したら
stage_mode = STAGE_GAME; // ゲーム状態に移行
}
}
break;
case STAGE_GAME:
{
game.update(gpEnemy);
}
break;
case STAGE_CLEAR:
{
//clear.update();
SCROLL_SPEED = 0; // スクロールをしないように
bouei.bouei_clear(); //!< 防衛が走り去る処理
bouei.animation(0,3); // アニメーション
//==========================================================
// 敵更新処理
//==========================================================
for( int i=0; i<ENEMY_COUNT_MAX; i++ ){
if( gpEnemy[i] == NULL ) continue;
gpEnemy[i]->update();
gpEnemy[i]->enemysetMove();
}
player.update(); // プレイヤー更新
if(bouei._pos._x > 1024.0f + bouei._radius){
// ゲームクリア処理(ゲームクリアの文字の移動やリザルト)
clear.update();
}
if(GetKeyState(VK_RETURN)& 0x8000){ // エンターキーを押したら
for(int i=0; i<ENEMY_COUNT_MAX; i++){
gpEnemy[i] = NULL; // 敵のデリート
}
init(); // 全初期化
stage_mode = STAGE_TITLE; // スタート画面に戻る
}
}
break;
case STAGE_GAMEOVER:
{
over.update();
player.update(); // プレイヤー更新
if(GetKeyState(VK_RETURN)& 0x8000){ // エンターキーを押したら
for(int i=0; i<ENEMY_COUNT_MAX; i++){
gpEnemy[i] = NULL; // 敵のデリート
}
init(); // 全初期化
stage_mode = STAGE_TITLE; // スタート画面に戻る
}
}
break;
}
}
// 描画処理
void Stage::draw()
{
switch( stage_mode )
{
case STAGE_TITLE:
{
title.draw();
player.draw();
}
break;
case STAGE_GAME:
case STAGE_CLEAR:
{
ofSetColor(255,255,255);
back.draw(); //!< 背景描画
game.draw(gpEnemy);
clear.draw();
player.draw(); //!< 操作キャラ(Player)の描画
}
break;
case STAGE_GAMEOVER:
{
over.draw();
player.draw();
}
break;
default:
cout<<"ステージ状態がエラーを起こしています"<<endl;
break;
}
}
void Stage::mouseMoved(int x, int y ){
player.setPos(x,y);
}
void Stage::mousePressed(int x, int y, int button){
player.setPos(x,y,button);
Vector2 pos;
pos._x = x;
pos._y = y;
player.active = true;
}
void Stage::mouseReleased(int x, int y, int button){
player.active = false;
}
上に書いた共有したい部分をうまく共有できていないため、Stageで値が変わった変数が、
StageGameの方では変わってなかったので、共有して同時に値が変わるようにしたいです。
出来れば関数(game.updateのように)の引数に渡したりせずに、継承したクラスでは共有したい部分を共通で使えるようにはできませんか?
うまく説明できていなくてすみません。