概述
本文介紹了一個基于C++的游戲物品與角色管理系統,該系統實現了游戲中的物品分類、角色屬性管理、隊伍組建以及背包物品使用等功能。該系統采用面向對象的設計原則,通過繼承和多態實現了可擴展的物品效果系統。
系統架構
1. 物品類型系統
系統定義了三種物品類型,通過枚舉類ItemType
實現:
enum class ItemType {FOOD, // 食物:可恢復角色屬性PROP, // 養成道具:用于角色培養MATERIAL, // 材料:用于合成或制作
};
2. 物品基類設計
物品基類Item
作為抽象類,定義了所有物品的共同屬性和接口:
class Item {
public:Item() {};int GetId() const { return id; }virtual~Item() = 0;
protected:int id; // 物品唯一標識ItemType m_itemType; // 物品類型string name; // 物品名稱
};
3. 食物效果系統
系統通過抽象類FoodWeight
和其派生類實現了多種食物效果:
class FoodWeight {
public:FoodWeight() {};virtual ~FoodWeight() = 0;virtual void restore() {};virtual void showRestore() {};virtual void restoreHp() {};virtual FoodWeightType getFoodWeightType() = 0;
};
4. 角色管理系統
Role
類封裝了游戲角色的各項屬性:
class Role {
public:Role() = default;Role(int id, string name, int lev, int ran, int Hp, int att, int deff, string ele): id(id), name(name), level(lev), rank(ran), hp(Hp), attack(att), defense(deff), element(ele) {}int Id() { return id; }string Name() { return name; }void sethp(int hp) { this->hp = hp; }int gethp() { return hp; }private:int id=0;string name="";int level = 1;int rank=0;int hp=0;int attack=0;int defense=0;string element="無";
};
5. 隊伍管理系統
Team
類實現了最多4名角色的隊伍管理功能:
class Team {
public:void addRole(Role& role) {if (roles.size() < Teamnumber) {roles.push_back(&role);} else {cout << "隊伍已滿,無法添加更多角色" << endl;}}void removeRole(int roleId) {// 移除指定ID的角色}void showRoles() {// 顯示隊伍中的所有角色}private:int id;string name;vector<Role*> roles;
};
6. 食物與效果實現
系統通過Food
類和其派生類實現了具體的食物物品:
class Food : public Item {
public:Food() { m_itemType = ItemType::FOOD; }~Food() {}int GetId() const{ return id; }int GetNum() const { return num; }void updateAddnum() { num +=1; }void updateSubnum() { num -= 1; }FoodWeight* getFoodWeight() { return FoodWeight; }protected:int num;FoodWeight* FoodWeight;
};
7. 背包管理系統
Knapsack
類實現了物品的存儲、檢索和使用功能:
class Knapsack {
public:Knapsack() {};~Knapsack() {for (auto f : Foods) { delete f; }Foods.clear();}void addFood(Food* food) {// 添加食物到背包,支持堆疊相同物品}Food* selectFood(Food& foodId) {// 選擇指定食物}void useFood(Food&& food) {// 使用食物}auto getFoods() { return Foods; }private:vector<Item*>Foods;
};
系統特點
1. 靈活的物品效果系統
通過FoodWeight
抽象類及其派生類,系統可以輕松擴展新的食物效果類型。例如,SunsetFruitRestore
類實現了日落果的生命恢復效果:
class SunsetFruitRestore : public RestoreHp {
public:int hp = 100;virtual void restoreHp() override {cout << "使用日落果 恢復角色生命值" << endl;}virtual FoodWeightType getFoodWeightType() override {return FoodWeightType::RESTOREHP;}virtual int getHp() { return hp; }
};
2. 智能的物品使用策略
系統提供了智能的食物選擇機制,可以根據角色需求自動選擇最適合的食物:
void useFoodCur(Role* role, Knapsack &Knapsack) {// 自動選擇恢復效果最好的食物auto fid = find_if(f.begin(), f.end(), [&](Item* item) {auto F = (Food*)item;auto getfw = (F->getFoodWeight());return ((SunsetFruitRestore*)getfw)->getHp() > max; });// 使用選中的食物恢復角色生命值if (fid != f.end()) {auto food = (Food*)(*fid);auto fw = food->getFoodWeight();if (fw->getFoodWeightType() == FoodWeightType::RESTOREHP) {auto rhp = dynamic_cast<RestoreHp*>(fw);role->sethp(role->gethp() + rhp->getHp());rhp->restoreHp();Knapsack.useFood(move(*food));}}
}
3. 安全的資源管理
系統通過適當的析構函數實現,確保了動態分配的內存得到正確釋放:
~Knapsack() {for (auto f : Foods) {delete f;}Foods.clear();
}~Sunset() {if (FoodWeight != nullptr) {delete FoodWeight;FoodWeight = nullptr;}
}
應用示例
系統提供了一個完整的使用示例,展示了如何創建角色、食物,以及如何使用食物恢復角色生命值:
int main(void) {// 創建角色Role r1(1,"迪盧特",50,2,0,618,914,"火");// 創建背包并添加食物Knapsack knapsack;Food* f1 = new Sunset();Food* f2 = new Sunset();Food* f3 = new Sunset();Food* f4 = new Sunset();Food* f5 = new Sunset();knapsack.addFood(f1);knapsack.addFood(f2);knapsack.addFood(f3);knapsack.addFood(f4);knapsack.addFood(f5);// 使用食物恢復角色生命值useFoodCur(&r1, knapsack);useFoodCur(&r1, knapsack);useFoodCur(&r1, knapsack);useFoodCur(&r1, knapsack);useFoodCur(&r1, knapsack);cout << "當前角色生命值為:" << r1.gethp() << endl;// 釋放資源delete f5;delete f4;delete f3;delete f2;delete f1;return 0;
}
完整代碼
#include<iostream>
#include<string>
#include<vector>
using namespace std;//物品類型
enum class ItemType {//食物FOOD,//養成道具PROP,//材料MATERIAL,
};
//物品類(抽象類)
class Item {public:Item() {};int GetId() const { return id; }virtual~Item() = 0;
protected://物品idint id;//物品類型ItemType m_itemType;//物品名稱string name;};Item::~Item(){}//食物類權值類型
enum class FoodWeightType {//恢復角色生命值RESTOREHP,//恢復角色加入時間限制RESTORETIME,
};// 食物類權值抽象類
class FoodWeight {
public:FoodWeight() {};virtual ~FoodWeight() = 0;//恢復角色加入時間限制virtual void restore() {};//查看恢復角色加入時間限制 virtual void showRestore() {};//恢復角色生命值virtual void restoreHp() {};virtual FoodWeightType getFoodWeightType() = 0;};FoodWeight::~FoodWeight() {}//角色
class Role {public:Role() = default;// 修正 Role 構造函數成員初始化列表,成員變量名應與聲明一致Role(int id, string name, int lev, int ran, int Hp, int att, int deff, string ele): id(id), name(name), level(lev), rank(ran), hp(Hp), attack(att), defense(deff), element(ele) {}~Role() {};//角色idint Id() { return id; }//角色名稱string Name() { return name; }//設置生命值void sethp(int hp) {this->hp = hp;}//獲取生命值int gethp() {return hp;}private://角色idint id=0;//角色名稱string name="";//角色等級int level = 1;//角色等階int rank=0;//角色生命值int hp=0;//角色攻擊力int attack=0;//角色防御力int defense=0;//角色元素 屬性string element="無";
};//特殊秘境判斷 可以為5//隊伍最大人數const int Teamnumber = 4;
//角色隊伍
class Team {public:Team() {};~Team() {};//添加角色成員void addRole(Role& role) {//判斷隊伍是否已滿auto&& size = roles.size();if (size < Teamnumber) {auto&& ptr = addressof(role);roles.push_back(ptr);}else {cout << "隊伍已滿,無法添加更多角色" << endl;}}//移除角色成員void removeRole(int roleId) {for (auto it = roles.begin(); it != roles.end(); ++it) {int is_id = (* it)->Id();if (is_id== roleId) {roles.erase(it);cout << "角色已移除" << endl;return;}}cout << "未找到該角色" << endl;}//查看隊伍成員void showRoles() {cout << "隊伍成員:" << endl;for (const auto& role : roles) {cout << "角色名稱: " << role->Name() << endl;}}
private://隊伍idint id;//隊伍名稱string name;//隊伍中角色成員vector<Role*> roles;
};//恢復角色生命值
class RestoreHp :public FoodWeight {
public://角色隊伍所對應成員恢復生命值RestoreHp() {}~RestoreHp() {};virtual void restoreHp() override {cout << "恢復角色生命值" << endl;}virtual int getHp() = 0;Team* m_Team;
};//日落果恢復
class SunsetFruitRestore : public RestoreHp {
public:SunsetFruitRestore() {}~SunsetFruitRestore() override {}int hp = 100;virtual void restoreHp() override {cout << "使用日落果 恢復角色生命值" << endl;}virtual FoodWeightType getFoodWeightType() override {return FoodWeightType::RESTOREHP;}virtual int getHp() {return hp;}
};// 食物類
class Food :public Item {
public:Food() {m_itemType = ItemType::FOOD;}//虛析構函數~Food() {}int GetId() const{ return id; }int GetNum() const { return num; }void updateAddnum() { num +=1; }void updateSubnum() { num -= 1; }FoodWeight* getFoodWeight() { return FoodWeight; }
protected:int num;FoodWeight* FoodWeight;
};//日落果
class Sunset:public Food{
public:Sunset() {id = 1;name = "日落果";FoodWeight = new SunsetFruitRestore();num = 1;}~Sunset() {if (FoodWeight != nullptr) {delete FoodWeight;FoodWeight = nullptr;}}};///背包類
class Knapsack {public:Knapsack() {};~Knapsack() {for (auto f : Foods) {delete f;}Foods.clear();}//添加食物void addFood(Food* food) {if (food == nullptr) {return;}if (!Foods.empty()) {auto fid = find_if(Foods.begin(), Foods.end(), [&](Item* item) {return item->GetId() == food->GetId();});//如果背包中已存在該食物 則數量加1if (fid != Foods.end()) {auto f = dynamic_cast<Food*>(*fid);f->updateAddnum();return;}}Foods.push_back(food);}//選擇食物Food* selectFood(Food& foodId) {auto fid = find_if(Foods.begin(), Foods.end(), [&](const Item* item) {return item->GetId() == foodId.GetId();});if (fid != Foods.end()) {auto f = dynamic_cast<Food*>(*fid);return f;}else {cout << "背包中無該食物" << endl;return nullptr;}}//消耗食物void useFood(Food&& food) {auto func= [&](const Item* item) {return item->GetId() == food.GetId();};auto fid = find_if(Foods.begin(), Foods.end(), func);if (fid != Foods.end()) {auto f = dynamic_cast<Food*>(*fid);int num = f->GetNum();if (num > 1) {f->updateSubnum();}else {Foods.erase(fid);}}else {cout << "背包中無該食物" << endl;}}auto getFoods() {return Foods;}private:vector<Item*>Foods;
};//使用背包恢復當前角色
void useFoodCur(Role* role, Knapsack &Knapsack) {if (role == nullptr) {cout << "當前角色為空" << endl;return;}auto f= Knapsack.getFoods();if (f.empty()) {cout << "背包中無食物" << endl;return;}int max = 10;//自動選擇 最好的auto fid = find_if(f.begin(), f.end(), [&](Item* item) {auto F = (Food*)item;auto getfw = (F->getFoodWeight());return ((SunsetFruitRestore*)getfw)->getHp() > max; });if (fid!=f.end()) {auto food = (Food*)(*fid);auto fw = food->getFoodWeight();if (fw->getFoodWeightType() == FoodWeightType::RESTOREHP) {auto rhp = dynamic_cast<RestoreHp*>(fw);rhp->m_Team = nullptr;role->sethp(role->gethp() + rhp->getHp());rhp->restoreHp();Knapsack.useFood(move(*food));}}else {cout << "背包中無合適食物" << endl;}}int main(void) {Role r1(1,"迪盧特",50,2,0,618,914,"火");Knapsack knapsack;Food* f1 = new Sunset();Food* f2= new Sunset();Food* f3 = new Sunset();Food* f4= new Sunset();Food* f5 = new Sunset();knapsack.addFood(f1);knapsack.addFood(f2);knapsack.addFood(f3);knapsack.addFood(f4);knapsack.addFood(f5);//使用背包里的食物 恢復當前角色生命值useFoodCur(& r1, knapsack );useFoodCur(&r1, knapsack);useFoodCur(&r1, knapsack);useFoodCur(&r1, knapsack);useFoodCur(&r1, knapsack);cout << "當前角色生命值為:" << r1.gethp() << endl;delete f5;delete f4;delete f3;delete f2;delete f1;return 0;
}
總結
本文介紹的游戲物品與角色管理系統具有以下優點:
- 模塊化設計:系統各個組件職責明確,便于維護和擴展
- 可擴展性:通過抽象類和繼承機制,可以輕松添加新的物品類型和效果
- 資源安全:合理的析構函數設計確保了內存管理的安全性
- 智能決策:系統能夠根據當前狀態自動選擇最合適的物品使用策略
這個系統為游戲開發提供了一個堅實的基礎框架,可以在此基礎上進一步開發更復雜的游戲機制和功能。