안녕하세요
이번 강좌에서는 지난시간에 이어 메뉴를 선택하는 기능을 구현해보도록 하겠습니다.
[목차]
1. 키보드 입력키 선정하기
2. 선정한 키값을 정의하기
3. 키보드 이벤트 처리하기
4. 메뉴 선택기능 구현하기
[1 키보드 입력키 선정하기]
게임 내 또는, 메뉴에서 사용할 키보드의 키를 미리 정의하기 위해서는
어떤키를 선택할지 고민해야합니다.
FPS게임은 주로 이동할 때 w, a, s, d 키를 사용합니다.
이와같이 내가 개발할 콘솔게임에서 어떤 키를 사용할지 정하는것도 꽤 중요합니다.
저는 탈출게임을 목표로 진행하고있기때문에
상하좌우를 이동하기위해 w, a, s, d 키로 정하도록 하겠습니다.
기타 키값으로는 게임을 종료할 땐 q를 사용하도록 하겠습니다.
[2 선정한 키값 정의하기]
선정한 키보드 값을 그대로 사용해도 무방하지만, 알기쉽게 정의해두면 추후에 유지보수 차원에서도 훨씬 좋습니다.
#define은 전처리기 중 정의하는 매크로인데요
#define 이름 값
형식으로 작성하시면 됩니다.
if(UP == 0) 이라고 작성된 조건문이 있다면 결과는 참이됩니다.
컴파일시, 이름으로 사용한것들은 정의된 값으로 동일하게 적용됩니다.
예) UP + DOWN; 라고 한다면 컴파일시에 0 + 1 로 변경됩니다.
위와같이 #define으로 정의해두면 UP이라는 이름을 통해 어떤 값인지 쉽게 판별할 수 있기때문에 사용하는것도 좋습니다.
저는 위로가는 키를 0, 아래는 1, 왼쪽 오른쪽은 2, 3으로 정의하였습니다.
[3 키보드 이벤트 처리하기]
키보드이벤트란? 처음 듣는분들도 계실거라 생각합니다.
말은 생소하지만 우리들은 컴퓨터를 사용하면서 매일매일 사용하고 있습니다.
키보드가 눌렸을 때를 이벤트라고 합니다. 어떠한 행위를 하면 그게 이벤트입니다.
키보드가 눌릴때마다 이벤트가 발생하는것이죠
메모장을 실행하고 키보드를 누르면 누른 키보드에 대한 글자가 작성됩니다. 이것이 바로 키보드이벤트입니다.
키보드이벤트는 프로그램마다 다를 수 있습니다.
게임같은 종류는 키보드를 누르면 스킬을 사용하거나 이동하지만, 워드와 같이 문서작성 프로그램에서는 글자가 표시되죠.
키보드이벤트에 대해서는 간단히 설명하고 본론으로 넘어오도록 하겠습니다.
콘솔게임은 대부분 키보드로만 조작합니다(마우스 이벤트도 있지만 비효율적)
키보드가 눌렸을 때 위에서 정의한 키값을 전달해주도록 하는 함수를 하나 구현할것입니다.
키보드이벤트 관련기능도 매우 자주 사용되므로
따로 함수로 구현하도록 하겠습니다.
w(또는 대문자 W)가 입력되면 UP 이라는 값을 반환하고
a(또는 대문자 A)가 입력되면 LEFT라는 값을 반환하는 함수를 구현해보도록 하겠습니다.
(s, d 키 포함)
getch 함수는 엔터를 입력하지 않아도 키가 눌리면 바로 반환해주는 입력함수입니다.
scanf나 cin으로 입력을 받을땐 글자를 입력하고 엔터를 눌러야 입력이 되지만,
getch는 a키를 누르면 화면에 보여주지않고 바로 반환해버립니다.
29번 행에는 temp = getch() 라고 되어있습니다.
키가 입력되면 바로 temp 변수에 임시로 값을 저장하고
아래의 if문에서 입력된 값이 w, a, s, d (대문자 포함)인지 확인하는 모습입니다.
해당하는 문자가 맞으면 그에 대응하는 UP, DOWN, LEFT, RIGHT의 값을 반환하는 모습입니다.
w를 누르면 UP(0) 이 반환될것이고
d를 누르면 RIGHT(3) 이 반환될 것입니다.
테스트를 위해 22, 23번줄에 간단한 코드를 작성하였습니다.
keyControl이 키를 눌렀을 때 키값을 반환해주는 함수입니다.
그 아래에서는 반환된 키값을 출력하는 모습입니다.
d키를 누르니 3이 입력됬다고 정상적으로 나옵니다.
이제 키보드 이벤트가 발생하면 알맞는 키값을 반환할 수 있게되었으니
중요기능들이 거의 구현되어가고있습니다.
[4 메뉴 선택기능 구현하기]
게임시작
게임정보
종료
이 세가지 메뉴를 이전 강좌에서 출력해보았습니다.
하지만 보이기만할뿐 움직이지도, 선택할수도 없는데요.
오늘의 4챕터에서 선택할 수 있는 기능을 구현해보도록 하겠습니다.
이동뿐만아니라 선택을 위한 키를 정의합니다. (9행)
15행의 메뉴출력 함수의 반환형을 void -> int로 변경해줍니다.
keyControl 함수 내에 스페이스바 입력에 대한 부분도 추가해줍니다. (37~39)
아래에서는 menuDraw 부분의 반환형을 선언한 부분과 일치하게 int형으로 변경해줍니다.
57~58, 65~93행은 새로 추가된 소스코드입니다.
65행의 무한 반복은 키보드입력을 무한정 받고 기다리고 하는 부분입니다.
계속 가만히있는게 아니라 스페이스바(위의 SUBMIT 코드)가 입력되면 return 하여 루프와 함수를 빠져나갑니다.
66행의 int n 은 키보드의 키코드를 임시로 저장하는 변수입니다.
키코드를 저장하였으면 67행의 switch 문에서 해당하는 키코드의 동작을 실행하죠
만약 입력된 키가 UP이면 y를 감소시키고
DOWN이면 y를 증가시킵니다.
if문도 있는데 이는 범위를 벗어나지 못하게하는 부분입니다.
게임시작
게임정보
종료
이 세가지 메뉴만 있는데 w키를 눌렀다고 위로 계속 올라가버리면 안되기때문에 범위를 조건문으로 지정하였습니다.
x축은 가만히 있으면 되고 y축으로 위, 아래로만 이동하면 되기때문에 y값을 증감하는 모습입니다.
y위치가 12부터 시작하고 있습니다.
12에는 게임시작
13에는 게임정보
14에는 종료
이렇게 되어있습니다.
12~14까지만 이동하면 되므로 이것이 조건문으로 제한해둔 이유입니다.
조건문에서 조건이 참이 되면 실제 이동(출력)하는 부분이 있습니다.
DOWN일 상태를 가정하여 설명하겠습니다.
1. 키보드 s키가 눌린다.
2. keyControl 함수에서 DOWN값을 반환
3. 67행의 switch문에서 DOWN에 해당하는 case로 이동
4. y가 14보다 작은가? 조건 체크
5. 작으면 gotoxy()로 현재 좌표위치로 이동 (아직 가만히있는 상태)
6. 출력되어있던 ">" 문자를 공백으로 덮어씌움(지우기)
7. gotoxy로 새로 이동할 위치로 이동(82행)
8. ">" 문자 출력
위의 과정이 길고 복잡해보일 수 있습니다.
하지만 천천히 과정을 생각해보시고 코드로 작성해서 살펴보신다면 큰 어려움은 없을겁니다.
위 사진은 실제 출력 과정입니다.
키보드가 입력되면 먼저 좌표값을 변경하는것이 아니라
우선 원래있던 위치로 이동하여 > 문자를 지워버립니다.
지운 후에 이동하여 새로 > 문자를 출력하는 방식이죠.
<실행결과>
처음에는 어려우실 수 있지만 이해하신다면 다음 강좌를 진행하셔도 좋습니다.
이후로도 출력에는 위와같은 방식을 사용하기때문에 꼭 숙지하셔야합니다.
감사합니다.