Eine Konsole in einer Anwendung schreiben

9

Für meine Anwendung muss eine Konsole innerhalb des Anwendungsfensters eingebettet sein. Ein Beispiel wäre ein Programm wie AutoCAD, bei dem die Konsole am unteren Rand des Fensters auf Befehle wartet.

Ich brauche die Konsole in meiner Anwendung, damit ich Variablen und andere Dinge ändern kann, so dass die Konsole keine komplett ausgebrannte Shell sein muss.

Im Moment habe ich eine einfache Konsole in meiner Anwendung, aber es scheint sehr klobig im Vergleich zu einem Terminal (Shell), so wie ich die Konsole sein möchte.

Die Art und Weise, wie ich es mit der Konsole gemacht habe, ist, wenn der Benutzer die Taste TAB drückt, die die Konsole zeigt, dann können sie ihren Befehl / Zeile eingeben; Sobald die Return Taste gedrückt wurde, wird die eingegebene Zeichenfolge geparst und der Befehl wird verarbeitet.

Ich verwende sf::Text Objekte, um Text in meinem Anwendungsfenster auszudrucken. Es gibt insgesamt 5 sf::Text -Objekte, 4 für die vorherigen Befehle / Fehlermeldungen und 1 für die aktuelle Befehlszeile. Wenn die Taste Return gedrückt wird, ändert die 4. sf::Text ihren aktuellen String auf den 3., den 3. auf den 2., den 2. auf den 1. und den 1. auf den aktuellen Befehls-String, dann wird der aktuelle Befehls-String gelöscht und bereit für erneut eingeben. Auf diese Weise gibt es Platz für 4 'Geschichte' von Befehlen und / oder Fehlern. Nicht das Beste, aber es war das Beste, was ich mir vorstellen konnte. Natürlich könnte der Umfang der Historie durch Hinzufügen weiterer sf::Text -Objekte geändert werden. So rende ich am Ende die Konsole auf den Bildschirm

%Vor%

App ist nur ein sf::RenderWindow*

Meine allgemeine Frage lautet: Gibt es eine Möglichkeit, dass ich eine Konsole in mein SFML-Fenster einbetten kann , ohne dass es einfach ein Bild von Textobjekten sein muss, die so aussehen wie eine Konsole . Ich würde lieber eine tatsächliche Konsole / Shell / Terminal in meiner Anwendung haben. Wie die Standard-Bash-Shell, aber natürlich mein eigener Shell-Interpreter.

    
Elgoog 12.06.2012, 23:48
quelle

4 Antworten

4

Ich habe das Folgende als Konsole für ein OpenGL-Spiel implementiert, das ich vor einiger Zeit geschrieben habe. Es ist keineswegs eine definitive Antwort auf Ihre Frage, aber es hat für mich funktioniert und Sie könnten etwas Nützliches daraus bekommen.

Die 2 Dateien befinden sich am Ende dieses Posts. Es ist unwahrscheinlich, dass der Code direkt ausgeführt wird, da es einen für 2 Bibliotheksheaderdateien gibt, die ich nicht einschließen werde. Wenn Sie die vollständige Quelle möchten, lassen Sie es mich wissen.

Grundsätzlich können Sie in der Konsolenklasse jedoch variable Zeiger hinzufügen, die zur Laufzeit geändert werden können. Es akzeptiert Eingaben von den Windows-Ereignisnachrichten. (Die eigentliche Eingabe erfolgt an anderer Stelle.) Das Parsen des Befehls erfolgt in der ProcessInput () -Methode, und Variablen werden in der ChangeVariable () -Methode aktualisiert.

Ein Wort der Warnung. Diese Methode gibt den Konsolenbenutzern im Wesentlichen direkten Zugriff auf die Speicherplätze der einzelnen Variablen. Dies erfordert eine gute Eingabeüberprüfung, um sicherzustellen, dass der Benutzer die Anwendung nicht zur Laufzeit zum Absturz bringen kann. Wenn ich mich jemals hinsetzen würde und versuchen würde, eine andere Konsole zu machen, würde ich die Dinge wahrscheinlich etwas anders machen. Ich hoffe aber, dass dir das ein wenig hilft.

Die Header-Datei:

%Vor%

Die cpp-Datei:

%Vor%

Bearbeiten 1: Hinzugefügt DrawConsole () Ich erhalte nur den Text von der Konsolenklasse, rendere ein Bild, das dem Quellengine-Konsolenfenster ähnlich sieht, das in irgendeinem neueren Ventilspiel gefunden wird, und dann wird der Text an den entsprechenden Stellen gezeichnet.

%Vor%     
Brendan 13.06.2012 03:54
quelle
2

Es gibt ein paar Dinge dazu. Zuerst möchten Sie eine Art von Zeilenbearbeitung unterstützen. Dazu gibt es Bibliotheken, zum Beispiel die editline Ссылка

von NetBSD

Dann müssen Sie irgendwie Tasten drücken. Jetzt beginnt hier der Spaß. Anstatt zu versuchen, die Schlüsselereignisse direkt zu verarbeiten, füge ich sie in eine anonyme Pipe ein, die mit dem pipe on (POSIX) / CreatePipe unter Windows erstellt wurde. Am anderen Ende kannst du sie lesen, als kämen sie von stdin herein. Eine zweite anonyme Pipe verdoppelt die Funktion von stdout und zeigt ihre Ausgabe auf der Konsole im Spiel an. Ich würde das resultierende Paar von FDs consolein und consoleout nennen. Ich würde auch eine consoleerr FD für dringende Fehlermeldungen hinzufügen; Die Konsole kann sie in einer anderen Farbe anzeigen oder sie filtern.

Das Schöne an diesem Ansatz ist, dass Sie alle netten Standard-Bibliotheksfunktionen verwenden können, um mit Ihrer Konsole zu sprechen. Sie können fprintf(consoleout, ...) , fscanf(consolein, ...) und so weiter verwenden; Es funktioniert natürlich auch mit C ++ iostreams. Aber noch wichtiger, Sie können es direkt an Bibliotheken wie die oben erwähnte editline anhängen.

Schließlich müssen Sie die Befehle verarbeiten, die der Benutzer in die Konsole eingegeben hat. Dort würde ich den faulen Weg gehen und nur einen Skriptsprachen-Interpreter einbetten, der die interaktive Bedienung unterstützt. Wie Python oder sehr weit verbreitet in Spielen, Lua . Sie können natürlich auch einen eigenen Befehlsinterpreter implementieren.

    
datenwolf 13.06.2012 06:27
quelle
0

Nun, was Sie wahrscheinlich wollen, wenn Sie möchten, dass es sich mehr wie eine Konsole anfühlt, ist:

  • Es kann mit einem Knopfdruck ein- und ausgeschaltet werden, wahrscheinlich so etwas wie ~ , das oft benutzt wird.
  • Geben Sie der Zeile, die Sie eingeben, eine Hintergrundfarbe, vielleicht transparent, aber stellen Sie sicher, dass nicht nur Text auf dem RenderWindow schwebt. Wenn die Ausgabe des Befehls aus mehreren Zeilen besteht, stellen Sie sicher, dass sie alle sichtbar sind oder dass die Benutzer zumindest durch den Verlauf scrollen können.
  • Stellen Sie sicher, dass die Befehle leicht verständlich und konsistent sind. Wenn ich mich zum Beispiel nicht irre, verwenden viele Spiele auf der Quell-Engine das Präfix cl_ für alles, was mit dem Rendern zusammenhängt. Siehe cl_showfps 1 zum Beispiel.
  • Traditioneller Terminal-Eingang wäre eine nette Geste. Nach oben zeigt dir den vorherigen Befehl, den du ausgefüllt hast. Wenn du dich abenteuerlustig fühlst, benutze Tab zum Abschluss.
  • Wenn Sie noch etwas Zeit haben, wäre es auch nett, verfügbare Befehle über --help anzuzeigen. Abhängig davon, wie kompliziert dein Spiel natürlich ist.

Sehen Sie sich im übrigen an, wie andere Spiele das gemacht haben. Du hast Quake erwähnt, das ein großartiges Beispiel für ein Ingame-Terminal hat. Ich für meinen Teil denke, dass das eine in vielen Source-Spielen auch einfach zu benutzen ist (siehe Half Life 2, Counter Strike Source, Team Fortress 2, Left 4 Dead, etc.). Ich denke nicht, dass es dafür Standard-Bibliotheken gibt, die kein anderes Framework wie OGRE oder IrrLicht enthalten.

    
RadicalRaid 13.06.2012 03:52
quelle
-1

Wenn Sie Ihre eigene benutzerdefinierte Konsole implementieren, müssen Sie diese selbst schreiben. Ein kurzer Skim von den SMFL-Dokumenten deutet darauf hin, dass nichts eingebaut ist, um Ihnen zu helfen. Dies ist nur eine einfache und schnelle Multimedia-Bibliothek ;-)

Wenn Sie etwas vollwertigeres brauchen, würde ich vorschlagen, OGRE nachzusehen.

    
Jon Cage 13.06.2012 00:20
quelle

Tags und Links