Problem mit Goto



  • Vor ein paar Tagen hab ich mit einem Spiel angefangen (mit Hilfe von SDL) und hab dazu eine Art Hauptmenü gemacht (mit Bildern, die man anklicken kann (SDL_Rect und Mauspositionen)). Während man sich im Hauptmenü befindet, ist man in einer While-Schleife, die z.B. Events abfragt. Eine der Schaltflächen im Hauptmenü kann die Schleife beenden und das Spiel starten. Das funktioniert auch wunderbar. Dann kommt die Spieloberfläche. Auch während dem Spiel befindet man sich in einer While-Schleife. Nun wollte ich es so machen, dass man per Escape ins Hauptmenü zurückkehrt. Ich habs mit goto probiert und das Label ziemlich am Anfang des Programms gesetzt, in der Hoffnung, bei Escape würde man das Programm sozusagen von vorne neu durchlaufen lassen. Hat leider nicht geklappt, sondern das Programm hat sich schlicht und einfach beendet.

    Den Quelltext hab ich absichtlich nicht gepostet, weil er viel zu umfangreich ist. Doch im Grossen und Ganzen sieht das Programm etwa so aus:

    Anfang:
    SDL-Initialisierung
    ...
    while (ImHauptmenü)
    {
           Druck auf Schaltfläche -> ImHauptmenü = false;
           ...
    }
    ...
    
    while (ImGame)
    {
           Druck auf Escape -> goto Anfang;
           ...
    }
    

    Wie ist es möglich, zum Hauptmenü zurückzukehren? Ich verstehe eben goto grundsätzlich nicht sehr gut (z.b. was es mit bereits deklarierten Variabeln macht), deshalb hab ich auch Schwierigkeiten. Und man findet auch nirgends etwas nützliches über goto, höchstens für Sprünge in kleinen Schleifen etc...



  • Hallo, mach es eher so und erspare der Welt ein weiteres goto 😃
    (Das mit den goto gibt IMMER code der bald nicht mehr zu durchblicken ist = spagetticode)

    SDL-Initialisierung
    ...
    while (ImHauptmenü)
    {
           Druck auf Schaltfläche -> ImGame = true;
           ...
    
           while (ImGame)
           {
               Druck auf Escape -> ImGame = false;          
               ...
           }
    
    }
    ...
    


  • Dieser Thread wurde von Moderator/in rapso aus dem Forum Spiele-/Grafikprogrammierung in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Danke für den Tipp, ich habs jetzt nach deiner Art strukturiert, aber es scheint trotzdem noch nicht zu gehen.
    Ich komme wieder vom Hauptmenü ins Spiel, dann drück ich im Spiel Escape, und das Programm beendet sich. Dabei bin ich sicher, dass nur die innere Schleife beendet wurde. Man sieht auch für eine ganz kurze Zeit wieder das Hauptmenü, also muss es nachher an einem Problem liegen... Weiss nicht jemand zufällig, an welchem?



  • Nimm dir mal einen Debugger und schau schrittweise durch, was während deiner Schleife(n) eigentlich passiert. (möglicherweise hast du ja (unbeabsichtigt) den Wert von ImHauptmenü zurückgesetzt, während deine Spielschleife lief - oder die Hauptschleife fängt auch das ESC ab)



  • Ich hab hier ein kleines Testprogramm mit der Anweisung geschrieben.
    Doch jetzt kann ich ins 2. Bild wechseln, wenn ich aber mit Backspace zurück will, wird sehr schnell zwischen den beiden Bildern gewechselt.

    Der Quelltext:

    #include <SDL.h>
    
    int main(int argc, char *argv[])
    {
        SDL_Init(SDL_INIT_VIDEO);
        atexit(SDL_Quit);
    
        SDL_Surface *screen, *bild1, *bild2;
        screen = SDL_SetVideoMode(640,480,16,SDL_HWSURFACE);
        bild1 = SDL_LoadBMP("t1.bmp");
        bild2 = SDL_LoadBMP("t2.bmp");
    
        bool s1 = true;
        bool s2 = false;
    
        while (s1)
        {
            SDL_BlitSurface(bild1,0,screen,0);
            SDL_UpdateRect(screen,0,0,0,0);
            SDL_Event E;
            SDL_PollEvent(&E);
    
            if (E.type == SDL_KEYDOWN)
            {
                if (E.key.keysym.sym == SDLK_ESCAPE)
                    s1 = false;
                else if (E.key.keysym.sym == SDLK_RETURN)
                    {
                        s2 = true;
                    }
            }
            if (E.type == SDL_QUIT)
            {
                s1 = false;
            }        
    
            while (s2)
            {
                SDL_BlitSurface(bild2,0,screen,0);
                SDL_UpdateRect(screen,0,0,0,0);
    
                SDL_Event E;
                SDL_PollEvent(&E);
                if (E.type == SDL_QUIT)
                {
                    s1 = false;
                    s2 = false;
                }
                else if (E.type == SDL_KEYDOWN)
                {
                    if (E.key.keysym.sym == SDLK_BACKSPACE)
                    {
                        s2 = false; // hier sollte es eigentlich wieder in 
                                    // die erste wechseln, das tut es zwar  
                                    // auch, aber nur mit Problemen
                    }
    
                }
            }
        }
    }
    

    Ich hab echt keine Ahnung, woran es liegt, aber ich denke, es ist eher ein Flüchtigkeitsfehler...



  • hi, ich würde die 2 'while'-Schleifen in eine funktion packen.
    die 'Event'-Abfrage ins Hauptmenü.



  • Wie meinst du das genau? Die Event-Abfrage gehört ja zur zweiten While-Schleife... Die kann ich nicht einfach rausnehmen... oder meinst du, ich soll einfach die beiden Bild-Aktualisierungszeilen

    SDL_BlitSurface(bild2,0,screen,0);
    SDL_UpdateRect(screen,0,0,0,0);
    

    in eine Funktion packen? Oder auch die Bestimmungen bei Tastendruck (dann müsste ich einfach noch zusätzlich das Event an die Funktion übergeben)?



  • #include <windows.h>
    #include <SDL.h>
    
    SDL_Surface *screen, *bild1, *bild2;
    SDL_Rect *groese;
    //groese.x = groese.y = 0;groese.h = 100; groese.w = 100;
    
    void zeigeBild1(void)
    {
        bild1 = SDL_LoadBMP("t1.bmp");
        SDL_BlitSurface(bild1,0,screen,0);
        SDL_UpdateRect(screen,0,0,0,0);
    
    };
    
    void zeigeBild2(void)
    {
        bild2 = SDL_LoadBMP("t2.bmp");
        SDL_BlitSurface(bild2,0,screen,0);
        SDL_UpdateRect(screen,0,0,0,0);
    };
    
    int main(int argc, char *argv[]) 
    { 
        SDL_Init(SDL_INIT_VIDEO); 
        atexit(SDL_Quit); 
    
        screen = SDL_SetVideoMode(640,480,16,SDL_HWSURFACE); 
        SDL_WM_SetCaption ("Drücke 1 oder 2", NULL);
    
        int exit = 1;
        while (exit)
        { 
            SDL_Event E; 
            SDL_PollEvent(&E);
            SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 255));
        switch (E.type)
          {
          case SDL_KEYDOWN:
              switch (E.key.keysym.sym)
              {
                case SDLK_ESCAPE:
                  exit = 0;
                  break;
                case SDLK_1:
                  zeigeBild2();
                  break;
                case SDLK_2:
                  zeigeBild1();
                  break;
                default:
                  break;
              }
          // case SDL_KEYUP: lösche hintergrund
          }
          SDL_Delay(100);
        }
    }
    

    😃 😮


Log in to reply