我目前正在和我的大学一起学习中级c ++课程,而且我们刚刚完成了课程/多态,因此我决定开展自己的一个小项目。这不是家庭作业,我认为这样可以解决问题。
所以我使用SFML做了一点空闲"游戏。这包括一个实体类,一个用于武器的类和一个用于装甲的类。我有2个实体,作为玩家和"其他"或敌人。到目前为止,一切都很好,但是当我尝试使用参数作为另一个实体调用实体类的成员函数时,我遇到了麻烦。 这是两个函数
/*
Simulates the entity attacking another entity
*/
void Entity::attackEntity(Entity other) {
other.decreaseHP(5);
if (other.getCurrentHP() <= 0) {
killEntity(other);
}
}
/*
Simulates main entity defeating another
*/
void Entity::killEntity(Entity other) {
if (other.getEntityType() == "Enemy") {
other.setXP(rand() % (other.getRequiredXP() / 9) + 1);
addXP(other.getXP());
//addXP(rand() % (rand() % (getRequiredXP() / 10) + 1) + getEntityLevel()); // testing
addGold(rand() % getEntityLevel() + getEntityLevel());
// Increment the level of the entity to give them better armor/weapon
other.incrementLevel();
// Regenerate a weapon and armor for the enemy
other.setWeapon(other.getWeapon().generateRandomWeapon(other.getEntityLevel()));
other.setArmor(other.getArmor().generateRandomArmor(other.getEntityLevel()));
}
else if (other.getEntityType() == "Player") {
other.setXP(other.getXP() / 10);
other.setCurrentHP(other.getMaxHP());
other.refreshEntityInfo();
}
}
目前,在主程序中,我将其称为
if (clock.getElapsedTime().asSeconds() >= 1.0f) {
player.attackEntity(enemy);
clock.restart();
}
我想要代码要做的是每1秒,玩家将&#34;攻击&#34;另一个实体,是敌人。这将使另一个实体的健康点降低5,当其他实体的健康点降至1以下时,它将“杀死”#34;实体,授予玩家体验并重置其他实体的护甲和武器,这将为其提供新的统计数据。 但是, 正在发生什么,什么都不是。健康点不会减少。 显然我在这里做错了,因为它不起作用。
我测试过只在时间循环中单独调用reduceHP()方法,并且有效:
if (clock.getElapsedTime().asSeconds() >= 1.0f) {
//player.attackEntity(enemy);
player.decreaseHP(5);
clock.restart();
}
但是我在使用attackEntity()方法之前提供的方式却没有。
这是reduceHP()方法。
/*
Decreases the entity's current health by amount
*/
void Entity::decreaseHP(int amount) {
setCurrentHP(getCurrentHP() - amount);
}
我是否需要传递其他实体对象作为参考?我是否以糟糕的方式处理这些功能?我该怎么接近这个?
编辑 - 所以我知道我刚发布了这个,但我更改了attackEntity()函数和killEntity()函数的参数,因此它通过引用获取实体对象,这似乎解决了解决方案。
/*
Simulates main entity defeating another
*/
void Entity::killEntity(Entity &other) {
if (other.getEntityType() == "Enemy") {
other.setXP(rand() % (other.getRequiredXP() / 9) + 1);
addXP(other.getXP());
//addXP(rand() % (rand() % (getRequiredXP() / 10) + 1) + getEntityLevel()); // testing
addGold(rand() % getEntityLevel() + getEntityLevel());
// Increment the level of the entity to give them better armor/weapon
other.incrementLevel();
// Regenerate a weapon and armor for the enemy
other.setWeapon(other.getWeapon().generateRandomWeapon(other.getEntityLevel()));
other.setArmor(other.getArmor().generateRandomArmor(other.getEntityLevel()));
}
else if (other.getEntityType() == "Player") {
other.setXP(other.getXP() / 10);
other.setCurrentHP(other.getMaxHP());
other.refreshEntityInfo();
}
}
/*
Simulates the entity attacking another entity
*/
void Entity::attackEntity(Entity &other) {
other.decreaseHP(5);
if (other.getCurrentHP() <= 0) {
killEntity(other);
}
}
然而,我的最后一个问题仍然存在:我是否以正确的方式解决这个问题?
答案 0 :(得分:3)
签名void Entity::attackEntity(Entity other)
会导致other
成为该实体的副本。对other
所做的任何更改都是attackEntity
函数的本地更改。
如果您需要从源项目中保留更改,最直接的方法是通过引用传递other
,将签名更改为:void Entity::attackEntity(Entity& other)
答案 1 :(得分:1)
鉴于此......
void Entity::attackEntity(Entity other) {
...然后这段代码
Entity x;
foo.attackEntity(x);
...将创建一个X的COPY,将其传递给attackEntity,后者会修改立即丢弃的本地副本。所以x保持不变。
在这种情况下,请使用按引用传递。
void Entity::attackEntity(Entity &other)
如果该方法不是要修改x,请改为使用pass by const引用:
bool Entity::isWithinRange(const Entitiy &other)
在编辑之后,是的,引用绝对是处理此问题的正确方法。按值(或作为指针)传递对象通常是代码“气味”。
答案 2 :(得分:-1)
检查你对等号运算符的使用,&#34; ==&#34;。 C ++并不像Java和C#那样处理字符串。引用的字符串(例如&#34; Enemy&#34;)分解为指针,因此比较变为&#34;该指针指向与另一个指针相同的地址,&#34;答案几乎总是&#34;没有。&#34;
您可以尝试使用std :: string类型,它定义了compare()方法,但一般来说,C ++字符串只比C字符串稍微友好一点。
您可能应该使用老式的C字符串比较函数,例如strcmp()。