본문 바로가기

C언어/테트리스

[C언어] _kbhit(),getch()함수를 사용해 콘솔창에서 방향키 사용하는 방법!!!

728x90

오늘은 방향키를 통해 

콘솔 창에서 방향키 인식 및 이동하는 방법에 대해서

알려드리겠습니다.

+ 깜빡깜빡거리는 커서 숨기는 함수까지!!

 

  • _kbhit() 함수

방향키를 인식하기 전에

conio.h 헤더 파일에 들어있는,

_kbhit()함수를 사용해야 합니다.

_kbhit 이 함수는 키를 누른 경우 0이 아닌 값을 반환합니다. 

따라서 키보드에 key를 누른 경우 0이 아닌 해당 key 값을 

버퍼로 저장합니다.

 

(버퍼란 scanf()함수 등 을 통해 입력을 받으면, 화면에 출력되기 전까지 임시적으로 입력한 값들을 저장하는 메모리 상의 공간!!이라고 생각하시면 편합니다^..^)

 

따라서 버퍼에 저장된 key 값을 _getch()함수를 통해서 받아야 합니다. 

이때 _getch()함수는 

콘솔에서 단일 문자를 읽습니다!!  

 

이때의 단일 문자는 _kbhit()함수에서 반환된 ,

사용자가 누른 key 값입니다.

이 key값을 _getch()함수를 통해 한 글자 읽어서

int 형으로 반환합니다. 

#include <stdio.h>
#include <conio.h>

int main(void){
	if(_kbhit()){ // Key를 누르면 0이아닌 int형의 값을 반환한다!! 따라서 if문이 실행된다!!
    	int nkey=_getch(); //반환된값을 _getch()를 통해 캣치!후 nkey값에 return 한다!!
    }
}

이때의 nkey 값을 printf("%d", nkey);

를 할 경우 해당 key의 아스키 코드 값을 알 수 있습니다.

여기서 잠깐!!!!

 

방향키의 경우에는 특수키로 간주되어서 _khbit()함수는 2개의 정수 값을 return 합니다

첫 번째로 반환한 값의 경우에는

224로 어떤 방향키를 누르든 동일한 값을 반환합니다.

두 번째로 반환한 값에 따라서 상, 하, 좌, 우로 나뉘게 됩니다.

if (_kbhit()) {
	int nkey = _getch(); //방향키의 경우 nkey값은 224!
	if (nkey == 224) { //만약 nkey가 224, 공통적인 뱡향키의 첫번째 반환 값 이라면?
		nkey = _getch(); //두번째 nkey 값을 받는다. 이때의 nkey 값에 따라 방향키가 결정된다.
        }
    }

UP키 아스키코드 값 = 72;

DOWN키 아스키 코드 값 = 80;

LEFT키 아스키 코드 값 = 75;

RIGHT키 아스키 코드 값 = 77;

이들의 공통적인 첫 번째 반환 값

ARROW 아스키코드 값 = 224;

 

기본적으로 C언어로 게임을 만들 때는 위의 아스키코드값들을 

모두 #define 처리를 합니다. (있어 보이잖나~)

그래야 사용하기 편리합니다!!

 

또한 방향키로 물체를 이동시킬 때는

한번 누르고 끝이 아니라, 연속적이기 때문에 

while문과, switch() 문을 사용해서 표현합니다.

 

만약에 추가적으로 한 개의 key값을 반환하는

SPACE 바 key 또한 인식시키고 싶을 때는 어떻게 해야 할까요?

(SPACE BAR 아스키코드 값 = 32)

요론 식으로!!

#include <stdio.h>
#include <conio.h>
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define ARROW 224
#define SPACEBAR 32
int main(void) {
	while (1) {
		if (_kbhit()) {
			int nkey = _getch();
            if(nkey==SPACEBAR){
            	printf("space bar");
            }
			if (nkey == ARROW) {
				nkey = _getch();
				switch (nkey) {
				case UP:
					printf("up key");
					break;
				case LEFT:
					printf("left Key");
					break;
				case RIGHT:
					printf("right key");
					break;
				case DOWN:
					printf("down key");
					break;

				}
			}
		}
	}

	return 0;
}

사용을 할 수 있습니다.

 

그렇다면 맨 처음의 동영상처럼

★ 별 모양을 콘솔 창에 방향키가 눌리는 방향으로

이동하는 방법은??

 

바로 

GotoXY() 함수를 사용하여 이동시키면 되는 것입니다.

 

(GotoXY함수를 다룰 줄 모른다면?

아래 링크 정독 필수!!)

2021.09.06 - [C언어] - [C언어] GotoXY()함수로 콘솔 창의 커서를 내 마음대로 이동하기!

 

1. GotoXY()로 임의의 x, y좌표 값을 넣은 후, 별을 출력합니다.

2. UP키를 누를 경우, 임의의 x,y좌표 값에서 --y 한 값을 GotoXY(x,--y)로 대입 후,

3. system("cls"); 콘솔 창의 출력된 모든 내용을 지우는 함수. 을 통해

4. 콘솔 창을 비운 후 다시 printf("★");를 하면 되는 것입니다.

#include <stdio.h>
#include <Windows.h	>
#include <conio.h>
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define ARROW 224
void GotoXY(int x, int y) {
	COORD Pos;
	Pos.X = x;
	Pos.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}
void CursorView(char show)
{
	CONSOLE_CURSOR_INFO ConsoleCursor;
	ConsoleCursor.bVisible = show;
	ConsoleCursor.dwSize = 1;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ConsoleCursor);
}
int x = 30;
int y = 7;
int main(void) {

	CursorView(0);
	GotoXY(x, y);
	printf("★");
	while (1) {
		if (_kbhit()) {
			int nkey = _getch();
			if (nkey == ARROW) {
				nkey = _getch();
				switch (nkey) {
				case UP:
					system("cls");
					GotoXY(x, --y);
					printf("★");
					break;
				case LEFT:
					system("cls");
					GotoXY(x=x-2, y);
					printf("★");
					break;
				case RIGHT:
					system("cls");
					GotoXY(x=x+2, y);
					printf("★");
					break;
				case DOWN:
					system("cls");
					GotoXY(x, ++y);
					printf("★");
					break;

				}
			}
		}
	}

	return 0;
}

이때 CursorView(char show) 함수를 사용하였는데,

간략하게 이 함수를 설명하자면,

CONSOLE_CURSOR_INFO 구조체입니다.

dwSize( 단순히 커서의 크기를 정하는 변수입니다.)

bVisible(true일 경우 커서 값이 보이고, false 일 경우 커서 값을 숨깁니다.)

이 구조체를 ConsoleCursor로 선언 후, 구조체의 변수 값들, dwsize 크기 조정, bVisible 패널에 커서 보이기 true, 숨기기 false를 지정해 준 후,  SetConsoleCursorPosition(지정된 콘솔 화면 버퍼에서 커서 위치를 설정해주는 함수)의 매개변수로 대입하면 커서의 크기, 콘솔에 커서 보이기, 숨기기 가 활성화되는 것입니다!

 

커서를 숨기고 싶다면 

CursorView(false);

커서를 보이고 싶다면

CursorView(true);를 선언하면 됩니다!!

 

제 코드를 본 후 몇 번 따라서 nkey =_getch() 아래에 

printf("% d", nkey);를 선언하여 키가 눌렸을 때 무슨 값을 반환하는가? 에 대해

몇 번 반복적으로 연습하시다 보면 자연스레 Key값을 받는 것은 익숙해지실 거예요.

 

질문은 환영합니다!! 

728x90