2016-12-06 84 views
0

我對SFML和C++非常新穎。我的問題是我成功地向老鼠發射了炮彈。但是當我移動鼠標時,射彈也會移動。SFML:子彈停止

編輯:

好吧我解決了我以前的問題。然而,彈丸在到達鼠標位置時停止。子彈如何繼續比目的地更遠?

代碼:

if (isFiring == true) { 

     sf::Vector2f startPos = sf::Vector2f(myPipe.getX(), myPipe.getY()); 
     sf::Vector2i mousePos = sf::Mouse::getPosition(window); 
     sf::Vector2f endPos = sf::Vector2f(mousePos.x, mousePos.y); 

     double projSpeed{0.3}; 
     //float projSpeed = projSpeed * (myPipe.getY() - mousePos.y)/100; 
     Projectile newProjectile(20, startPos, endPos, projSpeed); 
     projVec.push_back(newProjectile); 
     isFiring = false; 
    } 

    for (int i = 0; i < projVec.size(); i++) { 

     projVec[i].fire(delta.asMilliseconds()); 
     projVec[i].draw(window); 
     clock.restart(); 

    } 

防火功能:

void fire(float delta) { 
    sf::Vector2f pos = projectile.getPosition(); 
    float veloX = (_end.x - pos.x); 
    float veloY = (_end.y - pos.y); 
    float distance = sqrt((veloX*veloX + veloY * veloY)); 

    float dx = veloX/distance; 
    float dy = veloY/distance; 
    projectile.move(dx * delta, dy * delta); 
} 

還有一個問題,我在做它用增量乘以是否正確?子彈真的很渺茫和怪異。

+0

順便說一句,你可以寫'爲(自動凸出:projVec)',而不是'的for(int i = 0 ...'等,並然後使用'proj'而不是'projVec [i]' –

+0

謝謝,我現在試着這樣做,但所有發生的事情是,彈丸卡在開始。超級怪異!:S – sockevalley

+0

你的激發碼有繪圖代碼。這不是很好,請保持關注分開,你在哪裏移動射彈一旦被解僱?你能發佈一個[mcve]嗎? – nvoigt

回答

1

(原答覆:)

我沒有足夠的信譽發表評論,因此我得把它放在這兒......

所以,如果我理解正確的話,你是說你想要朝着鼠標的位置射擊彈丸,但不希望它們一旦被解僱就追隨它的位置?在這種情況下:

我看到你有代碼在那個for-loop裏面畫出射彈,這讓我相信你正在不斷地調用循環。但是同樣的循環也包含用於射彈的代碼,這意味着你也在不斷地調用這個「火」代碼。因此,您在每次循環迭代中將射彈轉向當前鼠標位置,這意味着它們將始終遵循當前鼠標位置。

你應該做的是移動代碼來拍攝投射物並且只調用一次(你只能投射一次投射物,對嗎?)所以一個投射物的方向矢量不會經常改變,導致你陳述的問題。

並確保始終分離邏輯和渲染。理想情況下,您應該以固定的時間間隔更新物理(例如彈丸更新),以便遊戲在所有機器上運行相同,並分別繪製所有東西。

如果你想在彈丸始終跟隨鼠標,你可以使用這個(半僞)代碼(我用我的遊戲之一這段代碼):

sf::Vector2f normalizedVector = normalize(mousePos - projectilePos); 
normalizedVector.x *= speed * deltaTime; 
normalizedVector.y *= speed * deltaTime; 

projectile.move(normalizedVector); 

(編輯:)

我做了一個快速的示例項目,工程。這並沒有使用你的所有代碼,但希望能給你一個想法如何做。

下面是一個簡短的視頻顯示什麼下面的代碼所做的:https://webmshare.com/play/jQqvd

的main.cpp

#include <SFML/Graphics.hpp> 

#include "projectile.h" 

int main() { 
    const sf::FloatRect viewRect(0.0f, 0.0f, 800.0f, 600.0f); 

    sf::RenderWindow window(sf::VideoMode(viewRect.width, viewRect.height), "Test"); 
    window.setFramerateLimit(120); 
    window.setVerticalSyncEnabled(false); 
    window.setKeyRepeatEnabled(false); 

    sf::Clock deltaClock; 
    const sf::Time timePerFrame = sf::seconds(1.0f/60.0f); 
    sf::Time timeSinceLastUpdate = sf::Time::Zero; 

    std::vector<Projectile> projectiles; 

    while (window.isOpen()) { 

    timeSinceLastUpdate += deltaClock.restart(); 

    // process events 
    { 
     sf::Event evt; 
     while (window.pollEvent(evt)) { 
     switch (evt.type) { 
      case sf::Event::Closed: { window.close(); } break; 
      // shoot with left mouse button 
      case sf::Event::MouseButtonPressed: { switch (evt.mouseButton.button) { case sf::Mouse::Button::Left: { 
      const sf::Vector2f center(viewRect.left + viewRect.width/2, viewRect.top + viewRect.height/2); 
      const sf::Vector2f mousePos(window.mapPixelToCoords(sf::Mouse::getPosition(window))); 
      const float angle = atan2(mousePos.y - center.y, mousePos.x - center.x); 
      projectiles.push_back(Projectile(center, angle)); 
      } break; default: {} break; } } break; 
      default: {} break; 
     } 
     } 
    } 

    // update 
    { 
     while (timeSinceLastUpdate > timePerFrame) { 
     timeSinceLastUpdate -= timePerFrame; 
     // update projectiles 
     { 
      for (std::size_t i = 0; i < projectiles.size(); ++i) { 
      Projectile &proj = projectiles[i]; 
      proj.update(timePerFrame); 
      if (!viewRect.intersects(proj.getBoundingBox())) { proj.destroy(); } 
      } 
      projectiles.erase(std::remove_if(projectiles.begin(), projectiles.end(), [](Projectile const &p) { return p.getCanBeRemoved(); }), projectiles.end()); 
     } 
     } 
    } 

    // render 
    { 
     window.clear(); 
     for (std::size_t i = 0; i < projectiles.size(); ++i) { 
     window.draw(projectiles[i]); 
     } 
     window.display(); 
    } 

    } 

    return EXIT_SUCCESS; 
} 

彈。H:

#ifndef PROJECTILE_H_INCLUDED 
#define PROJECTILE_H_INCLUDED 

#include <SFML/Graphics.hpp> 

class Projectile : public sf::Drawable { 
public: 
    Projectile(); 
    Projectile(const sf::Vector2f pos, const float angle); 
    virtual ~Projectile(); 

    const bool &getCanBeRemoved() const; 
    const sf::FloatRect &getBoundingBox() const; 

    void destroy(); 
    void update(const sf::Time dt); 

private: 
    virtual void draw(sf::RenderTarget &renderTarget, sf::RenderStates renderStates) const; 

    bool canBeRemoved_; 
    sf::FloatRect boundingBox_; 
    float angle_; 
    float speed_; 

    sf::RectangleShape shape_; 

}; 

#endif 

projectile.cpp:

#include "projectile.h" 

Projectile::Projectile() : 
    canBeRemoved_(true), 
    boundingBox_(sf::FloatRect()), 
    angle_(0.0f), 
    speed_(0.0f) 
{ 
} 

Projectile::Projectile(const sf::Vector2f pos, const float angle) { 
    canBeRemoved_ = false; 
    boundingBox_ = sf::FloatRect(pos, sf::Vector2f(10.0f, 10.0f)); 
    angle_ = angle; 
    speed_ = 0.5f; 

    shape_.setPosition(sf::Vector2f(boundingBox_.left, boundingBox_.top)); 
    shape_.setSize(sf::Vector2f(boundingBox_.width, boundingBox_.height)); 
    shape_.setFillColor(sf::Color(255, 255, 255)); 
} 

Projectile::~Projectile() { 
} 

const bool &Projectile::getCanBeRemoved() const { 
    return canBeRemoved_; 
} 

const sf::FloatRect &Projectile::getBoundingBox() const { 
    return boundingBox_; 
} 

void Projectile::destroy() { 
    canBeRemoved_ = true; 
} 

void Projectile::update(const sf::Time dt) { 
    boundingBox_.left += static_cast<float>(std::cos(angle_) * speed_ * dt.asMilliseconds()); 
    boundingBox_.top += static_cast<float>(std::sin(angle_) * speed_ * dt.asMilliseconds()); 
    shape_.setPosition(boundingBox_.left, boundingBox_.top); 
} 

void Projectile::draw(sf::RenderTarget &renderTarget, sf::RenderStates renderStates) const { 
    renderTarget.draw(shape_); 
} 
+0

感謝你的回答。我正在嘗試讓射彈朝鼠標方向發展,但不要按照鼠標一次開火。我也相信之前出現過某種更新失敗。希望現在我的代碼更結構化一點。 – sockevalley

+0

@sockevalley看到我的編輯 – user3881815

+0

Ty!我已經很簡短地回顧了你的代碼。首先想到的問題是,你如何讓項目比鼠標更進一步? – sockevalley