(原答覆:)
我沒有足夠的信譽發表評論,因此我得把它放在這兒......
所以,如果我理解正確的話,你是說你想要朝着鼠標的位置射擊彈丸,但不希望它們一旦被解僱就追隨它的位置?在這種情況下:
我看到你有代碼在那個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_);
}
順便說一句,你可以寫'爲(自動凸出:projVec)',而不是'的for(int i = 0 ...'等,並然後使用'proj'而不是'projVec [i]' –
謝謝,我現在試着這樣做,但所有發生的事情是,彈丸卡在開始。超級怪異!:S – sockevalley
你的激發碼有繪圖代碼。這不是很好,請保持關注分開,你在哪裏移動射彈一旦被解僱?你能發佈一個[mcve]嗎? – nvoigt