Wie kann ich Eingaben in C verarbeiten, ohne die Hauptschleife anzuhalten?
Ich möchte, dass mein C-Programm die Konsole jede Sekunde aktualisiert, und es hat einwandfrei funktioniert, bis ich versucht habe, Eingaben zu verarbeiten. Jetzt wird das Programm angehalten, da es auf eine Eingabe des Benutzers wartet. Wie kann ich das machen?
while(true) {
ShowConsole(); //Show
Sleep(1000); //Wait
scanf("%s",&a) //Handle Input
Update();
ClearScreen(); //Clear
}
Antworten
Ich habe mir die Freiheit genommen, dies selbst in Angriff zu nehmen.
Nur basierend auf dem Fragentext ist nicht ganz klar, welche Art von Spiel Sie versuchen, also habe ich den Ansatz einer Art Schlangenspiel gewählt , bei dem sich die Schlange bewegt, was auch immer der Spieler tut (oder nicht tut). .
Ich benutzte Sleep
die Eingangswahl zu schreiten und die Neuzeichnung Rate und _kbhit()
zu vielleicht ein Zeichen zu lesen, und die clock_t
/ clock()
das Spiel einmal pro Sekunde zu aktualisieren.
Jetzt bin ich kein c
Programmierer, daher weiß ich nicht, ob dieser c
Code "elegant" ist (wahrscheinlich nicht), aber er hat auf meinem Computer (Windows, Visual Studio) funktioniert.
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <ctype.h>
#include <windows.h>
typedef int BOOL;
#define FALSE ((int)0)
#define TRUE ((int)1)
void ClearScreen()
{
// code here that clears the screen, see https://stackoverflow.com/a/42500322
}
int main( void )
{
BOOL run = TRUE;
clock_t lastTickClock = clock();
int position = 0;
char registeredCommand = 'd'; // Command that will be effective at the next game tick.
while ( run )
{
char currentCharIfAny = 0; // The char that is read this loop.
if ( _kbhit() )
currentCharIfAny = _getch();
if ( currentCharIfAny == 'a' || currentCharIfAny == 'd' )
registeredCommand = currentCharIfAny; // We only respond to 'a' or 'd'.
clock_t newClock = clock();
if ( ( newClock - lastTickClock ) > CLOCKS_PER_SEC )
{
// This is the command handling/the game tick
if ( registeredCommand == 'a' )
position = max( --position, 0 );
else if ( registeredCommand == 'd' )
position = min( ++position, 24 );
lastTickClock = newClock;
}
char buffer[1024];
buffer[0] = 0;
for ( int i = 0; i < position; ++i )
strcat_s( buffer, 1024, " " );
strcat_s( buffer, 1024, "_\n" ); // This underscore represents our "agent" or "game token" or "paddle".
// The following is only for debugging purpose; it prints the character we're currently handling.
if ( currentCharIfAny >= 'a' && currentCharIfAny <= 'z' )
{
char lbuff[2]; lbuff[0] = 0;
sprintf_s( lbuff, 2, "%c", currentCharIfAny );
strcat_s( buffer, 1024, lbuff );
}
ClearScreen();
printf( "%s\n", buffer );
Sleep( 1000 / 60 );
if ( currentCharIfAny == 'q' )
run = FALSE;
}
printf( "\ndone. press a key to quit." );
_getch();
return 0;
}
Ein paar Dinge zu beachten:
- Es gibt wahrscheinlich andere (bessere) Möglichkeiten, dies zu erreichen: Wenn ich jetzt (ClearScreen) aktualisiere, "flackert" der Bildschirm ein wenig.
- Unter Windows "beschleunigt" das Betriebssystem die Wiederholungsrate des Zeichens, das es an die Apps sendet. Wenn Sie dbeispielsweise ddrücken, zeigt das Programm an, dass Sie drücken, und zeigt dann an, dass Sie keine Taste drücken. dann wird angezeigt, dass Sie derneut schlagen , bis Sie die Taste loslassen.
- Wie Ihre eigene Implementierung ist sie aufgrund der Art der verwendeten Funktionen nicht portierbar.
Obwohl ich nicht portierbaren Code verwenden musste, funktionierte er ohne eine Bibliothek eines Drittanbieters. Außerdem stellt sich heraus, dass die Funktion _kbhit () den Puffer verzögert, sodass Sie nicht 1 Sekunde warten müssen, um die vollständige Zeichenfolge einzugeben. Die geschriebene Zeichenfolge wurde jedoch geschnitten, wenn sie nicht in einer Sekunde geschrieben wurde. Also habe ich es auch in der ShowConsole () -Funktion gezeigt.
Hinweis: Dies ist ein nicht standardmäßiger, nicht portabler Code. Funktioniert in meinem Betriebssystem (Windows).
char key;
if(_kbhit()){
key = _getch();
if(key == 13){ //If Enter key is pressed
HandleInput(moveInput); //handle the input string
memset(moveInput, 0, 6); //clear input string
moveIndex=0; //reset string index to 0
}
moveInput[moveIndex] = key; //If any other key is pressed, add the hit character to string input
moveIndex++;
}
In der ShowConsole () -Funktion:
ShowConsole(){
.
.
.
printf("%s", moveInput); // At the end of showing the graphics, also show the input that is being written.
}