【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_
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 }
派生【 玩家类】
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_
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 }
派生【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_
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派生【各种敌人类】
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_
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 }
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_
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 }
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_
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 }
派生【设计了一个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_
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 }