013 自动吃药功能的设计和实现


之前我们已经完成了自动打怪和自动技能的功能,但是会存在一个问题,当技能释放多了以后,MP就不够了。这个时候我们就需要通过自动吃药的功能,给前两个功能持续输出动力。

功能设计

自动吃药的逻辑和自动技能的逻辑思想一样,都是通过建表的思想,判断各种条件,筛选出当前最适合的一个药品,然后调用吃药call。

现在假设有三种药

药1 回血100 1级
药2 回血500 10级
药3 回血1000 20级

当角色在1-10级的时候只需要使用药1即可;在10-20级的时候,优先使用药2,药1的优先级低于药1;在20-30级的时候,药3的优先级大于药2大于药1

1-10级 药1
10-20级 药2和药1
20-30级 药3和药2和药1

根据上面设计的方法,就可以按照角色等级,当前的HP和MP来对药品设计一个权值

角色等级1-10级 
药1 HP 0-40% 权值50

角色等级11-20
药2  HP 0-40% 权值60
药1  HP 30-60% 权值50

角色等级21-30
药3  HP 0-40% 权值70
药2  HP 30-50% 权值60
药1  HP 50-60% 权值50

这里就可以在血量多的时候先吃小的药,然后在血量少的时候吃大的药,然后再将这套方法用代码实现即可。

药品表设计

首先新建一个UseItemManager

//药品使用详情
struct _stuItemUseInfo
{
	//药品名字
	wstring m_name;

	//药品类型
	EmDrugType m_drugtype;

	//权值
	int m_weight;

	//需求
	//自身条件  MP范围
	_stuValRange m_MpRange;

	//等级范围
	_stuValRange m_LevelRange;
};

接着创建一个药品使用详情结构体

enum EmDrugType
{
	Em_回血,
	Em_回蓝
};

//范围属性
struct _stuValRange
{
	//最小值
	int MinValue;
	//最大值
	int MaxValue;
};

还有药品类型的宏定义,和范围属性结构体

//药品管理
extern UseItemManager g_UserItemManager;

接着在GlobalData.h中引入药品管理的全局变量。

//药品管理
UseItemManager g_UserItemManager;

GlobalData.cpp中声明

//药品表
vector<_stuItemUseInfo> g_ItemList =
{
	{/* 药品名字*/L"魔法药(小量)",/*药品类型*/Em_回蓝,/* 权重*/60,/*HP范围*/{-1,-1},/*MP范围*/{10,800},/*等级范围*/{-1,-1}},
	{/* 药品名字*/L"魔法药(中量)",/*药品类型*/Em_回蓝,/* 权重*/70,/*HP范围*/{-1,-1},/*MP范围*/{10,700},/*等级范围*/{0,0}},
	{/* 药品名字*/L"强效魔法药",/*药品类型*/Em_回蓝,/* 权重*/80,/*HP范围*/{-1,-1},/*MP范围*/{10,600},/*等级范围*/{0,0}},
	{/* 药品名字*/L"金创药(小量)",/*药品类型*/Em_回血,/* 权重*/60,/*HP范围*/{50,150},/*MP范围*/{-1,-1},/*等级范围*/{-1,-1}},
	{/* 药品名字*/L"金创药(中量)",/*药品类型*/Em_回血,/* 权重*/70,/*HP范围*/{40,130},/*MP范围*/{-1,-1},/*等级范围*/{-1,-1}},
	{/* 药品名字*/L"强效金创药",/*药品类型*/Em_回血,/* 权重*/80,/*HP范围*/{30,100},/*MP范围*/{-1,-1},/*等级范围*/{-1,-1}},
};

然后设计一个全局的药品表,-1表示不判断条件。

代码实现

UseItemManager.h

class UseItemManager
{

	//设置药品数据
	void SetDrugData(vector<_stuItemUseInfo> drugdata);

	//获取最优的使用的技能 传入自身数据和目标数据
	_stuObj GetTheBestUseDrug(_stuObj role, _stuObj obj, _stuObjs druglist);

public:
	//药品的使用数据表
	vector<_stuItemUseInfo> m_DrugList;
};

UseItemManager.cpp

#include "pch.h"
#include "UseItemManager.h"

void UseItemManager::SetDrugData(vector<_stuItemUseInfo> drugdata)
{
	m_DrugList = drugdata;
}

_stuObj UseItemManager::GetTheBestUseDrug(_stuObj role, _stuObj obj, _stuObjs druglist)
{
	//符合条件的药品列表
	vector<_stuItemUseInfo> DataList;


	//遍历技能列表 筛选出符合条件的技能
	for (auto &item : m_DrugList)
	{
		//通过药品名字返回技能对象
		auto DrugObj = druglist.GetDataByName(item.m_name);


		//技能名称为空 跳过
		if (DrugObj.m_Name == L"")
		{
			continue;
		}

		//-1表示不判断
		if (item.m_HpRange.MinValue!=-1&& item.m_HpRange.MaxValue!=-1)
		{
			//判断血量是否在设置的范围内
			if (!(role.m_Obj_HP > item.m_HpRange.MinValue&&role.m_Obj_HP < item.m_HpRange.MaxValue))
			{
				continue;
			}
		}
		

		//-1表示不判断
		if (item.m_MpRange.MinValue != -1 && item.m_MpRange.MaxValue != -1)
		{
			//判断蓝量是否在设置的范围内
			if (!(role.m_Obj_MP > item.m_MpRange.MinValue&&role.m_Obj_MP < item.m_MpRange.MaxValue))
			{
				continue;
			}
		}
		


		//把符合的药品存放到表里
		DataList.push_back(item);
	}



	//筛选出权重最高的药品
	int NowValue = 0;
	_stuItemUseInfo ChooseDrug;
	for (auto drug : DataList)
	{
		if (drug.m_weight > NowValue)
		{
			//记录当前药品权重
			NowValue = drug.m_weight;

			//保存当前药品对象
			ChooseDrug = drug;

		}
	}


	//返回权值最高的药品
	return druglist.GetDataByName(ChooseDrug.m_name);
}

代码和自动技能差不多,自动吃药的逻辑也相对很简单,就是循环判断当前是否有符合条件的药品,如果有,那么说明角色血量和蓝量掉到了一定程度,就可以调用吃药call进行补充了。一共也就几行代码,这里就不写了。

这个游戏技能和药品都没有CD的概念,如果换到了别的游戏,则需要将CD的数据和条件考虑进去。

补充

最后,这个设计其实还有一个不完美的地方,就是判断的血值范围是用具体的数字,这样每次人物等级提升的时候都需要重新修改,最好的方式是修改成百分比,这样就不需要一直修改了。这个问题修改起来并不难,相信各位都可以自己完成。

Github:https://github.com/TonyChen56/GameReverseNote

完整代码:https://download.csdn.net/download/qq_38474570/79498815

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鬼手56

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值