Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

21.07.2022, 20:05

SFML erase from Vector, Iterator?

Hallo zusammen,
ich hab mal eine Frage zum Iterator bzw die Erase Funktion in Vectoren. Und zwar versteh ich das Prinzip, anhand von Tutorials mit der eunfachen Einbindung eines Integer durch einen Vector, aber ich bekomme es in SFML nicht hin, vielleicht kann mir jemand helfen.
Kurze Erklärung dazu: Ich habe ein einfaches Rechteck als Spieler(RectangleShape Player), dass kann ich frei bewegen. Des weiteren gibt es noch 2 Rechtecke (RectangleShape Door), die in einem Vector sind, nun möchte ich, dass wenn der Player sie berührt, die Rechtecke verschwinden, klingt ziemlich einfach, aber irgendwie komme ich nicht darauf, hier die Codeschnipsel für die Rechtecke die verschwinden sollen

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
RectangleShape door;
std::vector<RectangleShape> doors(3);

...

while (window.isOpen())
    {
        
        sf::Event event;
        while (window.pollEvent(event));



for (int j = 0; j < doors.size(); j++){
    
    
    
doors[j].setFillColor(Color::Cyan);
    
 doors[1].setSize(Vector2f(100, 100));
 doors[1].setPosition(Vector2f(650, 1000));
    
 doors[2].setSize(Vector2f(100, 100));
 doors[2].setPosition(Vector2f(650, 700));
    
    
 }

for (auto& door: doors){
    
 FloatRect doorBounds =  door.getGlobalBounds();
 FloatRect PlayerBounds = player.getGlobslBounds();

if(doorBounds. intersects(playerBounds)){
        
     doors.erase(doors.begin(), doors.end());
    
 }

window.draw(doors[1]);
 window.draw(doors[2]);
    
    
 }


In dem.jetzigen Code verschwinden doors[1] und doors[2] zusammen auf einmal wenn ich nur euns von beiden berühre mit dem Player, es soll aber nur das verschwinden welches ich aktuell berühre.Ich weiß es nichts von Iterator zu sehen, hab schon soviel damit rumprobiert, aber nichts klappt. Villeicht kann mir jemand ein Tipp geben.
Gruß Jan

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jan666« (21.07.2022, 20:43)


Timmyew

Treue Seele

Beiträge: 128

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

2

22.07.2022, 00:32

Hey Jan666,

ich sende dir jetzt hiermit mal ungetesteten Code mit ^^.
Versuche es mal hiermit :)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
RectangleShape door;
std::vector<RectangleShape> doors(3);

...

while (window.isOpen())
    {
        
        sf::Event event;
        while (window.pollEvent(event));



for (int j = 0; j < doors.size(); j++){
    
    
    
doors[j].setFillColor(Color::Cyan);
    
 doors[1].setSize(Vector2f(100, 100));
 doors[1].setPosition(Vector2f(650, 1000));
    
 doors[2].setSize(Vector2f(100, 100));
 doors[2].setPosition(Vector2f(650, 700));
    
    
 }

for (auto& door: doors){
    
 FloatRect doorBounds =  door.getGlobalBounds();
 FloatRect PlayerBounds = player.getGlobslBounds();

if(doorBounds. intersects(playerBounds)){
        
     //Hier hat sich was getan ####################################################
     doors.erase(std::find(doors.begin(), doors.end(), door));
    
 }

window.draw(doors[1]);
 window.draw(doors[2]);
    
    
 }


Sollte es auf anhieb nicht helfen, dann schau doch mal hier vorbei :)
https://iq.opengenus.org/ways-to-remove-…rom-vector-cpp/

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Timmyew« (22.07.2022, 01:08)


3

22.07.2022, 07:08

Klappt leider nicht aber trotzdem Danke

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jan666« (22.07.2022, 08:02)


Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

4

22.07.2022, 07:56

Puh, Du hast da ne Menge Elend drin, aber da kommst Du selbst drauf. Dein eigentliches Problem ist, dass Du über einen std::vector iterierst (Zeile 29), aus dem Du gleichzeitig was raus löschst (Zeile 37). Das überspringt aus Versehen einen Eintrag und crasht evtl. sogar, weil Du aus Versehen über's Ende hinaus liest.

Wandel die Schleife in eine Iterator-Schleife um. Dann kannst Du den Rückgabewert von erase verwenden, anstatt zu inkrementieren. Und das musst Du, das ist der offizielle Weg, um dieses Problem zu vermeiden.

Quellcode

1
2
3
4
5
6
7
8
9
for (auto it = doors.begin(); it != doors.end(); /* absichtlich kein ++ */) {
  if(doorBounds. intersects(playerBounds)) {
    // Löschen, Schleife geht mit dem ersten nach dem gelöschten Eintrag weiter
    it = doors.erase(it);
  } else {
    // nicht löschen, Schleife geht einfach zum nächsten Eintrag über
    ++it;
  }
}
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

5

22.07.2022, 09:42

Hmm, da passiert auch nichts

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jan666« (22.07.2022, 09:50)


6

22.07.2022, 09:58

Also so sieht der Code jetzt aus, aber es verschwinden immer noch beide anstatt nur eins

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
RectangleShape door;

std::vector<RectangleShape> doors(3);



...

while (window.isOpen())
    {
        
        sf::Event event;
        while (window.pollEvent(event));

...

 for (int j = 0; j < doors.size(); j++){
    
    
    
    doors[j].setFillColor(Color::Cyan);
    
    doors[1].setSize(Vector2f(100, 100));
    doors[1].setPosition(Vector2f(650, 1000));
    
    doors[2].setSize(Vector2f(100, 100));
     doors[2].setPosition(Vector2f(650, 700));
    
    
 }
 for (auto& door: doors){

 FloatRect playerBounds = player.getGlobalBounds();
 
 FloatRect doorBounds = door.getGlobalBounds();
 
 for ( auto it = doors.begin(); it != doors.end();)
  {
        
  if(doorBounds. intersects(playerBounds)) { 
     it = doors.erase(it);
     
      } 
      else 
      { 
      ++it; 
      }
      
        
    
 window.draw(doors[1]);
 window.draw(doors[2]);
    
    
 }
 
 }

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

7

22.07.2022, 21:17

Wessen doorBounds prüfst Du denn da in der Schleife?

Das ist ne rhetorische Frage, ich weiß es. Aber Du wirst damit hoffentlich auch sehen, woran es liegt :-) Du hast jetzt zwei Schleifen über alle doors. Einmal meinen Vorschlag, aber Deinen hast Du außenrum einfach stehen lassen.

Weitere Empfehlung: ich *vermute*, Du benutzt Visual Studio. Setze mal einen Breakpoint auf eine Zeile irgendwo, wo Du denkst, dass es passiert, und starte Dein Programm mal mit "Debuggen". Dann kannst Du Zeile für Zeile durch Dein Programm gehen und siehst genau, was gerechnet wird und welche Abzweigungen das Programm nimmt.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

8

22.07.2022, 21:30

Ich benutze als IDE c4droid und mache alles auf dem Smartphone wird schwierig das mit dem debuggen :), ich weiß nicht denke ich mit meinem Code zu kompliziert, eigentlich will ich das objekt löschen das ich mit dem spieler berühre, daß in einem Vector steckt

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

9

22.07.2022, 23:31

Debuggen sollte überall gehen. War aber nur ein Vorschlag. Lies bitte nochmal genau Deinen letzten Code und beobachte, dass Du zwei ineinander geschachtelte Schleifen hast: die ursprüngliche

Quellcode

1
for (auto& door: doors)
, in der Du nichts löschen kannst, und die neue mit Iterator, in der Du löschen kannst. Eine von diesen beiden muss weg.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Werbeanzeige