2015-01-06 160 views
2

我正在SFML中制作2D游戏,我试图弄清楚如何在瓷砖地图中与瓷砖相撞。我写了一些代码,但问题是我卡在我碰撞的瓦片中,如下图所示。我无法向任何方向移动,并且玩家的5个像素位于墙上。 enter image description hereSFML瓷砖地图冲突

这是我的碰撞/移动代码

void Player::update(float delta, std::vector<Tile>& tiles) { 
    canMove = true; 

    for (int i = 0; i < tiles.size(); i++) { 
     if (Collision::PixelPerfectTest(sprite, tiles[i].sprite) && tiles[i].collision) { 
      canMove = false; 
     } 
    } 

    if (canMove) { 
     move(delta); 
    } 
} 

void Player::move(float delta) { 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) || sf::Keyboard::isKeyPressed(sf::Keyboard::Up) || sf::Joystick::getAxisPosition(0, sf::Joystick::Y) < -20) { 
     movement.y -= speed * delta; 
    } 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::A) || sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Joystick::getAxisPosition(0, sf::Joystick::X) < -20) { 
     movement.x -= speed * delta; 
    } 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) || sf::Keyboard::isKeyPressed(sf::Keyboard::Down) || sf::Joystick::getAxisPosition(0, sf::Joystick::Y) > 20) { 
     movement.y += speed * delta; 
    } 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::D) || sf::Keyboard::isKeyPressed(sf::Keyboard::Right) || sf::Joystick::getAxisPosition(0, sf::Joystick::X) > 20) { 
     movement.x += speed * delta; 
    } 

    sprite.setPosition(movement); 
} 

这是PixelPerfectTest功能(它不是我)

bool PixelPerfectTest(const sf::Sprite& Object1, const sf::Sprite& Object2, sf::Uint8 AlphaLimit) { 
     sf::FloatRect Intersection; 
     if (Object1.getGlobalBounds().intersects(Object2.getGlobalBounds(), Intersection)) { 
      sf::IntRect O1SubRect = Object1.getTextureRect(); 
      sf::IntRect O2SubRect = Object2.getTextureRect(); 

      sf::Uint8* mask1 = Bitmasks.GetMask(Object1.getTexture()); 
      sf::Uint8* mask2 = Bitmasks.GetMask(Object2.getTexture()); 

      // Loop through our pixels 
      for (int i = Intersection.left; i < Intersection.left + Intersection.width; i++) { 
       for (int j = Intersection.top; j < Intersection.top + Intersection.height; j++) { 

        sf::Vector2f o1v = Object1.getInverseTransform().transformPoint(i, j); 
        sf::Vector2f o2v = Object2.getInverseTransform().transformPoint(i, j); 

        // Make sure pixels fall within the sprite's subrect 
        if (o1v.x > 0 && o1v.y > 0 && o2v.x > 0 && o2v.y > 0 && 
         o1v.x < O1SubRect.width && o1v.y < O1SubRect.height && 
         o2v.x < O2SubRect.width && o2v.y < O2SubRect.height) { 

         if (Bitmasks.GetPixel(mask1, Object1.getTexture(), (int)(o1v.x) + O1SubRect.left, (int)(o1v.y) + O1SubRect.top) > AlphaLimit && 
          Bitmasks.GetPixel(mask2, Object2.getTexture(), (int)(o2v.x) + O2SubRect.left, (int)(o2v.y) + O2SubRect.top) > AlphaLimit) 
          return true; 

        } 
       } 
      } 
     } 
     return false; 
    } 

编辑:这是我如何得到它的情况下,任何人的工作从未来需要帮助

void Player::update(float delta, std::vector<Tile>& tiles) { 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) || sf::Keyboard::isKeyPressed(sf::Keyboard::Up) || sf::Joystick::getAxisPosition(0, sf::Joystick::Y) < -20) { 
     newPos.y -= speed * delta; 
    } 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::A) || sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Joystick::getAxisPosition(0, sf::Joystick::X) < -20) { 
     newPos.x -= speed * delta; 
    } 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) || sf::Keyboard::isKeyPressed(sf::Keyboard::Down) || sf::Joystick::getAxisPosition(0, sf::Joystick::Y) > 20) { 
     newPos.y += speed * delta; 
    } 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::D) || sf::Keyboard::isKeyPressed(sf::Keyboard::Right) || sf::Joystick::getAxisPosition(0, sf::Joystick::X) > 20) { 
     newPos.x += speed * delta; 
    } 

    sf::Vector2f oldPos = sprite.getPosition(); 
    sprite.setPosition(newPos); 

    for (int i = 0; i < tiles.size(); i++) { 
     if (Collision::PixelPerfectTest(sprite, tiles[i].sprite) && tiles[i].collision) { 
      sprite.setPosition(oldPos); 
      newPos = oldPos; 
     } 
    } 
} 

回答

3

你的问题本质上是这样的:

如果你的球员是而不是在墙上,他可以向任何方向移动。这包括将他置于墙上的运动。如果你的球员在墙上是,他根本无法移动。所以,如果他进入了一堵墙(因为你允许他这样做),他永远无法摆脱它。

所以,最明显的解决方法是不让玩家进入墙壁。一种简单的方法是尝试移动玩家,然后检查与墙壁的碰撞。如果发生碰撞,请将播放器移回原始位置。

这应该解决您在墙上卡住的基本问题。尽管它可能会给你带来其他问题,比如不能在墙壁旁边站立。为此,您可以做的是在发生碰撞时确切检查墙壁的位置,然后将玩家向右移动。

+0

我无法起步,也许是因为它在上午的3。你能写一些伪代码吗? – Wahoozel

+0

@Wahoozel:我没有编写伪代码。 *“尝试移动播放器,然后检查是否与墙壁碰撞。如果有碰撞,移动玩家回到它原来的位置。” * –

+0

非常感谢,我得到它的工作。但是现在,如果我试图在同一时间说出,说出正确的话,我不能沿着墙壁滑动。我只是被卡住,不能移动,直到我释放或正确。 – Wahoozel

0

编辑:当碰撞检测返回false保存以前的位置,当与物体你的性格collise所有的u需要做的是恢复先前的非碰撞位置。

void Player::update(float delta, std::vector<Tile>& tiles) { 
for (int i = 0; i < tiles.size(); i++) 
    Collision::PixelPerfectTest(sprite, tiles[i].sprite) && tiles[i].collision) ? canMove = false : prevpos = sprite.getPosition(); 

if (canMove) { 
    move(delta); 
} 
else 
{ 
sprite.setPosition(prevpos); 
canMove = true; 
} 
} 

就是这样的。