【发布时间】:2014-05-23 03:36:42
【问题描述】:
我正在尝试为我用 SFML 2.1 用 c++ 制作的 2D 超级马里奥兄弟克隆解决冲突。我已经尝试了很多不同的解决方案和想法,但我无法让任何东西正常工作。
我有一个播放器,它目前在它自己的 Update() 中检查碰撞(如下所示)
目前:
1. 我的碰撞检测到碰撞略微偏移。如果您能发现任何明显的错误,我很乐意知道。
2. 我不确定这是否是一个足够好的解决方案,因为我需要检测 4 个方向的碰撞(跳跃、撞到我的头在块上。跌落到块上,以及左/右碰撞)
3. 当我检测到碰撞时,我不知道如何将玩家纠正到正确的方向。
我已经清理了所有不必要的代码并删除了下面不起作用的代码。
void Player::Update(Camera& camera, Level& level, sf::RenderWindow& window)
{
input.Update(*this); // Read input logic
physics.update(*this, level, camera, window); // Update physics (movement, gravity)
drawing.update(*this); // Update animation ( does NOT draw player )
if(Collision(level, camera, getPosition())) // Check for collision
{
CollisionResponse(); // If we had collision, do something about it
}
}
Collision() 函数接受三个参数:
- 级别:是地图
- 相机:返回地图上显示的图块,在屏幕上
- getPosition(): 只是玩家在窗口中的位置
函数如下所示:
bool Player::Collision(Level& level, const Camera& camera, const sf::Vector2f& position)
{
// Rectangle surrounding player
sf::FloatRect playerRectangle = sprite.getGlobalBounds();
int tileSize = 32;
Tile* tile;
// smallBounds is the area on the screen where we check collision.
// We dont check the whole screen, only tiles that CAN collide with player.
sf::IntRect smallBounds = sf::IntRect(
(position.x / tileSize) + camera.GetTileBounds(tileSize).left,
position.y / tileSize,
((position.x + tileSize) / tileSize) + camera.GetTileBounds(tileSize).left,
(position.y + tileSize) / tileSize);
// Loop through all tiles
for (int y = smallBounds.top; y < smallBounds.height; y++)
{
for (int x = smallBounds.left; x < smallBounds.width; x++)
{
// Get the tile we are drawing
tile = level.GetTile(x, y);
if(tile && !tile->GetWalkable())
{
sf::FloatRect tileRectangle(tile->GetSprite().getPosition().x,
tile->GetSprite().getPosition().y,
tileSize,
tileSize);
tileRect = tileRectangle;
if(Intersect(playerRectangle, tileRectangle))
{
// Woah, collision detected!
return true;
}
}
}
}
return false;
}
和 CollisionResponse 函数:
void Player::CollisionResponse(void)
{
}
如果我错过了任何有用的信息,请在下方留言。
地图由不同的图块组成,坐标保存的不是它们实际所在的位置,而是它们在数组中的位置,因此示例地图如下所示:
0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
然后,碰撞函数会检查与玩家周围的瓷砖相关的碰撞。
我尝试过的:
很多不同的碰撞方法可以同时解决 x 和 y 碰撞。
将玩家移回上一个位置的碰撞响应。
碰撞响应将玩家向后移动相交矩形的大小(这在 y 轴上有效,但在 x 轴上无效)。
当我的头感觉不像融化的奶酪时,我会写更多。
【问题讨论】:
-
我没有阅读所有内容,尤其是代码(c++ 不是我最喜欢的语言^^),但我有几个问题:您想要检测碰撞的字符是什么形状,制成的?他们可以高速移动(1 次更新中超过 1 个图块)吗?
-
我使用的是矩形(我相信是 AABB),它们的移动速度不够快,无法解决“子弹穿纸”问题。
标签: c++ collision-detection sfml