【C++】小游戏:怪物英雄

发布于:2024-05-17 ⋅ 阅读:(147) ⋅ 点赞:(0)

目录

一、游戏需求

二、程序架构

三、代码实现

四、实现效果


一、游戏需求

有一个英雄,和一个怪物:
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;
}

四、实现效果


网站公告

今日签到

点亮在社区的每一天
去签到