gpt4 book ai didi

C++ 对象不保存变量值

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:33:03 24 4
gpt4 key购买 nike

我是一名初学者 C++ 程序员,自学成才。我正在开发一个简单的 roguelike 游戏作为学习项目。我遇到的问题是用于确定玩家是否能够向指定方向移动的代码。例如,当玩家想要向东移动一个方格时,将运行以下代码,其中 int a 和 b 是intended方格的 X 和 Y 坐标:

bool Location::canMove(int a, int b)
{
for (int i = 0; i < Decorations.size(); i++)
{
if (Decorations[i].getPosX() == b && Decorations[i].getPosY() == a)
{
Match = true;
Matched = Decorations[i];
break;
} else
{
Match = false;
}
}

if (Match == true)
{
if (Matched.Clips() == true)
{
Blocked = true;
return false;
} else
{
Blocked = false;
return true;
}
} else
{

switch(Map[a][b])
{
case TILE_VOID:
case TILE_FLOOR:
Blocked = false;
return true;
break;
case TILE_WALL:
Blocked = true;
return false;
break;
}
}
}

基本上它所做的是查看玩家的当前位置在那些 X 和 Y 坐标处是否有任何装饰性对象,例如 table 、柱子等。如果它发现它有一个,则它会运行检查以查看该对象是否允许播放器通过 Clips() 函数是否通过它并返回 true 或 false 以确定播放器是否可以移动到那里。如果没有找到装饰对象,它会检查该位置的基础图 block ,如果是空地或地板则玩家可以移动,如果是墙则不能。

据我所知,这段代码运行良好(玩家无法穿过墙壁或固体物体)。然而,在主循环中还有另一个函数,当玩家被告知他们不能移动时会调用另一个函数,它会告知玩家原因:

string Location::blockMsg()
{
blockmsg = "You bump into the ";
if (Blocked == false)
{
blockmsg = blockmsg + "wall";
} else
{
blockmsg = blockmsg + Matched.getName();
}
return blockmsg;

}

这用于通知玩家为什么他们不能朝那个方向移动。例如,如果他们撞到了一张 table ,它应该说“你撞到了 table ”。

我遇到的问题是它看起来不像 bool Matched 或 Blocked,或者装饰 Matched 在第一段代码完成后被保存。因此,逻辑总是表现得好像 Blocked == false,即使玩家撞到了阻止他们移动的装饰。结果是,如果一个玩家被什么东西挡住了,它总是会说“你撞到墙上了”,即使是别的东西。

我唯一可以做的假设是,出于某种原因,当在第一个函数中分配 Blocked = true 时,无论出于何种原因,它都不会保留以供下一个函数使用它。

谁能指出我哪里出错了?我一直认为,一旦在 canMove() 函数期间设置了 Location 的 Match、Matched 和 Blocked 值,它们应该保留相同的值供 blockMsg() 使用,但显然不是。

最佳答案

我做了几个关键假设,例如原始代码中的“a”参数相当于“x” map 坐标,而“b”参数等于“y” map 坐标。我更改了参数名称以使您的代码操作更加清晰。

我还假设“Locations”类可以访问“Decorations”对象和“Map”二维数组。如果“Locations”类无法访问 Decorations 对象或 Map 数组,则可能会导致一些问题。

此外,如果 Blocked、Matched 和 Match 是 Location 类的数据成员,它们的值应该在函数调用之后持续存在,但只是为了确保它不是一些奇怪的编译器错误,请尝试包括显式的“this->”("this”是指向父对象或进程的指针)对所有实例变量的引用。这样做将确保您的代码操作将数据保存在某种持久变量中,而不是在执行后消失。请注意,我已在下面的代码示例中进行了更改:

bool Location::canMove(int x, int y) //change param names for clarity sake
{
//I recommend turning the "bool Location::Match" into a "int Location::Match"
// I also recommend this for the "bool Location::Blocked" variable
// This way you can have a flag that says, yes, no, error, etc.
// For illustration purposes I commented out old and inserted new with that integer assumption
// Key for the new "Location::Match" and "Location::Blocked" values:
// -1 = error
// 0 = false
// 1 = true

//Initialize Match to an error state, that way if the for loop below fails to
// execute, your application will flag that failure
this->Match = -1;

for (int i = 0; i < Decorations.size(); i++)
{
// did you mean to have your values criss-crossed in the "if" statement below?
if (Decorations[i].getPosX() == y && Decorations[i].getPosY() == x)
{
this->Match = 1;
this->Matched = Decorations[i];
break;
} else
{
this->Match = 0;
}
}

if (this->Match == 1) //Match found!
{
if (this->Matched.Clips() == true)
{
this->Blocked = 1;
return false;
} else
{
this->Blocked = 0;
return true;
}
} else if (this->Match == 0) // no match found
{

switch(Map[x][y]) //changed to reflect new parameter names
{
case TILE_VOID:
case TILE_FLOOR:
this->Blocked = 0; //false
return true;
//break; // break is unreachable, due to the return above, therefore not needed
case TILE_WALL:
this->Blocked = 1; //true
return false;
//break; //see case above
default:
//Always include a default case
// log it, report it, write it to file, print to screen, debug, etc.
this->Blocked = -1; //error
break;
}
} else if (this->Match == -1) // error case
{
//Yet another error case...
// By adding separate, discrete error cases you can track down the
// source of your errors more efficiently
this->Blocked = -1; // error
return false;
}

在进行这些小的更改以允许 Blocked 和 Match 具有比 bool 标志更多的选项之后,您必须更改输出消息函数以使用新值。 (是的,我知道如果您在其他地方使用 Match 或 Blocked,则必须更新它们。)

这是输出消息的样子:

string Location::blockMsg()
{
blockmsg = "You bump into the ";
if (this->Blocked == 0)
{
blockmsg += "wall";
} else if(this->Blocked == 1)
{
blockmsg += Matched.getName();
}else if(this->Blocked == -1)
{
blockmsg += "ERROR!";
}
return blockmsg;

通过进行这些更改,您应该能够更有效地调试代码,并能够弄清楚发生了什么以及哪里出了问题。此外,如果您能够,请使用调试器并标记“canMove()”方法,以便在调用它时您可以一步一步地观察执行过程。

祝你好运,玩得开心!

~Hv6^3

关于C++ 对象不保存变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9657889/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com