【C++第一个Demo】---控制台RPG游戏4【角色系统】

【角色基类】

  1 #ifndef  _ROLE_H_
  2 #define  _ROLE_H_
  3 
  4 #include<list>
  5 #include<vector>
  6 #include "..//Marco.h"
  7 class Tip;
  8 class Body;
  9 class Backpack;  
 10 class TaskList;
 11 class GameOI;
 12 class Map;
 13 class Task;
 14 using namespace std;
 15 
 16 // =========================角色抽象类===========================
 17 class Role
 18 {
 19 public://人物的形状
 20     struct Shape
 21     {
 22         Shape()
 23         {
 24             data = nullptr;
 25             pos = nullptr;
 26             count = 0;
 27         }
 28         ~Shape()
 29         {
 30 
 31             if (data != nullptr)
 32             {
 33                 delete[] data;
 34                 data = nullptr;
 35             }
 36 
 37 
 38             for (int i = 0; i < count; i++)
 39             {
 40                 if (pos[i] != nullptr)
 41                 {
 42                     delete[] pos[i];
 43                     pos[i] = nullptr;
 44                 }
 45             }
 46 
 47 
 48             if (pos != nullptr) return;
 49             {
 50                 delete[] pos;
 51                 pos = nullptr;
 52             }
 53 
 54         }
 55 
 56         char* data;     //形状字符
 57         int** pos;     //坐标
 58         int   count; //组合图形个数
 59     };
 60 
 61 public:
 62     Role(int lv, RaceType, ArmType, int x, int y);
 63     virtual ~Role();
 64 
 65 public:
 66     //===================角色行为函数 ==========================
 67     virtual void AttackAction(Map* pMap);        //攻击行为
 68     virtual void BeHit(Role* role,int atk,Map* pMap) = 0;    //受到伤害
 69 
 70     virtual void RoleHandle(){};                //角色的操作杆
 71     virtual void OutputInfo(int x, int y) {};    //打印人物界面
 72     virtual void OutputTip(int x, int y);        //打印简介
 73     virtual void OutputShout(int count){};        //打印喊话
 74 
 75     virtual void OutputRoleOI() = 0;            //打印人物OI上的信息图形
 76     virtual void OutputRoleBloodBar(int x, int y);//打印人物血条
 77     virtual void OutputRoleExpBar(int x, int y){};//打印人物经验
 78 
 79 
 80     virtual void OutputRole(Map* pMap);            //打印人物图形
 81     virtual void RemoveRole(Map* pMap);            //清除人物图形
 82     virtual void EquipSurface(){};                //装备外观(换装备就换外观)
 83     virtual void RoleMove(Map* pMap, char);        //角色移动
 84     virtual void ChangeDirection(Map* pMap);    //换方向
 85     virtual bool PreRoleMove(Map* pMap, char);    //角色预移动
 86     //virtual bool PreChangeDirection(Map* pMap);//预换方向
 87     virtual void EffectRemove(Body* pBody);        //Effect的移除
 88     virtual void EffectAppend(Body* pBody, Map* pMap);//Effect的添加
 89     virtual void CheckEffect();                    //效果检测
 90 
 91     virtual void UpdateRoleSight(Map* pMap){};    //更新角色视野    
 92     virtual bool JudgeSight(Map* pMap,int x,int y){ return true; }//视野判断
 93     virtual void ImplementAIAction(Map* pMap, list<Role*>* pObj) = 0;
 94     
 95     //================== 纯虚函数 ==============================
 96     virtual int CausedByDamage() { return m_atkBase; }//计算制造的伤害量
 97     virtual int AmountOfDamage(int atk){ return atk; }//计算受到的伤害量
 98     virtual Backpack* GetBackpack(){ return nullptr; }
 99     virtual TaskList* GetTaskList(){ return nullptr; }
100     virtual GameOI* GetGameOI(){ return nullptr; }
101     virtual void InitShape(string) = 0;            //导入人物图形(3D 2D)
102     virtual int GetExtent(){ return 0; }        //获取武器射程
103     virtual void UnderAttack(Role*, int){};
104     virtual void PushbackTask(Task* task){};    //添加新任务
105     virtual void SetExpCur(int exp){};
106     virtual int GetExpCur(){ return 0; };
107     virtual void SetExpMax(int exp){};
108     virtual int GetExpMax(){ return 0; };
109     virtual bool CanDelete(){ return true; }//可被释放
110     //喊话
111     virtual void GetSay(Map* pMap){};
112 
113 private:
114     //================== 基础属性 ==============================
115     CC_PROPERTY_READ_ONLY(char*, m_name, Name);    //名字
116 public: void SetName(char* name);
117 
118 private:Tip* m_tip;                                //人物简介
119 public: void SetTip( char* str);                //设置简介
120 
121 
122     CC_PROPERTY(char, m_direct, Direct);        //方向
123     CC_PROPERTY(int, m_x, X);                    //坐标x
124     CC_PROPERTY(int, m_y, Y);                    //坐标y
125 
126     CC_PROPERTY_READ_ONLY(const int, c_x, CX);    //刷新点坐标x
127     CC_PROPERTY_READ_ONLY(const int, c_y, CY);    //刷新点坐标y
128 
129     CC_PROPERTY_READ_ONLY(int, m_hpCur, HpCur);    //当前血量
130     virtual void SetHpCur(int dHp);                //设置当前血量
131     CC_PROPERTY(int, m_hpMax, HpMax);            //最大血量
132     CC_PROPERTY(int, m_liveCount, LiveCount);    //生命次数
133     CC_PROPERTY(int, m_sight, Sight);            //视力范围
134     CC_PROPERTY(int, m_atkCur, AtkCur);            //当前攻击力
135     CC_PROPERTY(int, m_atkBase, AtkBase);        //基本攻击力
136     CC_PROPERTY(int, m_def, Def);                //防御力
137     CC_PROPERTY(int, m_money,Money);            //金钱
138 
139     CC_PROPERTY(int, m_distance, Distance);        //攻击范围
140     CC_PROPERTY(int, m_ats, Ats);                //攻击速度
141     CC_PROPERTY(int, m_ms, MS);                    //水平速度
142     CC_PROPERTY(int, m_mg, MG);                    //重向速度
143     CC_PROPERTY(int, m_lv, LV);                    //等级
144     CC_PROPERTY(ArmType, m_armType, Arm);        //兵种
145     CC_PROPERTY_READ_ONLY(Shape*,m_shape,Shape) //形状
146     CC_PROPERTY(RaceType, m_race, Race);        //国籍
147     CC_PROPERTY(bool, m_suspend, Suspend);        //悬挂状态(悬空true)
148 
149     //效果的列表(装备、道具产生的效果)
150     CC_PROPERTY(list<Body*>*, m_effectList, EffectList);
151 };
152 
153 
154 
155 #endif  // ! _ROLE_H_
Role.h
  1 #include "..//Tip.h"
  2 #include "Role.h"
  3 #include "..//Task//Task.h"
  4 #include "..//Body/BloodNum.h"
  5 #include "..//Map//Map.h"
  6 using namespace std;
  7 extern int  GameTime;
  8 
  9 
 10 Role::Role(int lv, RaceType race, ArmType arm, int x, int y)
 11     :c_x(x), c_y(y)
 12 {
 13     //主动初始化属性
 14     m_lv = lv;    
 15     m_race = race;
 16     m_armType = arm;
 17     m_shape = new Shape;
 18     m_direct = 'a';
 19     m_x = x;
 20     m_y = y;
 21     //默认属性
 22     m_sight = 12;
 23     m_distance = 1;        //攻击距离1(近战距离)
 24     m_ms = 1;            //水平速度
 25     m_mg = 0;            //重向速度
 26     m_name = nullptr;
 27 
 28     m_tip = new Tip;
 29     m_hpCur = 1000 + m_lv * 2000;
 30     m_hpMax = m_hpCur;
 31     m_liveCount = 1;
 32     m_atkBase = m_lv * 15 + 5;
 33     m_atkCur = m_atkBase;
 34     m_ats = 50;
 35     m_def = m_lv * 5;
 36     m_money = m_lv * 200;
 37     m_suspend = false;
 38 
 39     m_effectList = new list < Body* > ;
 40 }
 41 
 42 Role::~Role()
 43 {
 44     if (m_name != nullptr)
 45     {
 46         delete[]  m_name;
 47         m_name = nullptr;
 48     }
 49 
 50     if (m_tip != nullptr)
 51     {
 52         delete m_tip;
 53         m_tip = nullptr;
 54     }
 55 
 56     if (m_shape != nullptr)
 57     {
 58         delete m_shape;
 59         m_shape = nullptr;
 60     }
 61 
 62     if (m_effectList != nullptr)
 63     {
 64         delete m_effectList;
 65         m_effectList = nullptr;
 66     }
 67 
 68 }
 69 //===================角色行为函数(外部接口) ==========================
 70 
 71 //攻击行为
 72 void Role::AttackAction(Map* pMap)    
 73 {
 74 
 75 }
 76 
 77 //打印人物血条
 78 void Role::OutputRoleBloodBar(int x, int y)
 79 {
 80     //遍历血条
 81     int count = (int)((double)m_hpCur / (double)m_hpMax * 20.0f);//当前血量值
 82     GotoXY(x, y);
 83     for (int i = 0; i < 20; i++)
 84     {
 85         if(count <= 6)//血量少于30%
 86             i < count ? Color(CT_Red, CT_White) : Color(CT_Grey, CT_White);
 87         else if(count<= 14)//血量少于70%
 88             i < count ? Color(CT_Yellow, CT_White) : Color(CT_Grey, CT_White);
 89         else //血量大于30%
 90             i < count ? Color(CT_Green, CT_White) : Color(CT_Grey, CT_White);
 91         cout << " ";
 92     }
 93     Color(CT_White, CT_Black);
 94 }
 95 
 96 
 97 //打印人物图形
 98 void Role::OutputRole(Map* pMap)
 99 {
100     char* shapeData = m_shape->data;
101     int** shapePos = m_shape->pos;
102     int   shapeCount = m_shape->count;
103     
104     for (int i = 0; i < shapeCount; i++)
105     {
106         pMap->GetRoleLayer()[shapePos[i][0]][shapePos[i][1]] = shapeData[i];
107         pMap->OutputMap(shapePos[i][0], shapePos[i][1]);
108     }
109 
110     //打印人物坐标
111     GotoXY(31, 5);
112     printf("< %2d / %2d >", shapePos[0][0], shapePos[0][1]);
113 }
114 
115 //清除人物图形
116 void Role::RemoveRole(Map* pMap)
117 {
118     char* shapeData = m_shape->data;
119     int** shapePos = m_shape->pos;
120     int   shapeCount = m_shape->count;
121 
122     for (int i = 0; i < shapeCount; i++)
123     {
124         pMap->GetRoleLayer()[shapePos[i][0]][shapePos[i][1]] = '0';
125         pMap->OutputMap(shapePos[i][0], shapePos[i][1]);
126     }
127 }
128 
129 //角色移动
130 void Role::RoleMove(Map* pMap, char direct)
131 {
132     if (GameTime% m_ms != 0)
133         return;
134 
135     if (direct == 72) direct = 'w'; 
136     else if (direct == 80) direct = 's';
137     else if (direct == 75) direct = 'a';
138     else if (direct == 77) direct = 'd';
139 
140     int** shapePos = m_shape->pos;
141     int   shapeCount = m_shape->count;
142 
143     this->RemoveRole(pMap);
144 
145     if ((direct == 'a' || direct == 'd') && m_direct != direct)
146     {
147         m_direct = direct;
148         this->ChangeDirection(pMap);
149         this->OutputRole(pMap);
150         return;
151     }
152 
153     int dX = 0, dY = 0;
154     switch (direct)
155     {
156     case 'w': if (pMap->FeasibleRegion(m_x - 1, m_y)) dX = -1; break;
157     case 's': if (pMap->FeasibleRegion(m_x + 1, m_y)) dX = 1; break;
158     case 'a': if (pMap->FeasibleRegion(m_x, m_y - 1)) dY = -1; break;
159     case 'd': if (pMap->FeasibleRegion(m_x, m_y + 1)) dY = 1; break;
160     }
161 
162     m_x += dX; m_y += dY;
163     for (int i = 0; i < shapeCount; i++)
164     {
165         shapePos[i][0] += dX;
166         shapePos[i][1] += dY;
167     }
168 
169     this->UpdateRoleSight(pMap);    //更新角色视野
170     this->OutputRole(pMap);
171 }
172 
173 //换方向
174 void Role::ChangeDirection(Map* pMap)
175 {
176     int** shapePos = m_shape->pos;
177     int   shapeCount = m_shape->count;
178 
179     //以锚点Y坐标翻转图形
180     for (int i = 1; i < shapeCount; i++)
181         shapePos[i][1] = 2 * shapePos[0][1] - shapePos[i][1];
182 }
183 
184 //角色预移动
185 bool Role::PreRoleMove(Map* pMap, char direct)
186 {
187     int** shapePos = m_shape->pos;
188 
189     int dX = 0, dY = 0;
190 
191     switch (direct)
192     {
193     case 'w':  dX = -1; break;
194     case 's':  dX = 1; break;
195     case 'a':  dY = -1; break;
196     case 'd':  dY = 1; break;
197     }
198 
199     int preX = m_x + dX;
200     int preY = m_y + dY;
201 
202     //角色在地图中移动后位置判断
203     //if (pMap->FeasibleRegion(preX, preY))
204     //    return true;
205 
206     char** backLayer = pMap->GetBackLayer();
207     if (backLayer[preX][preY] == 'q'|| backLayer[preX][preY] == 'm')
208         return false;
209     return true;
210 }
211 
212 ////预换方向
213 //bool Role::PreChangeDirection(Map* pMap)
214 //{
215 //    int** shapePos = m_shape->pos;
216 //    int   shapeCount = m_shape->count;
217 //
218 //    //预旋转的图像
219 //    int** preShape = GetIntMemory(shapeCount ,2 );
220 //
221 //    //以锚点Y坐标翻转预旋转
222 //    for (int i = 0; i < shapeCount; i++)
223 //    {
224 //        preShape[i][0] = shapePos[i][0];
225 //        preShape[i][1] = 2 * shapePos[0][1] - shapePos[i][1];
226 //    }
227 //
228 //    char** backLayer = pMap->GetBackLayer();
229 //    for (int i = 0; i < shapeCount; i++)
230 //    {
231 //        if (backLayer[preShape[i][0]][preShape[i][1]] == 'q'\
232 //            || backLayer[preShape[i][0]][preShape[i][1]] == 'm')
233 //        {
234 //            DeleteIntMemory(preShape, shapeCount);
235 //            return false;
236 //        }        
237 //    }
238 //    DeleteIntMemory(preShape, shapeCount);
239 //    return true;
240 //}
241 
242 
243 //=================== 属性操作函数(内部专用) ======================================
244 //设置人名
245 void Role::SetName(char* name)
246 {
247     if (name == nullptr)  return;
248 
249     if (m_name != nullptr)
250     {
251         if (strlen(m_name) >= strlen(name))
252         {
253             strcpy(m_name, name);
254             return;
255         }
256         delete[]  m_name;
257     }
258 
259     m_name = new char[strlen(name) + 1];
260     strcpy(m_name, name);
261 }
262 
263 //设置tip信息
264 void Role::SetTip(char* str)
265 {
266     //str是内容, weith 是信息宽度
267     m_tip->SetTip(str, 46);
268 }
269 
270 //打印tip信息
271 void Role::OutputTip(int x, int y)
272 {
273     m_tip->OutputTip(x, y);
274 }
275 
276 //设置血量(不能小于0, 不能大于HpMax)
277 void Role::SetHpCur(int dHp)
278 {
279     if (dHp < 0)
280         m_hpCur = 0;
281     else if (dHp > m_hpMax)
282         m_hpCur = m_hpMax;
283     else
284         m_hpCur = dHp;
285 }
286 
287 //Effect的移除                
288 void Role::EffectRemove(Body* pBody)
289 {
290     pBody->RemoveEffect(this);
291 }
292 
293 //Effect的添加
294 void Role::EffectAppend(Body* pBody,Map* pMap)
295 {
296     pBody->AppendEffect(this,pMap);
297 }
298 
299 //效果检测
300 void  Role::CheckEffect()
301 {
302     list<Body*>::iterator iBegin = m_effectList->begin();
303 
304     while (iBegin != m_effectList->end())
305     {
306         //如果物品产生无效,移除该物体
307         if (!(*iBegin)->CheckEffect())
308         {
309             this->EffectRemove(*iBegin);  //移除物品效果
310             iBegin = m_effectList->erase(iBegin);
311             continue;
312         }
313         iBegin++;
314     }
315 }
Role.cpp

派生【 玩家类】

 1 #ifndef _HERO_H_
 2 #define _HERO_H_
 3 
 4 #include "Role.h"
 5 #include "..//Task//TaskList.h"
 6 class GameOI;
 7 class Equip;
 8 
 9 class Hero  : public Role
10 {
11 public:
12     ////武器熟练度(0% - 100% 决定命中率)
13     //struct WeaponPy
14     //{
15     //    double WP_Dagger;                //匕首
16     //    double WP_Pistol;                //手枪
17     //    double WP_Pillbox;                //机关枪
18     //    double WP_SniperRifle;            //狙击枪
19     //};
20 
21 public:
22     Hero(int lv, RaceType race, int x, int y);
23     ~Hero();
24 
25 public:
26     virtual int CausedByDamage() ;            //计算制造的伤害量
27     virtual int AmountOfDamage(int atk) ;    //计算受到的伤害量
28     virtual void BeHit(Role* role,int atk, Map* pMap);
29     virtual void OutputRoleOI();            //打印人物OI上的信息图形
30 
31     virtual void InitShape(string );        //导入人物图形
32     virtual void EquipSurface();            //装备外观(换装备就换外观)
33 
34     virtual void UpdateRoleSight(Map* pMap);//更新角色视野    
35     virtual bool JudgeSight(Map* pMap, int x, int y);    //视野判断
36 
37     virtual int GetExtent();                //获取武器射程
38     virtual void ImplementAIAction(Map* pMap, list<Role*>* pObj){};
39 
40     //virtual void SetHpCur(int dHp);            //设置当前血量
41     virtual void OutputRoleExpBar(int x, int y);//打印人物经验
42 private:
43 
44     CC_PROPERTY(double, m_EVA, EVA);                //身手(闪避)
45     //CC_PROPERTY(WeaponPy, m_weaponPy, WeaponPy)    //武器熟练度
46 
47     CC_PROPERTY(int, m_expMax, ExpMax);                //升经验
48     CC_PROPERTY_READ_ONLY(int, m_expCur, ExpCur);    //当前经验
49     void SetExpCur(int exp);                        //设置经验(升级,更改基础属性)
50 
51     //OI界面
52     CC_PROPERTY(GameOI*, m_gameOI, GameOI);            //OI界面
53 
54     // 背包
55     CC_PROPERTY(Backpack*, m_backpack, Backpack);    //背包
56 
57 
58     // 任务列表
59 public:
60     virtual void PushbackTask(Task* task);            //添加新任务
61 
62 
63     CC_PROPERTY(TaskList*, m_taskList, TaskList);    //任务列表
64 };
65 
66 
67 
68 #endif //_HERO_H_
Hero.h
  1 #include "Hero.h"
  2 #include "..//Backpack//Backpack.h"
  3 #include "..//Body/BloodNum.h"
  4 #include "..//GameMgr//GameOI.h"
  5 #include "..//Body//Body.h"
  6 #include "..//Map//Map.h"
  7 
  8 
  9 //             等级   国籍         坐标x    坐标y
 10 Hero::Hero(int lv, RaceType race, int x, int y)
 11     :Role(lv, race, ArmType::AT_Hero, x, y)
 12 {
 13     m_EVA = 0;            //身手,闪避率初始0
 14     SetLiveCount(3);
 15     m_expCur = 0;
 16     m_expMax = GetLV() * 300;
 17     SetHpMax(10000 + GetLV() * 50000);
 18     SetHpCur(10000 + GetLV() * 50000);
 19 
 20     this->InitShape("3D");
 21 
 22     //背包、物品栏、任务列表
 23     m_backpack = new Backpack(this);
 24     m_taskList = new TaskList(this);
 25     m_gameOI = new GameOI(this);
 26 }
 27 
 28 Hero::~Hero()
 29 {
 30     if (m_backpack != nullptr)
 31     {
 32         delete m_backpack;
 33         m_backpack = nullptr;
 34     }
 35 
 36     if (m_gameOI != nullptr)
 37     {
 38         delete m_gameOI;
 39         m_gameOI = nullptr;
 40     }
 41 }
 42 
 43 //计算制造的伤害量
 44 int Hero::CausedByDamage()
 45 {
 46     Body** bodyArr = m_gameOI->GetBodyArr();
 47     //return bodyArr[0]->BeUse(this);
 48     return 0;
 49 }
 50 
 51 //计算受到的伤害量
 52 int Hero::AmountOfDamage(int atk)
 53 {
 54     int harm = atk - GetDef() > 0 ? atk - GetDef() : 0;
 55 
 56     return harm;
 57 }
 58 
 59 //受到伤害
 60 void Hero::BeHit(Role* role, int atk, Map* pMap)
 61 {
 62     int harm = AmountOfDamage(atk);
 63     this->SetHpCur(GetHpCur() - harm);
 64 
 65     //在头顶创造一个血字
 66     int x = GetX(); int y = GetY();
 67     Body* body = new BloodNum(this, x - 3, y, -1 * harm);
 68     pMap->GetBodyTmpList()->push_back(body);
 69 
 70     //显示血字
 71     GotoXY(x - 3, y);
 72     Color(CT_White, CT_Red);
 73     cout << -1 * harm;
 74 
 75     //更新血条
 76     this->OutputRoleBloodBar(30, 5);
 77 }
 78 
 79 //打印人物OI上的信息图形
 80 void Hero::OutputRoleOI()
 81 {
 82     Color(CT_White, CT_Black);
 83     GotoXY(28, 5); cout << "" << this->GetName() << "";
 84     GotoXY(29, 5); printf("  %2d 级", this->GetLV());
 85     this->OutputRoleBloodBar(30, 5);
 86     this->OutputRoleExpBar(31, 16);
 87     GotoXY(31, 5);//打印人物坐标
 88     printf("< %2d / %2d >", this->GetX(), this->GetY());
 89 }
 90 
 91 //获取人物图形
 92 void Hero::InitShape(string str)
 93 {
 94     if (str == "3D")
 95     {
 96         //3D图形资源
 97         char shapeRes[5] = { "u95x" };
 98         //    ○        ○
 99         //╤□        ■╤
100         //  ⊥        ⊥
101         //   |这是锚点
102 
103         //开辟人物图形数据内存
104         Shape* shape = GetShape();
105         shape->count = 4;
106         shape->data = new char[shape->count];
107         if (shape->data == nullptr) return;
108 
109         shape->pos = new int*[shape->count];
110         if (shape->pos == nullptr) return;
111 
112         for (int i = 0; i < shape->count; i++)
113         {
114             shape->pos[i] = new int[2];
115             if (shape->pos[i] == nullptr)
116                 return;
117         }
118 
119         //人物图形资源导入
120         //data
121         for (int i = 0; i < shape->count; i++)
122             shape->data[i] = shapeRes[i];
123         //pos
124         int x = GetX(); int y = GetY();
125         shape->pos[0][0] = x;
126         shape->pos[0][1] = y;
127         shape->pos[1][0] = x - 1;
128         shape->pos[1][1] = y;
129         shape->pos[2][0] = x - 2;
130         shape->pos[2][1] = y;
131         shape->pos[3][0] = x - 1;
132         shape->pos[3][1] = GetDirect() == 'a' ? y - 1 : y + 1;
133     }
134 
135     else if (str == "2D")
136     {
137         //2D图形资源
138         char shapeRes[5] = { "xxxx" };
139         //开辟人物图形数据内存
140         Shape* shape = GetShape();
141         shape->count = 4;
142         shape->data = new char[shape->count];
143         if (shape->data == nullptr) return;
144 
145         shape->pos = new int*[shape->count];
146         if (shape->pos == nullptr) return;
147 
148         for (int i = 0; i < shape->count; i++)
149         {
150             shape->pos[i] = new int[2];
151             if (shape->pos[i] == nullptr)
152                 return;
153         }
154 
155         //人物图形资源导入
156         //data
157         for (int i = 0; i < shape->count; i++)
158             shape->data[i] = shapeRes[i];
159         //pos
160         for (int i = 0; i < shape->count; i++)
161         {
162             shape->pos[i][0] = GetX();
163             shape->pos[i][1] = GetY();
164         }
165     }
166 }
167 
168 //装备外观(换装备就换外观)
169 void Hero::EquipSurface()
170 {
171     //    ○        ○
172     //╤□        ■╤
173     //  ⊥        ⊥
174     // 2号衣服、4号武器
175     //□9■q    ╤&  —%
176 
177     char* shapeData = GetShape()->data;
178     Body** bodyBar =  m_gameOI->GetBodyArr();
179     //物品栏1武器、6衣服
180     shapeData[3] = (bodyBar[0] == nullptr ? 'x' : '&');
181     shapeData[1] = (bodyBar[5] == nullptr ? '9' : 'q');
182 
183 }
184 //获取武器射程
185 int Hero::GetExtent()
186 {
187     Body** bodyBar = m_gameOI->GetBodyArr();
188 
189     if (bodyBar[0] == nullptr)
190         return 0;
191 
192     return bodyBar[0]->GetExtent();
193 }
194 
195 //更新角色视野    
196 void Hero::UpdateRoleSight(Map* pMap)
197 {    
198     if (pMap->GetIsDay())
199         return;
200 
201     //地图属性
202     bool** MapSight = pMap->GetSightLayer();
203 
204     //人物属性
205     int sight = this->GetSight();
206     int x = GetX();
207     int y = GetY();
208 
209     //-----视野范围----------------------------
210     int SmallX = x - sight > 2 ? x - sight : 2;
211     int BigX = x + sight < 25 ? x + sight : 24;
212     int SmallY = y - sight > 2 ? y - sight : 2;
213     int BigY = y + sight < 77 ? y + sight :76;
214 
215     //----循环打印,可见区域--------------------
216     for (int row = SmallX - x; row <= BigX - x; row++)
217     {
218         for (int colu = SmallY - y; colu <= BigY - y; colu++)
219         {
220             bool befor = MapSight[row + x][colu + y];    //原来情况
221             bool back = JudgeSight(pMap, row, colu);    //后来情况
222             //如果该位置视野情况发生变化(重新打印该位置)
223             if (befor != back)
224             {
225                 MapSight[row + x][colu + y] = back;
226                 pMap->OutputMap(row + x, colu + y);        
227             }
228         }
229     }
230 }
231 
232 
233 //视野判断
234 bool Hero::JudgeSight(Map* pMap, int x, int y)
235 {
236     //递增递减判断
237     int dX = x > 0 ? 1 : -1;
238     int dY = y > 0 ? 1 : -1;
239     //人物视野
240     int sight = this->GetSight();
241     //地图背景层
242     char** backLayer = pMap->GetBackLayer();
243 
244     //在圆形范围内--------
245     if (x* x+ y* y< (sight - 1)* (sight - 1))
246     {
247         //显示所有的墙
248         if (backLayer[x + GetX()][y + GetY()] == '9'&& pMap->GetType() == "2D")
249             return true;
250 
251         if (y == 0) //****这种情况下,直线没有斜率
252         {
253             for (int row = 0; dX * row <= dX * x; row += dX)//遍历2点之间是否存在障碍物
254             {
255                 //如果遍历到最后1个,就说明没障碍物
256                 if (row == x)
257                     return true;
258 
259                 //有障碍物,标记为阴影区
260                 if (backLayer[row + GetX()][GetY()] == '9'&& pMap->GetType() == "2D")
261                     return false;
262             }
263         }
264         else   //当COLU != 0时,计算斜率,模拟缓冲区判断
265         {
266             //该点与角色位置的线性方程为: row = ratio * col 
267             double ratio = (double)x / (double)y;    //计算线性方程的系数
268             double d = sqrt(ratio * ratio + 2) / 2;       //缓冲区半径
269 
270             for (int row = 0; dX * row <= dX * x; row += dX)
271             {
272                 for (int col = 0; dY*col <= dY*y; col += dY)
273                 {
274                     //如果遍历到最后一个,就说明没障碍物
275                     if ((row == x) && (col == y))
276                         return true;
277                     //在缓冲范围内 且有障碍物
278                     if (row <= ratio* col + d && row >= ratio* col - d
279                         && (backLayer[row + GetX()][col + GetY()] == '9') && pMap->GetType() == "2D")
280                         return false;
281                 }
282             }
283         }
284     }
285     //其他情况都为阴影区
286     return false;
287 }
288 
289 //设置经验(升级,更改基础属性)
290 void Hero::SetExpCur(int exp)
291 {
292     //升级
293     if (exp >= m_expMax)
294     {
295         int lv = GetLV();
296         SetLV( ++lv );
297         m_expCur = exp - m_expMax;
298         m_expMax = lv * 300;
299         SetHpMax(1000 + lv * 10000);
300         SetHpCur(1000 + lv * 10000);
301         SetAtkBase(lv * 15 + 5);
302         SetAtkCur(lv * 15 + 5);
303         SetDef(lv * 5 );
304 
305         //升级,更新整个OI
306         this->OutputRoleOI();
307         return;
308     }
309 
310     m_expCur = exp;
311     //未升级,只更新经验条
312     this->OutputRoleExpBar(31, 16);
313 }
314 
315 
316 //打印人物经验
317 void Hero::OutputRoleExpBar(int x, int y)
318 {
319     //遍历经验条
320     int count = (int)((double)m_expCur / (double)m_expMax * 94.0f);//当前血量值
321 
322     GotoXY(x, y);
323     for (int i = 0; i < 94; i++)
324     {
325         i < count ? Color(CT_Blue, CT_White) : Color(CT_Grey, CT_White);
326 
327         cout << " ";
328     }
329     Color(CT_White, CT_Black);
330 }
331 
332 //添加新任务
333 void Hero::PushbackTask(Task* task)
334 {
335     m_taskList->PushBackTask(task);
336 }
Hero.cpp

派生【Ai角色】 会逃跑、追击、喊话(多个敌对目标会有仇恨列表,目前没法测试)

 1 #ifndef _AI_ROLE_H_
 2 #define _AI_ROLE_H_
 3 
 4 #include <list>
 5 #include "Role.h"
 6 using namespace std;
 7 class Map;
 8 
 9 //========== AI系统 ===========
10 //00怪物自发性动作
11 //2 停留、行走、警戒
12 //每个2个停留点之间的连线是行走路径
13 //怪物在行走过程中搜寻进入范围的目标触发反应事件
14 
15 //00怪物反应事件判断:
16 //1 目标选取判断 2 战斗道具使用判断 3 追击判定 4 逃跑判定
17 
18 class AiRole : public Role
19 {
20 public://攻击列表节点
21     struct Node
22     {
23         Node(Role* pObj)
24         {
25             obj = pObj;        //目标
26             hatred = 10;    //初始仇恨
27         }
28         Role*  obj;
29         int    hatred;
30     };
31 
32 public:
33     AiRole(int lv, RaceType race, ArmType arm, int x, int y);
34     ~AiRole();
35 
36 public://=========== AI操作外部接口 =============================
37     void ImplementAIAction(Map* pMap, list<Role*>* pObj);//执行AI行为(与地图、所有敌人list的交互)
38 
39     //触发事件判断和行为(对战斗列表的自动操作)
40     void PatrolAction(Map* pMap, list<Role*>* pObj);    //巡逻行为
41     bool JudgeAlertArea(char** pMap, Role* pObj);        //判断是否进入警戒范围
42     void UnderAttack(Role* Obj, int atk);                //被攻击触发
43     void SortAttackListByHatred();                        //跟据仇恨值更新攻击列表
44     virtual void ActiveAttack(Map*);                    //发动攻击行为(使用道具、追击)
45     void TimeLapse();                                    //列表第1位,超出警戒范围仇恨减少(时间推移)
46     virtual void RunAway(Map* pMap);                    //逃跑行为
47     virtual void DirectToObj(Map* pMap, Role* Obj);        //转向面对目标
48     virtual void AttackAction(Map* pMap);                //攻击行为
49     virtual int GetExtent();                            //获取武器射程
50     
51     void OutputRole(Map* pMap);                        //打印人物图形
52     virtual void OutputRoleOI();                    //打印人物OI上的信息图形
53     virtual void BeHit(Role* role, int atk, Map* pMap);    //受到伤害
54 
55     //喊话
56     virtual void GetSay(Map* pMap);
57 
58 public://战斗状态
59     enum BattleState
60     {
61         BS_YES,    //战斗中
62         BS_NO,    //非战斗
63         BS_RUN,    //惊慌逃跑
64     };
65 
66 private:// ============ 私有属性 ===============================
67     CC_PROPERTY(Body*,m_weapon,Weapon);                    //武器
68     CC_PROPERTY(Role*, m_obj, Obj);                        //当前目标    
69 
70     CC_PROPERTY(list<Node*>*, m_attackList,AttackList);    //攻击列表
71     CC_PROPERTY(int, m_alertArea, AlertArea);            //警戒范围
72     CC_PROPERTY(BattleState, m_condition, Condition);    //战斗状态
73 
74     CC_PROPERTY(string**, m_dalogue, Dialogue);            //说的所有话
75     CC_PROPERTY(int, m_dialIndex, DialIndex);            //当前说的话
76 
77 };
78 
79 
80 #endif // _AI_ROLE_H_
AiRole.h
  1 #include "AiRole.h"
  2 #include "..//Map//Map.h"
  3 #include "..//Body/BloodNum.h"
  4 #include "..//Body//Say.h"
  5 
  6 //声明一个全局变量(模拟游戏时间)
  7 extern int GameTime;
  8 
  9 AiRole::AiRole(int lv,RaceType race,ArmType arm,int x, int y)
 10     :Role(lv,race,arm,x,y)
 11 {
 12     SetMS(30);
 13     m_alertArea = 18;            //默认警戒范围
 14     m_attackList = nullptr;        //开始置空
 15     m_condition = BS_NO;        //非战斗
 16     m_weapon = nullptr;
 17     m_obj = nullptr;
 18 
 19     SetHpMax(2000 + GetLV() * 800);
 20     SetHpCur(2000 + GetLV() * 800);
 21 
 22     m_dalogue = new string*[3];
 23     for (int i = 0; i < 3; i++)
 24         m_dalogue[i] = nullptr;
 25     m_dialIndex = 0;
 26 }
 27 
 28 AiRole::~AiRole()
 29 {
 30     if (m_attackList == nullptr)
 31         return;
 32 
 33     //遍历释放战斗list中所有的Node*
 34     list<Node*>::iterator iBegin;
 35     for (iBegin = m_attackList->begin(); iBegin != m_attackList->end();iBegin++)
 36     {
 37         delete *iBegin;
 38         *iBegin = nullptr;
 39     }
 40     //释放战斗列表
 41     delete m_attackList;
 42     m_attackList = nullptr;
 43 }
 44 
 45 //========= 执行AI行为   外部接口函数 =====================================
 46 // 执行AI行为(警戒巡逻、被攻击触发、自动更新战斗列表、自动移除目标、自动追击、自动逃跑)
 47 void AiRole::ImplementAIAction(Map* pMap, list<Role*>* pObj)
 48 {
 49     //非战斗状态时
 50     if (m_attackList == nullptr)    
 51         this->PatrolAction(pMap, pObj); //巡逻(里面含有 判断警戒范围)
 52 
 53     //战斗状态时
 54     else if (m_attackList != nullptr)
 55     {
 56         this->SortAttackListByHatred(); //跟据仇恨值更新攻击列表
 57         this->ActiveAttack(pMap);        //自动攻击(使用武器、追击)
 58         this->RunAway(pMap);            //逃跑行为
 59     }
 60 }
 61 
 62 //被攻击触发(如果没有该角色,添加进战斗列表,有就仇恨增加)
 63 void  AiRole::UnderAttack(Role* Obj, int atk)
 64 {
 65     unsigned int dHatred = atk / 5 + 1;            // 每5点伤害产生1点仇恨值
 66 
 67     if (m_attackList != nullptr)
 68     {
 69         list<Node*>::iterator iBegin;
 70         for (iBegin = m_attackList->begin(); iBegin != m_attackList->end(); iBegin++)
 71         {    //如果该角色以在战斗列表
 72             if ((*iBegin)->obj == Obj)
 73             {
 74                 (*iBegin)->hatred += dHatred;  //仇恨修改
 75                 return;
 76             }
 77         }
 78     }
 79     else
 80     {
 81         m_attackList = new list < Node* > ; //战斗列表开辟内存
 82         m_condition = BS_YES;                //战斗状态
 83     }
 84 
 85     //添加该角色到战斗列表
 86     Node* pNode = new Node(Obj);    //用当前对象定义一个节点
 87     pNode->hatred += dHatred;
 88     m_attackList->push_back(pNode);    //添加当前结点    
 89 }
 90 
 91 
 92 //============== 内部操作判断 函数 ================
 93 
 94 //巡逻动作
 95 void  AiRole::PatrolAction(Map* pMap, list<Role*>* pObj)
 96 {
 97     char** map = pMap->GetBackLayer();
 98 
 99     //用迭代器遍历目标list(查找第一个进入警戒范围的目标)
100     list<Role*>::iterator iBegin;
101     for (iBegin = pObj->begin(); iBegin != pObj->end(); iBegin++)
102     {
103         //如果找到目标进入警戒范围且有视野(就添加进战斗列表,更改角色状态进入战斗)
104         if (this->JudgeAlertArea(map, *iBegin))
105         {
106             m_attackList = new list < Node* > ; //战斗列表开辟内存
107             Node* pNode = new Node(*iBegin);    //用当前对象定义一个节点
108             m_attackList->push_back(pNode);        //添加当前结点    
109             
110             this->DirectToObj(pMap, *iBegin);    //转身面向目标
111 
112             m_condition = BS_YES;                //战斗状态
113             return;
114         }
115     }
116 }
117 
118 //判断是否进入警戒范围(在当前地图上判断是否有视野)
119 bool AiRole::JudgeAlertArea(char** pMap, Role* pObj)
120 {
121     int thisX = this->GetX();                //自己的x坐标
122     int thisY = this->GetY();                //自己的y坐标
123     int x = pObj->GetX() - thisX;            //与目标的坐标差
124     int y = pObj->GetY() - thisY;            //与目标的坐标差
125 
126     //在警戒范围内
127     if (x * x + y * y <= (m_alertArea - 1)* (m_alertArea))
128         return true;
129     else //if ((x * x + y * y) > (m_alertArea - 1) * m_alertArea)
130         return false;
131 }
132 
133 
134 //跟据仇恨值更新攻击列表
135 void AiRole::SortAttackListByHatred()
136 {
137     //------根据仇恨值排序战斗列表-----
138     m_attackList->sort();            // ???? hatred 排序方法
139 
140     //------仇恨为0移出战斗列表-----
141     list<Node*>::iterator iBegin = m_attackList->begin();//用迭代器遍历目标list(查找目标)
142     m_obj = (*iBegin)->obj;  //更新当前目标//攻击战斗列表的第一个元素(仇恨值最高的)
143 
144     for (; iBegin != m_attackList->end(); iBegin++)
145     {
146         if (!(*iBegin)->hatred)                    //如果仇恨值为0(就移除战斗列表)
147         {
148             iBegin = m_attackList->erase(iBegin);    //移除该结点    
149 
150             if (m_attackList->empty())                //当列表为empty时,释放列表内存,更改角色为非战斗状态
151             {
152                 m_condition = BS_NO;                //设置非战斗状态
153                 delete m_attackList;                //释放战斗列表内存
154                 m_attackList = nullptr;                //战斗列表置null
155                 return;
156             }
157         }
158     }
159 }
160 
161 //超出警戒范围时间推移(仇恨减少)
162 void  AiRole::TimeLapse()
163 {
164     int dx = m_obj->GetX() - this->GetCX();
165     int dy = m_obj->GetY() - this->GetCY();
166 
167     //超出警戒范围
168     if (dx*dx + dy * dy > m_alertArea * m_alertArea)
169     {
170         if (GameTime % 200 == 0)
171         {
172             int hat = m_attackList->front()->hatred;
173 
174             m_attackList->front()->hatred = hat > 20 ? hat - 20 : 0;
175         }
176     }
177 }
178 
179 //自动攻击(使用武器、追击)
180 void AiRole::ActiveAttack(Map* pMap)
181 {
182     if (m_condition != BS_YES)
183         return;
184 
185     //攻击战斗列表的第一个元素(仇恨值最高的)
186     int x = m_obj->GetX() - this->GetX();    //与目标的坐标差
187     int y = m_obj->GetY() - this->GetY();    //与目标的坐标差
188     int dist = this->GetDistance();            //自己的射程
189 
190     //进入射程就攻击
191     if (x == 0 && y * y <= dist * dist )
192     {
193         if (GameTime % this->GetAts() == 0)
194         {
195             //--------转身面向目标--------
196             this->DirectToObj(pMap,m_obj);
197             this->AttackAction(pMap);
198         }
199     }
200 
201     //否则,追击目标
202     else // (x * x + y * y > dist * dist )
203     {
204         if (GameTime % this->GetMS() == 0)
205         {
206             char ch;
207             if (x!= 0)
208                 ch = x > 0 ? 's' : 'w';
209             else
210                 ch = y > 0 ? 'd' : 'a';
211             
212             this->RoleMove(pMap,ch);
213         }
214     }
215 }
216 
217 //逃跑行为
218 void AiRole::RunAway(Map* pMap)
219 {
220     //如果不是逃跑状态,血量低于20%总血量,就设定为逃跑状态
221     if (m_condition == BS_YES  && this->GetHpCur() <= this->GetHpMax()*0.2)
222         m_condition = BS_RUN;
223 
224     //如果是逃跑状态,就指向逃跑程序
225     if (m_condition == BS_RUN)
226     {
227         //战斗列表的第一个元素(仇恨值最高的)
228         int y = m_obj->GetY() - this->GetY();    //与目标的坐标差
229 
230         if (GameTime %( this->GetMS()/2) == 0)
231         {
232             //向反方向移动
233             char ch = y > 0 ? 'a' : 'd';
234             this->RoleMove(pMap,ch);
235         }
236     }
237 }
238 
239 
240 //攻击行为
241 void AiRole::AttackAction(Map* pMap)
242 {
243     //无武器单位,徒手攻击
244     if (m_weapon == nullptr)
245     {
246         m_obj->BeHit(this,this->GetAtkCur(), pMap);
247         return;
248     }
249 
250     m_weapon->BeUse(pMap);
251 }
252 
253 //获取武器射程
254 int AiRole::GetExtent()
255 {
256     if (m_weapon == nullptr)
257         return  2;
258 
259     int extent = m_weapon->GetExtent();
260     return extent;
261 }
262 
263 //打印人物图形
264 void AiRole::OutputRole(Map* pMap)
265 {
266     char* shapeData = GetShape()->data;
267     int** shapePos = GetShape()->pos;
268     int   shapeCount = GetShape()->count;
269 
270     for (int i = 0; i < shapeCount; i++)
271     {
272         pMap->GetRoleLayer()[shapePos[i][0]][shapePos[i][1]] = shapeData[i];
273         pMap->OutputMapOfEnemy(shapePos[i][0], shapePos[i][1]);
274     }
275 }
276 
277 //受到伤害
278 void AiRole::BeHit(Role* role, int atk, Map* pMap)
279 {
280     int harm = AmountOfDamage(atk);
281     this->SetHpCur(GetHpCur() - harm);
282     this->GetSay(pMap);//说话
283 
284     //死亡获得经验
285     if (this->GetHpCur() == 0)
286     {
287         role->SetExpCur(role->GetExpCur() + this->GetLV() * 100);
288         role->SetMoney(role->GetMoney() + this->GetLV() * 20);
289     }
290 
291     //在头顶创造一个血字
292     int x = GetX(); int y = GetY();
293     Body* body = new BloodNum(this, x - 3, y,-1* harm);
294     pMap->GetBodyTmpList()->push_back(body);
295 
296     //显示血字
297     GotoXY(x - 3, y);
298     Color(CT_White, CT_Red);
299     cout <<-1 * harm;
300 
301     //更新敌人OI
302     this->OutputRoleOI();
303 }
304 
305 //打印人物OI上的信息图形
306 void AiRole::OutputRoleOI()
307 {
308     Color(CT_White, CT_Black);
309     GotoXY(28, 67); cout << "" << this->GetName() << "";
310     GotoXY(29, 67); printf("  %2d 级", this->GetLV());
311     this->OutputRoleBloodBar(30, 67);
312     GotoXY(31, 67);//打印人物坐标
313     printf("< %2d / %2d >", this->GetX(), this->GetY());
314 }
315 
316 
317 //转向面对目标
318 void AiRole::DirectToObj(Map* pMap, Role* Obj)
319 {
320     char direct = Obj->GetY() > this->GetY() ? 'd' : 'a';
321     if (direct != this->GetDirect())
322     {
323         this->RemoveRole(pMap);
324         this->SetDirect(direct);
325         this->ChangeDirection(pMap);
326         this->OutputRole(pMap);
327     }
328 }
329 
330 
331 //喊话
332 void AiRole::GetSay(Map* pMap)
333 {
334     if (m_dalogue == nullptr)
335         return;
336 
337     //获取要说的话
338     double part = (double)GetHpCur() / (double)GetHpMax();
339     int x = this->GetX() - 6; int y = this->GetY();
340     Body* sayCur = nullptr;
341 
342     if (m_dialIndex<1 && part <= 0.7f && part > 0.5f)
343     {
344         sayCur = new Say(this, x, y, m_dalogue[0]);
345         m_dialIndex++;
346     }
347     else if (m_dialIndex<2 &&  part <= 0.5f && part > 0.2f)
348     {
349         sayCur = new Say(this, x, y, m_dalogue[1]);
350         m_dialIndex++;
351     }
352     else if (m_dialIndex<3 && part <= 0.2f)
353     {
354         sayCur = new Say(this, x, y, m_dalogue[2]);
355         m_dialIndex++;
356     }
357 
358     //创建对象到物品List,并打印显示
359     if (sayCur != nullptr)
360     {
361         pMap->GetBodyTmpList()->push_back(sayCur);
362         sayCur->OutputSelf(pMap);
363     }
364 }
AiRole.cpp

 

AiRole派生【各种敌人类】

 1 #ifndef _SPEAR_MAN_H_
 2 #define _SPEAR_MAN_H_
 3 
 4 #include "AiRole.h"
 5 //================== 枪兵 ================
 6 
 7 class SpearMan : public AiRole
 8 {
 9 
10 public:
11     SpearMan(int lv, RaceType race, int x, int y);
12 
13 
14 public:
15     //===================行为函数 ==========================
16     virtual int AmountOfDamage(int atk);    //计算受到的伤害量
17 
18     virtual void OutputShout(int count);    //打印喊话
19     virtual void InitShape(string str = "3D");    //导入人物图形
20 
21     virtual void GetSay(Map* pMap);
22 
23 private:
24     bool m_isSay;
25 };
26 
27 
28 #endif // _SPEAR_MAN_H_
SpearMan.h
  1 #include "SpearMan.h"
  2 #include "..//Marco.h"
  3 #include "..//Body//Pistol.h"
  4 #include "..//Map//Map.h"
  5 #include "..//Body//Say.h"
  6 
  7 
  8 SpearMan::SpearMan(int lv, RaceType race, int x, int y)
  9     :AiRole(lv, race, AT_Spearman, x, y)
 10 {
 11     //防止等级越界
 12     if (GetLV() > 6)
 13         SetLV(6);
 14 
 15     this->SetHpMax(2000 + GetLV() * 2000);    //血量
 16     this->SetHpCur(2000 + GetLV() * 2000);    //血量
 17 
 18     this->SetMS(GetMS() + GetLV() * 5);    //移动速度增加
 19 
 20     this->InitShape();                    //导入图形数据
 21 
 22     Body* body = new Pistol(4);
 23     body->SetOwner(this);
 24     SetWeapon(body);
 25     SetDistance(body->GetExtent());
 26     SetName("[枪兵]");
 27     SetTip("注意他们手上的枪!人面兽心,说的就是他们...");
 28 
 29     //说话的内容
 30     string** sapArr = GetDialogue();
 31     sapArr[0] = new string("啊... 啊...伊斯兰万岁!");
 32 
 33     m_isSay = false;
 34 }
 35 
 36 
 37 
 38 
 39 //===================行为函数 ==========================
 40 
 41 //计算受到的伤害量
 42 int SpearMan::AmountOfDamage(int atk)
 43 {
 44     return atk;
 45 }
 46 
 47 
 48 //打印喊话
 49 void SpearMan::OutputShout(int count)
 50 {
 51     switch (count)
 52     {
 53     case 1: cout << "汪!汪!汪!……"; break;
 54     case 2: cout << "嗷!嗷!嗷!……"; break;
 55     case 3: cout << "嗷!嗷!嗷!……"; break;
 56     }
 57 }
 58 
 59 //获取人物图形
 60 void SpearMan::InitShape(string str)
 61 {
 62     if (str == "3D")
 63     {
 64         //图形资源
 65         char shapeRes[5] = { "uq5&" };
 66         //    ○        ○
 67         //╤□        ■╤
 68         //  ⊥        ⊥
 69         //   |这是锚点
 70         //开辟人物图形数据内存
 71         Shape* shape = GetShape();
 72         shape->count = 4;
 73         shape->data = new char[shape->count];
 74         if (shape->data == nullptr) return;
 75 
 76         shape->pos = new int*[shape->count];
 77         if (shape->pos == nullptr) return;
 78 
 79         for (int i = 0; i < shape->count; i++)
 80         {
 81             shape->pos[i] = new int[2];
 82             if (shape->pos[i] == nullptr)
 83                 return;
 84         }
 85 
 86         //人物图形资源导入
 87         //data
 88         for (int i = 0; i < shape->count; i++)
 89             shape->data[i] = shapeRes[i];
 90         //pos
 91         int x = GetX(); int y = GetY();
 92         shape->pos[0][0] = x;
 93         shape->pos[0][1] = y;
 94         shape->pos[1][0] = x - 1;
 95         shape->pos[1][1] = y;
 96         shape->pos[2][0] = x - 2;
 97         shape->pos[2][1] = y;
 98         shape->pos[3][0] = x - 1;
 99         shape->pos[3][1] = y - 1;
100     }
101     else if (str == "2D")
102     {
103         //2D图形资源
104         char shapeRes[5] = { "++++" };
105         //开辟人物图形数据内存
106         Shape* shape = GetShape();
107         shape->count = 4;
108         shape->data = new char[shape->count];
109         if (shape->data == nullptr) return;
110 
111         shape->pos = new int*[shape->count];
112         if (shape->pos == nullptr) return;
113 
114         for (int i = 0; i < shape->count; i++)
115         {
116             shape->pos[i] = new int[2];
117             if (shape->pos[i] == nullptr)
118                 return;
119         }
120 
121         //人物图形资源导入
122         //data
123         for (int i = 0; i < shape->count; i++)
124             shape->data[i] = shapeRes[i];
125         //pos
126         for (int i = 0; i < shape->count; i++)
127         {
128             shape->pos[i][0] = GetX();
129             shape->pos[i][1] = GetY();
130         }
131     }
132 }
133 
134 //喊话
135 void SpearMan::GetSay(Map* pMap)
136 {
137     //获取要说的话
138     double part = (double)GetHpCur() / (double)GetHpMax();
139     int x = this->GetX() - 6; int y = this->GetY();
140     Body* sayCur = nullptr;
141 
142     if (!m_isSay  && part <= 0.3f)
143     {
144         sayCur = new Say(this, x, y, GetDialogue()[0]);
145         m_isSay = true;
146     }
147 
148     //创建对象到物品List,并打印显示
149     if (sayCur != nullptr)
150     {
151         pMap->GetBodyTmpList()->push_back(sayCur);
152         sayCur->OutputSelf(pMap);
153     }
154 }
SpearMan.cpp
 1 #ifndef _DOG_H_
 2 #define _DOG_H_
 3 
 4 #include "AiRole.h"
 5 //================== 军犬类 ================
 6 
 7 class Dog : public AiRole
 8 {
 9 public:
10     Dog(int lv, RaceType race, int x, int y);
11 
12 public:
13     //===================行为函数 ==========================
14     virtual int CausedByDamage();            //计算制造的伤害量
15     virtual int AmountOfDamage(int atk) ;    //计算受到的伤害量
16 
17     virtual void OutputShout(int count);    //打印喊话
18     virtual void InitShape(string str = "3D");//导入人物图形
19     virtual void AttackAction(Map* pMap);    //攻击行为
20 
21 private:
22 
23 
24 };
25 
26 
27 #endif // _DOG_H_
Dog.h
  1 #include "Dog.h"
  2 #include "..//Marco.h"
  3 #include "..//Body/BloodNum.h"
  4 
  5 Dog::Dog(int lv,RaceType race, int x, int y)
  6 :AiRole(lv, race, ArmType::AT_Dog, x, y)
  7 {
  8     //防止等级越界
  9     if (GetLV()>6)
 10         SetLV(6);
 11 
 12     this->SetHpMax(1000 + GetLV() * 1000);    //血量
 13     this->SetHpCur(1000 + GetLV() * 1000);    //血量
 14 
 15     this->SetMS(GetMS() + GetLV() * 5);    //移动速度增加
 16     this->SetAtkBase(100 + GetLV() * 50);
 17     this->InitShape();                    //导入图形数据
 18 
 19     switch (GetLV())
 20     {
 21     case 1: 
 22         SetName("[狼犬]");
 23         SetTip("狼犬形像野狼,性凶猛,嗅觉敏锐。多饲养来帮助看家、打猎或牧羊。因外表像狼而得名。");
 24         break;
 25     case 2:
 26         SetName("[昆明犬]");
 27         SetTip("神经类型兴奋灵敏,猎取反射强,防御反射主动,适应环境快。四肢奔跑有力,依恋性强,有耐力。");
 28         break;
 29     case 3:
 30         SetName("[罗威纳犬]");
 31         SetTip("俗称“大头犬”,中等体型,头部宽大,垂耳,肌肉发达,四肢强壮有力");
 32         break;
 33     case 4:
 34         SetName("[多伯曼犬]");
 35         SetTip("也称杜宾犬,呈方形中等体型,结构紧凑、肌肉发达有力,有耐力和速度,勇敢忠诚,精力充沛。");
 36         break;
 37     case 5: 
 38         SetName("[高加索犬]");
 39         SetTip("高加索犬性情勇猛而忠顺于主人;抗病力强;被毛厚密形成天然蓑衣和冷热隔绝层,适应各种气候条件。");
 40         break;
 41     case 6: 
 42         SetName("[纯种藏獒]");
 43         SetTip("体格高大,性格刚毅,力大勇猛,野性尚存,使人望而生畏,“犬中之王”美誉完全名副其实。");
 44         break;
 45     }
 46 
 47     //说话的内容
 48     string** sapArr = GetDialogue();
 49     sapArr[0] = new string("汪!汪!汪!……");
 50     sapArr[1] = new string("嗷!嗷!嗷!……");
 51     sapArr[2] = new string("嗷呜!嗷呜!……");
 52 }
 53 
 54 
 55 
 56 
 57 //===================行为函数 ==========================
 58 //攻击行为
 59 void Dog::AttackAction(Map* pMap)
 60 {
 61     Role* pObj = this->GetAttackList()->front()->obj;
 62     pObj->BeHit(this,CausedByDamage(), pMap);
 63     PlaySound(TEXT(".\\Music\\sence\\dog4.wav"), NULL, SND_ASYNC);
 64 }
 65 
 66 //计算制造的伤害量
 67 int Dog::CausedByDamage()
 68 {
 69     //血量低于30%时,狂暴伤害增加一倍
 70     if (GetHpCur()<= GetHpMax() * 0.3)
 71     {
 72         SetAtkCur(GetAtkBase()* 2); //2倍伤害
 73     }
 74 
 75     return GetAtkCur();
 76 }
 77 
 78 
 79 //计算受到的伤害量
 80 int Dog::AmountOfDamage(int atk)
 81 {
 82     return atk;
 83 }
 84 
 85 
 86 //打印喊话
 87 void Dog::OutputShout(int count)
 88 {
 89     switch (count)
 90     {
 91     case 1: cout << "汪!汪!汪!……"; break;
 92     case 2: cout << "嗷!嗷!嗷!……"; break;
 93     case 3: cout << "嗷呜!嗷呜!……"; break;
 94     }
 95 }
 96 
 97 //获取人物图形
 98 void Dog::InitShape(string str)
 99 {
100     //图形资源
101     char shapeRes[7] = {"vv+qq%"};
102     //¤■■━
103     //  ∧∧
104     //   |这是锚点
105 
106     //开辟人物图形数据内存
107     Shape* shape = GetShape();
108     shape->count = 6;
109     shape->data = new char[shape->count];
110     if (shape->data == nullptr) return;
111 
112     shape->pos = new int*[shape->count];
113     if (shape->pos == nullptr) return;
114 
115     for (int i = 0; i < shape->count; i++)
116     {
117         shape->pos[i] = new int[2];
118         if (shape->pos[i] == nullptr)
119             return;
120     }
121     
122     //人物图形资源导入
123     //data
124     for (int i = 0; i < shape->count; i++)
125         shape->data[i] = shapeRes[i];
126     //pos
127     int x = GetX(); int y = GetY();
128     shape->pos[0][0] = x;
129     shape->pos[0][1] = y;
130     shape->pos[1][0] = x;
131     shape->pos[1][1] = y + 1;
132     shape->pos[2][0] = x - 1;
133     shape->pos[2][1] = y - 1;
134     shape->pos[3][0] = x - 1;
135     shape->pos[3][1] = y;
136     shape->pos[4][0] = x - 1;
137     shape->pos[4][1] = y + 1;
138     shape->pos[5][0] = x - 1;
139     shape->pos[5][1] = y + 2;
140 }
Dog.cpp
 1 #ifndef _CAVALRY_H_
 2 #define _CAVALRY_H_
 3 
 4 #include "AiRole.h"
 5 //================== 装甲车 ================
 6 
 7 class Cavalry : public AiRole
 8 {
 9 
10 public:
11     Cavalry(int lv, RaceType race, int x, int y);
12 
13 
14 public:
15     //===================行为函数 ==========================
16     virtual int AmountOfDamage(int atk);    //计算受到的伤害量
17 
18     virtual void OutputShout(int count){};    //打印喊话
19     virtual void InitShape(string str = "3D");    //导入人物图形
20     void ActiveAttack(Map*);                //发动攻击行为(使用道具、追击)
21     virtual bool CanDelete();            //可被释放
22 
23 private:
24     int m_fireTime;
25     int m_dTime;
26 };
27 
28 
29 #endif // _CAVALRY_H_
Cavalry.h
  1 #include "Cavalry.h"
  2 #include "..//Marco.h"
  3 #include "..//Body//Grenade.h"
  4 
  5 extern int GameTime;
  6 
  7 Cavalry::Cavalry(int lv, RaceType race, int x, int y)
  8     :AiRole(lv, race, ArmType::AT_Cavalry, x, y)
  9 {
 10     //防止等级越界
 11     if (GetLV() > 6)
 12         SetLV(6);
 13 
 14     this->SetHpMax(10000 + GetLV() * 5000);    //血量
 15     this->SetHpCur(10000 +GetLV() * 5000);    //血量
 16 
 17     this->SetMS(200);                    //移动速度增加
 18     this->InitShape();                    //导入图形数据
 19 
 20     Body* body = new Grenade(4,20);
 21     body->SetOwner(this);
 22     SetWeapon(body);
 23     SetDistance(body->GetExtent());
 24     SetName("[装甲车]");
 25     SetTip("拥有高护甲,高攻击...");
 26 
 27     m_fireTime = 0;
 28     m_dTime = 300;
 29 
 30 
 31     //说话的内容
 32     string** sapArr = GetDialogue();
 33     sapArr[0] = new string("轰隆!轰隆!");
 34     sapArr[1] = new string("轰隆!轰隆!");
 35     sapArr[2] = new string("轰隆!轰隆!");
 36 }
 37 
 38 
 39 
 40 
 41 //===================行为函数 ==========================
 42 //计算受到的伤害量
 43 int Cavalry::AmountOfDamage(int atk)
 44 {
 45     return (int)(atk * 0.7);
 46 }
 47 
 48 
 49 //获取人物图形
 50 void Cavalry::InitShape(string str)
 51 {
 52     //图形资源
 53     char shapeRes[7] = { "111%qq" };
 54     //━■■      
 55     //◎◎◎
 56     // |这是锚点
 57     //开辟人物图形数据内存
 58     Shape* shape = GetShape();
 59     shape->count = 6;
 60     shape->data = new char[shape->count];
 61     if (shape->data == nullptr) return;
 62 
 63     shape->pos = new int*[shape->count];
 64     if (shape->pos == nullptr) return;
 65 
 66     for (int i = 0; i < shape->count; i++)
 67     {
 68         shape->pos[i] = new int[2];
 69         if (shape->pos[i] == nullptr)
 70             return;
 71     }
 72 
 73 
 74     //人物图形资源导入
 75     //data
 76     for (int i = 0; i < shape->count; i++)
 77         shape->data[i] = shapeRes[i];
 78     //pos
 79     int x = GetX(); int y = GetY();
 80     shape->pos[0][0] = x;
 81     shape->pos[0][1] = y;
 82     shape->pos[1][0] = x;
 83     shape->pos[1][1] = y + 1;
 84     shape->pos[2][0] = x;
 85     shape->pos[2][1] = y + 2;
 86     shape->pos[3][0] = x - 1;
 87     shape->pos[3][1] = y;
 88     shape->pos[4][0] = x - 1;
 89     shape->pos[4][1] = y + 1;
 90     shape->pos[5][0] = x - 1;
 91     shape->pos[5][1] = y + 2;
 92 }
 93 
 94 //可被释放
 95 bool Cavalry::CanDelete()
 96 {
 97 if(    GameTime - m_fireTime >= m_dTime)
 98     return true;
 99 return false;
100 }
101 
102 //自动攻击(使用武器、追击)
103 void Cavalry::ActiveAttack(Map* pMap)
104 {
105     if (GetCondition() != BS_YES)
106         return;
107 
108     //攻击战斗列表的第一个元素(仇恨值最高的)
109     int x = GetObj()->GetX() - this->GetX();    //与目标的坐标差
110     int y = GetObj()->GetY() - this->GetY();    //与目标的坐标差
111     int dist = this->GetDistance();            //自己的射程
112 
113     //进入射程就攻击
114     if (x == 0 && y * y <= dist * dist)
115     {
116         if (GameTime % this->GetAts() == 0)
117         {
118             //--------转身面向目标--------
119             this->DirectToObj(pMap, GetObj());
120             this->AttackAction(pMap);
121             m_fireTime = GameTime;
122         }
123     }
124 
125     //否则,追击目标
126     else // (x * x + y * y > dist * dist )
127     {
128         if (GameTime % this->GetMS() == 0)
129         {
130             char ch;
131             if (x != 0)
132                 ch = x > 0 ? 's' : 'w';
133             else
134                 ch = y > 0 ? 'd' : 'a';
135 
136             this->RoleMove(pMap, ch);
137         }
138     }
139 }
Cavalry.cpp

派生【设计了一个Boss】

  Boss有4个战斗阶段

 1 #ifndef _BOSS_H_
 2 #define _BOSS_H_
 3 
 4 #include "AiRole.h"
 5 //================== 装甲车 ================
 6 
 7 class Boss : public AiRole
 8 {
 9 
10 public:
11     Boss(int x, int y);
12 
13 
14 public:
15     //===================行为函数 ==========================
16     virtual int AmountOfDamage(int atk);    //计算受到的伤害量
17 
18     virtual void OutputShout(int count){};    //打印喊话
19     virtual void InitShape(string str = "3D");//导入人物图形
20 
21     virtual void ActiveAttack(Map*);        //发动攻击行为(使用道具、追击)
22     virtual void BattlePart(Map*);            //阶段
23     virtual void RunAway(Map* pMap);        //逃跑行为
24     virtual void ChangeDirection(Map* pMap);//换方向
25 
26 private:
27 
28     int   m_part;            //阶段
29     Body* m_weapon1;        //武器1
30     Body* m_weapon2;        //武器2
31 };
32 
33 
34 #endif // _BOSS_H_
Boss.h
  1 #include "Boss.h"
  2 #include "..//Marco.h"
  3 #include "..//Body//PillBox.h"
  4 #include "..//Body//Pistol.h"
  5 #include "..//Body//Grenade.h"
  6 #include "..//Map//Map_1.h"
  7 
  8 
  9 //声明一个全局变量(模拟游戏时间)
 10 extern int GameTime;
 11 
 12 Boss::Boss(int x, int y)
 13     :AiRole(6, RT_IS, ArmType::AT_Boss, x, y)
 14 {
 15     //防止等级越界
 16     if (GetLV() > 6)
 17         SetLV(6);
 18 
 19     this->SetHpMax(1000000);        //血量
 20     this->SetHpCur(1000000);        //血量
 21     this->SetMS(50);                //移动速度增加
 22     this->InitShape();                //导入图形数据
 23 
 24     SetDistance(10);
 25     SetName("巴格达迪");
 26     SetTip("一名前伊斯兰大学教授,现IS“伊斯兰国”最高领导人。");
 27 
 28     //武器1 手枪
 29     m_weapon1 = new Pistol(9);
 30     m_weapon1->SetOwner(this);
 31     m_weapon1->SetHarm(2222);
 32     //武器2 机关枪
 33     m_weapon2 = new PillBox(9);
 34     m_weapon2->SetOwner(this);
 35     m_weapon2->SetHarm(6666);
 36 
 37     m_part = 1;            //第1阶段
 38     SetWeapon(m_weapon1);
 39 
 40 
 41     //说话的内容
 42     string** sapArr = GetDialogue();
 43     sapArr[0] = new string("小的们!快给我干掉他!");
 44     sapArr[1] = new string("啊...让你瞧瞧我的兜家底的武器!");
 45     sapArr[2] = new string("你真的让我很生气!看我厉害....");
 46 
 47 }
 48 
 49 
 50 
 51 
 52 //===================行为函数 ==========================
 53 //计算受到的伤害量
 54 int Boss::AmountOfDamage(int atk)
 55 {
 56     return (int)(atk * 0.8);
 57 }
 58 
 59 
 60 //获取人物图形
 61 void Boss::InitShape(string str)
 62 {
 63     //图形资源
 64     char shapeRes[11] = { "uuqqhqqgAB" };
 65     //  ()          
 66     //←■■→ 
 67     //  ■■
 68     //    ⊥⊥
 69     //开辟人物图形数据内存
 70     Shape* shape = GetShape();
 71     shape->count = 10;
 72     shape->data = new char[shape->count];
 73     if (shape->data == nullptr) return;
 74 
 75     shape->pos = new int*[shape->count];
 76     if (shape->pos == nullptr) return;
 77 
 78     for (int i = 0; i < shape->count; i++)
 79     {
 80         shape->pos[i] = new int[2];
 81         if (shape->pos[i] == nullptr)
 82             return;
 83     }
 84 
 85 
 86     //人物图形资源导入
 87     //data
 88     for (int i = 0; i < shape->count; i++)
 89         shape->data[i] = shapeRes[i];
 90     //pos
 91     int x = GetX(); int y = GetY();
 92     shape->pos[0][0] = x;
 93     shape->pos[0][1] = y;
 94     shape->pos[1][0] = x;
 95     shape->pos[1][1] = y + 1;
 96     shape->pos[2][0] = x - 1;
 97     shape->pos[2][1] = y;
 98     shape->pos[3][0] = x - 1;
 99     shape->pos[3][1] = y + 1;
100     shape->pos[4][0] = x - 2;
101     shape->pos[4][1] = y - 1;
102     shape->pos[5][0] = x - 2;
103     shape->pos[5][1] = y;
104     shape->pos[6][0] = x - 2;
105     shape->pos[6][1] = y + 1;
106     shape->pos[7][0] = x - 2;
107     shape->pos[7][1] = y + 2;
108     shape->pos[8][0] = x - 3;
109     shape->pos[8][1] = y;
110     shape->pos[9][0] = x - 3;
111     shape->pos[9][1] = y + 1;
112 }
113 
114 //换方向
115 void Boss::ChangeDirection(Map* pMap)
116 {
117     //不含方向
118 }
119 
120 
121 
122 //攻击行为(Boos有特效 根据生命值转阶段)
123 void Boss::BattlePart(Map* pMap)
124 {
125     int cur = this->GetHpCur();
126     int max = this->GetHpMax();
127 
128     //当生命之低于80时(且为1阶段时)  呼叫部队支援
129      if (m_part < 2 && (double)cur <= max * 0.8f)
130     {
131         pMap->AppendEnmeyTip(ArmType::AT_Spearman, 15, 16, 5, 500);
132         pMap->AppendEnmeyTip(ArmType::AT_Spearman, 15, 17, 5, 500);
133         pMap->AppendEnmeyTip(ArmType::AT_Spearman, 15, 18, 5, 500);
134         m_part++;
135     }
136     //当生命之低于60时(且为2阶段时)  Boss换装神器机关枪
137      else if (m_part < 3 && (double)cur <= max * 0.6f)
138     {
139         this->SetWeapon(m_weapon2);
140         m_part++;
141     }
142      //当生命之低于30时(且为3阶段时)  狂暴移动速度加快
143      else if (m_part < 4 && (double)cur <= max * 0.3f)
144      {
145          this->SetMS(10);
146          m_part++;
147      }
148 }
149 
150 
151 //自动攻击(使用武器、追击)
152 void Boss::ActiveAttack(Map* pMap)
153 {
154     if (GetCondition() != BS_YES)
155         return;
156 
157     //BOSS战斗阶段控制
158     if( m_part!=4 )this->BattlePart(pMap);
159 
160     //攻击战斗列表的第一个元素(仇恨值最高的)
161     int x = GetObj()->GetX() - this->GetX();    //与目标的坐标差
162     int y = GetObj()->GetY() - this->GetY();    //与目标的坐标差
163     int dist = this->GetDistance();            //自己的射程
164 
165     //进入射程就攻击
166     if ( abs(x) <= 1 && y * y <= dist * dist)
167     {
168         if (GameTime % this->GetAts() == 0)
169         {
170             //--------转身面向目标--------
171             this->DirectToObj(pMap, GetObj());
172             this->AttackAction(pMap);
173         }
174     }
175 
176     //否则,追击目标
177     else // (x * x + y * y > dist * dist )
178     {
179         if (GameTime % this->GetMS() == 0)
180         {
181             char ch;
182             if (x != 0)
183                 ch = x > 0 ? 's' : 'w';
184             else
185                 ch = y > 0 ? 'd' : 'a';
186 
187             this->RoleMove(pMap, ch);
188         }
189     }
190 }
191 
192 
193 //无逃跑行为
194 void Boss::RunAway(Map* pMap)
195 {
196 
197 }
Boss.cpp

 

posted @ 2017-06-27 23:50  ariboy  阅读(655)  评论(0编辑  收藏  举报