Есть ли способ заменить функции kbhit() и getch() в стандарте C?
Я пытаюсь получить быстрый тип событий взаимодействия с консолью, и мне удалось получить его с помощью библиотеки conio. К сожалению, проект, над которым я работаю, требует, чтобы код был компилируемым как в Windows, так и в Linux, и я не могу найти способ изменить его.
Что я могу сделать, чтобы получить желаемый эффект, или я должен отказаться от этого понятия? Ниже приведен код для функции, которую я создал.
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
void battle(int x) {
srand(time(0));
printf("Use Q to dodge projectile attacks, E to block melee attacks and W to attack when the boss is stunned. Button mashing will not work! Press any key to start the battle.\n\nYou face Brutus, Lord Incarcerator!\n\n");
getchar();
bool ok;
int dealt = 0 ,recieved = 0 , state, prev = 0;
time_t start, end;
double elapsed;
while(dealt < 5 && recieved < 3)
{
do
{
state = rand() % 3 + 1;
}
while(prev == state);
prev = state;
time(&start);
switch(state)
{
case(1):
ok = 1;
printf("Brutus uses Hook Attack!\n\n");
do
{
time(&end);
elapsed = difftime(end, start);
if(kbhit())
{
if( getchar() == 'q')
{
printf("Dodged!\n\n");
ok = 0;
break;
}
else
{
break;
}
}
}
while(elapsed < 3);
if(ok)
{
printf("You took damage!\n\n");
recieved++;
break;
}
break;
case(2):
ok = 1;
printf("Brutus is stunned!\n\n");
do
{
time(&end);
elapsed = difftime(end, start);
if(kbhit())
{
if( getchar() == 'w')
{
printf("You dealt damage!\n\n");
dealt++;
ok = 0;
break;
}
else
{
break;
}
}
}
while(elapsed < 3);
if(ok)
{
printf("Too slow!\n\n");
break;
}
break;
case(3):
ok = 1;
printf("Brutus uses Blood Slam!\n\n");
do
{
time(&end);
elapsed = difftime(end, start);
if(kbhit())
{
if( getchar() == 'e')
{
printf("Blocked!\n\n");
ok = 0;
break;
}
else
{
break;
}
}
}
while(elapsed < 3);
if(ok)
{
printf("You took damage!\n\n");
recieved++;
break;
}
break;
}
}
if(recieved >= 3)
{
printf("Battle lost; you will now respawn in town.");
getchar();
}
else
{
printf("Battle won!");
getchar();
}
}
int main()
{
battle(2);
}
4 ответа
Вы можете написать свой собственный getch().
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
/* reads from keypress, doesn't echo */
int getch(void)
{
struct termios oldattr, newattr;
int ch;
tcgetattr( STDIN_FILENO, &oldattr );
newattr = oldattr;
newattr.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
return ch;
}
Не совсем, так как они не могут быть реализованы в некоторых реализациях и могут быть реализованы только с большими затратами в других.
Хотя это и не стандартно, существуют переносимые библиотеки, такие как ncurses
которые поддерживают такого рода операции.
Я думаю, что вам нужно использовать библиотеку ncurses.
вот похожий вопрос: создайте функцию для проверки нажатия клавиш в Unix с помощью ncurses
Есть два варианта
- Найдите некоторую кроссплатформенную библиотеку, которая абстрагирует детали для вас ( SDL может подойти для этого.)
- Сделайте абстрагирование самостоятельно.
Чтобы сделать 2. вам нужно будет определить свою собственную версию функций ввода. Затем вы создаете разные реализации для каждой платформы. Это означает, что ваш основной код остается общим для разных платформ.