我是c++新手,我在大学学过java。我试图从一个小型的初学者项目开始。一款控制台角色扮演游戏。我创建了一个 GameEntity 类,一个继承 GameEntity 类的玩家类和一些枚举:GameType、Stats
int main(){
GameEntity *opponent = new GameEntity("enemy", 20, 3, 4);
Player *player = new Player("player", 40, 4, 4);
//initialize combatStats
player->prepareForCombat();
opponent->prepareForCombat();
int r = 0;
while(!player->isDead() && !opponent->isDead()){
player->chooseMove(*opponent, r);
opponent->chooseMove(*player, r);
r++;
}
if(!player->isDead()){
cout << "you won!";
}else{
cout << "you lost!";
}
return 0;
}
我的问题: 我有一个包含所有统计数据的数组,包括马力。
int combatStats[7];
以及减少 GameEntity hp 的方法:
void decreaseHp(int damage)
{
if(damage <= 0)return;
combatStats[Hp] = combatStats[Hp] - damage;
cout << name << ": gets "<< damage << " damage." << '\n';
cout << name << ": current health: " << getHp() << '\n';
if(combatStats[Hp] <= 0){
die();
}
}
该方法将 hp 更改为正确的值并将其打印出来,但在该方法停止后,它又变回其初始状态。
我预计数组不会自行重置其值。
它有一个私有访问修改器,所以我尝试将其更改为公共,但它什么也没做。
这是完整代码:
//#include "GameEntity.cpp";
//#include "Player.cpp";
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::string;
enum Stats{
Hp = 0,Mind = 1,Str = 2,Dex = 3,End = 4,Int = 5,Wis = 6
};
enum GameType{
thrust,slash,bludgeon,light,dark,heat,cold, mind, arcane
};
class GameEntity{
protected:
int baseStats[7];
string name;
bool isAllive = true;
int blockVal = 0;
public:
GameEntity(string name, int hp, int pVal, int mVal){
this->name = name;
baseStats[Hp] = hp;
baseStats[Mind] = 100;
baseStats[Str] = pVal;
baseStats[Dex] = pVal;
baseStats[End] = hp/10;
baseStats[Int] = mVal;
baseStats[Wis] = mVal;
}
int combatStats[7];
string getName(){return name;}
int getHp(){return combatStats[Hp];}
int getDex(){return combatStats[Dex];}
int getInt(){return combatStats[Int];}
int getEnd(){return combatStats[End];}
int getStr(){return combatStats[Str];}
int getWis(){return combatStats[Wis];}
int getMind(){return combatStats[Mind];}
void incrementDex(int i){combatStats[Dex] += i;}
void incrementInt(int i){combatStats[Int]+= i;}
void incrementEnd(int i){combatStats[End]+= i;}
void incrementStr(int i){combatStats[Str]+= i;}
void incrementWis(int i){combatStats[Wis]+= i;}
void decrementDex(int d){combatStats[Dex]-= d;}
void decrementInt(int d){combatStats[Int]-= d;}
void decrementEnd(int d){combatStats[End]-= d;}
void decrementStr(int d){combatStats[Str]-= d;}
void decrementWis(int d){combatStats[Wis]-= d;}
void chooseMove(GameEntity target, int round){
cout << name << " health: " << combatStats[Hp] << '\n';
blockVal = 0;
if(round%2 == 0){
cout << name << ": does a slash attack." << '\n';
target.damage(10 , GameType::slash);
}
else if(round == 5 || round == 12){
heal(5, GameType::light);
}
else{
block(8);
}
}
void damage(int damage, GameType type){
if(blockVal > damage){
blockVal -= damage;
cout << name << ": blocked "<< damage << " damage." << '\n';
damage = 0;
}else if(blockVal < damage){
damage -= blockVal;
cout << name << ": blocked "<< blockVal << " damage." << '\n';
blockVal = 0;
}else{
cout << name << ": blocked all damage. ("<< blockVal << ")" << '\n';
damage = 0;
blockVal = damage;
}
switch(type){
case GameType::arcane:
decreaseHp(damage);
break;
default:
cout << name << ": endured "<< combatStats[End] << " damage." << '\n';
decreaseHp(damage-combatStats[End]);
break;
}
}
void heal(int healing, GameType type){
if(type == GameType::light){
combatStats[Hp] += healing;
cout << name << ": healed by "<< healing << '\n';
}
if(combatStats[Hp] > baseStats[Hp]){
combatStats[Hp] = baseStats[Hp];
}
}
void block(int block){
blockVal = block;
cout << name << ": prepares to block." << '\n';
}
bool isDead(){
return !isAllive;
}
void prepareForCombat(){
combatStats[Hp] = baseStats[Hp];
combatStats[Mind] = baseStats[Mind];
combatStats[Str] = baseStats[Str];
combatStats[Dex] = baseStats[Dex];
combatStats[End] = baseStats[End];
combatStats[Int] = baseStats[Int];
combatStats[Wis] = baseStats[Wis];
}
void decreaseHp(int damage)
{
if(damage <= 0)return;
combatStats[Hp] = combatStats[Hp] - damage;
cout << name << ": gets "<< damage << " damage." << '\n';
cout << name << ": current health: " << getHp() << '\n';
if(combatStats[Hp] <= 0){
die();
}
}
void die(){
cout << name << ": died" << '\n';
isAllive = false;
}
};
class Player : public GameEntity
{
public:
using GameEntity::GameEntity;
//using GameEntity::isDead;
void chooseMove(GameEntity target, int round){
cout << name << " health: " << combatStats[Hp] << '\n';
blockVal = 0;
cout <<"System: what do you want to do?" << '\n';
cout <<"1) slash attack" << '\n';
cout <<"2) punch" << '\n';
cout <<"3) riposte" << '\n';
cout <<"4) heal" << '\n';
cout <<"5) block" << '\n';
string input;
cin >> input;
switch (stoi(input))
{
case 1:
cout << name << ": does a slash attack." << '\n';
target.damage(10 , GameType::slash);
break;
case 2:
cout << name << ": punches " << target.getName() << " really hard"<< '\n';
target.damage(4 , GameType::bludgeon);
block(2);
break;
case 3:
cout << name << ": hits " << target.getName() << " and retracts, really fast"<< '\n';
target.damage(7, GameType::thrust);
block(5);
break;
case 4:
cout << name << ": channels the light element"<< '\n';
target.damage(7, GameType::thrust);
heal(4, GameType::light);
break;
case 5:
block(12);
default:
break;
}
}
};
int main(){
GameEntity *opponent = new GameEntity("enemy", 20, 3, 4);
Player *player = new Player("player", 40, 4, 4);
player->prepareForCombat();
opponent->prepareForCombat();
int r = 0;
while(!player->isDead() && !opponent->isDead()){
player->chooseMove(*opponent, r);
opponent->chooseMove(*player, r);
r++;
}
if(!player->isDead()){
cout << "you won!";
}else{
cout << "you lost!";
}
return 0;
}
问题来了
void chooseMove(GameEntity target, int round){
正如怀疑的那样,您正在更改
target
,这是您实际想要更改的对象的 副本。只需更改您的代码即可使用参考
void chooseMove(GameEntity& target, int round){
在 Java 中,所有对象变量自动都是引用。在 C++ 中情况并非如此。这是学习 C++ 意味着放弃 Java 的第一条线索。
还有一个免费的建议,不要在这里使用
new
,只是
GameEntity opponent("enemy", 20, 3, 4);
Player player("player", 40, 4, 4);
(以及随之而来的其余部分的变化
main
)。