欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-18 16:57:28
...


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

英雄

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

#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

运行结果

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

总结说明

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

添加倚天剑实现多态

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

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