SFML 的 2D 瓦片地图冲突
2d tilemap collision for SFML
我目前正在用SFML开发一款2D RPG游戏,我正在尝试让玩家与某些瓷砖发生碰撞。我已经到了玩家可以与我想要的瓷砖碰撞以及使用以下代码沿着墙壁滑动的地步:
sf::Vector2f movement(0.f, 0.f);
if (isMovingUp)
movement.y -= 1.f;
if (isMovingDown)
movement.y += 1.f;
if (isMovingLeft)
movement.x -= 1.f;
if (isMovingRight)
movement.x += 1.f;
sf::Vector2f oldpos = Player.getPosition();
sf::Vector2f newpos = Player.getPosition() + movement*speed*dt.asSeconds();
Player.setPosition(newpos); // the player is an sf::sprite that is 16*24px
for (int i = 0; i < tiler.solids.size(); i++) // each solid is an sf::FloatRect that is 16*16px
{
if (Player.getPosition().x + 16 >= tiler.solids[i].left && Player.getPosition().x <= tiler.solids[i].left + tiler.solids[i].width && Player.getPosition().y + 24 >= tiler.solids[i].top && Player.getPosition().y <= tiler.solids[i].top + tiler.solids[i].height) // if the player is touching the tile
{
Player.setPosition(oldpos);
}
}
它基本上所做的是迭代每个实体并测试玩家是否与其中任何一个相交。如果有交叉点,玩家将在没有碰撞时返回之前的位置。
我遇到的主要问题是,当我同时按下两个方向时(例如,在向右和向上移动时与右侧的墙壁相撞)时,玩家会卡住,因为它正在重置 x 和 y 坐标。大多数代码都基于此问题。提出问题的人也有同样的问题。答案的最后一条评论建议他们尝试将垂直运动与水平运动分开。我在我的代码中尝试过,但这不起作用,因为它基本上是在测试是否存在 x 碰撞或 y 碰撞,并且即使玩家符合固体,也会重置玩家的位置。
所以我想我的主要问题是:我怎样才能以更好的方式将垂直碰撞与水平碰撞分开,或者有没有另一种进行瓷砖碰撞的方法,允许玩家在保持两个方向的同时沿着墙壁滑动?
您要做的是分别测试两个轴上的碰撞。这意味着您可以保护玩家的当前位置,然后计算两个边界框。其中一个是添加了水平偏移的玩家边界框,另一个是添加了垂直偏移量。
sf::FloatRect oldBounds = Player.getPosition();
sf::FloatRect newBoundsH = (oldBounds.left + movement.x *speed*dt.asSeconds(), oldBounds.top, oldBounds.width, oldBounds.height);
sf::FloatRect newBoundsV = (oldBounds.left, oldBounds.top + movement.y *speed*dt.asSeconds(), oldBounds.width, oldBounds.height);
所以你可以写:
// Test horizontal collision.
if(tiler.intersects(newBoundsH)){
Player.setPosition(oldpos.x, Player.getPositions().y);
}
// Test vertical collision.
if(tiler.intersects(newBoundsV)){
Player.setPosition(Player.getPositions().x, oldpos.y);
}
这种方法绝对有其缺陷,但我认为它很容易理解。
相关文章:
- 为什么不;名字在地图上是按顺序排列的吗
- 写入位置0x0000000C时发生访问冲突
- 基于多个条件处理地图中的所有元素
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 在C++中将矢量转换为嵌套地图
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- 替换基于地图的所有引用
- 如何区分地图中的 0 和 false?
- 地图计数确实很重要,或者只是检查是否存在
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- 如何从地图中删除矢量对象
- 是否有任何C++功能可以对地图进行排序?
- 如何使用 std::variant 打印地图键/值?
- C++尝试深度复制唯一指针时出现内存访问冲突
- 切片地图冲突
- SFML 的 2D 瓦片地图冲突