Solved

Game Programming

Posted on 2000-04-06
14
218 Views
Last Modified: 2010-04-02
Usually games accept input. And the input is just taken when it happens. If it doesnt happen, then it'll just go on and do what its going to do. I don't know how to do this. I only know how to use getch(); so the program has to wait for the user to enter something. Is their a way in c++ to just go on if their is no input? Im using Console in Borland c++ builder 1.0
0
Comment
Question by:cdc_sickle
  • 8
  • 5
14 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 2691836
Standard C++ actually has no features for this.  In standard C++ all input is line buffered.  That means the user must termiante a line with <enter> before the input is made available to you program.  In standard C++ there is no way around this.

Obviosuly there are wasy around it though.  You have to resort to non-standard procedures or to OS-specific procedures.  I'll post a few windows procedures that shoudl get you going.

continues
0
 
LVL 2

Accepted Solution

by:
xLs earned 200 total points
ID: 2691840
hmm, look for kbhit() in your online help.
not sure if its an ansi compliant function..
under visual studio its _kbhit()

if you're using directx or something you can use the Input device to do this safer.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2691849
Since these are windows API procedures, they will not be portable to other platforms, but you really don't have much choice in this instance anyways.

You will need to include <windows.h> to get these procedures.

You can use the SetConsoleMode() function to turn off the line buffering.  You will also have to turn of echoing (where the character typed by the user appears on the console as these work together.)  If that is a problem, you will have to manually echo the character, by printing it to the screen after you read it.  However, most games don't want that ech anyways.

The following procedure can be a convenient way to turn on and off the echoing and line buffing.

//------------------------------------------------------------------------------------------------//
// PROC:   PUBLIC                                                                                 //
// TYPE:   BASCON                                                                                 //
// TITLE:  Set Wait Mode.                                                                         //
//      This procedure places the console in "wait"/"non-wait" mode.                              //
//                                                                                                //
//      When the console is in wait mode, input typed by the user is automatically displayed on   //
// the console and the input is line buffered.  That is, the input typed by the user is not read  //
// until the user presses <enter>.  In this mode the user may backspace over the text they have   //
// typed to make corrections.                                                                     //
//                                                                                                //
//      When the console is not in wait mode, the input typed by the user is not automatically    //
// displayed on the console and the input is not buffered.  That is, the characters can be read   //
// as soon as they have been typed.  The user does not have the ability to backspace over input   //
// to make corrections, unless the calling program implements such a feature manually.            //
void
ConSetWatMod(bool WatFlg)                        // Should console be placed in wait mode?        //
{
   DWORD Mod;                                    // Current mode.                                 //
    HANDLE StdInpHndt = GetStdHandle(STD_INPUT_HANDLE);
   GetConsoleMode(StdInpHnd,&Mod);               // Get the console mode.                         //
   if (WatFlg)                                   // If in wait mode, then                         //
      Mod |= ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT; // Enable echo and line buffering.            //
   else                                          // Otherwise, if in non-wait mode, then          //
      Mod &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); // Disable echo and line buffering.        //
   SetConsoleMode(StdInpHnd,Mod);                // Set the console mode.                         //
}

continues
0
 
LVL 22

Expert Comment

by:nietod
ID: 2691852
The following procedure can be used to read a character without echo and without waiting.  You might want to use it as is, or you might want to simply turn of echoand wait at the start of the program and then turn it back on at the end of the program

//------------------------------------------------------------------------------------------------//
// PROC:   PUBLIC                                                                                 //
// TYPE:   BASCON                                                                                 //
// TITLE:  Get Wait Mode.                                                                         //
//      This procedure returns a boolean indicating if the console is in "wait mode"
//                                                                                                //
//      When the console is in wait mode, input typed by the user is automatically displayed on   //
// the console and the input is line buffered.  That is, the input typed by the user is not read  //
// until the user presses <enter>.  In this mode the user may backspace over the text they have   //
// typed to make corrections.                                                                     //
//                                                                                                //
//      When the console is not in wait mode, the input typed by the user is not automatically    //
// displayed on the console and the input is not buffered.  That is, the characters can be read   //
// as soon as they have been typed.  The user does not have the ability to backspace over input   //
// to make corrections, unless the calling program implements such a feature manually.            //
bool                                             // Is the console in wait mode?                  //
ConGetWatMod(void)
{
   DWORD Mod;                                    // Current mode.                                 //
   HANDLE StdInpHndt = GetStdHandle(STD_INPUT_HANDLE);
 
   GetConsoleMode(StdInpHnd,&Mod);               // Get the current console mode.                 //
   return (Mod & ENABLE_LINE_INPUT) != 0;        // Indicate if line buffering is enabled.        //
}


//------------------------------------------------------------------------------------------------//
// PROC:   PUBLIC                                                                                 //
// TYPE:   BASCONINP                                                                              //
// TITLE:  Get Character.                                                                         //
//      This procedure reads a character typed by the user.  The charcter read is not echoed to   //
// the screen.                                                                                    //
char                                             // Character typed by the user.                  //
ConGetChr(void)
{
   char  Chr;
   DWORD ChrRed;
   bool  SavWatMod = ConGetWatMod();            // Original wait mode.                           //
    HANDLE StdInpHndt = GetStdHandle(STD_INPUT_HANDLE);

   ConSetWatMod(false);
   ReadConsole(StdInpHnd,&Chr,1,&ChrRed,NULL);
   ConSetWatMod(SavWatMod);                      // Restore the wait mode.                        //
   return Chr;
}
0
 
LVL 22

Expert Comment

by:nietod
ID: 2691853
You may find this useful too.  it allows you to control the size of the cursor and to hide the cursor

//------------------------------------------------------------------------------------------------//
// TITLE:  Get Cursor Size.                                                                       //
//      This procedure returns the current cursor size.  The size is returned as a value between  //
// 0 and 100 (inclusive) indicating the percent of the character cell height that is filled with  //
// the cursor.  0 will be returned if the cursor is invisible.                                    //
int                                              // Cursor size.                                  //
GetCrsSiz(void)
{
   CONSOLE_CURSOR_INFO CrsInf;
   static HANDLE StdOutHnd = GetStdHandle(STD_OUTPUT_HANDLE); // >> standard output.                 //

   GetConsoleCursorInfo(StdOutHnd,&CrsInf);
   if (CrsInf.bVisible)                          // If the cursor is visible, then                //
      return CrsInf.dwSize;                      // Return the cursor size.                       //
   return 0;                                     // Indicate the cursor is invisible.             //
}
//------------------------------------------------------------------------------------------------//
// TITLE:  Set Cursor Size.                                                                       //
//      This procedure sets the current cursor size.  The size is specified as a value between    //
// 0 and 100 (inclusive) indicating the percent of the character cell height that is filled with  //
// the cursor.  Specify 0 to make the cursor invisible.                                           //
void
QConSetCrsSiz(int Siz)                           // New cursor size.  This value should be from 0 //
                                                 // to 100.                                       //
{
   CONSOLE_CURSOR_INFO CrsInf;
   static HANDLE StdOutHnd = GetStdHandle(STD_OUTPUT_HANDLE); // >> standard output.                 //

   if (Siz <= 0)                                 // If cursor should be made invisible, then      //
   {
      CrsInf.bVisible = FALSE;                   // Indicate cursor is invisible.                 //
      CrsInf.dwSize   = 1;                       // Set cursor size to its minimum.               //
   }
   else                                          // Otherwise, if cursor should be made visible,  //
   {
      CrsInf.bVisible = TRUE;                    // Indicate cursor is visible.                   //
      CrsInf.dwSize   = min(Siz,100);            // Set cursor size to specified size.            //
   }
   SetConsoleCursorInfo(StdOutHnd,&CrsInf);      // Set the cursor size.                          //
}
0
 
LVL 22

Expert Comment

by:nietod
ID: 2691857
And finally here is some code for positioning text at various places on the screen and controlling the text's color.  again you may want to use it as is, or take it appart and use the pieces directly.

#include <stdio.h>
      #include <string.h>
      #include <stdlib.h>
      #include <windows.h>
      FILE*fp;

enum Color
{
   Red,
   Green,
   Blue,
   Yellow,
   Purple,
   Cyan,  
   White,
   Black
};

void GotoXY(int X,int Y)
{
      HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
      COORD Coord = {X,Y};
      SetConsoleCursorPosition(StdOut,Coord);
}
void OutputStr(const char *S)
{
      HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
      int StrLen = strlen(S);
      DWORD LenWrt;
      WriteConsole(StdOut,S,StrLen,&LenWrt,NULL);
}
void OutputStr(int X,int Y,const char *S)
{
      GotoXY(X,Y);
      OutputStr(S);
}

void ClearScreen()
{
   HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   CONSOLE_SCREEN_BUFFER_INFO BufInf;
   COORD Origin = {0,0};
   DWORD LenWrt;

   GetConsoleScreenBufferInfo(StdOut,&BufInf); // Get screen rows and columns.
 
   int ChrCnt = BufInf.dwSize.X * BufInf.dwSize.Y; // Number of chars on screen.
   
   FillConsoleOutputAttribute(StdOut,0,ChrCnt,Origin,&LenWrt);
   FillConsoleOutputCharacter(StdOut,' ',ChrCnt,Origin,&LenWrt);
}
void SetColor(Color TxtCol,Color BckCol)
{
   HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   WORD   Col    = 0;

   switch (TxtCol)
   {
   case Red:    Col |= FOREGROUND_RED;   break;
   case Green:  Col |= FOREGROUND_GREEN; break;
   case Blue:   Col |= FOREGROUND_BLUE;  break;
   case Yellow: Col |= FOREGROUND_RED | FOREGROUND_GREEN;   break;
   case Purple: Col |= FOREGROUND_RED | FOREGROUND_BLUE;    break;
   case Cyan:   Col |= FOREGROUND_GREEN | FOREGROUND_BLUE;  break;
   case White:  Col |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
   }
   switch (BckCol)
   {
   case Red:    Col |= BACKGROUND_RED;   break;
   case Green:  Col |= BACKGROUND_GREEN; break;
   case Blue:   Col |= BACKGROUND_BLUE;  break;
   case Yellow: Col |= BACKGROUND_RED | BACKGROUND_GREEN;   break;
   case Purple: Col |= BACKGROUND_RED | BACKGROUND_BLUE;    break;
   case Cyan:   Col |= BACKGROUND_GREEN | BACKGROUND_BLUE;  break;
   case White:  Col |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; break;
   }
   SetConsoleTextAttribute(StdOut,Col);
}

      main()
      {

      char buf[1000], garbage[10], filename[15], inChar[1000], text;
      int m, length, choice, count=1, longs=0, x=0, cnt=0, y=0;
      static int n=0;


   while(1)
   {
      ClearScreen();
      longs=0, n=0, x=0, y=0; cnt=0;
      HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
           
      SetColor(Red,Black);
      OutputStr(0,1,"********************************************************");
      SetColor(Black,Cyan);
      OutputStr(20,2,"P A R A G R A P H");
      SetColor(Purple,Black);
      OutputStr(0,3,"********************************************************");
      SetColor(Black,Cyan);
      OutputStr(20,4,"C O N V E R T E R");
      SetColor(Blue,Black);
      OutputStr(0,5,"********************************************************");

      SetColor(Yellow,Black);
      OutputStr(0, 7,"Paragraph Converter Menu");
      OutputStr(0, 8,"1.  Enter a paragragh");
      OutputStr(0, 9,"2.  Read from file");
      OutputStr(0,10,"3.  Exit");
      OutputStr(0,11,"#########################");
      SetColor(White,Black);
      OutputStr(0,13,"Enter you choice : ");
      GotoXY(20,13);

      ClearScreen();
      GotoXY(0,0);

      return 0;
 }
0
 

Author Comment

by:cdc_sickle
ID: 2691869
Again, Will any of those functions pass and let me continue if the user doesnt enter anything?
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:cdc_sickle
ID: 2691870
Could you give me an example of how to use them, or do what i want to do, i cant learn it by just seeing your code.
0
 

Author Comment

by:cdc_sickle
ID: 2691885
Tell me more about kbhit()

It seems to work:

while(!kbhit())

int c = getch();
cout << c;


?
0
 
LVL 22

Expert Comment

by:nietod
ID: 2691998
kbhit() is a non-standard library function, it is not part of the windows API so it may not be portable from compiler to compiler.  (like the BC compiler doesn't have, it but does have a keypressed() function.)

It is fine to use, if you don't care about portablility to other compilers.  Otherwise you can use

bool IsKeyPressed()
{
   static HANDLE StdInHnd = GetStdHandle(STD_INPUT_HANDLE);
   return WaitForSingleObject(0,StdInHnd) == WAIT_OBJECT_0;
}

Which can be ported from compiler to compiler as it uses the windows API.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2692008
for an example, try

char Ch = ConGetChr();

to read a character without input or line buffering.  If you want to read only if a key is pressed, try

if (IsKeyPressed())
   Ch = ConGetChr();

The code I posted has VERY detailed and complete documentation explaining what the functions do.  Be sure to read it.  I also have examples there showing how to use the ouput functions, which are likely to be very important to you too.
0
 

Author Comment

by:cdc_sickle
ID: 2694874
hey nietod... ill give you 50 points for that character size comment.. want it?
0
 
LVL 22

Expert Comment

by:nietod
ID: 2694942
Huh?
0
 

Author Comment

by:cdc_sickle
ID: 2694955
i mean the cursor size
where i can make it go away
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now