所以我知道这是一个非常广泛的主题,但我不确定如何描述它,我不知道错误在哪里。所以我在控制台窗口制作一个游戏,一个roguelike-rpg,(我还没有做过随机地牢,但是我已经用其他语言完成了。)而且我'我在处理墙壁方面遇到了问题。
我有一个名为placeMeeting(REAL X, REAL Y)
的函数用于检查碰撞,但它似乎返回了错误的值,我无法告诉你原因。我定义了几个宏:#define AND &&
和#define REAL double
。
这是功能:
bool GlobalClass::placeMeeting(REAL X, REAL Y)
{
//The return value -- False until proven otherwise
bool collision = false;
//Loop through all walls to check for a collision
for(int i = 0; i < wallCount; i++)
{
//If there was a collision, 'say' so
if (X == wallX[ i ] AND Y == wallY[ i ])
{
//Set 'collision' to true
collision = true;
}
}
return collision;
}
但奇怪的是,它只是在显示屏幕时不起作用。即使没有显示,玩家也会与他们碰撞。更奇怪的是,只展示了第一面墙。 这是墙的定义:
int wallCount;
//Array of walls
REAL wallX[ 1 ];
REAL wallY[ 1 ];
和
wallCount = 1;
//Basic wall stuff; basically just a placeholder
wallX[ 0 ] = 10;
wallY[ 0 ] = 10;
所以我有一个用于渲染屏幕的函数(当然在控制台窗口中)。它看起来像这样:
for (int y = oGlobal.viewY; y < oGlobal.viewY + oGlobal.viewHeight; y++)
{
//The inner 'x' loop of the view
for(int x = oGlobal.viewX; x < oGlobal.viewX + oGlobal.viewWidth; x++)
{
//Call the function to check this spot and print what it returns
screen += oGlobal.checkSpot(x, y);
}
}
这不是整个功能,只是实际屏幕刷新。屏幕后&#39;被打印到屏幕上,以减少缓冲时间。当然,checkSpot:
STRING GlobalClass::checkSpot(REAL x, REAL y)
{
STRING spriteAtSpot;
//First check for the player
if (x == oPlayer.x AND y == oPlayer.y)
{
spriteAtSpot = oPlayer.sprite;
}
else if (placeMeeting(x, y)) //ITS TEH WALL SUCKAS
{
spriteAtSpot = WALL_SPRITE;
}
else //Nothing here, return a space
{
spriteAtSpot = EMPTY_SPRITE;
}
//Return the sprite
return spriteAtSpot;
}
我知道很多代码,但我真的不知道我搞砸了。
我真的很感激任何帮助!
P.S。这是一张有助于理解的图片 http://i.imgur.com/8XnaHIt.png
答案 0 :(得分:1)
我不确定我是否遗漏了某些东西,但由于类似流氓的游戏是基于磁贴的,是否有必要使X和Y值加倍?我记得被告知双打很难比较,因为即使你认为它们应该是平等的,它们可能会略微偏离,导致比较,当你认为它会恢复正确时返回假。
答案 1 :(得分:1)
我不确定我们是否有足够的代码来调试它,但我开发了类似Rogue的控制台游戏,这是我的$ .02 ......
这就是我开发游戏的方式;我希望它有所帮助。
答案 2 :(得分:1)
除了使用double而不是int之外,我在你的墙壁定义中看到了一些奇怪的东西:
int wallCount;
//Array of walls
REAL wallX[ 1 ];
REAL wallY[ 1 ];
和
wallCount = 1;
//Basic wall stuff; basically just a placeholder
wallX[ 0 ] = 10;
wallY[ 0 ] = 10;
您正在定义一个名为wallCount
的变量,稍后您可以使用该变量在placeMeeting
函数中浏览数组元素:
//Loop through all walls to check for a collision
for(int i = 0; i < wallCount; i++)
那么为什么不使用wallCount
来定义数组的大小?当然你不能使用那种语法,因为静态数组的大小必须在编译时知道,所以你应该使用new
或std::vector
,但你仍然不应该有变量定义数组的长度,然后在实际创建数组时使用另一个值,如果你不能保持它们对齐,它就是bug的来源。例如,你可以这样做:
const int wallCount = 1;
int* wallX = new int[wallCount];
int* wallY = new int[wallCount];
但是有一个更大的问题:为什么要创建大小为1的数组?你只有一面墙!拥有大小为1的数组并没有多大意义,除非你打算使用另一个值但是为了调试目的而将它减少到1。但是,你写了这个:
更奇怪的是,只显示了第一面墙。
那是因为你只有一面墙!
顺便说一句,您设计数据的方式并不是我要使用的方式。从您的checkSpot
我明白这一点:oPlayer.x
和oPlayer.y
是您的播放器的坐标,x
和y
是您需要的磁贴坐标绘制(并且您需要选择适当的精灵)。如果您的地图中有3个墙,则必须在wallX
中放置3个值,在wallY
中放置3个,并且必须确保将2个数组保持“对齐”(如果您的坐标为第二个墙是例如x = 10和y = 20,你可能会感到困惑,或者有错误的代码,而不是将其保存为
wallX[1] = 10;
wallY[1] = 20;
你可以写
wallX[1] = 10;
wallY[2] = 20; // wrong index!
因此它是另一个错误的来源),更糟糕的是,你必须检查它们是否与其他对象的其他数组一致:例如,你可以拥有门,然后按照你的方法进行{{1 }和doorX[]
,你怎么能确定你在同一个地方没有墙和门?就像,如果你有
doorY[]
它与墙在同一个地方,错误并不明显,因为您必须交叉检查所有数组才能找到它。所以我建议改为doorX[0] = 10;
doorY[0] = 20;
,并且在x = 10和y = 20时有一个墙可以使用level[height][width]
。这将确保每个图块只有一个对象。此外,检查碰撞会更快:通过你的方法,如果你有50个墙,你需要50个检查;与我的一起,你总是只需要一个。好的,在这些游戏中,性能肯定不是问题,但我认为你应该考虑我的方法(当然,除非有其他理由更喜欢你的)。