2014-01-19 62 views
0

我有一個Player類......他需要訪問PlayerStateFlying和PlayerStateHit類中的組件,以便我從他們身上繼承...誆騙自己與類繼承,需要一些指導

class PlayerStateFlying 
{ 
    // Includes a function that sets Player::currentState = something 
} 

class PlayerStateHit 
{ 
    // Includes a function that sets Player::currentState = something 
} 

class Player : public PlayerStateFlying, 
       public PlayerStateHit 
{ 
    public: 
     STATE currentState; // Needs to be accessed by the State classes 
} 

問題是,我的國家課程需要訪問玩家的某個屬性

我該如何解決這個問題?

--------- -----------編輯

所以它應該是這樣的? PS我不能完全得到它的工作

class IBaseStates 
{ 
    public: 
     STATE currentState; 
} 

class PlayerStateFlying : public IBaseStates 
{ 
    // Includes a function that sets IBaseStates::currentState = something 
} 

class PlayerStateHit : public IBaseStates 
{ 
    // Includes a function that sets IBaseStates::currentState = something 
} 

class Player : public IBaseStates 
{ 
    // Includes a function that checks what IBaseStates::currentState equals 
} 

這裏是我的困境的一個例子:

void Player::ChangeState(STATE state) 
{ 
    switch(state) 
    { 
    case FLYING: 
     currentState = FLYING; 
     break; 
    case HIT: 
     currentState = HIT; 
     break; 
    } 
} 

void Player::StateUpdate() 
{ 
    switch(currentState) 
    { 
    case FLYING: 
     PlayerStateFlying::Update(); 
     currentTextureIndex = PlayerStateFlying::current; 
     break; 
    case HIT: 
     PlayerStateHit::Update(); 
     currentTextureIndex = PlayerStateHit::current; 
     break; 
    } 
} 

void PlayerStateHit::Update() 
{ 
    ... 
      currentState = FLYING; 
      index = 0; 
    ...  
} 
+0

http://en.wikipedia.org/wiki/Composition_over_inheritance –

+0

谷歌「國家設計模式」的一些想法。 – godel9

+0

爲什麼不直接在狀態類中添加'STATE currentState;'呢? – Proxy

回答

1

玩家應該是設置當前狀態的人。不是國家本身。狀態更新函數應該如下所示:

void Player::StateUpdate() { 
    mCurrentState->update(this); 
} 

void PlayerHitState(Player * player) { 
    player->setCurrentState(player->getStateFromListOfAvailableStates(FLYING)) 
} 

一個簡單的狀態機應該存儲所有需要的狀態和轉換。就像你在水中或類似的東西時不能飛行一樣。

+1

ahhhhh國家有一個參考球員......你的美麗,我想這就是我需要看到的。謝啦! – Jimmyt1988

+0

感謝您的評論,我得到了它的工作兄弟!好建議! – Jimmyt1988

0

具有存儲所需要訪問和繼承國家和信息的通用類從這兩個球員狀態。

+0

我想我可以幫到你,讓我重新調整代碼,看看我能否實現它。 – Jimmyt1988

+0

你可以看看我的OP更新嗎? – Jimmyt1988

2

不要忘記多態性。你不需要執行任何switch'es。

我認爲解決的辦法應該是這樣的:

class PlayerState { 
} 

class PlayerStateFlying : public PlayerState { 
} 

class PlayerStateHit : public PlayerState { 
} 

現在你Player類(對象)應該包含(或接入)的狀態對象:

class Player { 
protected: 
    PlayerState *playerState; 
public: 
    void setPlayerState(PlayerState *newState); 
} 

setPlayerState()應該是這樣的:

Player::setPlayerState(PlayerState *newState) { 
    playerState = newState; 
} 

現在你可以簡單地重寫你的方法未來支持多種PlayerState子類:

void Player::StateUpdate() { 
    playerState->Update(); // Polymorphism! 
    currentTextureIndex = playerState->current; 
} 

在下一個方法,你仍然可以使用一個開關,如果你還真需要存儲您的currentState變量並使用它:

void Player::ChangeState(STATE state) { 
    switch(state) { 
    case FLYING: 
     currentState = FLYING; 
     playerState = new PlayerStateFlying(); 
     break; 
    case HIT: 
     currentState = HIT; 
     playerState = new PlayerStateHit(); 
     break; 
    } 
} 

...但還有另外一個 - 更方便的解決方案 - 我們已經有了它,但是如果我們仍然需要currentState enum(或int或其他)變量,我們可以簡單地用一個新字段擴展我們的PlayerState類(和子類) - label

class PlayerState { 
public: 
    int label; 
} 

PlayerStateFlying::PlayerStateFlying() { 
    label = FLYING; 
} 

PlayerStateHit::PlayerStateHit() { 
    label = HIT; 
} 

現在可以:

Player::setPlayerState(PlayerState *newState) { 
    playerState = newState; 
    currentState = playerState->label; 
} 

您也可以嘗試用恆定的領域,那就是:

class PlayerState { 
public: 
    const int label; 
} 

PlayerStateFlying::PlayerStateFlying() : label(FLYING) {}; 

PlayerStateHit::PlayerStateHit() : label(HIT) {}; 

關心。

+0

哦,媽媽!那是全面的...我也喜歡它! booyaka shannnn!現在就要實現這個接口!你好! – Jimmyt1988

+0

很高興喜歡它。我想它仍然需要一些修改來適應你的代碼。 – ktalik