概述
本文介绍了一个基于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;
}
总结
本文介绍的游戏物品与角色管理系统具有以下优点:
- 模块化设计:系统各个组件职责明确,便于维护和扩展
- 可扩展性:通过抽象类和继承机制,可以轻松添加新的物品类型和效果
- 资源安全:合理的析构函数设计确保了内存管理的安全性
- 智能决策:系统能够根据当前状态自动选择最合适的物品使用策略
这个系统为游戏开发提供了一个坚实的基础框架,可以在此基础上进一步开发更复杂的游戏机制和功能。