当前位置: 首页 > 知识库问答 >
问题:

SFML二维tilemap冲突

乐正嘉瑞
2023-03-14

我目前正在用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碰撞,并且会重置玩家的位置,即使玩家与一个实心线一致。

所以我想我的主要问题是:我如何以一种更好的方式将垂直和水平碰撞分开,或者有没有另一种方式来做瓦片碰撞,允许玩家在保持两个方向的同时沿着一堵墙滑动?

共有1个答案

晏兴发
2023-03-14

你要做的是分别测试两个轴上的碰撞。这意味着您安全的当前位置的球员,然后计算两个边界盒。其中一个是添加了水平偏移量的玩家边界框,另一个添加了垂直偏移量。

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);
    }

这个方法绝对有它的缺点,但我认为它很容易理解。

 类似资料:
  • 这是我的碰撞/移动代码 这是PixelPerfectTest函数(不是我的) 编辑:这就是我如何让它工作,以防将来有人需要帮助

  • 我的2D平台游戏有问题。由于我刚刚开始使用c,因此我在瓷砖碰撞方面遇到了麻烦。我能够阻止玩家进入图块,并且能够远离它,但不知何故,他不能沿着图块移动。 此功能用于检查新位置是否位于实心瓷砖内: 空地图::drawColMap(播放器 } 以下是移动播放器的代码: void Player::update() { } 感谢任何帮助! //编辑1 我试着记录碰撞,它显示即使我不按任何键,玩家仍然在碰撞区

  • 我正在用C++的SFML制作一个2D游戏,我有一个冲突的问题。我有一个玩家和一张用瓷砖做的地图。不起作用的是我的碰撞检测不准确。当我将玩家向上移动然后向下移动到瓷砖上时,结果会有所不同。 我知道这个问题的根源可能是在计算球员移动时使用帧间的delta时间--所以它不是恒定的。但它平滑了运动,所以我不知道如何做它的其他方式。我试着用定速阀来使碰撞完全准确--速度必须非常低,我对此不满意。 在玩家位置

  • 好的,我想试试这个: > 然后检查碰撞检测,如图所示。第一种是正面碰撞,第二种是侧面碰撞。碰撞http://img802.imageshack.us/img802/2934/rectangles2.png 然后删除精灵,只保留代码中的向量。(位置和旋转)我希望如此,因为我想在这些位置添加3d Cars和他的旋转。我的意思是,在2d中没有精灵的碰撞检测。 在游戏结束时,将没有精灵。仅三维对象。 有人

  • 所以,最近我开始用C和SFML制作一个Pacman克隆。开发游戏时一切都很顺利,直到我需要创建墙碰撞。我不擅长碰撞,所以我以为会有问题。 我想做的是检查你上方是否有一堵墙,除了你或其他什么,然后如果你与一堵墙相撞,阻止玩家。 问题是,当你撞到墙时,你很早就停下来了。有时你会陷入困境。这并不是要与代码混淆,因为代码使Pacman在你身上有一堵墙的时候不能转身,而是在遇到墙的时候停下来。 这是我刚才提

  • SFML 是一个免费的 C++ 多媒体 API,提供了低级和高级的图形、输入、音频等信息的访问。