Ich poste hier nach einem Versuch auf einem französischen Forum namens OpenClassrooms, aber ohne Antworten, poste ich hier auch.std :: vector Sprite Segmentierung Fehler
Also warne ich, ich bin neu in C++ und SFML, also gibt es wahrscheinlich zehntausend Fehler, und es scheint, dass das Buch, das ich gelesen habe, ein wirklich schlechtes Buch war, also versuche ich das mit Bjarne Stroustrups Buch zu korrigieren.
Mein Problem ist folgendes:
I Projektilen erstellen, wenn ich die Eingabetaste drücken oder Raum (es gibt zwei Spieler auf der gleichen Tastatur). Und jedes Mal, wenn ich es drücke, erstelle ich eine Kopie des Sprites des Projektils für das neue Projektil, und wir legen es in eine std::vector<sf::Sprite>
. Das Problem ist, wenn ich das Spiel starte, wenn die beiden Spieler ihre Shoot-Taste (Enter und Space) gleichzeitig drücken (ich meine, solange das erste Projektil sichtbar ist), stürzt das Spiel ab und zeigt Segmentation Fault (core dumped)
. Um dies zu beheben, habe ich zwei Sprites (eines für jeden Spieler) erstellt und sie für ihre Projektile beeinflusst. Das Problem ist, wenn ihre Angriffsgeschwindigkeit riesig ist, können sie ihr zweites Projektil schießen, bevor das erste verschwindet, so dass die Kollisionen ein Problem haben werden, weil es das gleiche Sprite zweimal gibt ... und das erste wird nicht funktionieren. Um dieses Problem zu lösen, wollte ich einen std :: vector verwenden. Übrigens, ich versuche nicht, dies nur für zwei Spieler zu lösen, ich habe vor, etwas mehr hinzuzufügen, also brauche ich etwas, das zum Beispiel mit 1000 Spielern funktionieren würde (natürlich werde ich das nicht mit 1000 Spielern tun, aber wenn es mit dieser Menge funktioniert, wird es auch für 5 Spieler funktionieren).
Um mein Projektil zu erstellen, verwende ich einen Verweis auf das Objekt Sprite, das ich später dank einer Methode in meiner Klasse Game zeige. Diese Referenz ist der Verweis auf ein Sprite im std :: vector. Ich erkannte auch, dass wenn wir ein erstes Projektil schießen, warten, bis es verschwindet und dann die beiden Spieler schießen lassen, es funktioniert richtig (manchmal stürzt es manchmal auch) ... Ich verstehe nicht warum, aber es ist meistens, wenn ich starte das Spiel, dass es abstürzt.
Hier ist mein Code:
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;
}
Natürlich nahm ich einige Teile, würde ich meinen ganzen Code nicht kopieren und einfügen, gibt es nutzlose Dinge. Wenn Sie das Gefühl haben, dass Sie meine Klassen brauchen (Projektil, Spiel, Entität, Bombardierung), werde ich sie veröffentlichen.
Ich denke, es kann Ihnen helfen, das Projektil Konstruktor, um zu sehen:
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. */ }
Vielen Dank für Ihre Hilfe!
* * 'std :: vector', 'verwenden std :: vector >' (oder möglicherweise 'std :: vector >' - auf diese Weise wird es sein, Sofort geklärt –
@MartinBonner: Ich habe gezögert, es zu erwähnen, da ich nicht zu viel STL-Zeug in die Antwort setzen wollte (er sollte auch 'make_unique' anstelle von neu verwenden) ... Aber du hast Recht, Ich bearbeite die Antwort, um es zu erwähnen: Gute Praktiken werden besser früh gelernt. –
Wie ich schon sagte, habe ich mit einem schlechten Buch gelernt, also ja, es ist besser, gute Dinge zu wissen, wie ich std :: vector <*Something> überall>. < Ich werde versuchen, was Sie gerade sagen, und antworten nach ^^ Und sicher, ich würde gerne mehr über unique_ptr wissen, ich sah es nie: D – FeelZoR