010 自动技能的设计和实现

自动技能的设计

在这里插入图片描述

首先新增一个技能管理类。

我们先说最简单的自动技能的逻辑,实际上就是让玩家自己将技能设置好,然后挨个释放技能。这种逻辑写起来并不复杂,只需要将所有的技能数据全部放到容器里,然后挨个释放即可。

在这个基础上,可以再增加一些逻辑,例如有一部分技能是回血技能,那么我们就去判断当前的人物血量,只有当血量到一定的阈值才进行释放。

技能表的设计

接着我们来设计一套自己的选技能的逻辑。首先设计一个技能详情的结构体

//技能使用详情
struct _stuSkillUseInfo
{
	//技能名字
	wstring m_name;

	//技能类型
	EmSkillType m_skilltype;

	//权值
	int m_weight;

	//原始权值
	int m_OriginWeight;


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

	//冷却时间
	DWORD m_CDTime;

	//.....
};

技能详情里有以下几个属性:

  1. 技能名字
  2. 技能类型:是攻击技能还是BUFF技能还是回血技能还是移动技能等等
  3. 权值:根据权值的大小来释放技能,权值高的优先释放,释放完成后将权值归零
  4. 原始权值:保存该技能最开始设置的权值
  5. MP范围:由于是法师职业,所以在释放的时候需要考虑到当前的MP范围。如果是近战职业,各位可以将这里换成HP范围
  6. 技能冷却时间

然后可以根据需求添加一些可能需要用到的值,比如说目标怪物的血量,如果说目标怪物血量太少,那么就不使用高等级技能。然后还可以加一个技能等级的字段,不过这个游戏等级影响不是很大,所以我这里就没有添加。总之这个表把你所有需要的字段全部添加上去就行。

其他两个结构体如下:

//技能类型
enum EmSkillType
{
	Em_攻击技能,
	Em_BUFF技能,
	Em_加血技能,
};


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

以法师的第一个技能为例:

//火球术   攻击技能	HP范围(不判断) MP范围(10-100)	 技能等级3   消耗魔法值5    80权值

然后将当前职业的所有技能全部按照技能详情列举出来,就完成了一张技能表的设计

//火球术   攻击技能	HP范围(不判断) MP范围(10-100)	 技能等级3   消耗魔法值5    80权值
//抗拒火环 攻击技能	HP范围(不判断) MP范围(10-100)	 技能等级3	 消耗魔法值8    60权值
//诱惑之光 攻击技能	HP范围(不判断) MP范围(10-100)	 技能等级3	 消耗魔法值6    50权值
//地狱火   攻击技能	HP范围(不判断) MP范围(25-100)	 技能等级3	 消耗魔法值20   40权值
//雷电术   攻击技能 HP范围(不判断) MP范围(20-100)	 技能等级3   消耗魔法值18   45权值
//魔法盾   BUFF技能 HP范围(不判断) MP范围(50-100)	 技能等级3   消耗魔法值50   90权值

自动技能的设计原则就是首先判断技能是否满足各种需求,判断完成之后从中筛选出权值最高的。权重设计原则是加血技能>BUFF技能>攻击技能 攻击技能优先使用等级高的 技能冷却快的优于冷却慢的。

然后设置一个全局的技能表,这个表放在GlobalData.cpp

vector<_stuSkillUseInfo> g_skilllist =
{
	{/* 技能名字*/L"火球术",/* 技能类型*/Em_攻击技能,/* 技能权重*/80,/* 原始权重*/80,/* 自身条件*/{10,1000},/*冷却时间*/3000},
	{/* 技能名字*/L"抗拒火环",/* 技能类型*/Em_攻击技能,/* 技能权重*/60,/* 原始权重*/60,/* 自身条件*/{10,1000},/*冷却时间*/3000},
	{/* 技能名字*/L"诱惑之光",/* 技能类型*/Em_攻击技能,/* 技能权重*/50,/* 原始权重*/50,/* 自身条件*/{10,1000},/*冷却时间*/3000},
	{/* 技能名字*/L"地狱火",/* 技能类型*/Em_攻击技能,/* 技能权重*/40,/* 原始权重*/40,/* 自身条件*/{25,1000},/*冷却时间*/3000},
	{/* 技能名字*/L"雷电术",/* 技能类型*/Em_攻击技能,/* 技能权重*/45,/* 原始权重*/30,/* 自身条件*/{25,1000},/*冷却时间*/3000},
	{/* 技能名字*/L"魔法盾",/* 技能类型*/Em_BUFF技能,/* 技能权重*/90,/* 原始权重*/90,/* 自身条件*/{50,1000},/*冷却时间*/1000*30},
};

表里面包含所有的技能详情。由于这个游戏技能是没有冷却时间的,所以我这里全部设置为3秒。

初始化全局技能表

首先在UseSkillManager类新增一个类成员。

public:
	//技能的使用数据表
	vector<_stuSkillUseInfo> m_SkillList;

这个技能表实际上就是全局技能表的复制,因为后续需要修改全局技能表,所以直接复制到类成员里。

接着在UseSkillManager类,新增一个函数

void SetSkillData(vector<_stuSkillUseInfo> skilldata);

实现如下:

void UseSkillManager::SetSkillData(vector<_stuSkillUseInfo> skilldata)
{
	m_SkillList = skilldata;
}

这个函数用于给类成员的全局技能表赋值,在dll注入的时候调用。

//技能管理器
extern UseSkillManager g_SkillUseManager;

GlobalData.h新增一个技能管理器的类变量

//设置技能列表
g_SkillUseManager.SetSkillData(g_skilllist);

然后在窗口初始化的时候设置一下技能列表,这样g_SkillUseManagerm_SkillList就填充了技能详情。

获取最优技能

接着声明一个函数,用于获取最优技能

_stuObj UseSkillManager::GetTheBestUseSkill(_stuObj role, _stuObj obj, _stuObjs skilllist);

函数实现如下:

_stuObj UseSkillManager::GetTheBestUseSkill(_stuObj role, _stuObj obj, _stuObjs skilllist)
{

	//判断所有权值是否已经归零
	if (CheckAllWeightIsZero())
	{
		ReSetSkillWeight();
	}


	//符合条件的技能列表
	vector<_stuSkillUseInfo> DataList;


	//遍历技能列表 筛选出符合条件的技能
	for (auto &skill : m_SkillList)
	{
		//通过技能名字返回技能对象
		auto SkillObj = skilllist.GetDataByName(skill.m_name);


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


		//判断蓝量是否在设置的范围内
		if (!(role.m_Obj_MP > skill.m_MpRange.MinValue&&role.m_Obj_MP < skill.m_MpRange.MaxValue))
		{
			continue;
		}


		//把符合的技能存放到表里
		DataList.push_back(skill);
	}



	//筛选出权重最高的技能
	int NowValue = 0;
	_stuSkillUseInfo ChooseSkill;
	for (auto skill : DataList)
	{
		if (skill.m_weight > NowValue)
		{
			//记录当前技能权重
			NowValue = skill.m_weight;

			//保存当前技能对象
			ChooseSkill = skill;

		}
	}

	//将当前技能权值置为0
	ClearSkillWeight(ChooseSkill.m_name);

	//返回权值最高的技能
	return skilllist.GetDataByName(ChooseSkill.m_name);

}

代码解释如下:

  1. 首先判断所有技能权值是否已经全部归零,如果是则重置所有权值
  2. 通过设定的条件,筛选出所有符合条件的技能;这里就看各位的需求了,判断当前人物血量,判断当前人物蓝量,判断当前怪物血量等等
  3. 然后将筛选通过的技能进行权值排序,筛选出权值最高的技能
  4. 最后将权值最高的技能权值置零,下一次就不筛选该技能了,然后返回该技能对象

最后来看实际效果:

在这里插入图片描述

首先选择BUFF技能,然后选择低等级,CD短的技能,然后是高等级技能,最后是大招。这个排列顺序是符合我们预期的。

到这里,自动打怪自动技能的功能都已经完成了,下一篇接着来完成自动吃药功能。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鬼手56

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

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

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

打赏作者

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

抵扣说明:

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

余额充值