- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在一个名为 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/
我正在开发一个小型图书馆,我需要做的一件事是让访问者访问一些数据并返回结果。 在一些较旧的 C++ 代码中,访问者需要声明一个 typedef return_type .例如,boost::stati
我正在尝试使用std:map类型的键和值制作std::any Visual Studio 2017 std::map m("lastname", "Ivanov"); std::cout (m["la
我已经在 C++ 的 map 中声明了一个集合为 std::map> .如何循环访问或打印设定值? 最佳答案 如果你知道如何迭代 std::map或 std::set单独地,您应该可以毫无问题地组合迭
如何循环? 我已经试过了: //----- code std::vector >::iterator it; for ( it = users.begin(); it != users.end();
我有两个用例。 A.我想同步访问两个线程的队列。 B.我想同步两个线程对队列的访问并使用条件变量,因为其中一个线程将等待另一个线程将内容存储到队列中。 对于用例 A,我看到了使用 std::lock_
我正在查看这两种类型特征的文档,但不确定有什么区别。我不是语言律师,但据我所知,它们都适用于“memcpy-able”类型。 它们可以互换使用吗? 最佳答案 不,这些术语不能互换使用。这两个术语都表示
我有以下测试代码,其中有一个参数 fS,它是 ofstream 的容器: #include #include #include #include int
这是这个问题的延续 c++ function ptr in unorderer_map, compile time error 我试图使用 std::function 而不是函数指针,并且只有当函数是
std::unordered_map str_bool_map = { {"a", true}, {"b", false}, {"c", true} }; 我们可以在此映射上使
我有以下对象 std::vector> vectorList; 然后我添加到这个使用 std::vector vec_tmp; vec_tmp.push_back(strDRG); vec_tmp.p
为什么 std::initializer_list不支持std::get<> , std::tuple_size和 std::tuple_element ?在constexpr中用得很多现在的表达式,
我有一个像这样定义的变量 auto drum = std::make_tuple ( std::make_tuple ( 0.3f , Ex
假设我有一个私有(private)std::map在我的类(class)里std::map 。我怎样才能将其转换为std::map返回给用户?我想要下面的原型(prototype) const std
假设我有一个私有(private)std::map在我的类(class)里std::map 。我怎样才能将其转换为std::map返回给用户?我想要下面的原型(prototype) const std
问题 我正在尝试将 lambda 闭包传递给 std::thread,它使用任意封闭参数调用任意封闭函数。 template std::thread timed_thread(Function&& f
我想创建一个模板类,可以容纳容器和容器的任意组合。例如,std::vector或 std::map ,例如。 我尝试了很多组合,但我必须承认模板的复杂性让我不知所措。我编译的关闭是这样的: templ
我有一个 std::vector>我将其分配给相同类型的第二个 vector 。 我收到这个编译器错误: /opt/gcc-8.2.0/include/c++/8.2.0/bits/stl_algob
有时候,我们有一个工厂可以生成一个 std::unique_ptr vector ,后来我们想在类/线程/你命名的之间共享这些指针。因此,最好改用 std::shared_ptr 。当然有一种方法可以
这个问题在这里已经有了答案: Sorting a vector of custom objects (14 个答案) 关闭 6 年前。 我创建了一个 vector vector ,我想根据我定义的参
我有三个类(class)成员: public: std::vector > getObjects(); std::vector > getObjects() const; privat
我是一名优秀的程序员,十分优秀!