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

18.10.2010, 06:10

Bug mit STL

Hallo Community
Ich habe es mal wieder geschafft einen für mich unauffindbaren Bug in den Code
einzubauen und nachdem ich ihm jetzt seit ein paar Tagen hinterherjage, hoffe ich,
dass ihr mir weiterhelfen könnt.
Folgendes:
Ich habe eine STL Liste für 2D Schüsse und nun möchte ich diese Schüsse rendern:

C-/C++-Quelltext

1
2
3
4
5
6
    list<CShot*>::iterator ItShot;

    for(ItShot = lShots.begin(); ItShot != lShots.end(); ++ItShot)
    {
        g_pFramework->Render((*ItShot)->GetSprite());
    }


Sollte dafür eigentlich funktionieren, allerdings wird der Schuss lediglich im ersten Frame nach dem Schießen gerendert, danach nichtmehr.
Nach 1-2 Sekunden gibt es dann eine Fehlermeldung im Debugger und es öffnet sich eine Datei namens xtree in Vc++ 08.
Bewegen tue ich die Schuesse bis jetzt noch nicht und der RenderMethode ist soweit imho
alles in Ordnung, da sie mit anderen Sprites funktioniert.

Shot.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef SHOT_HPP
#define SHOT_HPP

#include "Framework.hpp"

class CShot
{
public:
    CShot(sf::Image *Image, sf::Vector2f Position, float Rotation, float Speed);
    
    void Move();
    //Aus unerfindlichen gründen geben meine Printlines hier nichts aus
    sf::Sprite GetSprite(){return Sprite;}

private:
    sf::Sprite Sprite;
    float m_Speed;
};

#endif


Shot.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "Shot.hpp"

CShot::CShot(sf::Image *Image, sf::Vector2f Position, float Rotation, float Speed)
{
    Sprite.SetImage(*Image);
    Sprite.SetPosition(Position);
    Sprite.SetRotation(Rotation);
    m_Speed = Speed;
}

void CShot::Move()
{
    float Up    = (g_pFramework->GetCos(Sprite.GetRotation()))* (-m_Speed);
    float Right = (g_pFramework->GetSin(Sprite.GetRotation()))* m_Speed;
    Sprite.Move(Up,Right);
}
Gewinnen ist, wenn man einmal mehr aufsteht, als man zu Boden geht.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

2

18.10.2010, 08:31

Ist das Absicht, dass die GetSprite()-Funktion eine Kopie des Sprites zurückgibt? Je nachdem, was die Klasse im Hintergrund alles tut, kann es da nach ner Weile schon zu seltsamen Effekten kommen.

Außerdem: schau Dir mal die Stelle an, die Du im Debugger gezeigt bekommst. Jetzt nicht direkt im xtree, was er Dir zuerst zeigt - das ist nur das Symptom - sondern geh im Callstack ein paar Stufen zurück bis zum ersten File, dass von Dir geschrieben ist. Dort wirst Du dann vielleicht besser sehen, woran es liegt.
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.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

3

18.10.2010, 10:59

i.d.r. ist es besser der klasse einen zeiger auf das framework und eine rendermethode zu geben und nicht andersherum. es passiert schonmal, dass du neben dem rendern auch was anderes machen musst.
von zusammengesetzen datentypen übergibt man wenn nicht anders benötigt eine referenz auf const oder einen zeiger.(z.b. bei deiner getspritemethode und im konstruktor bei der position)
schau dir mal die initialisierungsliste an
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

4

19.10.2010, 02:21

Okay, ich habe jetzt ein paar Stunden debuggt und folgendes ist dabei rausgekommen:
Im ersten Frame(relativ zur Schussabgabe) verhält sich der Schuss wie er soll (wird gerendert)
Beim Update des Frameworks am Anfang des zweiten Frames wird er aber gründlich zerschossen,
d.h. Zeiger auf Image auf 0 gesetzt, Positionen in gigantisch winzige Werte geändert usw.

Den Fehler konnte ich auf eine Funktion zurückführen nämlich: EventLoop():

C-/C++-Quelltext

1
2
3
4
5
6
7
8
void CFramework::EventLoop()
{
    while (App->GetEvent(Event))
    {
    if (Event.Type == sf::Event::Closed)
        App->Close();
    }
}


Innerhalb dieser Zeilen (oder jedenfalls passiert esimmer dann, wenn die Funktion ausgeführt wird)
muss der Fehler liegen.
Eigentlich müssten sie richtig sein, aber es produziert immer wieder den selben Müll.
Ich bin langsam mit meinem Debuggerlatein am Ende, es wäre also nett, wenn ihr mir sagt,
wie ich weitersuchen soll.

Danke schonmal bis hierhin
Gewinnen ist, wenn man einmal mehr aufsteht, als man zu Boden geht.

5

19.10.2010, 02:42

Hallo Flonk,

auch wenn du vermutlich bald die Nase davon gestrichen voll hast... such weiter. Wenn das die gesamte EventLoop()-Funktion ist, dann liegt der Fehler hier ganz sicher nicht. Zum einen hat das ja gar nichts mit dem Rendern etc. zu tun und zum anderen hälst du dich hier schön an das SFML Tutorial für Event-Handling und das ist korrekt, keine Angst! ;)

Aber du sag mal... warum hast du denn in dieser Zeile ein Minus vor der Geschwindigkeit?

C-/C++-Quelltext

1
float Up = (g_pFramework->GetCos(Sprite.GetRotation()))* (-m_Speed); 


Und wenn ich noch einen Tipp geben darf... benutze Vektoren ( in der SFML z.B. sf::vector2f ) für Position und Bewegung deiner Objekte. ;)

Gruß
SaRu_

6

19.10.2010, 03:24

hmm ja nur hab ich technisch keine ahnung mehr, da ich nicht so gut mit
dem Debugger bin, wäre also für ein paar Tuts sehr dankbar
Ja die bewegung ist noch nicht optimal, aber immerhin funktioniert sie...
Gewinnen ist, wenn man einmal mehr aufsteht, als man zu Boden geht.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

7

19.10.2010, 10:57

benutz mal die sufu und suche NULL(falls du das verwendest, wenn nicht bist du selbst schuld^^) und delete. dein zeiger muss da ja vorbei kommen wenn er auf einmal auf null steht. also suchst du die stellen bei denen die methode aufgerufen wird usw.

achja... je schlechter du debugen kannst desto mehr besteht dein hobby aus debugen. :)
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

8

19.10.2010, 18:57

hmm delete und =NULL wird nur im Destruktor des Spieles aufgerufen, und da es ja noch weiterlaeuft,
ist es wohl kaum zerstoert.
Es ist wirklich zum Haare raufen, die Funktion hat noch nicht einmal einen Pointer auf den Spieler, aber
dennoch zerschiesst sie ihn... vllt ist irgendwas mit der Schleife nicht in ordnung, werd ich mir
heut nachmittag mal ansehen
Gewinnen ist, wenn man einmal mehr aufsteht, als man zu Boden geht.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

19.10.2010, 19:10

Hast du denn schon überprüft worauf Schrompf dich anfangs hingewiesen hat? Warum genau gibt GetSprite() eine Kopie des Sprite zurück? Kann es nicht sein dass genau so eine temporäre Kopie in ihrem Destruktor irgendwas freigibt was eigentlich noch gebraucht wird!?

10

20.10.2010, 00:26

hmm is jetzt als pointer, klappt aber immer noch nicht... :(
Gewinnen ist, wenn man einmal mehr aufsteht, als man zu Boden geht.

Werbeanzeige