设计一个回合制战斗系统Combat(C++)
C++设计一个回合制战斗系统Combat
目录
- C++设计一个回合制战斗系统Combat
- 题目
- 重要提醒
- Soldier类
- Wizard类
- Master类
- Warsystem类
题目
设计和实现回合制战斗系统Combat
1. Soldier战士类
Soldier的属性(protected作用域)
最大生命 maxHP 当前生命 HP 最大体力maxSP 当前体力SP
攻击力 damage 经验 exp 等级 level 姓名 name
药瓶数量 drugNumSoldier的动作(public作用域)
决策 makeDecision 攻击 attack 休息 rest 吃药 takingDrugSoldier被创建后,maxHP和HP为100,maxSP和SP为100,damage为20,exp为0, level为1,drugNum为5;
每回合Soldier通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、休息rest或吃药takingDrug,注意每回合只能做其中一个动作)。请自行设计和调整每种动作发出的必要条件,例如:生命值若低于最大值的30%该回合就吃药,体力低于最大值的50%该回合就休息,生命力和体力都充足该回合就发起攻击,等等;
攻击(attack)敌人一次,体力(SP)减少10,经验(exp)增加5。敌人的生命值(HP)减去攻击方攻击力值(damage)的大小。敌人生命值(HP)减少到0时死去,如果敌人被自己打死,获得敌人身上的所有药瓶;
经验(exp)每增加20,等级(level)就提高1级,maxHP、maxSP、damage分别增加20;Soldier, Wizard, Master升级后,当前HP,SP,MP和NP的值皆按比例(xx:MaxXX)增长,注意:不是升级后上述当前属性值就自动全满。例如:Wizard的 HP/MaxHP 50/100,升级后,HP/MaxHP调整为60/120。升级前HP:MaxHP比例为0.5,升级后MaxHP变成120,若要保持0.5的比例,HP自动调整为60。这种设定类似于魔兽争霸III。
休息(rest)一次,生命值(HP)、体力(SP)增加最大值的50%,但不要超过最大值。(例如,当前生命值是30,最大生命值是100,则吃药后的当前生命值为30+100*50%=80。)
吃药(takingDrug),如果药瓶数量为0,不能吃药。吃药一次,药瓶数量减少1,生命值(HP)增加最大值的80%,但不能超过maxHP。
2. Wizard巫师类,从Soldier类公有继承Wizard的属性(protected作用域)
新增的属性: 最大魔法值 maxMP 当前魔法值 MPWizard的动作(public作用域)
决策 makeDecision 攻击 attack 休息 rest 吃药 takingDrug
魔法攻击wizard_attackWizard被创建后,maxMP和MP为100 ,maxHP和HP为100,maxSP和SP为100,maxMP和MP为100,damage为20,exp为0,level为1;
每回合Wizard通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、魔法攻击wizard_attack、休息rest或吃药takingDrug,注意每回合只能做一个动作);
魔法攻击(wizard_attack):如果魔法值小于25、或体力小于10无法使用该技能。一次魔法攻击能同时攻击几个敌人,但每对付一个敌人,自己的体力(SP)减少10、魔法值减少25、经验(exp)增加5、敌人的生命值(HP)减去自己攻击力值(damage)。敌人生命值(HP)减少到0时死去,同时自己获得敌人身上的所有药瓶;
经验(exp)每增加20,等级(level)提高1级,maxHP、maxSP、maxMP、damage分别增加20;(如果觉得升级太快了,或者升级增加的HP和damage不太协调,可以调整这些参数)
休息(rest)一次,生命值(HP)、体力(SP)恢复效果同Soldier的休息(rest)动作。魔法值增加最大魔法值的30%,但不要超过最大魔法值,例如:_mp=_mp+_maxMp*30%。
吃药(takingDrug)一次,效果等同于Soldier吃药。
攻击(attack),攻击效果同Soldier。
3. Master巫师类,从Wizard类公有继承Master的属性(protected作用域)
新增的属性: 最大内力 maxNp 当前内力 NPMaster的动作(public作用域)
决策 makeDecision 攻击 attack 休息 rest 吃药 takingDrug
魔法攻击wizard_attack 绝杀攻击master_attackMaster被创建后,maxMP和MP为100 ,maxHP和HP为100,maxSP和SP为100,maxNP和NP为100,damage为30,exp为0,level为1;
每回合Wizard通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、魔法攻击wizard_attack、绝杀攻击master_attack、休息rest或吃药takingDrug,注意每回合只能做一个动作);
大师攻击(master_attack),如果内力(NP)大于50时,可以使用大师(master_attack)攻击。一次大师攻击能让被攻击的敌人的生命值(HP)减少其最大生命值的(maxHP)50%(可能有点太强了,破坏平衡性!容易导致游戏在短短几个回合就结束,可以考虑适当减小。),例如敌人HP为100,maxHP为160,被大师攻击后,生命值变为HP-maxHP50%=100-16050%=20。一次大师攻击会内力(NP)损耗50、体力(SP)损耗30,经验增加5。
魔法攻击(wizard_attack),攻击效果等同于Wizard的攻击(attack)动作
攻击(attack),攻击效果等同于Soldier的攻击(attack)动作。
使用大师攻击后,经验(exp)每增加20,等级(level)就提高1级,maxHP、maxSP、maxMP、maxNP分别增加20,damage增加20;
休息(rest)一次,内力增加最大内力的30%,但不要超过最大内力值。其余如HP、SP、MP的恢复等同于Wizard的休息(rest)动作。
吃药(takingDrug)一次,效果等同于Soldier的吃药(takingDrug)动作。
4. WarSystem战斗系统类
WarSystem类的属性
军团A Soldier ** _pGroupA; 军团B Soldier ** _pGroupB;WarSystem类的动作
战斗开始startWar 回合开始startRound每次战斗,双方派出一个军团,军团由数名战士、巫师和大师组成。战斗按回合制进行,即每回合中,一方军团的每个成员做完各自的一次动作(由makeDecision决定)后,另一方军团每个成员接着完成自己的一次动作。战斗开始,由哪个军团先发起攻击,系统随机决定。回合的生成和结束由WarSystem类控制;
WarSystem类拥有两个数据成员(指向指针变量的指针,即二级指针):
Soldier ** _pGroupA;
Soldier ** _pGroupB;
分别对应战斗的双方军团。(提示,军团可以由Soldier *数组的形式生成,在WarSystem的pGroupA和pGroupB分别指向两个军团,注意OOP的多态实现。)WarSystem类可以发出战斗开始即startWar()动作。在startWar()中,随机决定由哪一方率先发起攻击(恐怕是每个回合都随机决定谁先出手会比较公平,如果每回合先出手都是固定一方,那么战斗结果完全是确定性的。而且由于两支队伍的成员一样,交换先出手权后的结果也是对称的。),然后调用WarSystem的另一动作:回合开始,即startRound()。
startRound()动作的描述:在startRound()中,按军团顺序调用每个战士的makeDecision()动作(也可以考虑两个军团轮流一次一人行动,比较公平)。
重要提醒
本博客是博主花几个小时弄的,尚未完全满足题目要求,例如未进行随机开启军团战斗(用随机函数判断即可,较简单),本博客意在为广大初学者提供类的设计思路,故不提供主函数代码,请自行设计,由于时间仓促代码多有不足,请读者朋友仔细甄别其中优劣之处,再次提醒,代码仅提供给大家作为思路参考!!!!
Soldier类
#ifndef A1
#define A1
#include<iostream>
#include<string>using namespace std;
class Soldier//战士类
{protected:double maxHP=100,HP=100,maxSP=100,SP=100,damage=20,drugNum=5,level=1;int exp=0;string name;
public:Soldier(){}int enemynum = 3;//设置一个默认敌人数量void setHP()//重置生命值为0{HP = 0;}void underattack(double x);virtual void setname();//设置名字virtual ~Soldier(){}virtual void makeDecision(Soldier **t);void attack(Soldier **t);virtual void rest();void takingDrug();string getname()//获取名字{return name;}double getmaxHP()//获取最大生命值{return maxHP;}double getHP()//获取生命值{return HP;}double getdrugnum()//获取药瓶数量{return drugNum;}
};
void Soldier::makeDecision(Soldier **t)//决策
{if (HP < (maxHP * 0.3))//生命值若低于最大值的30%该回合就吃药takingDrug();else if (SP < (maxSP * 0.5))//体力低于最大值的50%该回合就休息rest();else//生命力和体力都充足该回合就发起攻击tattack(t);
}
void Soldier::underattack(double hurt)
{HP -= hurt;
}
void Soldier::attack(Soldier **enemy)//攻击函数(平A)
{for (int i = 0; i < enemynum; i++){if (HP > 0 && enemy[i]->getHP()> 0 && SP > 0){cout << name << "攻击了" << enemy[i]->getname()<< endl;enemy[i]->underattack(damage);SP -= 10;exp += 5;cout << name << "的体力值下降至" << SP << '\t' << "经验+5(" << exp << ")" << endl;if (exp % 20 == 0){double BHP = HP / maxHP;double BSP = SP / maxSP;level++;damage *= 1.2;maxHP *= 1.2;maxSP *= 1.2;HP = maxHP * BHP;SP = maxSP * BSP;cout << name << "升级至等级" << level << endl;}if (enemy[i]->getHP()<= 0){enemy[i]->setHP();drugNum += enemy[i]->getdrugnum();cout << enemy[i]->getname()<< "死亡,生命值为" <<HP<< "\t" << name << "获得药瓶数量" << enemy[i]->getdrugnum()<< endl;}cout << enemy[i]->getname() << "受到" << damage << "伤害 当前生命值为" << enemy[i]->getHP() << endl << endl;return;}}
}
void Soldier::takingDrug()//吃药
{cout << name << "***开始吃药***" << endl;if (drugNum == 0){cout << "很遗憾," << name << "没有药瓶了" << endl;return;}else {drugNum--;HP += maxHP * 0.8;if (HP > maxHP)HP = maxHP;}cout << "***结束吃药***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP << endl;
}
//coding by wangxiao/wansixinxin/wangboxin/liuyang
void Soldier::rest()//休息
{cout << name << "***开始休息***" << endl;HP += maxHP * 0.5;if (HP > maxHP)HP = maxHP;SP += maxSP * 0.5;if (SP > maxSP)SP = maxSP;cout << "***休息结束***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP << endl;
}void Soldier::setname()//命名
{cout << "请为战士命名:";cin >> name;
}
#endif // !A1
Wizard类
#ifndef A2
#define A2
#include"Soldier.h"
#include<iostream>
using namespace std;
class Wizard :public Soldier//巫师类
{protected:double MP=100;double maxMP = 100;
public:Wizard() {}~Wizard() {}virtual void setname();virtual void rest();virtual void makeDecision(Soldier **enemy);void wizard_attack(Soldier **enemy);//法术攻击
};
void Wizard::rest()//巫师休息
{cout << name << "***开始休息***" << endl;HP += maxHP * 0.5;if (HP > maxHP)HP = maxHP;SP += maxSP * 0.5;if (SP > maxSP)SP = maxSP;MP+= maxMP * 0.5;if (MP > maxMP)MP = maxMP;cout << "***休息结束***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP <<"魔法值"<<MP<<endl;
}
void Wizard::makeDecision(Soldier** enemy)
{if (MP <= 25 && SP <= 10)rest();else if (MP <= 25 && SP>=10)attack(enemy);else if (HP <= 20)takingDrug();elsewizard_attack(enemy);
}
void Wizard::wizard_attack(Soldier** enemy)
{if (HP>0){for (int i = 0; i < enemynum; i++){if (enemy[i]->getHP()>0){if (MP > 25 && SP > 10){MP -= 25;SP -= 10;cout << endl<< name << "对" << enemy[i]->getname() << "发动魔法攻击"<< endl;enemy[i]->underattack(damage * 0.2);cout << enemy[i]->getname() << "的生命值下降至" << enemy[i]->getHP() << endl;exp += 5;cout << name << "的体力值/魔法值下降为:" << SP << "/" << MP << "经验+5(" << exp << ")" << endl;if (enemy[i]->getHP() <= 0){enemy[i]->setHP();drugNum += enemy[i]->getdrugnum();cout << enemy[i]->getname()<< "死亡" << "\t" << name << "获得药瓶数量" << enemy[i]->getdrugnum()<< endl;}if (exp % 20 == 0){double BHP = HP / maxHP;double BSP = SP / maxSP;double BMP = MP / maxMP;level++;damage *= 1.2;maxHP *= 1.2;maxSP *= 1.2;maxMP *= 1.2;HP = maxHP * BHP;SP = maxSP * BSP;MP = maxMP * BMP;cout << name << "升级至等级" << level << endl;}}else{cout << "魔法值或者体力值不足无法继续魔法攻击" << endl;return;}}}}
}
void Wizard::setname()
{cout << "请为法师命名:";cin >> name;
}
#endif // !A2
Master类
#ifndef A3
#define A3
#include"Wizard.h"
class Master :public Wizard
{protected:double NP = 100;double maxNP = 100;
public:Master() {};~Master() {};void setname();void master_attack(Soldier **enemy);void makeDecision(Soldier** enemy);void rest();
};
void Master::master_attack(Soldier** enemy)//大师攻击(终结技)
{if (HP > 0){for (int i = 0; i < enemynum; i++){if (enemy[i]->getHP() > 0 && NP >= 50 && SP >= 30){NP -= 50;SP -= 30;enemy[i]->setHP();cout << enemy[i]->getname() << "被" << name << "终结" << endl;cout << enemy[i]->getname() << "的生命值当前为" << enemy[i]->getHP()<<endl;exp += 5;if (exp % 20 == 0){double BHP = HP / maxHP;double BSP = SP / maxSP;double BMP = MP / maxMP;double BNP = NP / maxNP;level++;damage *= 1.2;maxHP *= 1.2;maxSP *= 1.2;maxMP *= 1.2;HP = maxHP * BHP;if (HP > maxHP)HP = maxHP;SP = maxSP * BSP;if (SP > maxSP)SP = maxSP;MP = maxMP * BMP;if (MP > maxMP)MP = maxMP;NP = maxNP * BNP;if (NP > maxNP)NP = maxNP;cout << name << "升级至等级" << level << endl;cout << name<<"各项属性提升至:生命" << HP << "体力" << SP << "魔法值" << MP << "内力" << NP << endl << endl;}}else if (NP < 50 && SP < 30){cout <<name<< "内力或体力不足无法继续发动终结技" << endl;return;}}}
}
void Master::rest()
{cout << name << "***开始休息***" << endl;HP += maxHP * 0.5;if (HP > maxHP)HP = maxHP;SP += maxSP * 0.5;if (SP > maxSP)SP = maxSP;MP += maxMP * 0.5;if (MP > maxMP)MP = maxMP;NP += maxNP * 0.5;if (NP > maxNP)NP = maxNP;cout << "***休息结束***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP << "魔法值" << MP << "内力" << NP << endl;
}
void Master::makeDecision(Soldier** enemy)
{for (int i = 0; i < enemynum; i++){if (enemy[i]->getHP() <= enemy[i]->getmaxHP() * 0.4){master_attack(enemy);return;}}if (MP <= 25 && SP <= 10)rest();else if (MP <= 25 && SP >= 10)attack(enemy);else if (HP <= 20)takingDrug();elsewizard_attack(enemy);
}
void Master::setname()
{cout << "请为此大师命名:";cin >> name;
}
#endif // !A3
Warsystem类
#ifndef A5
#define A5
#include"Master.h"
#include<windows.h>
#include<cstdlib>
class Warsystem
{private:Soldier** _pgroupA;Soldier** _pgroupB;void startround(Soldier **A,Soldier **B);
public:bool isgrouplose(Soldier** A);Warsystem(Soldier** A, Soldier** B){_pgroupA = A;_pgroupB = B;}void startwar();
};
void Warsystem::startwar()
{int round = 1;do{cout << endl<<endl<<endl<<"第" << round << "回合:" << endl << endl;if (round++ & 1)startround(_pgroupA, _pgroupB);elsestartround(_pgroupB, _pgroupA);Sleep(3000);} while (!isgrouplose(_pgroupA) && !isgrouplose(_pgroupB));if (isgrouplose(_pgroupA))cout << "B军团胜利";elsecout << "A军团胜利";
}
void Warsystem::startround(Soldier** A, Soldier** B)
{for (int i = 0; i < A[0]->enemynum; i++){if(A[i]->getHP()>0)A[i]->makeDecision(B);}
}
bool Warsystem::isgrouplose(Soldier** A)
{for (int i = 0; i < A[0]->enemynum; i++){if (A[i]->getHP()>0)return false;}return true;
}
#endif // ! A4
设计一个回合制战斗系统Combat(C++)相关推荐
- 设计和实现回合制战斗系统Combat(C++)(Soldier战士类,Wizard巫师类,Master巫师类,WarSystem战斗系统类)
回合制为什么会大受欢迎?因为这个世界历来就是得轻度用户者(light users)得天下,以这个为出发点上,它比即时制有自己独到的优势.慢节奏.易操作.收集养成.聊天交友给回合制带来了众多即时制所带不 ...
- 设计和实现回合制战斗系统
设计和实现回合制战斗系统Combat的要求(一) 1. Soldier战士类 1) Soldier的属性(protected作用域) 最大生命 maxHP 当前生命 HP 最大体力 ...
- Unity 回合制战斗系统(中级篇)
项目文件找出来了,老版本的脚本有报错,我在新版2019.4.21f1c1下解决了报错,战斗场景可以正常跑的. 需要的同学点下面地址下载(关注就行啦不用积分),祝大家都早日学成 项目包下载 ------ ...
- Unity 回合制战斗系统(初级篇)
项目文件找出来了(后面中级/高级的),老版本的脚本有报错,我在新版2019.4.21f1c1下解决了报错,战斗场景可以正常跑的. 需要的同学点下面地址下载(关注就行啦不用积分),祝大家都早日学成 项目 ...
- JAVA 面向对象编程练习(一个回合制的战斗游戏:战士,骑兵,法师,电脑互相攻击)
文章目录 一. 小编有话说 二. 游戏的要求 三. 编程前的准备 四. 代码及详细注释 五. 结果 一. 小编有话说 前面一篇文章写了JAVA面向对象编程的思想,本文主要展示关于面向对象编程的实例(一 ...
- 表演的艺术,妖尾回合制战斗系统客户端设计
妖尾历经几年开发,终于在今年6月底顺利上线,笔者从2017年初参与开发,主要负责妖尾战斗系统开发.战斗作为游戏的核心玩法系统,涉及很多技术点,希望能借几篇文字,系统性总结MMORPG战斗系统的开发经验 ...
- Unity_回合制战斗系统_01
回合制是一种游戏打怪形式,所有游戏内玩家轮流自己的回合,只有轮到自己的回合,才能够进行操纵.早期战略由于硬件运算能力有限,在考量游戏乐趣与操作简易得情况下,多半采取这种型式.目前常见的回合制手游有&l ...
- 最近完成了一个回合制网游的服务器架构
最近在弄服务器架构,现在基本算是完成了,朋友泰兰德の記憶在过程中帮了很多忙,在此谢谢他. 考虑到是回合制网游,所以交叉逻辑(即用户与用户之间的交互操作)会少于一般的A-RPG游戏,所以最终采用的是按照 ...
- c语言 回合制小游戏,一个回合制小游戏的设计笔记
发在这的目的: 1.做个记录 2.与人交流讨论 场景:二维方格组成的场景,一个格子里只能有一个单位,每个单位都会占据自己的格子. 行为:每个回合里,每个单位都有一定的行为点数,单位的任何行为都需要消耗 ...
最新文章
- SpringBoot开发案例从0到1构建分布式秒杀系统
- 数据库设计--数据字典
- apk之间数据共享的方式
- jQuery对象与DOM对象的相互转换
- boot druid 长时间不连接 异常_Spring Boot学习:如何使用Druid数据源
- java 三大特性理解_java 三大特性--封装、继承和多态理解
- JEECG企业微云快速二次开发平台-新版本首页展示
- TCP/IP网络编程之多种I/O函数
- 软件配置,软件配置及变更管理的重要意义与价值
- 哪里找电商素材模板?
- 【2000*】【Codeforces Round #518 (Div. 1) [Thanks, Mail.Ru!] B】Multihedgehog
- 【邮政编码识别】基于matlab灰度二值化邮政编码识别【含Matlab源码 788期】
- 冯诺依曼元胞计算机,冯诺依曼元胞自动机
- linux的的符号,linux特殊符号
- android 联系人 拼音,Android 2.1 (Eclair)的中文联系人拼音检索问题
- SpringBoot整合Elasticsearch,2021最新Java面试真题解析
- 加密U盘专业加密芯片方案
- 使用D2RQ转换关系型数据库Mysql数据为RDF
- 项目一 认识Linux操作系统
- 白色相簿的季节(递归)
热门文章
- 学生老师的家教服务平台小程序制作
- mysql unix_timestamp now() dfdfd f_数据库函数lpad的搜索结果-阿里云开发者社区
- 【MySQL报错】1366 - Incorrect string value: ‘\xE6\x80\xBB\xE7\xBB\x8F...‘ for column ‘name‘ at row 1
- Win10 安装 SU2
- 【Node.js】之项目准备和首页
- 职业访谈计算机学院老师,理想照亮现实 访谈引领未来数学计算机学院举行首届职业生涯人物访谈大赛...
- linux中查不到ip地址
- 无人驾驶汽车是如何进行行为决策的?
- FTP服务器配置(虚拟用户)
- 关于区块链共识类型:PoW, PoS, DPoS, PoST的解释