gpt4 book ai didi

c++ - std::vector Sprite 分割错误

转载 作者:太空狗 更新时间:2023-10-29 21:36:24 26 4
gpt4 key购买 nike

我在一个名为 OpenClassrooms 的法语论坛上尝试后发帖,但没有答案,我也发帖在这里。

所以我警告你,我是 C++ 和 SFML 的新手,所以可能有一万个错误,而且我读的书似乎是一本非常糟糕的书,所以我尝试用 Bjarne Stroustrup 的书来纠正它。

我的问题如下:

当我按下 Enter 或 Space 时我会创建射弹(同一个键盘上有两个玩家)。每次我按下它,我都会为新射弹创建一个射弹 Sprite 的拷贝,然后我们将它放入 std::vector<sf::Sprite> 中。 .问题是当我启动游戏时,如果两个玩家同时按下他们的射击键(Enter 和 Space)(我的意思是,只要第一颗弹丸可见),游戏就会崩溃并显示 Segmentation Fault (core dumped) .为了解决这个问题,我创建了两个 Sprite (每个玩家一个),并为他们的射弹影响它。问题是当他们的攻击速度很高时,他们可以在第一颗炮弹消失之前发射第二颗炮弹,所以碰撞会有问题,因为有两次相同的 Sprite ......而第一个不会起作用。所以,为了解决这个问题,我想使用 std::vector。顺便说一下,我不会尝试只为两个玩家解决这个问题,我打算添加更多,所以我需要一些可以与 1000 名玩家一起使用的东西,例如(当然我不会对 1000 名玩家这样做,但如果它适用于该数量,它也适用于 5 个玩家)。

为了创建我的射弹,我使用了对 Sprite 对象的引用,由于类 Game 中的一个方法,我稍后将显示该对象。此引用是对 std::vector 中 Sprite 的引用。我还意识到,如果我们发射第一颗炮弹,等待它消失,然后让两个玩家射击,它会正常工作(有时,有时也会崩溃)......我不明白为什么,但主要是当我启动它崩溃的游戏。

这是我的代码:

std::vector<sf::Sprite> sprites;

int main()
{
Game game;

sf::ContextSettings settings;
settings.antialiasingLevel = 8;
sf::RenderWindow window(sf::VideoMode(1600, 900), "Bombardes", sf::Style::Default, settings);
sf::Texture text;
if (!text.loadFromFile("resources/projectile.png")) {
logg.error("Could not create texture for projectile. Aborting.");
}
Bombard bomb(50, 150, &game, &pSprite, &movement2); // player class
Bombard bomb2(1550, 850, &game, &pSprite2, &movement);
std::vector<std::shared_ptr<Projectile>> p;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type) {
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
if (event.key.code == sf::Keyboard::Return) { // Player 2
auto current2 = std::chrono::steady_clock::now();
auto elapsed2 = std::chrono::duration_cast<std::chrono::milliseconds>(current2 - last2);
if (elapsed2.count() >= 1000 / bomb2.getAttackSpeed()) { // Time the frequency of shots
last2 = std::chrono::steady_clock::now();
if (bomb2.getAmmo() > 0) { // Check if there's still ammo
sprites.push_back(sf::Sprite(text)); // New sprite in vector
p.push_back(std::make_shared<Projectile>(bomb2.getPos().getX(), bomb2.getPos().getY(), &sprites[sprites.size()-1], &game, bomb2.getProjectileMovement(), bomb2.getPenetration(),
bomb2.getSpeed())); // Create the projectile
bomb2.fire(); // Remove an ammo
}
}
}
else if (event.key.code == sf::Keyboard::Space) { // Player 1
auto current = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(current - last);
if (elapsed.count() >= 1000 / bomb.getAttackSpeed()) {
last = std::chrono::steady_clock::now();
if (bomb.getAmmo() > 0) {
sprites.push_back(sf::Sprite(text));
p.push_back(std::make_shared<Projectile>(bomb.getPos().getX(), bomb.getPos().getY(), &sprites[sprites.size()-1], &game, bomb.getProjectileMovement(), bomb.getPenetration(), bomb.getSpeed()));
bomb.fire();
}
}
}
break;
}
}
}
return 0;
}

当然,我删除了一些部分,我不会复制粘贴我的整个代码,有无用的东西。如果您觉得需要我的类(class)(射弹、游戏、实体、轰击),我会发布它们。

我想它可以帮助您了解 Projectile 的构造函数:

Projectile::Projectile(int posX, int posY, sf::Sprite *sprite, Game *game, sf::Vector2f direction, double penetration, double speed) {
/** @brief Full constructor.
@param int posX : The X position on the map.
@param int posY : The Y position on the map.
@param sf::Sprite *sprite : A pointer to the sprite.
@param Game *game : A pointer to the game.
@param sf::Vector2f direction : The direction in which the projectile will move. */ }

感谢您的帮助!

最佳答案

已经发生了很多事情,所以我可能错过了一些事情。

有一件事看起来很奇怪:两个玩家都使用相同的 Projectile他们射击时的指针!

玩家 1 射击:第一个射弹是堆分配的,您将其地址保存在 p 中.到目前为止一切顺利。

然后玩家 2 射击。您创建了一个新的射弹(具有正确的位置和 Sprite 等...)但是,您还将其地址存储在 p 中.

除非您在代码中的其他地方保存了第一个射弹的地址,否则您如何设法访问它?你怎么知道它是否达到了目标(然后,玩家 1 应该得分)或者是否已经超出了屏幕(然后你可以删除它以清理内存)?

我怀疑它周围有东西。也许你应该尝试将所有射弹存储在 std::vector<Projectile*> 中甚至更好,std::vector<std::unique_ptr<Projectile>> .这样(如果我确实理解了代码)玩家可以发射不止一枚射弹。

(如果您想知道 unique_ptr 部分,请不要介意问)

让我们了解您的尝试,好吗?

关于c++ - std::vector Sprite 分割错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40562269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com