【问题标题】:Continuous keyboard input in CC中的连续键盘输入
【发布时间】:2013-11-21 09:53:21
【问题描述】:

我正在用 C 语言创建一个控制台应用程序。这是一个游戏,其中角色跌倒,用户必须按键盘上的特定键。我不知道如何在不暂停下降字符的情况下检测用户按下了哪个键。当我使用 scanf 时,程序等待输入并且一切都暂停。 请尽快帮助我!

【问题讨论】:

  • 这其实很有趣..期待一些答案
  • 没有ncurses还有其他方法吗
  • 您可以尝试挂钩一个窗口过程并监听事件。与 scanf 不同,这不应阻塞。
  • 你可以推送函数来获取键盘输入到另一个线程

标签: c++ c console


【解决方案1】:

您可能会寻找ncurses

ncurses(新的curses)是一个提供API的编程库 它允许程序员编写基于文本的用户界面 终端独立的方式。它是一个用于开发“GUI-like”的工具包 在终端模拟器下运行的应用软件。

同时检查C/C++: Capture characters from standard input without waiting for enter to be pressed

#include <conio.h>

if (kbhit()!=0) {
    cout<<getch()<<endl;
}

【讨论】:

  • 不太确定,但如果是用于图形实现,那么可以使用 SDL 完成
  • ncurses 是不可行的。 windows.h库里没有东西吗?
  • Windows 中 ncurses 的等价物是 PDCurses。 pdcurses.sourceforge.net
【解决方案2】:

有一个名为kbhit() 或_kbhit 的函数位于&lt;conio.h&gt; 库中,它根据是否按下键返回true 或false。所以你可以用这样的东西:

while (1){
    if ( _kbhit() )
        key_code = _getch();
        // do stuff depending on key_code
    else 
        continue;

也可以使用getch() 或_getch 直接从控制台而不是缓冲区读取字符。您可以阅读更多关于 conio.h 函数 here 的信息,它们可能对您想做的事情非常有用。

注意:conio.h 不是标准库,实现可能因编译器而异。

【讨论】:

  • 使用 getch() 我的游戏仍然暂停并等待输入。我只是在输入字符后不需要按回车键。这不是问题!
  • @zaingz 这就是你必须使用if ( kbhit() ) 的原因,这样它只有在按下某些东西时才会“等待”。但是因为当涉及到 key_code = getch(); 时它已经被按下了,所以它会读取被按下的键。
  • 非常感谢...这对我很有帮助。使用 Visual Studio 的人的一个提示应该是在每个 conio 函数的开头添加下划线“_”。即:_kbhit() 和 _getch()
  • 只是为了进行更新,目前在 ANSI C 中,不推荐使用 kbhit() 和 getch(),而是使用 _kbhit() 和 _getch()!虽然有用的答案:)
  • @SanketPatel 随时使用此信息编辑我的答案。
【解决方案3】:

我认为这可能是您正在寻找的非阻塞键盘输入。

void simple_keyboard_input()  //win32 & conio.h
    {
        if (kbhit())
          {
                KB_code = getch();
                //cout<<"KB_code = "<<KB_code<<"\n";

                switch (KB_code)
                {

                    case KB_ESCAPE:

                        QuitGame=true;

                    break;
                 }//switch
             }//if kb
          }//void

至于掉下来的角色..给你。

如果你在 Windows 上的代码:

/* The Matrix  falling numbers */

#include <iostream>
#include <windows.h> 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;


#define KB_UP 72
#define KB_DOWN 80
#define KB_LEFT 75
#define KB_RIGHT 77
#define KB_ESCAPE 27
#define KB_F8 66


/* Variables*/

char screen_buffer[2000]={' '};
int y_coord[2000]={0};
int x=0, y=0,dy=0;
int XMAX=77;
int YMAX=23;
int KB_code=0;
bool QuitGame=false;
int platformX=35, platformY=23;

/* function prototypes*/

void gotoxy(int x, int y);
void clrscr(void);
void setcolor(WORD color); 
void simple_keyboard_input();  
void draw_falling_numbers();
void draw_platform();

/*  main  */

int main(void)
{
  /* generate random seed */
  srand ( time(NULL) );

  /* generate random number*/
  for(int i=0;i<XMAX;i++) y_coord[i]=   rand() % YMAX;

  while(!QuitGame)
  {
      /* simple keyboard input */
      simple_keyboard_input();

      /* draw falling numbers */
      draw_falling_numbers();

  }

  /* restore text color */
  setcolor(7);
  clrscr( );
  cout<<" \n";

  cout<<" \nPress any key to continue\n";
  cin.ignore();
  cin.get();

   return 0;
}

/* functions  */

void draw_falling_numbers()
{

    for(x=0;x<=XMAX;x++)
    {
        /* generate random number */
        int MatixNumber=rand() % 2 ;

        /* update falling number */
        y_coord[x]=y_coord[x]+1;

        if (y_coord[x]>YMAX) y_coord[x]=0;

        /* draw dark color */
        setcolor(2);
        gotoxy(x ,y_coord[x]-1); cout<<"  "<<MatixNumber<<"   ";

        /* draw light color */
        setcolor(10);
        gotoxy(x ,y_coord[x]); cout<<"  "<<MatixNumber<<"   ";
    }
    /* wait some milliseconds */
    Sleep(50);
    //clrscr( );
}


void draw_platform()
{
  setcolor(7);
 gotoxy(platformX ,platformY);cout<<"       ";

 gotoxy(platformX ,platformY);cout<<"ÜÜÜÜÜÜ";
 setcolor(7);
 Sleep(5);
}




void simple_keyboard_input()
{
    if (kbhit())
      {
            KB_code = getch();
            //cout<<"KB_code = "<<KB_code<<"\n";

            switch (KB_code)
            {

                case KB_ESCAPE:

                    QuitGame=true;

                break;

                case KB_LEFT:
                           //Do something
                    platformX=platformX-4;if(platformX<3) platformX=3;
                break;

                case KB_RIGHT:
                           //Do something     
                    platformX=platformX+4;if(platformX>74) platformX=74;
                break;

                case KB_UP:
                           //Do something                     
                break;

                case KB_DOWN:
                           //Do something                     
                break;

            }        

      }

}


void setcolor(WORD color)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
    return;
}


void gotoxy(int x, int y)
{
  static HANDLE hStdout = NULL;
  COORD coord;

  coord.X = x;
  coord.Y = y;

  if(!hStdout)
  {
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  }

  SetConsoleCursorPosition(hStdout,coord);
}


void clrscr(void)
{
  static HANDLE hStdout = NULL;      
  static CONSOLE_SCREEN_BUFFER_INFO csbi;
  const COORD startCoords = {0,0};   
  DWORD dummy;

  if(!hStdout)               
  {
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hStdout,&csbi);
  }

  FillConsoleOutputCharacter(hStdout,
                             ' ',
                             csbi.dwSize.X * csbi.dwSize.Y,
                             startCoords,
                             &dummy);    
  gotoxy(0,0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多