010 自动技能的设计和实现
文章目錄
- 自動技能的設計
- 技能表的設計
- 初始化全局技能表
- 獲取最優技能
自動技能的設計
首先新增一個技能管理類。
我們先說最簡單的自動技能的邏輯,實際上就是讓玩家自己將技能設置好,然后挨個釋放技能。這種邏輯寫起來并不復雜,只需要將所有的技能數據全部放到容器里,然后挨個釋放即可。
在這個基礎上,可以再增加一些邏輯,例如有一部分技能是回血技能,那么我們就去判斷當前的人物血量,只有當血量到一定的閾值才進行釋放。
技能表的設計
接著我們來設計一套自己的選技能的邏輯。首先設計一個技能詳情的結構體
//技能使用詳情 struct _stuSkillUseInfo {//技能名字wstring m_name;//技能類型EmSkillType m_skilltype;//權值int m_weight;//原始權值int m_OriginWeight;//需求//自身條件 MP范圍_stuValRange m_MpRange;//冷卻時間DWORD m_CDTime;//..... };技能詳情里有以下幾個屬性:
然后可以根據需求添加一些可能需要用到的值,比如說目標怪物的血量,如果說目標怪物血量太少,那么就不使用高等級技能。然后還可以加一個技能等級的字段,不過這個游戲等級影響不是很大,所以我這里就沒有添加。總之這個表把你所有需要的字段全部添加上去就行。
其他兩個結構體如下:
//技能類型 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_SkillUseManager的m_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;}}//將當前技能權值置為0ClearSkillWeight(ChooseSkill.m_name);//返回權值最高的技能return skilllist.GetDataByName(ChooseSkill.m_name);}代碼解釋如下:
最后來看實際效果:
首先選擇BUFF技能,然后選擇低等級,CD短的技能,然后是高等級技能,最后是大招。這個排列順序是符合我們預期的。
到這里,自動打怪自動技能的功能都已經完成了,下一篇接著來完成自動吃藥功能。
Github:https://github.com/TonyChen56/GameReverseNote
完整代碼:https://download.csdn.net/download/qq_38474570/79498815
總結
以上是生活随笔為你收集整理的010 自动技能的设计和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 009 自动打怪功能的设计和实现
- 下一篇: 011 吃药call功能分析和代码编写