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

28.01.2012, 20:40

SDL: Schuss in eigenem Spiel funktioniert nicht!

Guten Abend,
nachdem ich das Buch "C++ für Spieleprogrammierer" von Heiko Kallista nun durchgearbeitet hab, wollte ich mich mal an einem eigenen Spiel versuchen.
Diese Idee ist zugleich mein Facharbeitsthema.

Das Prinzip des Spiels ist altbekannt: Wie in 'Space Invaders' erscheinen Aliens im oberen Bildschirmdrittel welche man alle zerstören muss.
Das Spiel funktioniert soweit wunderbar, die Aliens werden gespawnt und die Kollisionsabfrage funktioniert ebenfalls.

Doch bei den Aliens stellt sich ein Problem: Ich möchte, dass diese Schüsse auf den Spieler abfeuern können. Leider funktioniert das nicht so ganz.
Mein erstes Etappenziel ist es, dass jeder Alien einen Schuss abfeuert, bevor ich diese nachher time.

Folgendes sind wahrscheinlich relevante Code-Abschnitte:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void CGame::ProcessAliens()
{

    //Iterator für die AlienListe
    list<CAlien>::iterator ItAlien;

    //Alien Liste durchlaufen
    for (ItAlien = m_AlienList.begin(); ItAlien != m_AlienList.end(); ++ItAlien)
    {

        //Alien updaten
        ItAlien->Update();

        //Alien rendern
        ItAlien->Render();

    }
}//RenderAliens

Hier werden einfach alle Aliens aktualisiert und anschließend gerendert



C-/C++-Quelltext

1
2
3
4
5
6
void CAlien::Update()
{   
    //Alien schießen lassen
    Shoot();

}


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void CAlien::Shoot()
{
    if(m_bShotLock == false)
    {
        //Schuss erstellen, wenn es noch keinen gibt
        m_Shot = new CShot();

        //Schuss initalisieren
        m_Shot->Init(m_pSpriteShot, m_fXPos, m_fYPos, true);

        m_bShotLock = true;
    }

}

Hier wird nun ein Schuss des jeweiligen Aliens abgefeuert.



C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void CAlien::Render()
{

    m_pSpriteAlien->SetPos(m_fXPos, m_fYPos);
    m_pSpriteAlien->Render();

    //Wenn Schuss vorhanden, dann rednern
    if (m_Shot != NULL)
    {
        m_Shot->Update();
        
        //Ist der Schuss noch aktiv?
        if (m_Shot->IsAlive())
        {
            //Ja, dann rendern
            m_Shot->Render();
        }
        
    }

}

Zuletzt wird der Schuss gerendert

C-/C++-Quelltext

1
2
3
4
5
6
7
8
void CShot::Update ()
{
    //Überprüfen, ob Spieler den Schuss abgefeuert hat oder Alien
    if (m_bIsAlien == true)
    {
        //Wenn ein Alien geschossen hat, Schuss in Richtung des unteren Bildschirmrandes bewegen
        m_fYPos += 400.0f * g_pTimer->GetElapsed ();
    }

Das ist die kleine Änderung an der Funktion Update der Klasse CShot. Wenn es sich um einen Alien handelt, soll der Schuss einfach von oben nach unten "fliegen".



Ich weiß dass es einiges an Quelltext ist, ich sitze jedoch schon recht lange an dem Problem...ohne eine Lösung.
Der großteil ist, wie man sieht, aus den Klassen des SDL-Games aus Kapitel 12 übernommen. Eventuell hab ich dort auch einen Fehler gemacht?!

Wenn mir irgendjemand einen Tipp geben könnte oder sogar den Fehler findet wäre ich sehr dankbar, da ich das Programm so langsam mal fertig bekommen müsste^^

Danke im Voraus :-)

2

28.01.2012, 21:16

Indem ich nun in der Funktion CAlien::Shoot die If-Bedingung weglasse, erscheint zumindest die Grafik des Schusses an der Position des Aliens. Doch leider bekomm ich diesen nicht bewegt.
Is auch logisch, da jetzt ja immer ein neuer Schuss erstellt wird...aber wie ist es möglich das Problem zu umgehen?
ich verzweifle echt im moment..

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

3

28.01.2012, 21:32

Denk an die Memoryleak, die du damit erzeugst...

Du scheinst m_bShotLock nicht mit false zu initialisieren.

Kannst du mit dem Debuger umgehen? Wenn nicht solltest du es lernen.
"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

28.01.2012, 21:39

Danke für die Antwort.

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
void CAlien::Init(CSprite *pSpriteAlien, float fXPos, float fYPos)
{

    //Zeiger auf Sprite kopieren und die Koordinaten setzen
    m_pSpriteAlien = pSpriteAlien;

    //Schuss noch nicht vorhanden
    m_Shot = NULL;
    
    m_bShotLock = false;
    m_fXPos = fXPos;
    m_fYPos = fYPos;

    //Schuss Sprite erstellen
    m_pSpriteShot = new CSprite;
    m_pSpriteShot->Load ("Data/Laser2.bmp");
    m_pSpriteShot->SetColorKey (255,0,255);

    //Rect initalisieren
    m_Rect.x = static_cast<int> (fXPos);
    m_Rect.y = static_cast<int> (fYPos);
    m_Rect.h = m_pSpriteAlien->GetRect().h;
    m_Rect.w = m_pSpriteAlien->GetRect().w;

    //Alien aktivieren
    m_bIsAlive = true;


Ich initalisiere m_bShotLock auf false... also dürfte der Fehler dort eigentlich nicht sein. Und m_bShotlock wird sonst auch nicht irgendwie verändert. Deswegen verwundert mich die Sache auch, dass mit der If-Bedingung garnichts angezeigt und ohne die if-Bedingung nur ein "wackelnder" Schuss erzeugt wird. Offensichtlich ist, dass der Schuss immer wieder neu erzeugt wird oder die yPos nicht richtig übernommen wird.

Mit dem Debugger unter normalen Programmen konnte ich umgehen, bei diesem Programm hängt sich jedoch beim debuggen alles auf.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

5

29.01.2012, 10:23

Mit dem Debugger unter normalen Programmen konnte ich umgehen, bei diesem Programm hängt sich jedoch beim debuggen alles auf.

Das dürfte eigentlich nicht passieren. Debugst du denn mit der Debug- und nicht mit der Releaseversion?

Ich empfehle Anfängern, die gerade das Buch durchgearbeitet haben immer komplett neu anzufangen und etwas sehr leichtes zu machen. Vorzugsweise mit der SFML, weil die einfach mehr mit bringt und einfacher zu bedienen ist. Im Kapitel 12 kommt einfach zu viel vor, was du noch nicht richtig verstehen kannst. Deshalb ist es in meinen Augen blödsinnig den Code zu nutzen oder zu bearbeiten.


edit: Übrigens lädst du das Sprite für den Schuss mit jedem Alien neu. Wenn du mehrere Aliens hast ist das langsam und du verschwendest Speicher. Machs wie mit dem Sprite für das Alien und lade es eine Ebene drüber.
"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?

6

29.01.2012, 18:56

Okay, danke für den Tipp mit der SFML.
Trotzdem ist mein Problem, dass ich dieses Spiel für die Facharbeit in Informatik schreiben muss.

Wo könnte der Fehler denn liegen? Theoretisch mach ich doch alles richtig: Ich erstelle ein Schuss-Sprite, jeder Alien bekommt den Zeiger auf das Sprite, es wird ein Schuss erzeugt, gerendert und bewegt...
Hat niemand einen Vorschlag?

Wenn ihr weitere Codeabschnitte braucht sagt bescheid :-)

7

29.01.2012, 19:56

Doppelpointer..?

MfG
Check

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

29.01.2012, 21:01

Debuggen. Alles andere ist hier doch nur raten. Und da wir nicht den kompletten Code kennen ist es auch relativ schwer den Fehler zu finden.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige