C++学习笔记 —— 回合制小游戏案例


下面用多态实现一个回合制小游戏:

英雄

Hero.h

#ifndef __HERO_H__
#define __HERO_H__

class Weapon;
class Monster;
class Hero
{

public:
    Hero(/* args */);
    ~Hero();

    std::string m_Name;
    int m_Atk;
    int m_Def;
    int m_Hp;
    Weapon *weapon;

    void EquipWeapon(Weapon *weapon);
    void Attack(Monster *binbin);
};

#endif

Hero.cc

#include <iostream>
#include "Weapon.h"
#include "Monster.h"
#include "Hero.h"

using namespace std;

Hero::Hero(/* args */)
{
    this->m_Hp = 300;
    this->m_Atk = 50;
    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->getBaseDamage();
        //计算吸血
        addHp = this->weapon->getSuckBlood();
        //计算定神
        isHold = this->weapon->getHold();
        //计算暴击
        isCrit = this->weapon->getCrit();
    }
    if (isCrit) //暴击,伤害,加成
    {
        damage = damage * 2;
        cout << "触发暴击伤害: " << damage << endl;
    }
    if (isHold)
    {
        cout << "武器触发定身效果。" << endl;
    }
    if (addHp > 0)
    {
        cout << "触发吸血效果,英雄增加血量:" << 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;
}
Hero::~Hero()
{
}

怪物

Monster.h

#ifndef __MONSTER_H__
#define __MONSTER_H__


class Hero;
class Monster
{
private:
    /* data */
public:
    Monster(/* args */);
    ~Monster();

    int m_Hp;
    int m_Atk;
    int m_Def;
    int m_Hold;
    void Attack(Hero *hero);
    std::string m_Name;
};

#endif

Monster.cc

#include <iostream>

#include "Monster.h"
#include "Hero.h"

using namespace std;

Monster::Monster(/* args */)
{
    this->m_Hp = 200;
    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;
    
}

Monster::~Monster()
{
}

武器

武器父类

Weapon.h

#ifndef __WEAPON_H__
#define __WEAPON_H__

//抽象类
class Weapon
{
public:
    //  纯虚函数
    virtual int getBaseDamage() = 0;
    virtual int getSuckBlood() = 0;
    virtual bool getHold() = 0;
    virtual bool getCrit() = 0;
    virtual ~Weapon()
    {
    }

    std::string m_WeaponName; //武器名称
    int m_BaseDamage;         //基础伤害
};

#endif

小刀

Knife.h

#ifndef __KNIFE_H__
#define __KNIFE_H__

#include "Weapon.h"

class Knife : public Weapon
{
public:
    Knife();
    //子类要实现就不写成纯虚函数了
    virtual int getBaseDamage();
    virtual int getSuckBlood();
    virtual bool getHold();
    virtual bool getCrit();
};

#endif

Knife.cc

#include <iostream>
#include "Knife.h"

//构造函数
Knife::Knife(){
    this->m_BaseDamage = 10;
    this->m_WeaponName = "小刀";
}
int Knife::getBaseDamage(){
    return m_BaseDamage;
}
int Knife::getSuckBlood(){
    return 0;
}
bool Knife::getHold(){
    return false;
}
bool Knife::getCrit(){
    return false;
}

屠龙刀

DragonSword.h

#ifndef __DRAGONSWORD_H__
#define __DRAGONSWORD_H__
#include "Weapon.h"

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);

};
#endif

DragonSword.cc

扫描二维码关注公众号,回复: 10992920 查看本文章
#include <iostream>
#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 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)
{
    int num = rand() % 100 + 1; // 1-100
    if (num < Rate)
    {
        return true;
    }

    return false;
}

开始游戏main函数

playgame.cc

#include <iostream>
#include "Hero.h"
#include "Monster.h"
#include "Weapon.h"
#include "Knife.h"
#include "DragonSword.h"

using namespace std;

int main()
{
    //创建怪物
    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 << "赤手空拳干!" << endl;
        break;
    case 2:
        hero->EquipWeapon(kinfe);
        break;
    case 3:
        hero->EquipWeapon(dragon);
        break;
    default:
        break;
    }

    int round = 1;
    while (true)
    {
        getchar();
        cout << "------当前为第 " << round << "回合------" << endl;

        //英雄和怪物互相攻击
        hero->Attack(monster);
        monster->Attack(hero);

        cout << "英雄剩余血量: " << hero->m_Hp << endl;
        cout << "怪物剩余血量: " << monster->m_Hp << endl;

        //英雄与怪物死亡判断
        if (hero->m_Hp <= 0)
        {
            cout << "英雄死亡,游戏结束" << endl;
            break;
        }
        if (monster->m_Hp <= 0)
        {
            cout << "怪物死亡,游戏结束" << endl;
            break;
        }
        round++;
    }

    //释放
    delete hero;
    delete monster;
    delete kinfe;
    delete dragon;
}

编译运行:

g++ playgame.cc Monster.cc Hero.cc DragonSword.cc Knife.cc -o play
./play

运行结果

在这里插入图片描述

总结说明

我们通过武器类实现多态,当我们要扩展武器的时候,只需要添加新武器类型,就可以使用新的武器。
比如添加一个倚天剑:

添加倚天剑实现多态

我的倚天剑继承屠龙刀属性和函数,所以我仅修改倚天剑的参数属性就可以了。

SkySword.h

#ifndef __SKYSWORD_H__
#define __SKYSWORD_H__
#include "DragonSword.h"

class SkySword : public DragonSword
{
public:
    SkySword();

    //继承了DragonSword的成员函数与变量
    //虚函数与普通函数区别就是用于多态。虚函数是用来重写进行多态的。也可以继承来使用。
    //纯虚函数则子类必须重写。

};
#endif

SkySword.cc

#include <iostream>
#include "SkySword.h"


SkySword::SkySword()
{
    this->m_BaseDamage = 30;
    this->m_WeaponName = "倚天剑";

    this->suckRate = 50;//吸血概率
    this->holdRate = 30;
    this->critRate = 50;//暴击概率
}

main函数中添加判断

 //创建怪物
    Monster *monster = new Monster;
    //创建英雄
    Hero *hero = new Hero;
    //创建武器
    Weapon *kinfe = new Knife;
    Weapon *dragon = new DragonSword;
    Weapon *skySword = new SkySword;

    cout << "选择一个武器:" << endl;
    cout << "1. 赤手空拳" << endl;
    cout << "2. 小刀" << endl;
    cout << "3. 屠龙刀" << endl;
    cout << "4. 倚天剑" << endl;

    int oper;
    cin >> oper;
    switch (oper)
    {
    case 1:
        cout << "赤手空拳干!" << endl;
        break;
    case 2:
        hero->EquipWeapon(kinfe);
        break;
    case 3:
        hero->EquipWeapon(dragon);
        break;
    case 4:
        hero->EquipWeapon(skySword);
        break;
    default:
        break;
    }
发布了103 篇原创文章 · 获赞 94 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/chongbin007/article/details/104459243