【C++第一个Demo】---控制台RPG游戏4【角色系统】
【角色基类】
#ifndef _ROLE_H_
#define _ROLE_H_ #include<list>
#include<vector>
#include "..//Marco.h"
class Tip;
class Body;
class Backpack;
class TaskList;
class GameOI;
class Map;
class Task;
using namespace std; // =========================角色抽象类===========================
class Role
{
public://人物的形状
struct Shape
{
Shape()
{
data = nullptr;
pos = nullptr;
count = ;
}
~Shape()
{ if (data != nullptr)
{
delete[] data;
data = nullptr;
} for (int i = ; i < count; i++)
{
if (pos[i] != nullptr)
{
delete[] pos[i];
pos[i] = nullptr;
}
} if (pos != nullptr) return;
{
delete[] pos;
pos = nullptr;
} } char* data; //形状字符
int** pos; //坐标
int count; //组合图形个数
}; public:
Role(int lv, RaceType, ArmType, int x, int y);
virtual ~Role(); public:
//===================角色行为函数 ==========================
virtual void AttackAction(Map* pMap); //攻击行为
virtual void BeHit(Role* role,int atk,Map* pMap) = ; //受到伤害 virtual void RoleHandle(){}; //角色的操作杆
virtual void OutputInfo(int x, int y) {}; //打印人物界面
virtual void OutputTip(int x, int y); //打印简介
virtual void OutputShout(int count){}; //打印喊话 virtual void OutputRoleOI() = ; //打印人物OI上的信息图形
virtual void OutputRoleBloodBar(int x, int y);//打印人物血条
virtual void OutputRoleExpBar(int x, int y){};//打印人物经验 virtual void OutputRole(Map* pMap); //打印人物图形
virtual void RemoveRole(Map* pMap); //清除人物图形
virtual void EquipSurface(){}; //装备外观(换装备就换外观)
virtual void RoleMove(Map* pMap, char); //角色移动
virtual void ChangeDirection(Map* pMap); //换方向
virtual bool PreRoleMove(Map* pMap, char); //角色预移动
//virtual bool PreChangeDirection(Map* pMap);//预换方向
virtual void EffectRemove(Body* pBody); //Effect的移除
virtual void EffectAppend(Body* pBody, Map* pMap);//Effect的添加
virtual void CheckEffect(); //效果检测 virtual void UpdateRoleSight(Map* pMap){}; //更新角色视野
virtual bool JudgeSight(Map* pMap,int x,int y){ return true; }//视野判断
virtual void ImplementAIAction(Map* pMap, list<Role*>* pObj) = ; //================== 纯虚函数 ==============================
virtual int CausedByDamage() { return m_atkBase; }//计算制造的伤害量
virtual int AmountOfDamage(int atk){ return atk; }//计算受到的伤害量
virtual Backpack* GetBackpack(){ return nullptr; }
virtual TaskList* GetTaskList(){ return nullptr; }
virtual GameOI* GetGameOI(){ return nullptr; }
virtual void InitShape(string) = ; //导入人物图形(3D 2D)
virtual int GetExtent(){ return ; } //获取武器射程
virtual void UnderAttack(Role*, int){};
virtual void PushbackTask(Task* task){}; //添加新任务
virtual void SetExpCur(int exp){};
virtual int GetExpCur(){ return ; };
virtual void SetExpMax(int exp){};
virtual int GetExpMax(){ return ; };
virtual bool CanDelete(){ return true; }//可被释放
//喊话
virtual void GetSay(Map* pMap){}; private:
//================== 基础属性 ==============================
CC_PROPERTY_READ_ONLY(char*, m_name, Name); //名字
public: void SetName(char* name); private:Tip* m_tip; //人物简介
public: void SetTip( char* str); //设置简介 CC_PROPERTY(char, m_direct, Direct); //方向
CC_PROPERTY(int, m_x, X); //坐标x
CC_PROPERTY(int, m_y, Y); //坐标y CC_PROPERTY_READ_ONLY(const int, c_x, CX); //刷新点坐标x
CC_PROPERTY_READ_ONLY(const int, c_y, CY); //刷新点坐标y CC_PROPERTY_READ_ONLY(int, m_hpCur, HpCur); //当前血量
virtual void SetHpCur(int dHp); //设置当前血量
CC_PROPERTY(int, m_hpMax, HpMax); //最大血量
CC_PROPERTY(int, m_liveCount, LiveCount); //生命次数
CC_PROPERTY(int, m_sight, Sight); //视力范围
CC_PROPERTY(int, m_atkCur, AtkCur); //当前攻击力
CC_PROPERTY(int, m_atkBase, AtkBase); //基本攻击力
CC_PROPERTY(int, m_def, Def); //防御力
CC_PROPERTY(int, m_money,Money); //金钱 CC_PROPERTY(int, m_distance, Distance); //攻击范围
CC_PROPERTY(int, m_ats, Ats); //攻击速度
CC_PROPERTY(int, m_ms, MS); //水平速度
CC_PROPERTY(int, m_mg, MG); //重向速度
CC_PROPERTY(int, m_lv, LV); //等级
CC_PROPERTY(ArmType, m_armType, Arm); //兵种
CC_PROPERTY_READ_ONLY(Shape*,m_shape,Shape) //形状
CC_PROPERTY(RaceType, m_race, Race); //国籍
CC_PROPERTY(bool, m_suspend, Suspend); //悬挂状态(悬空true) //效果的列表(装备、道具产生的效果)
CC_PROPERTY(list<Body*>*, m_effectList, EffectList);
}; #endif // ! _ROLE_H_
Role.h
#include "..//Tip.h"
#include "Role.h"
#include "..//Task//Task.h"
#include "..//Body/BloodNum.h"
#include "..//Map//Map.h"
using namespace std;
extern int GameTime; Role::Role(int lv, RaceType race, ArmType arm, int x, int y)
:c_x(x), c_y(y)
{
//主动初始化属性
m_lv = lv;
m_race = race;
m_armType = arm;
m_shape = new Shape;
m_direct = 'a';
m_x = x;
m_y = y;
//默认属性
m_sight = ;
m_distance = ; //攻击距离1(近战距离)
m_ms = ; //水平速度
m_mg = ; //重向速度
m_name = nullptr; m_tip = new Tip;
m_hpCur = + m_lv * ;
m_hpMax = m_hpCur;
m_liveCount = ;
m_atkBase = m_lv * + ;
m_atkCur = m_atkBase;
m_ats = ;
m_def = m_lv * ;
m_money = m_lv * ;
m_suspend = false; m_effectList = new list < Body* > ;
} Role::~Role()
{
if (m_name != nullptr)
{
delete[] m_name;
m_name = nullptr;
} if (m_tip != nullptr)
{
delete m_tip;
m_tip = nullptr;
} if (m_shape != nullptr)
{
delete m_shape;
m_shape = nullptr;
} if (m_effectList != nullptr)
{
delete m_effectList;
m_effectList = nullptr;
} }
//===================角色行为函数(外部接口) ========================== //攻击行为
void Role::AttackAction(Map* pMap)
{ } //打印人物血条
void Role::OutputRoleBloodBar(int x, int y)
{
//遍历血条
int count = (int)((double)m_hpCur / (double)m_hpMax * 20.0f);//当前血量值
GotoXY(x, y);
for (int i = ; i < ; i++)
{
if(count <= )//血量少于30%
i < count ? Color(CT_Red, CT_White) : Color(CT_Grey, CT_White);
else if(count<= )//血量少于70%
i < count ? Color(CT_Yellow, CT_White) : Color(CT_Grey, CT_White);
else //血量大于30%
i < count ? Color(CT_Green, CT_White) : Color(CT_Grey, CT_White);
cout << " ";
}
Color(CT_White, CT_Black);
} //打印人物图形
void Role::OutputRole(Map* pMap)
{
char* shapeData = m_shape->data;
int** shapePos = m_shape->pos;
int shapeCount = m_shape->count; for (int i = ; i < shapeCount; i++)
{
pMap->GetRoleLayer()[shapePos[i][]][shapePos[i][]] = shapeData[i];
pMap->OutputMap(shapePos[i][], shapePos[i][]);
} //打印人物坐标
GotoXY(, );
printf("< %2d / %2d >", shapePos[][], shapePos[][]);
} //清除人物图形
void Role::RemoveRole(Map* pMap)
{
char* shapeData = m_shape->data;
int** shapePos = m_shape->pos;
int shapeCount = m_shape->count; for (int i = ; i < shapeCount; i++)
{
pMap->GetRoleLayer()[shapePos[i][]][shapePos[i][]] = '';
pMap->OutputMap(shapePos[i][], shapePos[i][]);
}
} //角色移动
void Role::RoleMove(Map* pMap, char direct)
{
if (GameTime% m_ms != )
return; if (direct == ) direct = 'w';
else if (direct == ) direct = 's';
else if (direct == ) direct = 'a';
else if (direct == ) direct = 'd'; int** shapePos = m_shape->pos;
int shapeCount = m_shape->count; this->RemoveRole(pMap); if ((direct == 'a' || direct == 'd') && m_direct != direct)
{
m_direct = direct;
this->ChangeDirection(pMap);
this->OutputRole(pMap);
return;
} int dX = , dY = ;
switch (direct)
{
case 'w': if (pMap->FeasibleRegion(m_x - , m_y)) dX = -; break;
case 's': if (pMap->FeasibleRegion(m_x + , m_y)) dX = ; break;
case 'a': if (pMap->FeasibleRegion(m_x, m_y - )) dY = -; break;
case 'd': if (pMap->FeasibleRegion(m_x, m_y + )) dY = ; break;
} m_x += dX; m_y += dY;
for (int i = ; i < shapeCount; i++)
{
shapePos[i][] += dX;
shapePos[i][] += dY;
} this->UpdateRoleSight(pMap); //更新角色视野
this->OutputRole(pMap);
} //换方向
void Role::ChangeDirection(Map* pMap)
{
int** shapePos = m_shape->pos;
int shapeCount = m_shape->count; //以锚点Y坐标翻转图形
for (int i = ; i < shapeCount; i++)
shapePos[i][] = * shapePos[][] - shapePos[i][];
} //角色预移动
bool Role::PreRoleMove(Map* pMap, char direct)
{
int** shapePos = m_shape->pos; int dX = , dY = ; switch (direct)
{
case 'w': dX = -; break;
case 's': dX = ; break;
case 'a': dY = -; break;
case 'd': dY = ; break;
} int preX = m_x + dX;
int preY = m_y + dY; //角色在地图中移动后位置判断
//if (pMap->FeasibleRegion(preX, preY))
// return true; char** backLayer = pMap->GetBackLayer();
if (backLayer[preX][preY] == 'q'|| backLayer[preX][preY] == 'm')
return false;
return true;
} ////预换方向
//bool Role::PreChangeDirection(Map* pMap)
//{
// int** shapePos = m_shape->pos;
// int shapeCount = m_shape->count;
//
// //预旋转的图像
// int** preShape = GetIntMemory(shapeCount ,2 );
//
// //以锚点Y坐标翻转预旋转
// for (int i = 0; i < shapeCount; i++)
// {
// preShape[i][0] = shapePos[i][0];
// preShape[i][1] = 2 * shapePos[0][1] - shapePos[i][1];
// }
//
// char** backLayer = pMap->GetBackLayer();
// for (int i = 0; i < shapeCount; i++)
// {
// if (backLayer[preShape[i][0]][preShape[i][1]] == 'q'\
// || backLayer[preShape[i][0]][preShape[i][1]] == 'm')
// {
// DeleteIntMemory(preShape, shapeCount);
// return false;
// }
// }
// DeleteIntMemory(preShape, shapeCount);
// return true;
//} //=================== 属性操作函数(内部专用) ======================================
//设置人名
void Role::SetName(char* name)
{
if (name == nullptr) return; if (m_name != nullptr)
{
if (strlen(m_name) >= strlen(name))
{
strcpy(m_name, name);
return;
}
delete[] m_name;
} m_name = new char[strlen(name) + ];
strcpy(m_name, name);
} //设置tip信息
void Role::SetTip(char* str)
{
//str是内容, weith 是信息宽度
m_tip->SetTip(str, );
} //打印tip信息
void Role::OutputTip(int x, int y)
{
m_tip->OutputTip(x, y);
} //设置血量(不能小于0, 不能大于HpMax)
void Role::SetHpCur(int dHp)
{
if (dHp < )
m_hpCur = ;
else if (dHp > m_hpMax)
m_hpCur = m_hpMax;
else
m_hpCur = dHp;
} //Effect的移除
void Role::EffectRemove(Body* pBody)
{
pBody->RemoveEffect(this);
} //Effect的添加
void Role::EffectAppend(Body* pBody,Map* pMap)
{
pBody->AppendEffect(this,pMap);
} //效果检测
void Role::CheckEffect()
{
list<Body*>::iterator iBegin = m_effectList->begin(); while (iBegin != m_effectList->end())
{
//如果物品产生无效,移除该物体
if (!(*iBegin)->CheckEffect())
{
this->EffectRemove(*iBegin); //移除物品效果
iBegin = m_effectList->erase(iBegin);
continue;
}
iBegin++;
}
}
Role.cpp
派生【 玩家类】
#ifndef _HERO_H_
#define _HERO_H_ #include "Role.h"
#include "..//Task//TaskList.h"
class GameOI;
class Equip; class Hero : public Role
{
public:
////武器熟练度(0% - 100% 决定命中率)
//struct WeaponPy
//{
// double WP_Dagger; //匕首
// double WP_Pistol; //手枪
// double WP_Pillbox; //机关枪
// double WP_SniperRifle; //狙击枪
//}; public:
Hero(int lv, RaceType race, int x, int y);
~Hero(); public:
virtual int CausedByDamage() ; //计算制造的伤害量
virtual int AmountOfDamage(int atk) ; //计算受到的伤害量
virtual void BeHit(Role* role,int atk, Map* pMap);
virtual void OutputRoleOI(); //打印人物OI上的信息图形 virtual void InitShape(string ); //导入人物图形
virtual void EquipSurface(); //装备外观(换装备就换外观) virtual void UpdateRoleSight(Map* pMap);//更新角色视野
virtual bool JudgeSight(Map* pMap, int x, int y); //视野判断 virtual int GetExtent(); //获取武器射程
virtual void ImplementAIAction(Map* pMap, list<Role*>* pObj){}; //virtual void SetHpCur(int dHp); //设置当前血量
virtual void OutputRoleExpBar(int x, int y);//打印人物经验
private: CC_PROPERTY(double, m_EVA, EVA); //身手(闪避)
//CC_PROPERTY(WeaponPy, m_weaponPy, WeaponPy) //武器熟练度 CC_PROPERTY(int, m_expMax, ExpMax); //升经验
CC_PROPERTY_READ_ONLY(int, m_expCur, ExpCur); //当前经验
void SetExpCur(int exp); //设置经验(升级,更改基础属性) //OI界面
CC_PROPERTY(GameOI*, m_gameOI, GameOI); //OI界面 // 背包
CC_PROPERTY(Backpack*, m_backpack, Backpack); //背包 // 任务列表
public:
virtual void PushbackTask(Task* task); //添加新任务 CC_PROPERTY(TaskList*, m_taskList, TaskList); //任务列表
}; #endif //_HERO_H_
Hero.h
#include "Hero.h"
#include "..//Backpack//Backpack.h"
#include "..//Body/BloodNum.h"
#include "..//GameMgr//GameOI.h"
#include "..//Body//Body.h"
#include "..//Map//Map.h" // 等级 国籍 坐标x 坐标y
Hero::Hero(int lv, RaceType race, int x, int y)
:Role(lv, race, ArmType::AT_Hero, x, y)
{
m_EVA = ; //身手,闪避率初始0
SetLiveCount();
m_expCur = ;
m_expMax = GetLV() * ;
SetHpMax( + GetLV() * );
SetHpCur( + GetLV() * ); this->InitShape("3D"); //背包、物品栏、任务列表
m_backpack = new Backpack(this);
m_taskList = new TaskList(this);
m_gameOI = new GameOI(this);
} Hero::~Hero()
{
if (m_backpack != nullptr)
{
delete m_backpack;
m_backpack = nullptr;
} if (m_gameOI != nullptr)
{
delete m_gameOI;
m_gameOI = nullptr;
}
} //计算制造的伤害量
int Hero::CausedByDamage()
{
Body** bodyArr = m_gameOI->GetBodyArr();
//return bodyArr[0]->BeUse(this);
return ;
} //计算受到的伤害量
int Hero::AmountOfDamage(int atk)
{
int harm = atk - GetDef() > ? atk - GetDef() : ; return harm;
} //受到伤害
void Hero::BeHit(Role* role, int atk, Map* pMap)
{
int harm = AmountOfDamage(atk);
this->SetHpCur(GetHpCur() - harm); //在头顶创造一个血字
int x = GetX(); int y = GetY();
Body* body = new BloodNum(this, x - , y, - * harm);
pMap->GetBodyTmpList()->push_back(body); //显示血字
GotoXY(x - , y);
Color(CT_White, CT_Red);
cout << - * harm; //更新血条
this->OutputRoleBloodBar(, );
} //打印人物OI上的信息图形
void Hero::OutputRoleOI()
{
Color(CT_White, CT_Black);
GotoXY(, ); cout << "【" << this->GetName() << "】";
GotoXY(, ); printf(" %2d 级", this->GetLV());
this->OutputRoleBloodBar(, );
this->OutputRoleExpBar(, );
GotoXY(, );//打印人物坐标
printf("< %2d / %2d >", this->GetX(), this->GetY());
} //获取人物图形
void Hero::InitShape(string str)
{
if (str == "3D")
{
//3D图形资源
char shapeRes[] = { "u95x" };
// ○ ○
//╤□ ■╤
// ⊥ ⊥
// |这是锚点 //开辟人物图形数据内存
Shape* shape = GetShape();
shape->count = ;
shape->data = new char[shape->count];
if (shape->data == nullptr) return; shape->pos = new int*[shape->count];
if (shape->pos == nullptr) return; for (int i = ; i < shape->count; i++)
{
shape->pos[i] = new int[];
if (shape->pos[i] == nullptr)
return;
} //人物图形资源导入
//data
for (int i = ; i < shape->count; i++)
shape->data[i] = shapeRes[i];
//pos
int x = GetX(); int y = GetY();
shape->pos[][] = x;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = GetDirect() == 'a' ? y - : y + ;
} else if (str == "2D")
{
//2D图形资源
char shapeRes[] = { "xxxx" };
//开辟人物图形数据内存
Shape* shape = GetShape();
shape->count = ;
shape->data = new char[shape->count];
if (shape->data == nullptr) return; shape->pos = new int*[shape->count];
if (shape->pos == nullptr) return; for (int i = ; i < shape->count; i++)
{
shape->pos[i] = new int[];
if (shape->pos[i] == nullptr)
return;
} //人物图形资源导入
//data
for (int i = ; i < shape->count; i++)
shape->data[i] = shapeRes[i];
//pos
for (int i = ; i < shape->count; i++)
{
shape->pos[i][] = GetX();
shape->pos[i][] = GetY();
}
}
} //装备外观(换装备就换外观)
void Hero::EquipSurface()
{
// ○ ○
//╤□ ■╤
// ⊥ ⊥
// 2号衣服、4号武器
//□9■q ╤& —% char* shapeData = GetShape()->data;
Body** bodyBar = m_gameOI->GetBodyArr();
//物品栏1武器、6衣服
shapeData[] = (bodyBar[] == nullptr ? 'x' : '&');
shapeData[] = (bodyBar[] == nullptr ? '' : 'q'); }
//获取武器射程
int Hero::GetExtent()
{
Body** bodyBar = m_gameOI->GetBodyArr(); if (bodyBar[] == nullptr)
return ; return bodyBar[]->GetExtent();
} //更新角色视野
void Hero::UpdateRoleSight(Map* pMap)
{
if (pMap->GetIsDay())
return; //地图属性
bool** MapSight = pMap->GetSightLayer(); //人物属性
int sight = this->GetSight();
int x = GetX();
int y = GetY(); //-----视野范围----------------------------
int SmallX = x - sight > ? x - sight : ;
int BigX = x + sight < ? x + sight : ;
int SmallY = y - sight > ? y - sight : ;
int BigY = y + sight < ? y + sight :; //----循环打印,可见区域--------------------
for (int row = SmallX - x; row <= BigX - x; row++)
{
for (int colu = SmallY - y; colu <= BigY - y; colu++)
{
bool befor = MapSight[row + x][colu + y]; //原来情况
bool back = JudgeSight(pMap, row, colu); //后来情况
//如果该位置视野情况发生变化(重新打印该位置)
if (befor != back)
{
MapSight[row + x][colu + y] = back;
pMap->OutputMap(row + x, colu + y);
}
}
}
} //视野判断
bool Hero::JudgeSight(Map* pMap, int x, int y)
{
//递增递减判断
int dX = x > ? : -;
int dY = y > ? : -;
//人物视野
int sight = this->GetSight();
//地图背景层
char** backLayer = pMap->GetBackLayer(); //在圆形范围内--------
if (x* x+ y* y< (sight - )* (sight - ))
{
//显示所有的墙
if (backLayer[x + GetX()][y + GetY()] == ''&& pMap->GetType() == "2D")
return true; if (y == ) //****这种情况下,直线没有斜率
{
for (int row = ; dX * row <= dX * x; row += dX)//遍历2点之间是否存在障碍物
{
//如果遍历到最后1个,就说明没障碍物
if (row == x)
return true; //有障碍物,标记为阴影区
if (backLayer[row + GetX()][GetY()] == ''&& pMap->GetType() == "2D")
return false;
}
}
else //当COLU != 0时,计算斜率,模拟缓冲区判断
{
//该点与角色位置的线性方程为: row = ratio * col
double ratio = (double)x / (double)y; //计算线性方程的系数
double d = sqrt(ratio * ratio + ) / ; //缓冲区半径 for (int row = ; dX * row <= dX * x; row += dX)
{
for (int col = ; dY*col <= dY*y; col += dY)
{
//如果遍历到最后一个,就说明没障碍物
if ((row == x) && (col == y))
return true;
//在缓冲范围内 且有障碍物
if (row <= ratio* col + d && row >= ratio* col - d
&& (backLayer[row + GetX()][col + GetY()] == '') && pMap->GetType() == "2D")
return false;
}
}
}
}
//其他情况都为阴影区
return false;
} //设置经验(升级,更改基础属性)
void Hero::SetExpCur(int exp)
{
//升级
if (exp >= m_expMax)
{
int lv = GetLV();
SetLV( ++lv );
m_expCur = exp - m_expMax;
m_expMax = lv * ;
SetHpMax( + lv * );
SetHpCur( + lv * );
SetAtkBase(lv * + );
SetAtkCur(lv * + );
SetDef(lv * ); //升级,更新整个OI
this->OutputRoleOI();
return;
} m_expCur = exp;
//未升级,只更新经验条
this->OutputRoleExpBar(, );
} //打印人物经验
void Hero::OutputRoleExpBar(int x, int y)
{
//遍历经验条
int count = (int)((double)m_expCur / (double)m_expMax * 94.0f);//当前血量值 GotoXY(x, y);
for (int i = ; i < ; i++)
{
i < count ? Color(CT_Blue, CT_White) : Color(CT_Grey, CT_White); cout << " ";
}
Color(CT_White, CT_Black);
} //添加新任务
void Hero::PushbackTask(Task* task)
{
m_taskList->PushBackTask(task);
}
Hero.cpp
派生【Ai角色】 会逃跑、追击、喊话(多个敌对目标会有仇恨列表,目前没法测试)
#ifndef _AI_ROLE_H_
#define _AI_ROLE_H_ #include <list>
#include "Role.h"
using namespace std;
class Map; //========== AI系统 ===========
//00怪物自发性动作
//2 停留、行走、警戒
//每个2个停留点之间的连线是行走路径
//怪物在行走过程中搜寻进入范围的目标触发反应事件 //00怪物反应事件判断:
//1 目标选取判断 2 战斗道具使用判断 3 追击判定 4 逃跑判定 class AiRole : public Role
{
public://攻击列表节点
struct Node
{
Node(Role* pObj)
{
obj = pObj; //目标
hatred = ; //初始仇恨
}
Role* obj;
int hatred;
}; public:
AiRole(int lv, RaceType race, ArmType arm, int x, int y);
~AiRole(); public://=========== AI操作外部接口 =============================
void ImplementAIAction(Map* pMap, list<Role*>* pObj);//执行AI行为(与地图、所有敌人list的交互) //触发事件判断和行为(对战斗列表的自动操作)
void PatrolAction(Map* pMap, list<Role*>* pObj); //巡逻行为
bool JudgeAlertArea(char** pMap, Role* pObj); //判断是否进入警戒范围
void UnderAttack(Role* Obj, int atk); //被攻击触发
void SortAttackListByHatred(); //跟据仇恨值更新攻击列表
virtual void ActiveAttack(Map*); //发动攻击行为(使用道具、追击)
void TimeLapse(); //列表第1位,超出警戒范围仇恨减少(时间推移)
virtual void RunAway(Map* pMap); //逃跑行为
virtual void DirectToObj(Map* pMap, Role* Obj); //转向面对目标
virtual void AttackAction(Map* pMap); //攻击行为
virtual int GetExtent(); //获取武器射程 void OutputRole(Map* pMap); //打印人物图形
virtual void OutputRoleOI(); //打印人物OI上的信息图形
virtual void BeHit(Role* role, int atk, Map* pMap); //受到伤害 //喊话
virtual void GetSay(Map* pMap); public://战斗状态
enum BattleState
{
BS_YES, //战斗中
BS_NO, //非战斗
BS_RUN, //惊慌逃跑
}; private:// ============ 私有属性 ===============================
CC_PROPERTY(Body*,m_weapon,Weapon); //武器
CC_PROPERTY(Role*, m_obj, Obj); //当前目标 CC_PROPERTY(list<Node*>*, m_attackList,AttackList); //攻击列表
CC_PROPERTY(int, m_alertArea, AlertArea); //警戒范围
CC_PROPERTY(BattleState, m_condition, Condition); //战斗状态 CC_PROPERTY(string**, m_dalogue, Dialogue); //说的所有话
CC_PROPERTY(int, m_dialIndex, DialIndex); //当前说的话 }; #endif // _AI_ROLE_H_
AiRole.h
#include "AiRole.h"
#include "..//Map//Map.h"
#include "..//Body/BloodNum.h"
#include "..//Body//Say.h" //声明一个全局变量(模拟游戏时间)
extern int GameTime; AiRole::AiRole(int lv,RaceType race,ArmType arm,int x, int y)
:Role(lv,race,arm,x,y)
{
SetMS();
m_alertArea = ; //默认警戒范围
m_attackList = nullptr; //开始置空
m_condition = BS_NO; //非战斗
m_weapon = nullptr;
m_obj = nullptr; SetHpMax( + GetLV() * );
SetHpCur( + GetLV() * ); m_dalogue = new string*[];
for (int i = ; i < ; i++)
m_dalogue[i] = nullptr;
m_dialIndex = ;
} AiRole::~AiRole()
{
if (m_attackList == nullptr)
return; //遍历释放战斗list中所有的Node*
list<Node*>::iterator iBegin;
for (iBegin = m_attackList->begin(); iBegin != m_attackList->end();iBegin++)
{
delete *iBegin;
*iBegin = nullptr;
}
//释放战斗列表
delete m_attackList;
m_attackList = nullptr;
} //========= 执行AI行为 外部接口函数 =====================================
// 执行AI行为(警戒巡逻、被攻击触发、自动更新战斗列表、自动移除目标、自动追击、自动逃跑)
void AiRole::ImplementAIAction(Map* pMap, list<Role*>* pObj)
{
//非战斗状态时
if (m_attackList == nullptr)
this->PatrolAction(pMap, pObj); //巡逻(里面含有 判断警戒范围) //战斗状态时
else if (m_attackList != nullptr)
{
this->SortAttackListByHatred(); //跟据仇恨值更新攻击列表
this->ActiveAttack(pMap); //自动攻击(使用武器、追击)
this->RunAway(pMap); //逃跑行为
}
} //被攻击触发(如果没有该角色,添加进战斗列表,有就仇恨增加)
void AiRole::UnderAttack(Role* Obj, int atk)
{
unsigned int dHatred = atk / + ; // 每5点伤害产生1点仇恨值 if (m_attackList != nullptr)
{
list<Node*>::iterator iBegin;
for (iBegin = m_attackList->begin(); iBegin != m_attackList->end(); iBegin++)
{ //如果该角色以在战斗列表
if ((*iBegin)->obj == Obj)
{
(*iBegin)->hatred += dHatred; //仇恨修改
return;
}
}
}
else
{
m_attackList = new list < Node* > ; //战斗列表开辟内存
m_condition = BS_YES; //战斗状态
} //添加该角色到战斗列表
Node* pNode = new Node(Obj); //用当前对象定义一个节点
pNode->hatred += dHatred;
m_attackList->push_back(pNode); //添加当前结点
} //============== 内部操作判断 函数 ================ //巡逻动作
void AiRole::PatrolAction(Map* pMap, list<Role*>* pObj)
{
char** map = pMap->GetBackLayer(); //用迭代器遍历目标list(查找第一个进入警戒范围的目标)
list<Role*>::iterator iBegin;
for (iBegin = pObj->begin(); iBegin != pObj->end(); iBegin++)
{
//如果找到目标进入警戒范围且有视野(就添加进战斗列表,更改角色状态进入战斗)
if (this->JudgeAlertArea(map, *iBegin))
{
m_attackList = new list < Node* > ; //战斗列表开辟内存
Node* pNode = new Node(*iBegin); //用当前对象定义一个节点
m_attackList->push_back(pNode); //添加当前结点 this->DirectToObj(pMap, *iBegin); //转身面向目标 m_condition = BS_YES; //战斗状态
return;
}
}
} //判断是否进入警戒范围(在当前地图上判断是否有视野)
bool AiRole::JudgeAlertArea(char** pMap, Role* pObj)
{
int thisX = this->GetX(); //自己的x坐标
int thisY = this->GetY(); //自己的y坐标
int x = pObj->GetX() - thisX; //与目标的坐标差
int y = pObj->GetY() - thisY; //与目标的坐标差 //在警戒范围内
if (x * x + y * y <= (m_alertArea - )* (m_alertArea))
return true;
else //if ((x * x + y * y) > (m_alertArea - 1) * m_alertArea)
return false;
} //跟据仇恨值更新攻击列表
void AiRole::SortAttackListByHatred()
{
//------根据仇恨值排序战斗列表-----
m_attackList->sort(); // ???? hatred 排序方法 //------仇恨为0移出战斗列表-----
list<Node*>::iterator iBegin = m_attackList->begin();//用迭代器遍历目标list(查找目标)
m_obj = (*iBegin)->obj; //更新当前目标//攻击战斗列表的第一个元素(仇恨值最高的) for (; iBegin != m_attackList->end(); iBegin++)
{
if (!(*iBegin)->hatred) //如果仇恨值为0(就移除战斗列表)
{
iBegin = m_attackList->erase(iBegin); //移除该结点 if (m_attackList->empty()) //当列表为empty时,释放列表内存,更改角色为非战斗状态
{
m_condition = BS_NO; //设置非战斗状态
delete m_attackList; //释放战斗列表内存
m_attackList = nullptr; //战斗列表置null
return;
}
}
}
} //超出警戒范围时间推移(仇恨减少)
void AiRole::TimeLapse()
{
int dx = m_obj->GetX() - this->GetCX();
int dy = m_obj->GetY() - this->GetCY(); //超出警戒范围
if (dx*dx + dy * dy > m_alertArea * m_alertArea)
{
if (GameTime % == )
{
int hat = m_attackList->front()->hatred; m_attackList->front()->hatred = hat > ? hat - : ;
}
}
} //自动攻击(使用武器、追击)
void AiRole::ActiveAttack(Map* pMap)
{
if (m_condition != BS_YES)
return; //攻击战斗列表的第一个元素(仇恨值最高的)
int x = m_obj->GetX() - this->GetX(); //与目标的坐标差
int y = m_obj->GetY() - this->GetY(); //与目标的坐标差
int dist = this->GetDistance(); //自己的射程 //进入射程就攻击
if (x == && y * y <= dist * dist )
{
if (GameTime % this->GetAts() == )
{
//--------转身面向目标--------
this->DirectToObj(pMap,m_obj);
this->AttackAction(pMap);
}
} //否则,追击目标
else // (x * x + y * y > dist * dist )
{
if (GameTime % this->GetMS() == )
{
char ch;
if (x!= )
ch = x > ? 's' : 'w';
else
ch = y > ? 'd' : 'a'; this->RoleMove(pMap,ch);
}
}
} //逃跑行为
void AiRole::RunAway(Map* pMap)
{
//如果不是逃跑状态,血量低于20%总血量,就设定为逃跑状态
if (m_condition == BS_YES && this->GetHpCur() <= this->GetHpMax()*0.2)
m_condition = BS_RUN; //如果是逃跑状态,就指向逃跑程序
if (m_condition == BS_RUN)
{
//战斗列表的第一个元素(仇恨值最高的)
int y = m_obj->GetY() - this->GetY(); //与目标的坐标差 if (GameTime %( this->GetMS()/) == )
{
//向反方向移动
char ch = y > ? 'a' : 'd';
this->RoleMove(pMap,ch);
}
}
} //攻击行为
void AiRole::AttackAction(Map* pMap)
{
//无武器单位,徒手攻击
if (m_weapon == nullptr)
{
m_obj->BeHit(this,this->GetAtkCur(), pMap);
return;
} m_weapon->BeUse(pMap);
} //获取武器射程
int AiRole::GetExtent()
{
if (m_weapon == nullptr)
return ; int extent = m_weapon->GetExtent();
return extent;
} //打印人物图形
void AiRole::OutputRole(Map* pMap)
{
char* shapeData = GetShape()->data;
int** shapePos = GetShape()->pos;
int shapeCount = GetShape()->count; for (int i = ; i < shapeCount; i++)
{
pMap->GetRoleLayer()[shapePos[i][]][shapePos[i][]] = shapeData[i];
pMap->OutputMapOfEnemy(shapePos[i][], shapePos[i][]);
}
} //受到伤害
void AiRole::BeHit(Role* role, int atk, Map* pMap)
{
int harm = AmountOfDamage(atk);
this->SetHpCur(GetHpCur() - harm);
this->GetSay(pMap);//说话 //死亡获得经验
if (this->GetHpCur() == )
{
role->SetExpCur(role->GetExpCur() + this->GetLV() * );
role->SetMoney(role->GetMoney() + this->GetLV() * );
} //在头顶创造一个血字
int x = GetX(); int y = GetY();
Body* body = new BloodNum(this, x - , y,-* harm);
pMap->GetBodyTmpList()->push_back(body); //显示血字
GotoXY(x - , y);
Color(CT_White, CT_Red);
cout <<- * harm; //更新敌人OI
this->OutputRoleOI();
} //打印人物OI上的信息图形
void AiRole::OutputRoleOI()
{
Color(CT_White, CT_Black);
GotoXY(, ); cout << "【" << this->GetName() << "】";
GotoXY(, ); printf(" %2d 级", this->GetLV());
this->OutputRoleBloodBar(, );
GotoXY(, );//打印人物坐标
printf("< %2d / %2d >", this->GetX(), this->GetY());
} //转向面对目标
void AiRole::DirectToObj(Map* pMap, Role* Obj)
{
char direct = Obj->GetY() > this->GetY() ? 'd' : 'a';
if (direct != this->GetDirect())
{
this->RemoveRole(pMap);
this->SetDirect(direct);
this->ChangeDirection(pMap);
this->OutputRole(pMap);
}
} //喊话
void AiRole::GetSay(Map* pMap)
{
if (m_dalogue == nullptr)
return; //获取要说的话
double part = (double)GetHpCur() / (double)GetHpMax();
int x = this->GetX() - ; int y = this->GetY();
Body* sayCur = nullptr; if (m_dialIndex< && part <= 0.7f && part > 0.5f)
{
sayCur = new Say(this, x, y, m_dalogue[]);
m_dialIndex++;
}
else if (m_dialIndex< && part <= 0.5f && part > 0.2f)
{
sayCur = new Say(this, x, y, m_dalogue[]);
m_dialIndex++;
}
else if (m_dialIndex< && part <= 0.2f)
{
sayCur = new Say(this, x, y, m_dalogue[]);
m_dialIndex++;
} //创建对象到物品List,并打印显示
if (sayCur != nullptr)
{
pMap->GetBodyTmpList()->push_back(sayCur);
sayCur->OutputSelf(pMap);
}
}
AiRole.cpp
AiRole派生【各种敌人类】
#ifndef _SPEAR_MAN_H_
#define _SPEAR_MAN_H_ #include "AiRole.h"
//================== 枪兵 ================ class SpearMan : public AiRole
{ public:
SpearMan(int lv, RaceType race, int x, int y); public:
//===================行为函数 ==========================
virtual int AmountOfDamage(int atk); //计算受到的伤害量 virtual void OutputShout(int count); //打印喊话
virtual void InitShape(string str = "3D"); //导入人物图形 virtual void GetSay(Map* pMap); private:
bool m_isSay;
}; #endif // _SPEAR_MAN_H_
SpearMan.h
#include "SpearMan.h"
#include "..//Marco.h"
#include "..//Body//Pistol.h"
#include "..//Map//Map.h"
#include "..//Body//Say.h" SpearMan::SpearMan(int lv, RaceType race, int x, int y)
:AiRole(lv, race, AT_Spearman, x, y)
{
//防止等级越界
if (GetLV() > )
SetLV(); this->SetHpMax( + GetLV() * ); //血量
this->SetHpCur( + GetLV() * ); //血量 this->SetMS(GetMS() + GetLV() * ); //移动速度增加 this->InitShape(); //导入图形数据 Body* body = new Pistol();
body->SetOwner(this);
SetWeapon(body);
SetDistance(body->GetExtent());
SetName("[枪兵]");
SetTip("注意他们手上的枪!人面兽心,说的就是他们..."); //说话的内容
string** sapArr = GetDialogue();
sapArr[] = new string("啊... 啊...伊斯兰万岁!"); m_isSay = false;
} //===================行为函数 ========================== //计算受到的伤害量
int SpearMan::AmountOfDamage(int atk)
{
return atk;
} //打印喊话
void SpearMan::OutputShout(int count)
{
switch (count)
{
case : cout << "汪!汪!汪!……"; break;
case : cout << "嗷!嗷!嗷!……"; break;
case : cout << "嗷!嗷!嗷!……"; break;
}
} //获取人物图形
void SpearMan::InitShape(string str)
{
if (str == "3D")
{
//图形资源
char shapeRes[] = { "uq5&" };
// ○ ○
//╤□ ■╤
// ⊥ ⊥
// |这是锚点
//开辟人物图形数据内存
Shape* shape = GetShape();
shape->count = ;
shape->data = new char[shape->count];
if (shape->data == nullptr) return; shape->pos = new int*[shape->count];
if (shape->pos == nullptr) return; for (int i = ; i < shape->count; i++)
{
shape->pos[i] = new int[];
if (shape->pos[i] == nullptr)
return;
} //人物图形资源导入
//data
for (int i = ; i < shape->count; i++)
shape->data[i] = shapeRes[i];
//pos
int x = GetX(); int y = GetY();
shape->pos[][] = x;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y - ;
}
else if (str == "2D")
{
//2D图形资源
char shapeRes[] = { "++++" };
//开辟人物图形数据内存
Shape* shape = GetShape();
shape->count = ;
shape->data = new char[shape->count];
if (shape->data == nullptr) return; shape->pos = new int*[shape->count];
if (shape->pos == nullptr) return; for (int i = ; i < shape->count; i++)
{
shape->pos[i] = new int[];
if (shape->pos[i] == nullptr)
return;
} //人物图形资源导入
//data
for (int i = ; i < shape->count; i++)
shape->data[i] = shapeRes[i];
//pos
for (int i = ; i < shape->count; i++)
{
shape->pos[i][] = GetX();
shape->pos[i][] = GetY();
}
}
} //喊话
void SpearMan::GetSay(Map* pMap)
{
//获取要说的话
double part = (double)GetHpCur() / (double)GetHpMax();
int x = this->GetX() - ; int y = this->GetY();
Body* sayCur = nullptr; if (!m_isSay && part <= 0.3f)
{
sayCur = new Say(this, x, y, GetDialogue()[]);
m_isSay = true;
} //创建对象到物品List,并打印显示
if (sayCur != nullptr)
{
pMap->GetBodyTmpList()->push_back(sayCur);
sayCur->OutputSelf(pMap);
}
}
SpearMan.cpp
#ifndef _DOG_H_
#define _DOG_H_ #include "AiRole.h"
//================== 军犬类 ================ class Dog : public AiRole
{
public:
Dog(int lv, RaceType race, int x, int y); public:
//===================行为函数 ==========================
virtual int CausedByDamage(); //计算制造的伤害量
virtual int AmountOfDamage(int atk) ; //计算受到的伤害量 virtual void OutputShout(int count); //打印喊话
virtual void InitShape(string str = "3D");//导入人物图形
virtual void AttackAction(Map* pMap); //攻击行为 private: }; #endif // _DOG_H_
Dog.h
#include "Dog.h"
#include "..//Marco.h"
#include "..//Body/BloodNum.h" Dog::Dog(int lv,RaceType race, int x, int y)
:AiRole(lv, race, ArmType::AT_Dog, x, y)
{
//防止等级越界
if (GetLV()>)
SetLV(); this->SetHpMax( + GetLV() * ); //血量
this->SetHpCur( + GetLV() * ); //血量 this->SetMS(GetMS() + GetLV() * ); //移动速度增加
this->SetAtkBase( + GetLV() * );
this->InitShape(); //导入图形数据 switch (GetLV())
{
case :
SetName("[狼犬]");
SetTip("狼犬形像野狼,性凶猛,嗅觉敏锐。多饲养来帮助看家、打猎或牧羊。因外表像狼而得名。");
break;
case :
SetName("[昆明犬]");
SetTip("神经类型兴奋灵敏,猎取反射强,防御反射主动,适应环境快。四肢奔跑有力,依恋性强,有耐力。");
break;
case :
SetName("[罗威纳犬]");
SetTip("俗称“大头犬”,中等体型,头部宽大,垂耳,肌肉发达,四肢强壮有力");
break;
case :
SetName("[多伯曼犬]");
SetTip("也称杜宾犬,呈方形中等体型,结构紧凑、肌肉发达有力,有耐力和速度,勇敢忠诚,精力充沛。");
break;
case :
SetName("[高加索犬]");
SetTip("高加索犬性情勇猛而忠顺于主人;抗病力强;被毛厚密形成天然蓑衣和冷热隔绝层,适应各种气候条件。");
break;
case :
SetName("[纯种藏獒]");
SetTip("体格高大,性格刚毅,力大勇猛,野性尚存,使人望而生畏,“犬中之王”美誉完全名副其实。");
break;
} //说话的内容
string** sapArr = GetDialogue();
sapArr[] = new string("汪!汪!汪!……");
sapArr[] = new string("嗷!嗷!嗷!……");
sapArr[] = new string("嗷呜!嗷呜!……");
} //===================行为函数 ==========================
//攻击行为
void Dog::AttackAction(Map* pMap)
{
Role* pObj = this->GetAttackList()->front()->obj;
pObj->BeHit(this,CausedByDamage(), pMap);
PlaySound(TEXT(".\\Music\\sence\\dog4.wav"), NULL, SND_ASYNC);
} //计算制造的伤害量
int Dog::CausedByDamage()
{
//血量低于30%时,狂暴伤害增加一倍
if (GetHpCur()<= GetHpMax() * 0.3)
{
SetAtkCur(GetAtkBase()* ); //2倍伤害
} return GetAtkCur();
} //计算受到的伤害量
int Dog::AmountOfDamage(int atk)
{
return atk;
} //打印喊话
void Dog::OutputShout(int count)
{
switch (count)
{
case : cout << "汪!汪!汪!……"; break;
case : cout << "嗷!嗷!嗷!……"; break;
case : cout << "嗷呜!嗷呜!……"; break;
}
} //获取人物图形
void Dog::InitShape(string str)
{
//图形资源
char shapeRes[] = {"vv+qq%"};
//¤■■━
// ∧∧
// |这是锚点 //开辟人物图形数据内存
Shape* shape = GetShape();
shape->count = ;
shape->data = new char[shape->count];
if (shape->data == nullptr) return; shape->pos = new int*[shape->count];
if (shape->pos == nullptr) return; for (int i = ; i < shape->count; i++)
{
shape->pos[i] = new int[];
if (shape->pos[i] == nullptr)
return;
} //人物图形资源导入
//data
for (int i = ; i < shape->count; i++)
shape->data[i] = shapeRes[i];
//pos
int x = GetX(); int y = GetY();
shape->pos[][] = x;
shape->pos[][] = y;
shape->pos[][] = x;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y - ;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
}
Dog.cpp
#ifndef _CAVALRY_H_
#define _CAVALRY_H_ #include "AiRole.h"
//================== 装甲车 ================ class Cavalry : public AiRole
{ public:
Cavalry(int lv, RaceType race, int x, int y); public:
//===================行为函数 ==========================
virtual int AmountOfDamage(int atk); //计算受到的伤害量 virtual void OutputShout(int count){}; //打印喊话
virtual void InitShape(string str = "3D"); //导入人物图形
void ActiveAttack(Map*); //发动攻击行为(使用道具、追击)
virtual bool CanDelete(); //可被释放 private:
int m_fireTime;
int m_dTime;
}; #endif // _CAVALRY_H_
Cavalry.h
#include "Cavalry.h"
#include "..//Marco.h"
#include "..//Body//Grenade.h" extern int GameTime; Cavalry::Cavalry(int lv, RaceType race, int x, int y)
:AiRole(lv, race, ArmType::AT_Cavalry, x, y)
{
//防止等级越界
if (GetLV() > )
SetLV(); this->SetHpMax( + GetLV() * ); //血量
this->SetHpCur( +GetLV() * ); //血量 this->SetMS(); //移动速度增加
this->InitShape(); //导入图形数据 Body* body = new Grenade(,);
body->SetOwner(this);
SetWeapon(body);
SetDistance(body->GetExtent());
SetName("[装甲车]");
SetTip("拥有高护甲,高攻击..."); m_fireTime = ;
m_dTime = ; //说话的内容
string** sapArr = GetDialogue();
sapArr[] = new string("轰隆!轰隆!");
sapArr[] = new string("轰隆!轰隆!");
sapArr[] = new string("轰隆!轰隆!");
} //===================行为函数 ==========================
//计算受到的伤害量
int Cavalry::AmountOfDamage(int atk)
{
return (int)(atk * 0.7);
} //获取人物图形
void Cavalry::InitShape(string str)
{
//图形资源
char shapeRes[] = { "111%qq" };
//━■■
//◎◎◎
// |这是锚点
//开辟人物图形数据内存
Shape* shape = GetShape();
shape->count = ;
shape->data = new char[shape->count];
if (shape->data == nullptr) return; shape->pos = new int*[shape->count];
if (shape->pos == nullptr) return; for (int i = ; i < shape->count; i++)
{
shape->pos[i] = new int[];
if (shape->pos[i] == nullptr)
return;
} //人物图形资源导入
//data
for (int i = ; i < shape->count; i++)
shape->data[i] = shapeRes[i];
//pos
int x = GetX(); int y = GetY();
shape->pos[][] = x;
shape->pos[][] = y;
shape->pos[][] = x;
shape->pos[][] = y + ;
shape->pos[][] = x;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
} //可被释放
bool Cavalry::CanDelete()
{
if( GameTime - m_fireTime >= m_dTime)
return true;
return false;
} //自动攻击(使用武器、追击)
void Cavalry::ActiveAttack(Map* pMap)
{
if (GetCondition() != BS_YES)
return; //攻击战斗列表的第一个元素(仇恨值最高的)
int x = GetObj()->GetX() - this->GetX(); //与目标的坐标差
int y = GetObj()->GetY() - this->GetY(); //与目标的坐标差
int dist = this->GetDistance(); //自己的射程 //进入射程就攻击
if (x == && y * y <= dist * dist)
{
if (GameTime % this->GetAts() == )
{
//--------转身面向目标--------
this->DirectToObj(pMap, GetObj());
this->AttackAction(pMap);
m_fireTime = GameTime;
}
} //否则,追击目标
else // (x * x + y * y > dist * dist )
{
if (GameTime % this->GetMS() == )
{
char ch;
if (x != )
ch = x > ? 's' : 'w';
else
ch = y > ? 'd' : 'a'; this->RoleMove(pMap, ch);
}
}
}
Cavalry.cpp
派生【设计了一个Boss】
Boss有4个战斗阶段
#ifndef _BOSS_H_
#define _BOSS_H_ #include "AiRole.h"
//================== 装甲车 ================ class Boss : public AiRole
{ public:
Boss(int x, int y); public:
//===================行为函数 ==========================
virtual int AmountOfDamage(int atk); //计算受到的伤害量 virtual void OutputShout(int count){}; //打印喊话
virtual void InitShape(string str = "3D");//导入人物图形 virtual void ActiveAttack(Map*); //发动攻击行为(使用道具、追击)
virtual void BattlePart(Map*); //阶段
virtual void RunAway(Map* pMap); //逃跑行为
virtual void ChangeDirection(Map* pMap);//换方向 private: int m_part; //阶段
Body* m_weapon1; //武器1
Body* m_weapon2; //武器2
}; #endif // _BOSS_H_
Boss.h
#include "Boss.h"
#include "..//Marco.h"
#include "..//Body//PillBox.h"
#include "..//Body//Pistol.h"
#include "..//Body//Grenade.h"
#include "..//Map//Map_1.h" //声明一个全局变量(模拟游戏时间)
extern int GameTime; Boss::Boss(int x, int y)
:AiRole(, RT_IS, ArmType::AT_Boss, x, y)
{
//防止等级越界
if (GetLV() > )
SetLV(); this->SetHpMax(); //血量
this->SetHpCur(); //血量
this->SetMS(); //移动速度增加
this->InitShape(); //导入图形数据 SetDistance();
SetName("巴格达迪");
SetTip("一名前伊斯兰大学教授,现IS“伊斯兰国”最高领导人。"); //武器1 手枪
m_weapon1 = new Pistol();
m_weapon1->SetOwner(this);
m_weapon1->SetHarm();
//武器2 机关枪
m_weapon2 = new PillBox();
m_weapon2->SetOwner(this);
m_weapon2->SetHarm(); m_part = ; //第1阶段
SetWeapon(m_weapon1); //说话的内容
string** sapArr = GetDialogue();
sapArr[] = new string("小的们!快给我干掉他!");
sapArr[] = new string("啊...让你瞧瞧我的兜家底的武器!");
sapArr[] = new string("你真的让我很生气!看我厉害...."); } //===================行为函数 ==========================
//计算受到的伤害量
int Boss::AmountOfDamage(int atk)
{
return (int)(atk * 0.8);
} //获取人物图形
void Boss::InitShape(string str)
{
//图形资源
char shapeRes[] = { "uuqqhqqgAB" };
// ()
//←■■→
// ■■
// ⊥⊥
//开辟人物图形数据内存
Shape* shape = GetShape();
shape->count = ;
shape->data = new char[shape->count];
if (shape->data == nullptr) return; shape->pos = new int*[shape->count];
if (shape->pos == nullptr) return; for (int i = ; i < shape->count; i++)
{
shape->pos[i] = new int[];
if (shape->pos[i] == nullptr)
return;
} //人物图形资源导入
//data
for (int i = ; i < shape->count; i++)
shape->data[i] = shapeRes[i];
//pos
int x = GetX(); int y = GetY();
shape->pos[][] = x;
shape->pos[][] = y;
shape->pos[][] = x;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y - ;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
shape->pos[][] = x - ;
shape->pos[][] = y;
shape->pos[][] = x - ;
shape->pos[][] = y + ;
} //换方向
void Boss::ChangeDirection(Map* pMap)
{
//不含方向
} //攻击行为(Boos有特效 根据生命值转阶段)
void Boss::BattlePart(Map* pMap)
{
int cur = this->GetHpCur();
int max = this->GetHpMax(); //当生命之低于80时(且为1阶段时) 呼叫部队支援
if (m_part < && (double)cur <= max * 0.8f)
{
pMap->AppendEnmeyTip(ArmType::AT_Spearman, , , , );
pMap->AppendEnmeyTip(ArmType::AT_Spearman, , , , );
pMap->AppendEnmeyTip(ArmType::AT_Spearman, , , , );
m_part++;
}
//当生命之低于60时(且为2阶段时) Boss换装神器机关枪
else if (m_part < && (double)cur <= max * 0.6f)
{
this->SetWeapon(m_weapon2);
m_part++;
}
//当生命之低于30时(且为3阶段时) 狂暴移动速度加快
else if (m_part < && (double)cur <= max * 0.3f)
{
this->SetMS();
m_part++;
}
} //自动攻击(使用武器、追击)
void Boss::ActiveAttack(Map* pMap)
{
if (GetCondition() != BS_YES)
return; //BOSS战斗阶段控制
if( m_part!= )this->BattlePart(pMap); //攻击战斗列表的第一个元素(仇恨值最高的)
int x = GetObj()->GetX() - this->GetX(); //与目标的坐标差
int y = GetObj()->GetY() - this->GetY(); //与目标的坐标差
int dist = this->GetDistance(); //自己的射程 //进入射程就攻击
if ( abs(x) <= && y * y <= dist * dist)
{
if (GameTime % this->GetAts() == )
{
//--------转身面向目标--------
this->DirectToObj(pMap, GetObj());
this->AttackAction(pMap);
}
} //否则,追击目标
else // (x * x + y * y > dist * dist )
{
if (GameTime % this->GetMS() == )
{
char ch;
if (x != )
ch = x > ? 's' : 'w';
else
ch = y > ? 'd' : 'a'; this->RoleMove(pMap, ch);
}
}
} //无逃跑行为
void Boss::RunAway(Map* pMap)
{ }
Boss.cpp
【C++第一个Demo】---控制台RPG游戏4【角色系统】的更多相关文章
- 【C++第一个Demo】---控制台RPG游戏3【登陆菜单树】
[登陆系统--树结构] 1 首先我这里设计,由一个基类MainMenu构建树结构,并实现控制台上菜单之间的切换和返回操作 #ifndef _UI_BASE_H_ #define _UI_BASE_H_ ...
- 【C++第一个Demo】---控制台RPG游戏2【通用宏、背包类】
[通用 ]--一些游戏中常用的宏.函数和枚举 #ifndef _MARCO_H_ #define _MARCO_H_ //------------------------常用系统库---------- ...
- 【C++第一个Demo】---控制台RPG游戏1【游戏简介】
经过1个月的制作和多次修改,终于有了基本雏形(此篇仅用于纪念历时3个多月C/C++学习所付出努力,也给和我一样苦恼于不能快速理解面向对象的同学们一点灵感) 在制作这个Demo过程中也受到了很多大 ...
- Android中Service的一个Demo例子
Android中Service的一个Demo例子 Service组件是Android系统重要的一部分,网上看了代码,很简单,但要想熟练使用还是需要Coding. 本文,主要贴代码,不对Servic ...
- Cocos2dx游戏开发系列笔记13:一个横版拳击游戏Demo完结篇
懒骨头(http://blog.csdn.net/iamlazybone QQ:124774397 ) 写下这些东西的同时 旁边放了两部电影 周星驰的<还魂夜> 甄子丹的<特殊身份& ...
- 【android原生态RPG游戏框架源码】
转载请注明原创地址:http://www.cnblogs.com/zisou/p/android-RPG.html 这份源码是在今年6月份写的,当时公司有一个技术部们的学习讨论的讲座,然后我自己就写了 ...
- RPG游戏开发基础教程
RPG游戏开发基础教程 第一步 下载RPG Maker 开发工具包 1.RPG Maker 是什么? RPG Maker 是由Enterbrain公司推出的RPG制作工具. 中文译名为RPG制作大师. ...
- 如何制作一款HTML5 RPG游戏引擎——第五篇,人物&人物特效
上一次,我们实现了对话类,今天就来做一个游戏中必不可少的——人物类. 当然,你完全是可以自己写一个人物类,但是为了方便起见,还是决定把人物类封装到这个引擎里. 为了使这个类更有意义,我还给人物类加了几 ...
- 使用HTML5制作简单的RPG游戏
很久以前就想着做一个游戏,但什么都不会又不知道从哪里开始,胡乱找来一些书籍和资料结果太深奥看不懂,无奈只能放弃.这一弃就是十多年,倥偬半生,眼看垂垂老矣,还是没能有什么成果. 近年来游戏引擎越来越多, ...
随机推荐
- python的列表与shell的数组
python:names=["a","b","c"] shell:names=(a b c)
- 用 Flask 来写个轻博客 (29) — 使用 Flask-Admin 实现后台管理 SQLAlchemy
目录 目录 前文列表 扩展阅读 Flask-Admin BaseView 基础管理页面 ModelView 实现效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写 ...
- git使用记录九:开发中临时加塞了紧急任务怎么处理
开发中临时加塞了紧急任务怎么处理 隐藏工作区域 git stash git status 查询隐藏的列表 git stash list 处理完bug,提交之后,再恢复隐藏的工作区域 git stash ...
- 兼容ie浏览器的方法
让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法 最近做一个Web网站,之前一直觉得bootstrap非常好,这次使用了bootstrap3,在chrome,f ...
- Java程序的设计环境配置
一.下载主要的开发工具 JDK的下载 www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html Ecli ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- 从OLLVM4.0.0升级到LLVM8.0.1,并且给LLVM增加Pass 插件系统
版本太低了,用得我这个揪心. 上周日决定把手头的ollvm从4.0.0升级到LLVM8.0.1. 里面的Pass的话,决定移植到8.0.1里面. 我习惯从代码上来动手 1:下载LLVM https: ...
- hashRouter and BrowserRouter
<html><body> <div> <button class="btn" onclick="btnFun();"& ...
- 【记录】ELK之logstash同步mysql数据到Elasticsearch ,配置文件详解
本文出处:https://my.oschina.net/xiaowangqiongyou/blog/1812708#comments 截取部分内容以便学习 input { jdbc { # mysql ...
- Hybrid App技术解析 — 原理篇
Hybrid App技术解析 — 原理篇 原文出处: https://segmentfault.com/a/1190000015678155 引言 随着 Web 技术和移动设备的快速发展,Hybr ...