玩法规则:
这篇博客介绍一个控制台输出的以探险为主题的小游戏,是文字形式的回合制游戏。
游戏开始后,玩家控制随机的7名冒险者,他们分为由四种职业,每个职业有不同的技能:
七名冒险者在20个关卡中前进,每个关卡都有可能遭遇怪兽,怪物的数量和种类是完全随机的,种类分为五种:
(其实这个游戏的自由发挥空间非常大,以上这些角色都是现编的,可以随便改)
当冒险家受到近距离攻击时,下个回合就只能用近距离攻击来反击,这是法师的软肋。每通过一个关卡,都会有随机奖励,比如增强血量上限的药水等。在没有怪物的关卡就什么都不会发生(其实可以加一些偶遇商店什么的,我没加),通过所有关卡就通关了,就这么简单。
代码:
该游戏主要是玩法逻辑比较麻烦,架构的思路很清晰,如下:
下面上代码。
首先是Creature类,游戏中的所有游戏对象都会继承自它:
#include<iostream>
#include <vector>
using namespace std;
#ifndef CREATURE_H
#define CREATURE_H
class Creature
{
protected:
int m_id;//编号
int m_maxhp;//最大血量
int m_curhp;//目前血量
int m_armor;//护甲值
int m_basedamage;//基础伤害
public:
Creature(){}
virtual ~Creature(){}
void BeDamaged(const int damage)
{
int delta(damage);
if (m_armor > 0)
{
if (damage < m_armor)
{
m_armor -= damage;
return;
}
else
{
delta = damage - m_armor;
m_armor = 0;
}
}
if(m_curhp>0)
m_curhp -= delta;
}
int ReturnRandom() const{return (rand() % 5);}
void AddArmor(const int armor) {m_armor += armor;}
int GetHp()const { return m_curhp; }
int GetBaseDamage()const { m_basedamage; }
int GetId() const{ return m_id; }
};
#endif
然后是冒险者基类和怪物基类,继承自生物类。
Adventurer类:
#include <string.h>
#include "Creature.h"
#ifndef ADVENTURE_H
#define ADVENTURE_H
enum AdventureType
{
Warriors,
Rogues,
OffensiveMages,
DefensiveMages,
};
class Adventurer:public Creature
{
protected:
AdventureType m_type;
string m_name;
int m_age;
int m_money;
bool m_isattackedbyclose;
public:
Adventurer(int basedamage,string name,int age,AdventureType type,int id)
:m_name(name),m_age(age),m_type(type)
{
m_basedamage = basedamage;
m_id = id;
m_maxhp = 100;
m_curhp = m_maxhp;
m_armor = 0;
m_money = 0;
m_isattackedbyclose = false;
}
virtual ~Adventurer(){}
virtual void CloseAttack(Creature&one) = 0;
virtual void DistanceAttackNoMp(Creature&a){}
virtual bool DistanceMagic(Creature&a) { return false; }
virtual bool DistanceMagic(Creature&a, Creature&b) { return false; }
virtual bool DistanceMagic(Creature&a, Creature&b, Creature&c) { return false; }
virtual void MpRestore(){}
AdventureType ReturnType() const{ return m_type; }//返回该冒险者的类型
void HpRestore() { m_curhp =m_maxhp; }
void AddMaxHp(int delta)
{
m_maxhp += delta;
m_curhp = m_maxhp;
}
string GetName()const { return m_name; }
int GetAge()const { return m_age; }
int GetMoney()const { return m_money; }
void AddMoney(const int delta) { m_money += delta; }
void AddBaseDamaged(const int delta) { m_basedamage += delta; }
bool IsAttackedByClose() { return m_isattackedbyclose; }
void SetAttackedByClose(bool attacked) { m_isattackedbyclose = attacked; }
int GetArmor() { return m_armor; }
};
#endif
Monster类:
#include <string.h>
#include "Creature.h"
#ifndef MONSTER_H
#define MONSTER_H
enum MonsterType
{
TIGER,
EAGLE,
WITCH,
MUMMY,
DRAGON,
};
class Monster :public Creature
{
protected:
MonsterType m_type;
public:
Monster(int basedamage, MonsterType type,int id):m_type(type)
{
m_id = id;
m_basedamage = basedamage;
m_maxhp = 100;
m_curhp = m_maxhp;
m_armor = 0;
}
virtual ~Monster() {}
virtual void CloseAttack(Creature&one) = 0;
virtual void DistanceAttackNoMp(Creature&a) {}
virtual bool DistanceMagic(Creature&a) { return false; }
virtual bool DistanceMagic(Creature&a, Creature&b) { return false; }
virtual bool DistanceMagic(Creature&a, Creature&b, Creature&c) { return false; }
virtual void KillSky(vector<Adventurer*>&all){}
virtual bool IsUsedKS() const { return false; }
MonsterType ReturnType() const { return m_type; }//返回该怪兽的类型
void AddHp(int delta)
{
m_curhp += delta;
if (m_curhp > m_maxhp)m_curhp = m_maxhp;
}
};
#endif
在冒险者基类的基础上,创建四个不同职业的冒险者类:
#include "Adventurer.h"
#ifndef WARRIOR_H
#define WARRIOR_H
class Warrior:public Adventurer
{
public:
Warrior( string name, int age,int id):
Adventurer(23, name, age, Warriors,id)
{}
~Warrior() {}
//近距离攻击
void CloseAttack(Creature&one)
{
one.BeDamaged(m_basedamage + ReturnRandom());
}
};
#endif
#include "Adventurer.h"
#ifndef ROGUE_H
#define ROGUE_H
class Rogue :public Adventurer
{
private:
int m_distancedamage;
public:
Rogue(string name, int age,int id):
Adventurer(15, name, age, Rogues,id),m_distancedamage(17)
{}
~Rogue() {}
//盗贼近距离攻击可吸血
void CloseAttack(Creature&one)
{
one.BeDamaged(m_basedamage + ReturnRandom());
m_curhp += m_basedamage;
cout << "吸取" << m_basedamage << "点血量!" << endl;
if (m_curhp > m_maxhp)m_curhp = m_maxhp;
}
//远距离无蓝攻击
void DistanceAttackNoMp(Creature&one)
{
one.BeDamaged(m_distancedamage + ReturnRandom());
}
};
#endif
#include "Adventurer.h"
#ifndef OFFENSIVEMAGE_H
#define OFFENSIVEMAGE_H
class OffensiveMage :public Adventurer
{
private:
int m_distancedamage;
int m_maxmp;
int m_curmp;
public:
OffensiveMage(string name, int age,int id) :
Adventurer(7, name, age, OffensiveMages,id), m_distancedamage(27), m_maxmp(100), m_curmp(m_maxmp)
{}
~OffensiveMage() {}
//近距离攻击
void CloseAttack(Creature&a)
{
a.BeDamaged(m_basedamage + ReturnRandom());
}
//远距离无蓝攻击
void DistanceAttackNoMp(Creature&a)
{
a.BeDamaged