目录
一、游戏需求
有一个英雄,和一个怪物:
1.
我们可以在终端初始化英雄的血量、蓝量,和攻击力,以及怪物的血量和攻击力。
2.
英雄有
4
个技能,每个技能都有一定的伤害(或者能够加血),但是需要消耗一定的蓝量(可
以在代码中写死)。(可以考虑冷却时间,比如说,第一个技能
3
个回合才能放一次)。
3.
游戏是回合制游戏,英雄可以放技能以及普通攻击,怪物只能普通攻击。 首先是英雄攻击,然
后是怪物攻击。然后再是英雄攻击,接着是怪物攻击。依次循 环。 英雄可以通过键盘的输入
来选择技能还是普通攻击,但是如果英雄蓝量不够的话,就 没法放技能,因此攻击失败,此回
合不会造成任何伤害。 每个回合结束后英雄会回复一定的蓝量。(随着回合的增加,英雄的蓝
量回复能力增 强)
4.
输出最终获胜的结果。
5.
可以通过输入
q
,结束游戏。 在回合中,可以输入某个命令来查看双方的信息(英雄的血量、
蓝量,攻击力、回复能力以及怪物 的血量,攻击力)
二、程序架构
(1) 文件分析:构建People类、Monster类、Hero类和Menu类。其中Monster类和Hero类继承People类,并实现People类中的“普通攻击”函数。因此,存在"People.h"、 "Monster.h"、 "Hero.h"、 "People.cpp"、 "Monster.cpp"、"Hero.cpp"、 "Menu.h"、 "Menu.cpp"、"main.cpp"九个文件。
(2) 对象分析:
- People:【属性】血量HP、攻击力attackPower【方法】普通攻击
- Monster:【新增属性】无【新增方法】受伤
- Hero:【新增属性】蓝量MP【新增方法】其他技能
- Menu:【属性】回合数total【方法】显示界面、其他选项的界面
三、代码实现
【1】People.h如下:
#pragma once
/***********************************************************
* @类名: People
* @摘要: 是Monster和Hero的父类
* @作者: 柯同学
* @注意: 抽象类,不可实例化
*********************************************************/
class People
{
protected:
int HP; //血量
int attackPower; //攻击力
public:
void setHP(int HP);
int getHP();
void setAttackPower(int attackPower);
int getAttackPower();
void hurt(int hurtValue); //受伤:血量减少hurtValue
virtual void normalAttack(class People &people) = 0; //虚函数:普通攻击
virtual ~People() {} //虚析构函数:防止内存泄露
};
【2】People.cpp如下:
#include "People.h"
/***********************************************************
* @函数名:setHP
* @功 能:设置属性HP
* @参 数:HP---要设置的属性
* @返回值:无
*********************************************************/
void People::setHP(int HP) {
this->HP = HP;
}
/***********************************************************
* @函数名:getHP
* @功 能:获取属性HP
* @参 数:无
* @返回值:属性HP
*********************************************************/
int People::getHP() {
return this->HP;
}
/***********************************************************
* @函数名:setAttackPower
* @功 能:设置属性attackPower
* @参 数:attackPower---要设置的属性
* @返回值:无
*********************************************************/
void People::setAttackPower(int attackPower) {
this->attackPower = attackPower;
}
/***********************************************************
* @函数名:getAttackPower
* @功 能:获取属性attackPower
* @参 数:无
* @返回值:属性attackPower
*********************************************************/
int People::getAttackPower() {
return this->attackPower;
}
/***********************************************************
* @函数名:hurt
* @功 能:受伤,减少HP
* @参 数:hurtValue---伤害值
* @返回值:无
*********************************************************/
void People::hurt(int hurtValue) {
this->HP -= hurtValue;
}
【3】Monster.h如下:
#pragma once
#include <iostream>
#include "People.h"
/***********************************************************
* @类名: Monster
* @摘要: 是People的子类
* @作者: 柯同学
* @注意: 实现纯虚函数normalAttack才能实例化
*********************************************************/
class Monster : public People
{
public:
Monster();
Monster(int hp, int attack);
virtual void normalAttack(class People& people) override; //普通攻击
};
【4】Monster.cpp如下:
#include "Monster.h"
/***********************************************************
* @函数名:Monster
* @功 能:无参的构造函数
* @参 数:无
* @返回值:无
*********************************************************/
Monster::Monster() {
this->HP = 0;
this->attackPower = 0;
}
/***********************************************************
* @函数名:Monster
* @功 能:两个参数的构造函数
* @参 数:hP---要设置的属性HP
* @参 数:attack---要设置的属性attackPower
* @返回值:无
*********************************************************/
Monster::Monster(int hp, int attack) {
this->HP = hp;
this->attackPower = attack;
}
/***********************************************************
* @函数名:normalAttack
* @功 能:怪物类的普通攻击
* @参 数:people---攻击的对象
* @返回值:无
*********************************************************/
void Monster::normalAttack(class People& people){
std::cout << "【怪物】 普通攻击 -----> 英雄损失" << this->attackPower << "血量" << "\n\n" << std::endl;
people.hurt(this->attackPower);
}
【5】Hero.h如下:
#pragma once
#include <iostream>
#include "People.h"
#define PEACH_MP 15 //桃花灼灼消耗的蓝量
#define PEACH_ADD 10 //桃花灼灼回复的血量
#define HAND_MP 20 //千手浮屠消耗的蓝量
#define HAND_HURT 25 //千手浮屠的伤害
#define THUNDER_MP 40 //万雷天牢引消耗的蓝量
#define THUNDER_HURT 45 //万雷天牢引的伤害
#define HP_MAX 100 //血量上限
#define MP_MAX 50 //蓝量上限
/***********************************************************
* @类名: Hero
* @摘要: 是People的子类
* @作者: 柯同学
* @注意: 实现纯虚函数normalAttack才能实例化
*********************************************************/
class Hero : public People
{
private:
int MP; //蓝量
int MP_Recover = 1; //回合结束回复的蓝量值 (每回合多回复1点)
public:
Hero();
Hero(int hp, int mp, int attack);
void setMP(int MP);
int getMP();
void recoverMP(); //每回合结束回复蓝量
virtual void normalAttack(class People& people) override;//普通攻击
void peachBlossom(); //桃花灼灼:耗蓝PEACH_MP,补血PEACH_ADD
void handHurt(class People& people); //千手浮屠:耗蓝HAND_MP,伤害HAND_HURT
void thunderHurt(class People& people); //万雷天牢引:耗蓝THUNDER_MP,伤害THUNDER_HURT
};
【6】Hero.cpp如下:
#include "Hero.h"
/***********************************************************
* @函数名:Hero
* @功 能:无参的构造函数
* @参 数:无
* @返回值:无
*********************************************************/
Hero::Hero() {
this->HP = 0;
this->MP = 0;
this->attackPower = 0;
}
/***********************************************************
* @函数名:Hero
* @功 能:三个参数的构造函数
* @参 数:hp---设置的属性HP
* @参 数:mp---设置的属性MP
* @参 数:attack---设置的属性attackPower
* @返回值:无
*********************************************************/
Hero::Hero(int hp, int mp, int attack) {
this->HP = hp;
this->MP = mp;
this->attackPower = attack;
}
/***********************************************************
* @函数名:setMP
* @功 能:设置属性MP
* @参 数:MP---设置的属性值
* @返回值:无
*********************************************************/
void Hero::setMP(int MP) {
this->MP = MP;
}
/***********************************************************
* @函数名:getMP
* @功 能:获取属性MP
* @参 数:无
* @返回值:获取的属性
*********************************************************/
int Hero::getMP() {
return this->MP;
}
/***********************************************************
* @函数名:recoverMP
* @功 能:回合结束英雄回复蓝量MP
* @参 数:无
* @返回值:无
*********************************************************/
void Hero::recoverMP() {
//回蓝不超过蓝量上限
this->MP += (this->MP_Recover)++;//随着回合数增加,回蓝能力提升1点
if (this->MP > MP_MAX) {
this->MP = MP_MAX;
}
}
/***********************************************************
* @函数名:normalAttack
* @功 能:英雄普通攻击
* @参 数:people---攻击的对象
* @返回值:无
*********************************************************/
void Hero::normalAttack(class People& people) {
std::cout << "【英雄】 普通攻击 -----> 怪物损失" << this->attackPower << "血量" << std::endl;
people.hurt(this->attackPower);
}
/***********************************************************
* @函数名:peachBlossom
* @功 能:英雄技能:桃花灼灼
* 回复血量PEACH_ADD,消耗蓝量PEACH_MP
* @参 数:无
* @返回值:无
*********************************************************/
void Hero::peachBlossom() {
//蓝量不足
if (this->MP < PEACH_MP) {
std::cout << "【英雄】 MP不足,桃花灼灼失败" << std::endl;
return;
}
//蓝量减少,不低于0
this->MP -= PEACH_MP;
if (this->MP < 0) {
this->MP = 0;
}
//回血不超过血量上限
int HP_Pre = this->HP;
this->HP += PEACH_ADD;
if (this->HP > HP_MAX) {
this->HP = HP_MAX;
}
std::cout << "【英雄】 桃花灼灼 -----> 英雄回复" << this->HP - HP_Pre << "血量" << std::endl;
}
/***********************************************************
* @函数名:handHurt
* @功 能:英雄技能:千手浮屠
* 伤害HAND_HURT,消耗蓝量HAND_MP
* @参 数:people---攻击的对象
* @返回值:无
*********************************************************/
void Hero::handHurt(class People& people) {
//蓝量不足
if (this->MP < HAND_MP) {
std::cout << "【英雄】 MP不足,千手浮屠失败" << std::endl;
return;
}
//蓝量减少,不低于0
this->MP -= HAND_MP;
if (this->MP < 0) {
this->MP = 0;
}
//怪物受伤
people.hurt(HAND_HURT);
std::cout << "【英雄】 千手浮屠 -----> 怪物损失" << HAND_HURT << "血量" << std::endl;
}
/***********************************************************
* @函数名:thunderHurt
* @功 能:英雄技能:万雷天牢引
* 伤害THUNDER_HURT,消耗蓝量THUNDER_MP
* @参 数:people---攻击的对象
* @返回值:无
*********************************************************/
void Hero::thunderHurt(class People& people) {
//蓝量不足
if (this->MP < THUNDER_MP) {
std::cout << "【英雄】 MP不足,万雷天牢引失败" << std::endl;
return;
}
//蓝量减少,不低于0
this->MP -= THUNDER_MP;
if (this->MP < 0) {
this->MP = 0;
}
//怪物受伤
people.hurt(THUNDER_HURT);
std::cout << "【英雄】 万雷天牢引 -----> 怪物损失" << THUNDER_HURT << "血量" << std::endl;
}
【7】Menu.h如下:
#pragma once
#include <iostream>
#include "Hero.h"
#include "Monster.h"
/***********************************************************
* @类名: Menu
* @摘要: 封装了菜单等功能
* @作者: 柯同学
* @注意: 无
*********************************************************/
class Menu
{
private:
int total; //游戏的回合数
void returnMenu(); //返回主菜单
public:
Menu() : total(1){}
void showMenu(); //显示主菜单
void introduceGame(); //游戏简介
void viewProperty(class Hero& hero, class Monster& monster);//查看属性
void setMonster(class Monster& monster); //设置怪物
void setHero(class Hero& hero); //设置英雄
void startGame(class Hero& hero, class Monster& monster); //开始游戏
};
【8】Menu.cpp如下:
#include "Menu.h"
using namespace std;
/***********************************************************
* @函数名:showMenu
* @功 能:显示游戏主界面
* @参 数:无
* @返回值:无
*********************************************************/
void Menu::showMenu() {
cout << "*****************************************" << endl;
cout << "**************游戏: 怪物英雄*************" << endl;
cout << "******** 1.游戏简介 2.查看属性 ********" << endl;
cout << "******** 3.设置怪物 4.设置英雄 ********" << endl;
cout << "******** 5.开始作战 6.退出游戏 ********" << endl;
cout << "*****************************************" << endl;
cout << "请输入选项:";
}
/***********************************************************
* @函数名:returnMenu
* @功 能:返回游戏主界面的按键判断
* @参 数:无
* @返回值:无
*********************************************************/
void Menu::returnMenu() {
cout << "请按0键返回主菜单!";
int tmp = -1;
while (1) {
cin >> tmp;
if (tmp != 0)
cout << "按键无效!请重新输入:";
else
break;
}
}
/***********************************************************
* @函数名:introduceGame
* @功 能:游戏简介
* @参 数:无
* @返回值:无
*********************************************************/
void Menu::introduceGame() {
cout << "************************游戏简介************************" << endl;
cout << "【概述】你将扮演一名英雄,去使用你的技能战胜怪物!" << endl;
cout << "【英雄】有血量、蓝量和攻击力三种属性。" << endl;
cout << " 当血量低于0时,英雄死亡。" << endl;
cout << " 每回合结束时,蓝量会自动回复一定数值。" << endl;
cout << " 回复的蓝量会随着回合数增加而增加。" << endl;
cout << "【怪物】有血量和攻击力两种属性。" << endl;
cout << " 怪物只会进行普通攻击。" << endl;
cout << "********************************************************" << endl;
this->returnMenu();
}
/***********************************************************
* @函数名:viewProperty
* @功 能:查看怪物和英雄属性
* @参 数:无
* @返回值:无
*********************************************************/
void Menu::viewProperty(class Hero& hero, class Monster& monster){
cout << "****************查看属性*****************" << endl;
cout << "【英雄】血量: " << hero.getHP() << ", 蓝量: " << hero.getMP() << ", 攻击力: " << hero.getAttackPower() << endl;
cout << "【怪物】血量: " << monster.getHP() << ", 攻击力: " << monster.getAttackPower() << endl;
cout << "*****************************************" << endl;
this->returnMenu();
}
/***********************************************************
* @函数名:setHero
* @功 能:设置英雄的属性
* @参 数:无
* @返回值:无
*********************************************************/
void Menu::setHero(class Hero& hero) {
cout << "****************设置英雄*******************" << endl;
cout << "* 提示: 英雄HP最大值为 " << HP_MAX << ", MP最大值为 " << MP_MAX << " *" << endl;
cout << "*******************************************" << endl;
int HP_tmp, MP_tmp, attack_tmp;
cout << "请输入英雄的血量(HP): ";
cin >> HP_tmp;
hero.setHP(HP_tmp);
cout << "请输入英雄的蓝量(MP): ";
cin >> MP_tmp;
hero.setMP(MP_tmp);
cout << "请输入英雄的攻击力: ";
cin >> attack_tmp;
hero.setAttackPower(attack_tmp);
cout << "设置英雄成功!" << endl;
cout << "【英雄】血量: " << hero.getHP() << ", 蓝量: " << hero.getMP() << ", 攻击力: " << hero.getAttackPower() << endl;
cout << "*******************************************" << endl;
this->returnMenu();
}
/***********************************************************
* @函数名:setMonster
* @功 能:设置怪物的属性
* @参 数:无
* @返回值:无
*********************************************************/
void Menu::setMonster(class Monster& monster) {
cout << "****************设置怪物*******************" << endl;
int HP_tmp, attack_tmp;
cout << "请输入怪物的血量(HP): ";
cin >> HP_tmp;
monster.setHP(HP_tmp);
cout << "请输入怪物的攻击力: ";
cin >> attack_tmp;
monster.setAttackPower(attack_tmp);
cout << "设置怪物成功!" << endl;
cout << "【怪物】血量: " << monster.getHP() << ", 攻击力: " << monster.getAttackPower() << endl;
cout << "*******************************************" << endl;
this->returnMenu();
}
/***********************************************************
* @函数名:startGame
* @功 能:开始回合制游戏,英雄先攻(可选3个技能+1个普通攻击)
* @参 数:hero---创建的英雄对象
* @参 数:monster---创建的怪物对象
* @返回值:无
*********************************************************/
void Menu::startGame(class Hero& hero, class Monster& monster) {
while (1) {
//玩家回合信息提示
cout << "****************玩家回合" << (this->total)++ << "*****************" << endl;
cout << "------【n】查看属性【q】结束游戏 ------" << endl;
cout << "------【1】普通攻击【2】桃花灼灼 ------" << endl;
cout << "------【3】千手浮屠【4】万雷天牢引 ------" << endl;
cout << "****************************************" << endl;
cout << "请输入您的选择: ";
char gameKey;
cin >> gameKey;
//不同选项
switch (gameKey) {
case 'n':
cout << "【英雄】血量: " << hero.getHP() << ", 蓝量: " << hero.getMP() << ", 攻击力: " << hero.getAttackPower() << endl;
cout << "【怪物】血量: " << monster.getHP() << ", 攻击力: " << monster.getAttackPower() << "\n\n" << endl;
break;
case 'q':
this->returnMenu();
return;
case '1':
hero.normalAttack(monster);
monster.normalAttack(hero);
hero.recoverMP();
break;
case '2':
hero.peachBlossom();
monster.normalAttack(hero);
hero.recoverMP();
break;
case '3':
hero.handHurt(monster);
monster.normalAttack(hero);
hero.recoverMP();
break;
case '4':
hero.thunderHurt(monster);
monster.normalAttack(hero);
hero.recoverMP();
break;
}
//判定死亡
if (monster.getHP() <= 0 && hero.getHP() > 0) {
cout << "怪物死亡,游戏胜利!" << endl;
break;
}
if (monster.getHP() > 0 && hero.getHP() <= 0) {
cout << "英雄死亡,游戏失败!" << endl;
break;
}
if (monster.getHP() <= 0 && hero.getHP() <= 0) {
cout << "游戏平局,再接再厉!" << endl;
break;
}
}
this->returnMenu();
}
【9】main.cpp如下:
#include <iostream>
#include <stdlib.h>
#include "People.h"
#include "Monster.h"
#include "Hero.h"
#include "Menu.h"
int main()
{
//创建相关对象
class Menu menu;
class Hero hero(100, 50, 15);
class Monster monster(110, 5);
//主循环
while (1) {
int keyNumber = -1;
// 显示菜单
system("cls");
menu.showMenu();
std::cin >> keyNumber;
// 不同模式
switch (keyNumber) {
case 1://游戏简介
system("cls");
menu.introduceGame();
break;
case 2://查看属性
system("cls");
menu.viewProperty(hero, monster);
break;
case 3://设置怪物
system("cls");
menu.setMonster(monster);
break;
case 4://设置英雄
system("cls");
menu.setHero(hero);
break;
case 5://开始作战
system("cls");
menu.startGame(hero, monster);
break;
case 6://退出游戏
return 0;
default:
std::cout << "按键值输入有误,请重新输入!" << std::endl;
}
}
return 0;
}