战斗游戏- c++,给定一个刷出职业,我如何每回合刷出更强的敌人
Combat Game - C++, Given a Spawner Class, How can I spawn stronger enemy every round
我在OOP作业中有一个问题。我必须编码一场1v1的战斗。
这是一款生存游戏,玩家与敌人持续战斗,直到玩家死亡。玩家在前进过程中变得更强大。敌人也变得越来越强大。
我已经创建了两个类,单位和产卵。我们不能使用继承和多态性。我们只能使用类的简单定义。
我的问题是,我不能想到一个简单的方法,使类刷出一个更强大的敌人每一轮。
我想过重载单元的构造函数,但我在操作时遇到了麻烦。
有人能帮忙吗?
这是我的单元头文件(Unit.h):
#pragma once
#include <string>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// Class Types
const string CLASS_WARRIOR = "Warrior" ;
const string CLASS_ASSASSIN = "Assassin";
const string CLASS_MAGE = "Mage" ;
// Class Choices
const int CHOICE_WARRIOR = 1;
const int CHOICE_ASSASSIN = 2;
const int CHOICE_MAGE = 3;
// Multipliers
const double MULTIPLIER_DAMAGE = 0.50f;
const double MULTIPLER_HEAL = 0.30f;
// Advantage
const bool ADVANTAGE = true;
// Win Bonus
const int BONUS_THREE = 3;
const int BONUS_FIVE = 5;
// Minimum and maximum values
const int HIT_RATE_MAX = 80;
const int HIT_RATE_MIN = 20;
const int DAMAGE_MIN = 1;
// Hit or miss
const bool ATTACK_HIT = true;
const bool ATTACK_MISS = false;
class Unit
{
public:
// Constructors
Unit(string name, int classChoice);
// Getters and setters
string getName();
string getClass();
int getHp();
int getMaxHp();
int getPower();
int getVitality();
int getAgility();
int getDexterity();
int getDamage();
int getHeal();
int getBonusDamage();
bool getFirstToAttack();
bool getHit();
void setClassStats(const int classChoice);
// Primary Actions
void attack(Unit* target);
// Secondary Actions
void check(const Unit* target); // Inspects the enemy
void lvlUp(); // Grants this Unit Bonus Stats on Victory
private:
// Info
string mName;
string mClass;
// Basic Stats
int mHp;
int mMaxHp;
int mPower;
int mVitality;
int mAgility;
int mDexterity;
// Derived Stats
int mDamage;
int mHitrate;
int mHeal;
int mBonusDamage;
// Miscellaneous
bool mAdvantage; // If the player has the advantage
string mTargetClass;// This Unit keeps in mind the class of this Unit's Opponent for reference
int mChanceOfHit; // The random chance if the attack will Hit/Miss
bool mFirstToAttack;//if this unit will attack first
bool mHit; // if the attack is a hit or miss
};
这是我的Unit.cpp文件(Unit.cpp):
#include "Unit.h"
Unit::Unit(string name, int classChoice)
{
mName = name;
setClassStats(classChoice);
}
string Unit::getName()
{
return mName;
}
string Unit::getClass()
{
return mClass;
}
int Unit::getHp()
{
return mHp;
}
int Unit::getMaxHp()
{
return mMaxHp;
}
int Unit::getPower()
{
return mPower;
}
int Unit::getVitality()
{
return mVitality;
}
int Unit::getAgility()
{
return mAgility;
}
int Unit::getDexterity()
{
return mDexterity;
}
int Unit::getDamage()
{
return mDamage;
}
int Unit::getHeal()
{
return mHeal;
}
int Unit::getBonusDamage()
{
return mBonusDamage;
}
bool Unit::getFirstToAttack()
{
return mFirstToAttack;
}
bool Unit::getHit()
{
return mHit;
}
void Unit::setClassStats(const int classChoice)
{
if (classChoice == CHOICE_WARRIOR) {
mClass = CLASS_WARRIOR;
mMaxHp = 20;
mHp = mMaxHp;
mPower = 15;
mVitality = 10;
mAgility = 7;
mDexterity = 7;
return;
}
else if (classChoice == CHOICE_ASSASSIN) {
mClass = CLASS_ASSASSIN;
mMaxHp = 15;
mHp = mMaxHp;
mPower = 17;
mVitality = 8;
mAgility = 12;
mDexterity = 10;
return;
}
else if (classChoice == CHOICE_MAGE) {
mClass = CLASS_MAGE;
mMaxHp = 30;
mHp = mMaxHp;
mPower = 12;
mVitality = 12;
mAgility = 9;
mDexterity = 8;
return;
}
throw exception("Error! Class not part of this game. ");
}
void Unit::attack(Unit * target)
{
// Determine Whether the attack will Hit/Miss Based on the hit rate
mChanceOfHit = rrand() % 100 + 1;
if (mChanceOfHit > mHitrate) {
mHit = ATTACK_MISS;
return;
}
// Deducts the targets Hp by the Damage given by this Unit (if the attack didn't miss)
target->mHp -= mDamage;
mHit = ATTACK_HIT;
// if target HP is negative, set it to zero
if (target->mHp < 0) target->mHp = 0;
}
void Unit::check(const Unit * target)
{
// The Unit Keeps in Mind his target's Class
if (target->mClass == CLASS_WARRIOR) mTargetClass = CLASS_WARRIOR;
else if (target->mClass == CLASS_ASSASSIN) mTargetClass = CLASS_ASSASSIN;
else if (target->mClass == CLASS_MAGE) mTargetClass = CLASS_MAGE;
// Checks if the Unit is Advantageous Against his Target
if (mClass == CLASS_WARRIOR) {
if (target->mClass == CLASS_ASSASSIN) mAdvantage = ADVANTAGE;
else mAdvantage = false;
}
else if (mClass == CLASS_ASSASSIN) {
if (target->mClass == CLASS_MAGE) mAdvantage = ADVANTAGE;
else mAdvantage = false;
}
else if (mClass == CLASS_MAGE) {
if (target->mClass == CLASS_WARRIOR) mAdvantage = ADVANTAGE;
else mAdvantage = false;
}
// Determine if this Unit Will Attack first
if (mAgility >= target->mAgility) mFirstToAttack = true;
else mFirstToAttack = false;
// Determines Damage, Bonus Damage ( If Applicable ), and Hit Rate Based on targets stats
mDamage = mPower - target->mVitality;
if (mDamage < DAMAGE_MIN) mDamage = DAMAGE_MIN;
mBonusDamage = mDamage * MULTIPLIER_DAMAGE;
// Evaluates Damage Based on advantage
if (mAdvantage) mDamage += mBonusDamage;
mHitrate = ((float)mDexterity / (float)target->mAgility) * 100;
// Clamps the Hit Rate within the Hit Rate Range
if (mHitrate > HIT_RATE_MAX) mHitrate = HIT_RATE_MAX;
else if (mHitrate < HIT_RATE_MIN) mHitrate = HIT_RATE_MIN;
}
void Unit::lvlUp()
{
// Determine Win Bonus Based on the target that he kept in mind
if (mTargetClass == CLASS_WARRIOR) {
mMaxHp += BONUS_THREE;
mVitality += BONUS_THREE;
}
else if (mTargetClass == CLASS_ASSASSIN) {
mAgility += BONUS_THREE;
mDexterity += BONUS_THREE;
}
else if (mTargetClass == CLASS_MAGE) {
mPower += BONUS_FIVE;
}
// Heals the player 30% of his Maximum HP
mHeal = mMaxHp * MULTIPLER_HEAL;
mHp += mHeal;
}
这是我的产卵头文件(产卵.h):
#pragma once
#include "Unit.h"
class Spawner
{
public:
Spawner();
~Spawner();
void spawn(Unit*& unit);
private:
Unit* mUnit;
int mRandomClass;
};
这是我的spawn .cpp文件(spawn .cpp):
#include "Spawner.h"
Spawner::Spawner()
{
}
Spawner::~Spawner()
{
delete mUnit;
mUnit = NULL;
}
void Spawner::spawn(Unit *& unit)
{
mRandomClass = rand() % 3 + 1;
unit = new Unit("Enemy", mRandomClass);
mUnit = unit;
}
最后是main。cpp:
#include "Unit.h"
#include "Spawner.h"
// Create player
Unit* createPlayer();
// Display Stats
void displayStats(Unit* unit);
// Play 1 round
void playRound(Unit*player, Unit* enemy);
// Simulate 1 attack (implement Higher agility gets to atttack first)
void combat(Unit* player, Unit* enemy);
void main()
{
srand(time(NULL));
Unit* player = createPlayer();
Unit* enemy = NULL;
Spawner *spawner = new Spawner();
int round = 1;
while (true) {
cout << "Round " << round << endl;
spawner->spawn(enemy);
player->check(enemy);
enemy->check(player);
playRound(player, enemy);
// if player is dead, end the game
if (player->getHp() == 0) break;
// else, add stats
player->lvlUp();
delete enemy;
enemy = NULL;
cout << "You defeted an enemy" << endl;
system("pause>nul");
system("cls");
round++;
}
cout << "You were defeted! " << endl;
cout << "You survived until Round " << round << endl;
displayStats(player);
delete player;
player = NULL;
delete spawner;
spawner = NULL;
system("pause>nul");
system("cls");
}
Unit* createPlayer()
{
Unit* unit = NULL;
string name;
int classChoice;
cout << "Enter your Name: ";
getline(cin, name);
system("cls");
cout << "Pick a class: " << endl
<< "t [ 1 ] Warrior" << endl
<< "t [ 2 ] Assassin" << endl
<< "t [ 3 ] Mage" << endl
<< endl;
cin >> classChoice;
while (classChoice > 3 || classChoice <= 0) {
cout << "INVALID INPUT! Please try again" << endl;
cout << "Pick a class: " << endl
<< "t [ 1 ] Warrior" << endl
<< "t [ 2 ] Assassin" << endl
<< "t [ 3 ] Mage" << endl
<< endl;
cin >> classChoice;
}
unit = new Unit(name, classChoice);
return unit;
}
void displayStats(Unit* unit)
{
cout << "=========================================================================================" << endl
<< "Name: " << unit->getName() << " t t t HP: " << unit->getHp() << " / " << unit->getMaxHp() << endl
<< "Class: " << unit->getClass() << endl
<< "==========================================================================================" << endl
<< "POW: " << unit->getPower() << endl
<< "VIT: " << unit->getVitality() << endl
<< "AGI: " << unit->getAgility() << endl
<< "DEX: " << unit->getDexterity() << endl
<< endl;
}
void playRound(Unit*player, Unit* enemy)
{
while (player->getHp() > 0 && enemy->getHp() > 0) {
displayStats(player);
displayStats(enemy);
system("pause>nul");
combat(player, enemy);
system("cls");
}
}
void combat(Unit* player, Unit* enemy)
{
if (player->getFirstToAttack()) {
player->attack(enemy);
if (player->getHit() == ATTACK_MISS) cout << player->getName() << "'s Attack Missed! " << endl;
else if (player->getHit() == ATTACK_HIT) cout << player->getName() << " dealt " << player->getDamage() << " Damage" << endl;
system("pause>nul");
if (enemy->getHp() == 0) return;
enemy->attack(player);
if (enemy->getHit() == ATTACK_MISS) cout << enemy->getName() << "'s Attack Missed! " << endl;
else if (enemy->getHit() == ATTACK_HIT) cout << enemy->getName() << " dealt " << enemy->getDamage() << " Damage" << endl;
system("pause>nul");
return;
}
else if (enemy->getFirstToAttack()) {
enemy->attack(player);
if (enemy->getHit() == ATTACK_MISS) cout << enemy->getName() << "'s Attack Missed! " << endl;
else if (enemy->getHit() == ATTACK_HIT) cout << enemy->getName() << " dealt " << enemy->getDamage() << " Damage" << endl;
system("pause>nul");
if (player->getHp() == 0) return;
player->attack(enemy);
if (player->getHit() == ATTACK_MISS) cout << player->getName() << "'s Attack Missed! " << endl;
else if (player->getHit() == ATTACK_HIT) cout << player->getName() << " dealt " << player->getDamage() << " Damage" << endl;
system("pause>nul");
return;
}
}
为Unit
类添加一个"等级",并使用该等级来增加单位的属性(例如,等级2可能意味着属性乘以1.5或诸如此类)。将level
作为参数传递给构造函数,类似于units类。
你需要让你的刷出器知道它已经刷出了多少敌人:
// this belongs into your class definition, it should start at zero
int mCurrentSpawn;
因此在构造函数中将其设置为0:
Spawner::Spawner()
{
mCurrentSpawn = 0;
}
然后当你刷出敌人时引用它:
void Spawner::spawn(Unit *& unit)
{
mRandomClass = rand() % 3 + 1;
unit = new Unit("Enemy", mRandomClass);
mUnit = unit;
mCurrentSpawn++;
int levelUps = mCurrentSpawn - 1;
while(levelUps > 0)
{
mUnit->lvlUp();
levelUps--;
}
}
相关文章:
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 没有为自己的结构调用列表推回方法
- 架构决策:返回std::future还是提供回调
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 正在为Xtensa simcall函数编写回调函数
- C++:正在检查LinkedList中的回文-递归方法-错误
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 如何在C++中使用非静态成员函数作为回调函数
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 存储模板类型以强制转换回派生<T>
- Python中的for循环与C++有何不同
- avrogencpp能为模式中的每种类型生成单独的头文件吗
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 维护unordered_map但同时每一步都需要最低的映射值
- Usaco第1.6节主要回文
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在GLUT中每秒产生2个敌人
- 全局排序和每原子变量排序有何不同
- Std::ostream,为每行调用一个回调
- 战斗游戏- c++,给定一个刷出职业,我如何每回合刷出更强的敌人