Solved

Game Programming

Posted on 2000-04-06
14
225 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 

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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

740 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