概述

本文介绍了一个基于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;
}

总结

本文介绍的游戏物品与角色管理系统具有以下优点:

  1. 模块化设计:系统各个组件职责明确,便于维护和扩展
  2. 可扩展性:通过抽象类和继承机制,可以轻松添加新的物品类型和效果
  3. 资源安全:合理的析构函数设计确保了内存管理的安全性
  4. 智能决策:系统能够根据当前状态自动选择最合适的物品使用策略

这个系统为游戏开发提供了一个坚实的基础框架,可以在此基础上进一步开发更复杂的游戏机制和功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96086.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96086.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/96086.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Grounded-Segment-Anything 环境配置

Grounded-Segment-Anything 环境配置Grounded-Segment-Anything 介绍环境配置Install osx&#xff08;非必须&#xff09;:Install RAM & Tag2Text:报错 module ‘pkgutil‘ has no attribute ‘ImpImporter‘. Did you mean: ‘zipimporter‘?运行输出分割文本提示检测远…

ZYNQ 定时器

一、ZYNQ定时器简介 每个Cortex-A9处理器都有自己的专用32位定时器和32位看门狗定时器。两个处理器共享一个全局64位定时器。这些计时器的时钟始终为CPU频率&#xff08;CPU_3x2x&#xff09;的1/2。在系统级&#xff0c;有一个24位看门狗定时器和两个16位三重定时器/计数器。系…

Java8 Comparator接口 和 List Steam 排序使用案例

在Java中&#xff0c;Comparator接口主要用于实现自定义排序逻辑&#xff0c;适用于未实现Comparable接口或需要覆盖默认比较规则的场景。以下是核心使用方法和注意事项&#xff1a;一、基础用法‌匿名内部类实现‌传统方式通过匿名内部类重写compare()方法&#xff0c;例如对整…

word2vec模型案例

代码实现&#xff1a;import torch.optim as optim from tqdm import tqdm, trange import numpy as np import torch from torch import nn import torch.nn.functional as FCONTEXT_SIZE 2raw_text """We are about to study the idea of a computational p…

< 自用文 OS 有关 > (续)发现正在被攻击 后的自救 Fail2ban + IPset + UFW 工作流程详解

继上编&#xff1a;&#xff1c; 自用文 主机 USC 记录&#xff1a;&#xff1e; 发现正在被攻击 后的自救-CSDN博客 环境&#xff1a; 改进&#xff1a; 以下是把代码&#xff0c;懒得写&#xff0c;扔给了 AI &#xff0c;让它出的&#xff1a; Fail2ban IPset UFW 工作…

Linux —— 虚拟进程地址空间

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录虚…

简单聊一聊js

JavaScript 是一种高级的、解释型的编程语言。它是现代 Web 开发的三大核心基石之一&#xff0c;与 HTML 和 CSS 并列。​HTML​&#xff1a;负责网页的结构和内容​&#xff08;如标题、段落、图片&#xff09;。​CSS​&#xff1a;负责网页的样式和布局​&#xff08;如颜色…

造粒机cad+设计说明书

摘要 随着现代化工业的快速发展&#xff0c;生产出大量的固体废弃物。这些废弃物对环境造成了很大的污染&#xff0c;因此需要采取有效的措施进行处理。机械强压式造粒机就是一种非常有效的处理工具&#xff0c;它可以将废渣、废料、饲料和化肥等材料通过机械强力挤压&#xff…

第五课 C#语言基本元素概览,初始类型,变量与方法,算法简介

熟悉C#语言要求&#xff1a;对构成C#语言的基本元素&#xff0c;随便拿出一个你都认识&#xff0c;对于常见基本元素&#xff0c;都能正确使用它 精通C#语言要求&#xff1a;对于构成C#语言的基本元素&#xff0c;随便拿出一个都会使用&#xff0c;对于常用基本元素&#xff0…

LLM学习:大模型基础——视觉大模型以及autodl使用

1、常见的VLM 在大模型中,VLM 是视觉语言模型(Vision-Language Model)的缩写,是一种多模态、生成式 AI 模型,能够理解和处理视频、图像和文本。 VLM 通过将大语言模型(LLM)与视觉编码器相结合构建而成,使 LLM 具有 “看” 的能力,从而可以处理并提供对提示中的…

Vue—路由配置中设置了meta.title,但页面标题仍然显示为“Vite App“?【让我来看看~】

路由配置中明明设置了meta.title&#xff0c;但是页面标题仍然显示为"Vite App"&#xff1f;这是因为仅仅在路由配置中设置meta.title是不够的&#xff0c;还需要在路由守卫中动态设置页面标题。需要做以下几件事来正确设置页面标题&#xff1a;1.首先更新HTML文件的…

【机器学习】综合实训(二)

项目五 电影评分预测【教学内容】使用 MovieLens 数据集&#xff0c;训练一个模型预测用户对电影的评分。主要有以下几个知识点&#xff1a;&#xff08;1&#xff09;数据加载与探索性分析&#xff08;EDA&#xff09;。&#xff08;2&#xff09;处理稀疏数据&#xff08;如用…

STM32 UART + DMA + 空闲中断使用中的帧错误(FE)问题及解决方案

STM32 UART + DMA + IDLE中断使用中的帧错误(FE)问题及解决方案 在我调试STM32H7串口空闲中断DMA接受时遇到了一个bug,这个现象发生在系统刚上电时,有个串口由于帧错误FE挂起了中断,之后在HAL_UART_IRQHandler这个全局中断处理函数结束后,所有的中断使能标志位都被清除了,经过…

TDengine 选择函数 BOTTOM() 用户手册

BOTTOM() 函数用户手册 函数定义 BOTTOM(expr, k)功能说明 BOTTOM() 函数统计表/超级表中某列的值最小 k 个非 NULL 值。如果多条数据取值一样&#xff0c;全部取用又会超出 k 条限制时&#xff0c;系统会从相同值中随机选取符合要求的数量返回。 返回值 数据类型: 同应用…

西门子 S7-200 SMART PLC 实现星三角降压启动控制:原理、案例与完整程序

在工业控制场景中&#xff0c;中型异步电机直接启动时会产生远超额定电流的冲击电流&#xff08;通常为额定电流的 5-7 倍&#xff09;&#xff0c;不仅会影响电网稳定性&#xff0c;还可能对机械设备造成损伤。星三角&#xff08;Y-Δ&#xff09;降压启动是解决这一问题的经典…

【Android】View 的基础知识

【Android】View 的基础知识 1. 什么是 View&#xff1f; View 是 Android 中所有UI组件的基础类。它表示屏幕上的一个矩形区域&#xff0c;负责绘制内容和处理用户交互事件。所有的 UI 组件&#xff08;如按钮、文本框等&#xff09;都是 View 的子类&#xff0c;而 ViewGroup…

西门子 S7-200 SMART PLC 实现电机点动与连续运行综合控制

在工业生产中&#xff0c;电机控制并非单一模式&#xff1a;调试设备时需要 “按动即转、松开即停” 的点动功能&#xff0c;正常生产时则需要 “一键启动、持续运行” 的连续控制。本文以西门子 S7-200 SMART PLC 为载体&#xff0c;详细讲解电机点动控制原理&#xff0c;并设…

如何解决pip安装报错ModuleNotFoundError: No module named ‘sphinx-rtd-theme’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘sphinx-rtd-theme’问题 摘要 在使用 PyCharm 开发 Python 项目时&#xff0c;pip install 报错是常见痛点。特别是在构建文档或引入第三方库时&#xff0c;开…

HakcMyVM-Literal

目录信息搜集漏洞利用权限提升信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.21.0/24 Nmap scan report for 192.168.21.5端口扫描 ┌──(kali㉿kali)-[~] └─$ nmap -sS -sV -O -p- 192.168.21.5 Starting Nmap 7.95 ( https://nmap.org ) a…

0904 类的继承

Part 1.梳理思维导图一.继承中的特殊成员函数1.构造函数父类的构造函数会被继承到子类中&#xff0c;在构造的顺序中&#xff0c;是先构造父类&#xff0c;再构造子类#include <iostream>using namespace std;class Father { public:string name; protected:int *age; pr…