我正在尝试用SFML 2.1为我的2D超级马里奥兄弟克隆包碰撞。我尝试了很多不同的解决方案和想法,但我无法让任何东西正常工作。
我有一个播放器,它目前在自己的更新()中检查碰撞(如下所示)
当前:
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()
函数有三个参数:
-level:是map-camera:返回从地图中显示的分片,在屏幕上-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;
}
和碰撞响应功能:
void Player::CollisionResponse(void)
{
}
如果我错过了任何有用的信息,请在下面发表评论。
地图由不同的方块组成,这些方块由坐标保存,而不是它们实际所在的位置,而是它们在数组中的位置,因此示例地图看起来像这样:< br> 0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
碰撞函数然后检查与玩家周围的这些方块相关的碰撞。
我尝试过的:
有很多不同的碰撞方法来同时解决x和y碰撞。
碰撞响应将玩家移回最后一个位置。
碰撞响应将玩家移回相交矩形的大小(这在y轴上有效,但在x轴上无效)。当我的头感觉不像融化的奶酪时,我会写更多。
对于我的游戏(在java和Libgdx中),我也使用了AABB冲突检测。有2种不同的方法可以检测和处理冲突:
当您使用基于图块的地图时,您不需要使用“交集”测试。相反,您可以存储角色的4个角点,四舍五入到他所在的图块(如果每个图块都有一个单位大,并且角色的脚在P(0.5; 0.5)上,您需要检查图块(0; 0))。
玩家的位置是他的左下角(通常),所以他的其他3个点是P2(player.position.x.player.width;player.position.y)
,P2(player.position.x.player.width;player.position.yplayer.height)
,P3(player.position.x;player.position.yplayer.height)
,总是向下舍入到Tile
的位置。
希望有帮助。
将播放器移回到最后一个已知的正确位置会导致您正在经历的行为;玩家将与他要碰撞的物体保持一段距离。举个例子:如果你的角色以300像素/秒的速度移动,而他们离墙有5个像素,下一次碰撞发生在1/60秒内。如果您的帧速率为60FPS,将在下一帧中检测到碰撞,并且角色将移动到距离碰撞发生前他所在的墙壁5个像素的位置。肯定不受欢迎。
只要正确计算数量,您所使用的方法应该有效(按相交矩形的大小将播放器向后移动)。分离轴定理对此很有用(在那篇文章中,具体参见第7节“寻找MTV”)。
你可以尝试另一种方法,不涉及计算:在碰撞时,以小的时间步长(甚至像素一像素一像素)向后移动玩家,直到他停止与墙碰撞。然后,你就会知道一个离墙更近的地方,在那里可以安全地安置他。效率较低,但易于实施。
还有一种方法是连续冲突检测。它本质上有点复杂。你应该能够通过简单地四处搜索“连续冲突”来找到一些信息,但基本思想是:
我正在尝试制作我的第一个Pacman游戏,但我遇到了一堵我自己似乎无法打破的墙:( 这是关于如何在我的游戏中检测碰撞,所以步行者不能穿过障碍物/墙壁。我已经使它不能去屏幕外与此代码: ,但如果我在屏幕中间的电路板上有一个矩形,我不知道如何编程,这样它就会在墙前停止。 我需要阻止我的pacman移动到竞技场内的墙上,如你所见(左上方的矩形) 我的Board类代码: 希望有人能告诉我该怎么做...似乎
我已经和LWJGL一起开发这个游戏几个星期了。自从我增加了跳跃的能力后,向上的碰撞给我带来了很多问题。 这个游戏是一个基于2D瓷砖的侧翻游戏。总的来说,除了玩家跳跃时,碰撞几乎是完美的。起初我想“哦,也许我只需要改变跳跃机制”,但后来我意识到只有当玩家通过某个x坐标时才会发生这种情况。 现在,对于实际问题本身:如果玩家在传递某个x坐标时跳转,他们将通过平铺,并测试顶部碰撞返回false。 这是整个
我计划一个独立游戏项目已经有一段时间了。我会为你总结一下,这样我就可以直接回答这个问题。 它是通过Visual Studio完全使用最新版本的XNA完成的。希望将其放在360和PC上,但目前我只是在真正寻找面向PC的解决方案。 这是一个2D侧向滚动射击游戏(想想大都会风格,甚至是Terraria)。它最终将包括一个游戏中的地图编辑器,地图是基于图块的(16x16)。会有向上和向下滚动。我希望在开发
问题内容: 我正在尝试制作一个Python游戏,其中红龟追逐蓝龟。当红色乌龟抓到蓝色乌龟时,我希望它在屏幕上说“碰撞”,但它不起作用。当它碰撞时,什么也没有发生,并且给我一个错误“ Turtle”对象不可调用”。 问题答案: 与实际编程相比,这段代码似乎更让人想不到: 乌龟没有方法。您不能使用此语句简单地将方法添加到现有类。没有和功能。每次运动后,如果需要,该碰撞测试将只执行一次。让我们尝试挽救我
我正在做一个2d平板游戏。到目前为止,我已经做了一些事情。我正在使用libgdx的矩形进行基本的碰撞检测,所以考虑到我现在只有草块,我用Java制作了一个单块世界(文件读取器还没有准备好),问题是我的检测只在第一次工作,换句话说,如果我产生碰撞到一个块,它会检测到碰撞并这样做。虽然如果我在没有碰撞的情况下,让我的球员在方块顶部出现,球员将永远摔倒。 这是代码=
我想创建一个二维游戏与瓷砖为基础的地图。我的主要问题是碰撞。如果有一棵树挡住了我的路,我怎么才能让我的精灵不穿过这棵树呢?