只是为了预先提出这个问题,请注意我并没有要求修复我的代码,而是采用了哪些技术来解决这个问题。如果我的拼写不是很好,我也会道歉。
好的,所以我有一个2D平台游戏,它将玩家的位置与所有的棋子进行比较(在一个循环中),相应地解决了碰撞。这几乎是主要游戏循环的结构:
但是,尽管这个系统工作,但碰撞系统有两个小的,但明显的问题(我提供了图像以使其更容易)。有两个问题,第一个不是那么糟糕,但第二个渲染游戏几乎无法播放!
问题1.当在游戏中左右移动时,玩家偶尔会失去它所获得的所有速度,然后必须重新累积该速度。我想这是因为偶尔我的碰撞检测功能不能正常返回。这是一张图片:
我希望很明显,这个问题只有在穿越大片平地时才会变得明显。
问题2(这个更糟糕)问题是玩家可以基本上跳墙,因为如果你说例如按住左箭头并按住跳跃,玩家将跳到墙上。我假设这是因为我的碰撞检测功能在碰撞来自侧面时返回true(尽管它不应该)。这是另一张图片(文字很小,对不起):
所以这是我的碰撞检测功能,它应该包含两个对象'然后从碰撞发生的第一个物体返回方向,我认为当确定方向时会引起问题,因为这会引起问题,如上所示:
//Find the collision vectors
float vectorX = (a.Position.x + (a.Scale.x / 2)) - (b.Position.x + (b.Scale.x / 2));
float vectorY = (a.Position.y + (a.Scale.y / 2)) - (b.Position.y + (b.Scale.y / 2));
//Find the distance between the two objects
float deltaWidth = (a.Scale.x / 2) + (b.Scale.x / 2);
float deltaHeight = (a.Scale.y / 2) + (b.Scale.y / 2);
//Stores the direction of collision
Direction collisionDir = Direction::None;
//Check if the two objects are intersecting on the x and y axis
if (fabs(vectorX) < deltaWidth && fabs(vectorY) < deltaHeight)
{
//The direction of collision
float directionX = deltaWidth - fabs(vectorX);
float directionY = deltaHeight - fabs(vectorY);
//Check for vertical collision
if (directionX >= directionY)
{
//Check for collisions from the top
if (vectorY > 0)
{
a.Velocity.y = 0;
a.Position.y += directionY;
collisionDir = Direction::Up;
}
//Collisions form the botttom
else
{
a.Velocity.y = 0;
a.Position.y -= directionY;
collisionDir = Direction::Down;
}
}
else if (directionX < directionY / 2)
{
//Check for collisions from the left
if (vectorX > 0 )
{
a.Velocity.x = 0;
a.Position.x += directionX;
collisionDir = Direction::Left;
}
//Collisions form the right side
else
{
a.Velocity.x = 0;
a.Position.x -= directionX;
collisionDir = Direction::Right;
}
}
}
//Return the direction.
return collisionDir;
这将返回一个方向,我的其他代码也检查该方向==底部,然后它将允许跳跃。
感谢您的帮助。我正在为Ludum Dare练习,因为我计划(可能)制作一个平台游戏。如果我无法弄清楚碰撞检测,我就不知道我的游戏会有多好。
无论如何谢谢 - Coder Cameron
答案 0 :(得分:3)
我建议的第一件事就是让自己成为一个Vector2D类,它保存你的x和y坐标,并且一些运算符重载一些运算符,允许两个Vector2D的加法和减法以及乘法,浮点数和双精度的乘法和除法。相信我,它会让你的生活变得更轻松,因为它们可以容纳你所有的力量和碰撞点。
接下来当我使用你正在使用的碰撞风格时,我总是发现它:
A)难以调试。
B)其他人更难以遵循您的代码。
所以我建议创建一个Rectangle2D类来处理与其他Rectangle的冲突和其他所需的功能。
建议将左上角和右下角作为矩形中心的矢量,这使得缩放和碰撞检测变得更加容易,这也意味着您可以在不直接存储它们的情况下导出其他角落。 / p>
这是一个代码示例,可能有助于我尝试解释的内容:
bool Intersects(Rectangle2D other)
{
//Checks the right, left, bottom then top of the rectangle
//against the other.
if(other.topLeftCorner.x >= bottomRightCorner.x //Checks the right
|| other.bottomRightCorner.x <= topLeftCorner.x //Checks the left
|| other.topLeftCorner.y >= bottomRightCorner.y //Checks the bottom
|| other.bottomRightCorner.y <= topLeftCorner.y) //Checks the top
return false;
else
return true;
}
您可以轻松操作此代码,为您提供碰撞的方向。希望这会有所帮助。