Die Geschichte mit dem hüpfenden Ball



  • cout ist gepuffert, die eigentliche Ausgabe erfolgt also u.U. erst sehr viel später. Für eine sofortige Ausgabe musst du den flush-Manipulator benutzen, z.B.:

    cout << flush;
    


  • juhu!

    Dankeschön... Der Ball wird jetzt angezeigt. Fehlt nur noch das Feintuning.

    cya buffoon



  • So, jetzt hab ich das Programm ein wenig weiter bearbeitet. Ich muss mir nur noch mal die Haare aus reisen.

    Idee: Der Ball sollte sich immer in einem Feld bewegen und bei den Ecken ähnlich wie ein Hüpfball abprallen.

    Problem: Der Ball hüpft nicht ab, sondern geht einfach in die linke untere Ecke. d.h.: Die Y und X Koordinaten bleiben gleich, Wenn die jeweilige Wand berührt wird.

    Hier der Quellcode (habs so programmiert, dass die wichtigsten variablen angezeigt werden):

    #include <iostream>
    #include <unistd.h>
    using namespace std;
    
    int ball(int breite, int hoehe)
    {
    	int pos_x, pos_y;						// Variablen für die Position deklarieren und initialisieren
    	pos_x = 1;
    	pos_y = 1;
    	int richtungx, richtungy;
    	richtungx = 1;
    	richtungy = 1;
    
    	cout << "\033[2J";						// Bildschirm löschen
    	while(true)
    	{
    		int i = 0;
    
    		cout <<"\033["<< 1 <<';'<< 1 <<'H';			// Position nach links oben wechseln
    
    		for (i = 0; i <= breite + 1; i++)			// Beginne das Feld zu erzeugen
    			cout << "X";
    		cout << endl;
    
    		for (i = 0; i <= hoehe + 1; i++)
    		{
    			cout << "X";
    			for (int n = 0; n < breite; n++)
    				cout << " ";
    			cout << "X" << endl;
    		}
    
    		for (i = 0; i <= breite + 1; i++)
    			cout << "X";
    		cout << endl;						// Feld erzeugt
    
    		cout <<"\033[" << pos_y + 1 << ";" << pos_x + 1 << 'H';		// zu Position wechseln, wo der Ball sein soll
    		cout << "o" << flush;
    
    		cout <<"\033[" << hoehe + 5 << ";" << 1 << 'H';
    		cout << "pos_x = " << pos_x << " | pos_y = " << pos_y << endl << flush;
    		cout << "richtungx = " << richtungx << " | richtungy = " << richtungy << flush;
    
    		if (pos_x >= breite)					// Variablen zur Position neu setzen
    		{
    			if (richtungx == 1)
    				richtungx = 2;
    			else
    				richtungx = 1;
    		}
    		else
    		{
    			if (richtungx == 1)
    				pos_x++;
    			else
    				pos_x--;
    		}
    
    		if (pos_y > hoehe+1)
    		{
    			if (richtungy == 1)
    				richtungy = 2;
    			else
    				richtungy = 1;
    		}
    		else
    		{
    			if (richtungy == 1)
    				pos_y++;
    			else
    				pos_y--;
    		}
    
    		cout << "\033[2J";					// Bildschirm wieder löschen, für eine neue generation des Bildes
    
    		sleep(1);						// Warten, damit der Benutzer den Ball sehen kann :)
    	}
    	return 0;
    }
    
    int main()
    {
    	int breite, hoehe;							// Deklaration der Variablen und Eingabe
    	cout << "Breite: ";
    	cin >> breite;
    	cout << "Hoehe: ";
    	cin >> hoehe;
    
    	ball(breite, hoehe);							// Funktion aufrufen, die den Ball springen lässt
    
    	return 0;
    }
    

    Danke schon mal für die Antworten...



  • Kann mir niemand helfen? Ich bin da schon am Verzweifeln... 😡



  • TaccoGo schrieb:

    wegen int i das kann in der ersten schleife stechen und es zächlt trosdem.

    Quatsch! Bei deinem Compiler vielleicht... Nicht jeder benutzt einen <= 6er MS-Compiler



  • Boah ne, ich glaubs net... Der fehler lag hier:

    if (pos_x >= breite)                    // Variablen zur Position neu setzen
            {
                if (richtungx == 1)
                    richtungx = 2;
                else
                    richtungx = 1;
            }
            else
            {
                if (richtungx == 1)
                    pos_x++;
                else
                    pos_x--;
    

    logischerweise wird hier der else Block nur ausgeführt, wenn der Ball nicht an einer Wand ist. Wenn der Ball mitten im Feld ist wird der Ball in die jeweilige Richtung bewegt. Da der Ball an der Wand ja in diesem Falle nicht bewegt wird, weil der else Block nicht ausgeführt wird findet auch kein Richtungswechsel statt...
    Der Code sieht jetzt so aus:

    if (pos_x >= breite)					// Variablen zur Position neu setzen
    			richtungx = 2;
    		else if (pos_x <= 1)
    			richtungx = 1;
    
    		if (richtungx == 1)
    			pos_x++;
    		if (richtungx == 2)
    		pos_x--;
    

    und wegen solchen logischen Fehlern muss man immer 2 Tage lang kopfen und andere Leute stressen -.-
    Ich hoffe mal ich lerne draus 🙂

    buffoon



  • Ach ja noch was:

    kann ich in Linux ne andere funktion außer sleep() verwenden? da kann man nämlich nur in Sekunden eingeben und das geht irgend wie zu langsam... da stockt der ball so. Sleep() geht ja nicht unter Linux soweit ich nicht falsch informiert bin.



  • nimm usleep()

    $ man 3 usleep

    da steht mehr dazu 🙂

    mfg, KdeE



  • Dankeschön... usleep ist fein...



  • btw

    cout << "\033[2J";                    // Bildschirm wieder löschen, für eine neue generation des Bildes
    sleep(1);                        // Warten, damit der Benutzer den Ball sehen kann :)
    

    glück, dass nicht geflusht wird und nicht eine sekunde lang ein leerer bildschirm angezeigt wird 😉



  • So, bin jetzt dabei, das Programm nach und nach zu verbessern. Hab schon eingebaut, dass der User die geschwindigkeit einstellen kann...

    Nun möchte ich aber folgendes machen: Das Programm soll das Feld automatisch über die ganze Konsole machen, außer es werden parameter angegeben (zb "./ball -x 50 -y 20")

    Im Internet kann man mal wieder nix brauchbares finden... Hat jemand ne ahnung wie das gehen kann?



  • davie schrieb:

    btw

    cout << "\033[2J";                    // Bildschirm wieder löschen, für eine neue generation des Bildes
    sleep(1);                        // Warten, damit der Benutzer den Ball sehen kann :)
    

    glück, dass nicht geflusht wird und nicht eine sekunde lang ein leerer bildschirm angezeigt wird 😉

    Ja, das stimmt. Ist mir aber schon ein bisschen früher aufgefallen und das Programm sieht jetzt sowieso ein bisschen anders aus.
    Jetzt wird nämlich nicht mehr der ganze bildschirm gelöscht... Dann flimmert das nicht so, sondern einfach ein " " über den alten ball gemacht und danach der neue gezeichnet... ist schöner so 🙂



  • hat niemand ne ahnung, wie ich die Größe der Konsole raus kriege?



  • Also da wärst du besser im Konsolenforum beraten (evtl. steht dazu schon etwas in der FAQ). Hier werden nur Standard C++ Probleme diskutiert 😉 .



  • Anscheinend schon... Ich wollte dafür nur nicht einen neuen thread aufmachen...


Anmelden zum Antworten