Laden...

Auf Console schreiben, falls "SetCursorPosition" aufgerufen wird ist Verhalten nicht gleich

Erstellt von Badaboo vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.084 Views
B
Badaboo Themenstarter:in
4 Beiträge seit 2019
vor 4 Jahren
Auf Console schreiben, falls "SetCursorPosition" aufgerufen wird ist Verhalten nicht gleich

Hallo,

ich bin blutiger Anfänger seit ein paar Monaten und spiele mich gerade mit allen möglichen Sachen herum um zu lernen. Bin gestern auf etwas gestoßen, das ich mir absolut nicht erklären kann:

Ich habe mich etwas mit der Konsole beschäftigt. Irgendwann versuchte ich, wie bei einem Spiel, einen char über die Tastaturpfeile über den Bildschirm zu bewegen. Habe ich auch im Rahmen meiner Möglichkeiten hinbekommen. Dabei bin ich aber auf folgendes gestoßen:

Anbei ein kleiner Code-Snippet

        public static void Main(string[] args)
        {
            char player = '*'; 

            int x = 0, y = 0; 

            schreibeChar(player);

            while (true)
            {
                if (Console.KeyAvailable)
                {
                    var command = Console.ReadKey().Key;

                    switch (command)
                    {
                        case ConsoleKey.RightArrow:
                            x++;
                            break;
                    }

                    schreibeChar(player, x, y);
                }
            }
        }

        public static void schreibeChar(char player, int x, int y)
        {
                    Console.SetCursorPosition(x, y);
                    Console.Write(player);
        }

Ergebnis ist für mich ok! Wenn ich die Pfeiltaste RECHTS drücke macht er einen Stern bzw. mehr Sterne - je weiter ich nach "rechts fahre". Also Ergebnis pro Tastendruck = ********* usw

Wenn ich aber folgendes hinzufüge bei der Methode schreibeChar:

               public static void schreibeChar(char player, int x = 0, int y = 0)
        {
                    Console.SetCursorPosition(x, y);
                    Console.Write(player);
                    Console.SetCursorPosition(x, y); //<-- add this
        }

Das kann ich mir jetzt nicht erklären: Ergebnis ist nun, dass er den vorherigen char'*' immer löscht. Ich "sage" ihm aber nie lösch ihn sondern setze ja nur den Cursor auf Position des char's zurück. Eigentlich müsste er ja dennoch ******* machen. Nun sieht es so aus als würde ich den char über den Bildschirm bewegen.

Wenn ich in den Editor gehe und in die Console (egal welche Eingabemaske, von mir aus auch Word), und ich schreibe einen * - fahre mit dem Cursor retour und schreibe auf die gleiche Position (x,y) erneut einen * - dann schiebe ich ja praktisch das (bereits bestehende) * vor mir her bzw. werden es auch immer mehr * je öfter ich das mache.

Warum ist das durch diese eine Zeile ** Console.SetCursorPosition(x, y);** nicht so? Warum löscht er sozusagen immer die vorherige x,y Position des Cursors?

Ich brauche jetzt auch nicht unbedingt diese Erklärung beruflich oder weil mein Leben davon abhängt 😃 aber ich probiere einfach viel rum damit ich lerne und wenn ich dann auf solche (für mich) Ungereimtheiten stoße, muss ich einfach wissen das da los ist 😃

Danke und Schöne Grüße
Badaboo

4.931 Beiträge seit 2008
vor 4 Jahren

Durch das Setzen an eine Konsolenposition und Schreiben eines Zeichens wird an der bestehenden Position dieses Zeichen gesetzt, d.h. das vorherige Zeichen dort dann überschrieben - die anderen Zeichen rechts davon bleiben völlig unangetastet.

Bei den Editoren (und auch der Konsoleneingabe) ist dies standardmäßig anders, erst durch Aktivieren des Überschreibenmodus wird der Einfügemodus deaktiviert (meist mittels der "Einfg"-Taste, welche zwischen diesen beiden Modi hin- und herwechselt).

B
Badaboo Themenstarter:in
4 Beiträge seit 2019
vor 4 Jahren

Danke vielmals für deinen Beitrag. Ok, das wusste ich gar nicht, dass bei der Konsolenanwendung automatisch der Überschreibmodus aktiviert ist sobald ich den Cursor explizit setze.

Hab mir das jetzt nochmal angesehen... Irgendwo habe ich hier einen Denkfehler.

Wenn der Überschreibmodus aktiviert wäre, dann würde es ja keinen Unterschied machen wenn ich ihn, via der letzten Codezeile nach Schreiben des Zeichens, erneut an die Position des Zeichens setze. (Dann wär die Codezeile ja unnötig bzw. hätte das gleiche Ergebnis -> denn nach einer Tasteneingabe im Überschreibmodus verändert sich die Position des Cursors nicht).

Mein Problem hingegen ist aber - es macht sehr wohl einen Unterschied.

Nämlich, dass er plötzlich(?), nach erneuter PFeiltaste-REchts das vorherige Zeichen löscht.

LG und Danke für eure Geduld.

EDIT:
Ah ok, ja das habe ich nun gesehen: Wenn ich den Cursor setze ist er im Überschreiben-Modus aber das u.a. Problem besteht weiterhin...

Irgendwie eigenartig (für mich zumindest)

Beispiel laut meinem Code oben:

Ich starte auf der Pos X = 0 einer Zeile.
Nun, Pfeiltaste rechts ->
Cursor geht auf X = 1 und setzt den Stern -> Cursor geht weiter auf X = 2 (automatisch) ->
Cursor geht zurück auf X = 1 (Anweisung, letzte Codezeile)

Alles gut bis jetzt - aber nun beginnt der Knoten in meinem Kopf:

Ich drücke erneut rechts ->
Cursor geht auf X = 2 und setzt den Stern -> Cursor geht weiter auf X = 3 (automatisch) ->
Cursor geht zurück auf x = 2 (Anweisung, letzte Codezeile)

Alles prima! Bis auf: Zeichen in x = 1 ist weg ?!?? Versteh das nicht. Das geht von hier an immer so weiter, egal wie weit ich mich auf X nach rechts bewege (oder links) - das vorherige Zeichen verschwindet.

4.931 Beiträge seit 2008
vor 4 Jahren

Ja, das kann verwirrend sein. 😉
Durch das Drücken der "Pfeiltaste rechts" wird automatisch (weil es ein nicht-druckbares Zeichen ist) ein Leerzeichen stattdessen angezeigt, so daß es das vorherige Zeichen überschreibt (bei einem anderen druckbaren Zeichen siehst du es ja stattdessen, z.B. 'A' oder 'z').

Um die Ausgabe (des eingegeben Zeichens) zu verhindern, gibt es den intercept-Parameter:


var command = Console.ReadKey(true).Key; // true für Unterdrücken der Ausgabe

Du bist also deswegen durcheinander gekommen, weil Ein- und Ausgabe vermischt waren.