1

特定の時間内に入力がない場合、ユーザー入力の呼び出しを効果的にキャンセルするにはどうすればよいですか? (Mac OS X でターミナル/コマンド ウィンドウ用のゲームをプログラミングしています)。

標準バッファリングをオフにして、ユーザー入力の呼び出し後に参加するタイマー スレッドを使用しようとしました。pthread_join()また、while ループのパラメーター内に呼び出しを実装しようとしました。まだ何もありません。問題は、正規のバッファリングがオフになっていても、入力がないときにユーザー入力の呼び出しが保留されることです。ただし、入力があれば問題なく動作します。

ncurses のダウンロードとインストールをいじらずにこれができれば最高ですが、必要に応じて実行します。

編集:ソースコード:

//Most headers only pertain to my main program. 
#include <iostream>
#include <termios.h>
#include <pthread.h>
#include <time.h>
#include <cstring>
#include <stdio.h>
#include <string.h>

using namespace std;

//Timer function.
void *Timer(void*) {

    time_t time1, time2;

    time1 = time(NULL);

    while (time2 - time1 < 1) {
        time2 = time(NULL);
    }

    pthread_exit(NULL);
}

int main() {

    //Remove canonical buffering.
    struct termios t_old, t_new;
    tcgetattr(STDIN_FILENO, &t_old);
    t_new = t_old;
    t_new.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &t_new);

    cout << "Press any key to continue." << endl;

    string szInput;

    int control = 0;

    do {

        pthread_t inputTimer;

        pthread_create(&inputTimer, NULL, Timer, NULL);

        szInput = "";

        while (szInput == "") {

            szInput = cin.get();


            //Handle keypresses instantly.
            if (szInput == "a") {
                cout << endl << "Instant keypress." << endl;
            }
        }    

        pthread_join(inputTimer, NULL); 

        cout << endl << "One second interval." << endl;

        control ++;

    } while (control < 25);

    cout << "Game Over." << endl;

    return 0;

}
4

3 に答える 3

1

これが機能するかどうかを確認してください!

char ch;  //Input character
int time = 0;     //Time iterator
int TIMER = 5000; //5 seconds
while(time<TIMER)
{
    if(!kbhit())
    {
        time = 0;
        ch = getch();
        //Do your processing on keypress
    }
    time++;
    delay(1);
}

kbhit()キーストロークが発生したかどうかを検出します。はいの場合は、 でキー キャラクターを取得しますch

于 2012-08-16T07:23:37.003 に答える
0

入力があるかどうかを確認する 1 つの方法は、システム コールなどSTDIN_FILENOを使用してファイル記述子をポーリングすることです。selectが読み取り可能な場合STDIN_FILENO、少なくとも 1 文字は読み取ることができます。呼び出しにタイムアウトを渡すこともできselectます。

于 2012-08-16T20:15:29.290 に答える
0

Shashwat に感謝します。以下の変更で動作します。

1)if(!kbhit())への変更if(kbhit())

2)delay(1);への変更Sleep(1);

コメントを投稿するのに十分な担当者がいないため、回答として追加します。

于 2014-02-20T09:29:53.043 に答える