《凡人修仙传》中打斗场景(c++多态实现)

在这里插入图片描述

  1. 我们 要实现打斗场景,第一,我们需要有打斗的双方,一个是英雄,一个是怪物,他们都有自己的属性,比如攻击,防御,血量。其次我们的英雄还会有武器。武器上有一些加成属性,可以帮英雄更好的打怪物,武器也有多种武器可以让英雄进行选择。

  2. 首先我们做武器类的声明,一个武器要有名称,还基础伤害,其次一些武器可能会有暴击,吸血,定身的效果,我们要对此进行判断。由于我们并不实现武器这个类,我们仅仅希望,后面的实现的武器继承他的属性并实现,所以我们武器类的属性都用纯虚函数来写。

    #pragma once
    #include<iostream> 
    #include<string>
    using namespace std;
    
    //抽象类
    class Weapon
    {
    public:
    	//获取基础伤害
    	virtual int getBaseDamage() = 0;
    
    	//获取吸血
    	virtual int getSuckBlood() = 0;
    
    	//获取是否定身
    	virtual bool getHold()=0;
    
    	//获取是否暴击
    	virtual bool getCrit() = 0;
    
    	string m_WeaponName; //武器名称
    	int m_BaseDamage;//基础伤害
    
    };
    
  3. 我们有了武器类,就可以细化做武器了,我们这里就做两个武器,一个是普通的小刀,另外一个是比较厉害的屠龙刀,我们先做小刀类的声明。小刀是武器,所以它要继承武器类的属性,并拥有自己的构造函数。虚函数可以实现动态多态

     #pragma once
     #include<iostream>
     #include"Weapon.h"
     #include<string>
     using namespace std;
     
     class Knife :public Weapon
     {
     public:
     	Knife();
     	//获取基础伤害
     	virtual int getBaseDamage() ;
     
     	//获取吸血
     	virtual int getSuckBlood() ;
     
     	//获取是否定身
     	virtual bool getHold();
     	//获取是否暴击
     	virtual bool getCrit();
     
     
     };
    
  4. 有了小刀类的声明后,我们可以在类外实现小刀这个类,小刀没有别的属性,所以,我们只用在构造中,把"小刀"这个名字和基础攻击力赋值,然后获取攻击力的函数中,返回基础攻击力就可以。

     #include"Knife.h"
     
     Knife::Knife()
     {
     	this->m_BaseDamage = 10;
     
     	this->m_WeaponName = "小刀";
     }
     
     int Knife::getBaseDamage()
     {
     
     	return this->m_BaseDamage;
     }
     
     int Knife::getSuckBlood()
     {
     	return 0;
     }
     bool Knife::getHold()
     {
     	return false;
     }
     
     bool Knife::  getCrit()
     {
     	return false;
     }
    
  5. 我们声明屠龙刀类,屠龙刀依旧是继承武器类,此外,作为一个强大的武器,它还必须具有其他的属性,它还有吸血,暴击,和可以让怪物定身的能力,但是它的这些能力,并不是一定会触发,需要一些属性也就是概率来触发。

     #pragma once  //防止头文件重复编译
     #include<iostream>
     #include"Weapon.h"
     #include<string>
     using namespace std;
     
     class DragonSword :public Weapon
     {
     public:
     	DragonSword();
     	//获取基础伤害
     	virtual int getBaseDamage();
     
     	//获取吸血
     	virtual int getSuckBlood();
     
     	//获取是否定身
     	virtual bool getHold();
     	//获取是否暴击
     	virtual bool getCrit();
     
     	//吸血率,暴击率,定身率
     	int SuckRate;
     	int holdRate;
     	int critRate;
     
     	//传入概率 判断是否触发
     	bool isTrigger(int rate);
     
     };
    
  6. 屠龙刀的实现:再构造中,把它的基本属性赋值,其他的属性,我们通过一个成员函数来判断是否触发特效,我们在构造中把触发特效的概率写出来,然后在判断概率函数中,设置一个随机数,如果这个随机数比概率小,则触发特效。

     #include"DragonSword.h"
     
     DragonSword::DragonSword()
     {
     	this->m_BaseDamage = 20;
     	this->m_WeaponName = "屠龙宝刀";
     	this->SuckRate = 20;
     	this->holdRate = 30;
     	this->critRate = 35;
     }
     
     int DragonSword::getBaseDamage()
     {
     	return this->m_BaseDamage;
     }
     
     int DragonSword::getSuckBlood()
     {
     	if (isTrigger(SuckRate))
     	{
     		return  this->m_BaseDamage*0.5;    //按照武器基础伤害一半吸血
     	}
     	return 0;
     }
     
     bool DragonSword::getHold()
     {
     	if (isTrigger(holdRate))
     	{
     		return true;
     	}
     	return false;
     }
     
     bool DragonSword::getCrit()
     {
     	if (isTrigger(critRate))
     	{
     		return true;
     	}
     	return false;
     }
     
     bool DragonSword::isTrigger(int rate)
     {
     	//通过isTrigger判断是否触发特效
     	//随机一个0~100的数字
     	//rand()%100 是0~99之间的随机数 +1后是1~100之间的一个随机数
     	//如果产生的随机数比设定的概率值小则发生,否则不发生
     	int num = rand() % 100 + 1;
     	if (num < rate)
     	{
     		return true;
     	}
     	return false;
     
     }
    
  7. 有了武器后,我们声明英雄类,英雄除了基本属性外,还要判断是否有武器,有什么样的武器

     #pragma once
     #include<iostream>
     #include"Weapon.h"
     #include<string>
     #include"Monster.h"
     using namespace std;
     
     class Monster;
     class Hero
     {
     public:
     	Hero();
     
     	string m_Name;//人名
     
     	int m_Atk;//攻击力
     
     	int m_Def;//防御力
     
     	int m_Hp;//血量
     
     	Weapon * weapon;//武器
     
     	void EquipWeapon(Weapon * weapon);
     
     	void Attack(Monster * monster);
     
     };
    
  8. 英雄类的实现。

     #include"Hero.h"
     
     Hero::Hero()
     {
     	this->m_Hp = 500;
     
     	this->m_Atk = 45;
     
     	this->m_Def = 50;
     
     	this->m_Name = "刘法师";
     
     	this->weapon = NULL;
     }
     //装备武器
     void  Hero::EquipWeapon(Weapon * weapon)
     {
     	this->weapon = weapon;
     
     	cout << "英雄:" << this->m_Name << "装备了武器" <<  this->weapon->m_WeaponName  << endl;
     }
     
     void  Hero::Attack(Monster * monster)
     {
     	int damage = 0;
     	int addHp = 0;
     	bool isHold = false;
     	bool isCrit = false;
     
     	if (this->weapon == NULL) //武器为空,没有加成
     	{
     		damage = this->m_Atk;
     	}
     
     	else
     	{
     		//基础伤害
     		damage = this->m_Atk + this->weapon->m_BaseDamage;
     		//计算吸血
     		addHp = this->weapon->getSuckBlood();
     		//计算定身
     		isHold = this->weapon->getHold();
     		//计算暴击
     		isCrit = this->weapon->getCrit();
     
     		if (isCrit) //暴击 伤害加成
     		{
     			damage = damage * 1.5;
     			cout << "英雄的武器触发了暴击效果,怪物受到了高额伤害,伤害值:" << damage << endl;
     
     		}
     		if (isHold)
     		{
     			cout << "英雄的武器触发了定身效果,怪物停止攻击一回合" << endl;
     		}
     		if (addHp)
     		{
     
     			cout << "英雄的武器触发了吸血效果,英雄" << this->m_Name << "的血量增加了" << addHp << endl;
     		}
     
     	}
     		//设置怪物定身
     		monster->m_Hold = isHold;
     
     		//计算真实伤害
     		int trueDamage = (damage - monster->m_Def) > 0 ? damage - monster->m_Def : 1;
     		monster->m_Hp -= trueDamage;
     
     		this->m_Hp += addHp;
     
     		cout << "英雄" << this->m_Name << "攻击了敌人" << monster->m_Name << "造成了伤害" << trueDamage << endl;
     
     	
     }
    
  9. 接下来我们就要声明怪物类,怪物里除了基本属性外,还有一些特殊属性,比如是否被定身。

     #pragma once
     #include<iostream>
     #include"Weapon.h"
     #include<string>
     #include"Hero.h"
     using namespace std;
     
     class Hero;
     
     class Monster
     {
     public:
     	Monster();
     
     	string m_Name;
     
     	int m_Hp;
     
     	int m_Atk;
     
     	int m_Def;
     
     	bool m_Hold;
     
     	void Attack(Hero * hero);
     }; 
    
  10. 怪物类的实现

    #include"Monster.h"
    
    Monster::Monster()
    {
    	this->m_Hp = 300;
    
    	this->m_Atk = 70;
    
    	this->m_Def = 40;
    
    	this->m_Hold = false;
    
    	this->m_Name = "比克大魔王";
    }
    
    void  Monster::Attack(Hero* hero)
    {
    	if (this->m_Hold)
    	{
    		cout << "怪物" << this->m_Name << "被定身了,本回合无法攻击" << endl;
    		return;
    	}
    
    	//计算攻击的伤害
    	int damage = (this->m_Atk - hero->m_Def ) > 0 ? this->m_Atk - hero->m_Def : 1;
    
    	hero->m_Hp -= damage;
    
    	cout << "怪物" << this->m_Name << "攻击了英雄" << hero->m_Name << "造成了伤害" << damage << endl;
    }
    
  11. 最后就是一个打斗的实现了

    #include<iostream>
    #include"Hero.h"
    #include"Monster.h"
    #include"Weapon.h"
    #include"Knife.h"
    #include"DragonSword.h"
    using namespace std;
    
    void play()
    {
    	//创建怪物
    	Monster * monster = new Monster;
    	//创建英雄
    	Hero *hero = new Hero;
    	//创建武器
    	Weapon * kinfe = new Knife;
    	Weapon * dragon =new DragonSword;
    
    	//让用户选择武器
    	cout << "请选择武器:" << endl;
    	cout << "1. 赤手空拳" << endl;
    	cout << "2. 小刀" << endl;
    	cout << "3. 屠龙刀" << endl;
    
    	int oper;
    	cin >> oper;
    	switch (oper)
    	{
    	case 1:
    		cout << "你真牛X,你还是太年轻了" << endl;
    		break;
    	case 2:
    		hero->EquipWeapon(kinfe);
    		break;
    	case 3:
    		hero->EquipWeapon(dragon);
    		break;
    	default:
    		cout << "没有你要选择的武器" << endl;
    		break;
    	}
    
    	getchar();//输入缓冲区里有个回车,多获取一次值
    
    	int round = 1;
    	while (true)
    	{
    		getchar();
    		system("cls");
    		cout << "--当前第" << round << "回合开始-----" << endl;
    		if (hero->m_Hp <= 0)
    		{
    			cout << "英雄" << hero->m_Name << "已挂,游戏结束" << endl;
    			break;
    		}
    		hero->Attack(monster);
    
    		if (monster->m_Hp <= 0)
    		{
    			cout << "怪物" << monster->m_Name << "已挂,顺利通关" << endl;
    			break;
    		}
    		monster->Attack(hero);
    
    		if (hero->m_Hp <= 0)
    		{
    			cout << "英雄" << hero->m_Name << "已挂,游戏结束" << endl;
    			break;
    		}
    		cout << "英雄" << hero->m_Name << "剩余血量" << hero->m_Hp << endl;
    		cout << "怪物" << monster->m_Name << "剩余血量" << monster->m_Hp << endl;
    
    		round++;
    	}
    
    
    	delete monster;
    	delete hero;
    	delete kinfe;
    	delete dragon;
    
    
    }
    

运行结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值