kleines problem mit getch() in Snake-Steuerung



  • hi
    ich hab mir mal überlegt mit meinen begrenzten c++ kenntnissen einen Snake Klon zu schreiben. Dazu werde ich die Standartausgabe benutzen. Dass die nicht so wirklich für sowas gemacht ist hab ich schon gemerkt aber trotzdem....

    also bis jetzt hab ich nur die steuerung. zumindest fast.

    Die Funktion int steuerung(int) soll eine sekunde lang auf die eingabe des benutzers warten und diese dann nach dieser sekunde ausgeben. wenn keine eingabe gemacht wird soll einfach der vorherige wert zurückgegeben werden, der der Funktion zuvor übergeben wurde. An sich funktioniert das auch alles wunderbar, nur der buffer stöhrt! wenn ich wild auf meinen Steuertasten ( W A S D ) rumhacke werden diese tasten beim nächsten aufruf der funktion "steuerung" als eingabe benutzt! so soll das nicht sein! Ich benutze Dev-C++. Hier mein nicht so ganz professioneller code.
    Die mit den Kommentaren geblockten befehle sollten eigentlich dazu dienen denn buffer zu leeren aber anstatt dessen bringen sie das programm zu einer totalen fehlfunktion es gibt dann nurnoch einsen aus.

    #include <iostream>
    #include <ctime>
    #include <conio.h>
    using namespace std;
    
    int steuerung(int);
    
    int main()
    {
        int i;
        int kommando = 1;
        for(i=0;i<20;i++)
        {
                         kommando = steuerung(kommando);
                         cout << "\n" << kommando;
        }
    }    
    int steuerung(int kommando_alt)
    {
        int eingabe = 0;
        //int leerer;
        int kommando_neu = 0;
        time_t jetzt = time(NULL);
    
        while(time(NULL) < jetzt + 1)
        {   
              if(kbhit() && eingabe == 0)
              {
                         eingabe = getch();
                         switch(eingabe)
                         {
                                        case 87: //W
                                        case 119: //w    
                                             kommando_neu = 1; //up                                      
                                        break;
    
                                        case 65: //A
                                        case 97: //a
                                             kommando_neu = 2; //left
                                        break;
    
                                        case 83: //S
                                        case 115: //s
                                             kommando_neu = 3; //down
                                        break;
    
                                        case 68: //D
                                        case 100: //d
                                             kommando_neu = 4; //up
                                        break;
    
                                        default:
                                                eingabe = 0;
                         }
              } //leerer = getch();
        }
    
        switch(kommando_neu)
        {
                            case 0:
                                 return kommando_alt;
                            break;
    
                            default:
                                    return kommando_neu;
        }
    }
    


  • GulupGul schrieb:

    der buffer stört!

    Ganz naiv gefragt: Ist dafür nicht "fflush" zuständig?



  • Geht doch viel einfacher:

    int steuerung(int kommando)
    { 
        time_t jetzt = time(0); 
    
        while ((time(0) <= jetzt) || kbhit()) 
        {   
            if (kbhit())
            {
                switch (getch()) 
                { 
                case 87: //W 
                case 119: //w     
                    kommando = 1; //up                                       
                    break; 
    
                case 65: //A 
                case 97: //a 
                    kommando = 2; //left 
                    break; 
    
                case 83: //S 
                case 115: //s 
                    kommando = 3; //down 
                    break; 
    
                case 68: //D 
                case 100: //d 
                    kommando = 4; //up 
                    break; 
    
                default: 
                    break; 
                } 
            }
        }
    
        return kommando;
    }
    


  • Wow 🙂
    Vielen danke hustbaer!

    Ich habe die Funktion jetzt noch kommentiert. Währe schön wenn du dir das nochmal angucken könntest nur um sicher zu gehen dass ich auch wirklich verstanden hab wie die jetzt funktioniert 😉

    int steuerung(int kommando)
    {
        time_t jetzt = time(0);
    
        while ((time(0) <= jetzt) || kbhit()) //das mit der Zeit ist klar. 
        //Das kbhit() in der Bedingung der while-schleife sorgt dafür, dass die
        //Funktion erst beendet wirde wenn alle Zeichen mit kbhit() aus dem          
        //Tastaturbuffer "gelöscht" wurden.... dachte ich! aber wenn man das kbhit()
        //weglässt funktioniert es auch, vermutlich weil man ja ALLE eingaben eh mit
        //switch (getch()) aus dem buffer zieht. Aber da dieses kbhit() bestimmt
        //nicht umsonst da steht wüste ich gerne was es da genau macht.  :confused: 
    
        {  
            if (kbhit()) //Da es hier keine Abfrage mehr gibt ob schon eine Eingabe
                         //gemacht wurde kann man in dieser Sekunde noch seine 
                         //Eingabe ändern. Gut so ^^
            {
                switch (getch())
                {
                case 87: //W
                case 119: //w    
                    kommando = 1; //up                                      
                    break;
    
                case 65: //A
                case 97: //a
                    kommando = 2; //left
                    break;
    
                case 83: //S
                case 115: //s
                    kommando = 3; //down
                    break;
    
                case 68: //D
                case 100: //d
                    kommando = 4; //up
                    break;
    
                default:
                    break;
                }
            }
        }
    
        return kommando;
    }
    

    Und nochmal vielen danke an hustbaer. Da währe ich nie im Leben selbst drauf gekommen. 👍

    Und mit fflush funktioniert das nicht Badestrand. Zumindest nicht mit fflush(stdin); oder welches meintest du?



  • wenn du kleine spiele Programmieren willst, dann versuch mal sowas wie SDL zu nehmen, das ist allein schon für die Steuerung besser, als iostream.



  • vermutlich weil man ja ALLE eingaben eh mit
    //switch (getch()) aus dem buffer zieht.

    Nö, getch() zieht immer nur ein Zeichen pro Aufruf aus dem Puffer. Funktionieren tut es trotzdem weil du nicht schneller tippen kannst als der Computer Zeichen auslesen kann. D.h. selbst wenn "jetzt" ein oder zwei Zeihen im Puffer stehen bleiben, dann sind die nach dem nächsten Aufruf sicher weg und die Situation hat sich wieder "normalisiert".



  • Ok hab ich verstanden ^^
    Vielen danke.
    Frage Beantwortet.


Anmelden zum Antworten