2015-01-06 204 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; 
} 
} 

就是這樣的。