2016-09-24 19 views
-1

我正在用C++創建一個遊戲。在這個遊戲中,我創建了一個名爲Player的類。 Player類具有一個稱爲magic的屬性。這個屬性是一個整數,在整個遊戲中不斷增加,當用戶做某事或完成一項任務時,他們可以獲得magic。一旦達到某個點,用戶就會獲得一個新的咒語,這些咒語在玩家類中被保存在一個陣列中。如何等待某個變量達到某個數字才能執行某些操作?

我希望能夠在整個遊戲中檢查這個屬性,看它是否達到了一定的水平。

我以爲每次magic屬性都會檢查一次,但是這會在每次添加很多條件時出現。如:

user.magic++ 
if(user.magic == 2) { 
    //Give a new spell 
} 
else if(user.magic == 3) { 
    //Give a new spell 
} 

而做到這一點的magic屬性被更新每次。這似乎需要花費大量的時間和精力來不斷輸入。我應該把上面的代碼放在一個函數中,並且每次更新magic時都運行它?

有沒有更好的方法來做到這一點?

+0

其他語言/環境尤其是圖形用戶界面使用「可觀察」對象(例如Javascript + DOM中的addEventListener),其中添加了一個回調函數,當變量發生變化時被調用 –

+0

我沒有看到任何問題以您的方式執行想要做到這一點。這對我來說確實很好 – Merlin

+0

@Lorenzo想想如果'user'已經獲得魔術師會發生什麼,並且該功能被多次調用。 – user4581301

回答

2

第一步:將user.magic從可用的法術中分離出來。原因:也許將來你也想爲NPC-es分配法術,而不僅僅是用戶。

struct spell { 
    int type; 
    int cost; 
    int damage; 
} 

static const spell walk_on_water={SURVIVAL, 10, 0}; 
static const spell resurect={DARK_MAGIC, 100, 0}; 
static const spell fireball_minor={OFFENSIVE, 30, 4}; 
static const spell fireball_big={OFFENSIVE, 300, 25}; 

void getSpellsForMagicLevel(int userMagic, std::vector<const spell&>& resultHere) { 
    resultHere.clear(); 
    switch(useMagic) { 
    case 1: 
     resultHere.push_back(walk_on_water); 
     break; 
    case 2: 
     resultHere.push_back(walk_on_water); 
     resultHere.push_back(fireball_minor); 
     break; 
    //... 
    case 10: 
     resultHere.push_back(walk_on_water); 
     resultHere.push_back(resurect); 
     resultHere.push_back(fireball_minor); 
     resultHere.push_back(fireball_big); 
     break; 
    } 
} 

然後調用這個單一的功能,你想知道什麼可用的法術的存在是有player.magic


然後你注意到用戶的咒語庫存僅改變magic修改時(達到任何時間 - 由於增加了經驗 - 或者由於例如由於破壞性藥水導致) - 那麼爲什麼依靠一次又一次地調用這個函數呢?所以:

class Player { 
protected: 
    int magic; 
    std::vector<const spell&> spell_inventory; 

// ... 
    void set_magic_level(int newMagicLevel) { 
    if(this->magic != newMagicLevel) { // do nothing if no change 
     this->magic = newMagicLevel; 
     getSpellsForMagicLevel(this->magic, this->spell_inventory); 
    } 
    } 
// ... 
public: 
// ... 
    int get_magic_level() const { 
    return this->magic; 
    } 
}; 

class User : public Player { 
    //... 
public: 

    void newExperience(const Event& somethingThatHappened) 
    { 
    switch(somethingThatHappened.type) { 
    case EXPERIENCE_THRESHOLD_REACHED: 
     this->set_magic_level(this->get_magic_level()+1); 
     break; 
    case DUMBING_POTION: 
     this->set_magic_level(
      this->get_magic_level()-somethingThatHappened.get_damage() 
     ); 
     break; 
    // etc... 
    } 
    } 
}; 

class NonPlayerCharacter : public Player { 
    //... 
public: 
    // NPC-es don't evolve, they are just spawned 
    // So no newExperience method for them. 
}; 
+0

(人們只能希望downvoter有勇氣解釋) –

+0

也許是因爲你的回答是一種「矯枉過正」。它不直接回答OP的問題。我贊成你,因爲你的答案的質量和它表現出很好地利用封裝(OP應該儘快學會)。人們似乎以任何理由downvote ... – Cedric

+0

@Cedric「封裝的一個很好的使用(OP應該儘快學會)」。我的矯枉過正的目的 - 教他們釣魚(而不是讓他們火焰:) :) –

1

如何使用地圖?所以你可以使用解鎖某些法術(又名int)作爲鑰匙所需的法力值數量,並存儲用於解鎖法術的字符串或其他工具,並授予玩家這種法術。我的意思是,從技術上來說,它比擁有大量硬編碼循環更好,在此實現中,您可以更改地圖並使用相同的函數。

編輯以另一種方式來設計這個,你給玩家所有從一開始的法術,但通過限制它「只能施放某種法術時,比賽MAGIC要求」,你仍然可以使用地圖作爲一個方便的工具

+0

有趣的想法!我會試試這個。 –

+0

我的意思是,你甚至可以使用另一種方法從文件中讀取信息並將法術信息存儲到地圖中,這樣更容易更新遊戲數據,因爲它們幾乎都是從配置文件加載的。 – BrokenCodex

0

可以隨時增加「持續」值(每次發出特定命令時都帶有一個定時器?)是可能的,但是那麼增加一個新咒語的步驟太小了。這意味着每一個動作你都會得到一個新的咒語!

取而代之,請使用如下所示:將experience的值設置爲0。然後,在你的主循環中(同一個定時器,或者你正在使用的任何東西),增加這個值。如果它達到一些合理的數值,比如100,則添加一個新的拼寫並將experience的值重新設置爲0

+0

我會編輯我的問題更清楚,獲得魔法,你必須完成任務,某些任務會給你一個新的魔法配額,它不在計時器上。 –

+0

@愛麗絲:無論變量何時增加,思路都是一樣的。你最多測試一次'經驗',如果達到,則添加一個咒語;然後重置該值,以便可以觸發下一個事件。 – usr2564301

5

充分利用.magic成員變量private,這樣來增加魔法的唯一方法是調用一個方法如user.IncrementMagic(),而不是被允許直接說user.magic++。隨後,該方法的實現可能看起來像:

Player::IncrementMagic() 
{ 
    magic++; 
    CheckUpdatedMagicLevel(); 
} 
Player::CheckUpdatedMagicLevel() 
{ 
    if(magic == 2) 
    { 
     // etc 
    } 
    // etc 
} 

如果需要的話,你也可以寫在不同的方式,e.g操縱magic另外的方法。 DecrementMagicSetNewMagicLevel(x)。這些方法也會在內部調用CheckUpdatedMagicLevel()

相關問題