0. 서론
우리는 아주 간단한 세가지 함수를 다루는 방법을 배웠습니다.
다만 간단하지만 아주 강력한 기능들입니다.
이를 통하여 간단한 게임을 한가지 만들어보고자 합니다.
1. 설계
규칙은 아주 간단합니다.
1. 랜덤한 위치에 별이 생성된다.
2. 캐릭터가 별에 닿으면 점수가 오르고 별이 사라진다.
3. 특정 점수까지 도달할때까지 1~2를 반복한다.
위의 규칙을 바탕으로 게임을 만들어 볼겁니다.
2. 구현
2-0. 완성된 코드
#include<iostream>
#include<conio.h>
#include<WIndows.h>
// 방향키
#define UP 72
#define LEFT 75
#define RIGHT 77
#define DOWN 80
//좌표 출력
#define POS 30
using namespace std;
void gotoxy(int x, int y) {
COORD pos = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
int player_x, player_y;
int object_x, object_y;
int score = 0;
int star = 0;
void make_star() {
srand(time(NULL));
object_x = rand() % 20;
object_y = rand() % 20;
gotoxy(object_x, object_y);
printf("★");
}
void draw_player() {
gotoxy(player_x, player_y);
printf("@");
}
void move(int input) {
switch (input) {
case DOWN:
player_y++;
break;
case UP:
player_y--;
break;
case LEFT:
player_x--;
break;
case RIGHT:
player_x++;
}
}
void check() {
if (object_x - player_x > -2 && object_x - player_x < 2 && object_y == player_y) {
score++;
star = 0;
gotoxy(object_x, object_y);
printf(" ");
}
}
int main(void) {
player_x = player_y = 20;
int c;
while (1) {
gotoxy(POS, POS);
printf("player : (%d, %d) \n", player_x, player_y);
gotoxy(POS, POS-1);
printf("star : (%d, %d) \n", object_x, object_y);
gotoxy(POS, POS-2);
printf("score : %d", score);
draw_player();
/* 별이 없다면 */
if (!star) {
make_star();
star = 1;
}
if (_kbhit()) {
/* 224 키보드 방향키값 제거 */
do { c = _getch(); } while (c != 224);
/* 기존 도형을 삭제*/
gotoxy(player_x, player_y);
printf(" ");
/* 이동 처리 */
move(_getch());
}
check();
}
}
먼저 소스 코드를 모두 공개했습니다.
여기서 하나하나 요소를 모두 살펴보면서 소스코드를 분석해보겠습니다.
2-1. 요소를 그리기
void gotoxy(int x, int y) {
COORD pos = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
앞서 구현한 위의 gotoxy함수를 활용합니다.
위를 통하여 해당하는 위치에 원하는 요소들을 그릴 수 있습니다.
이번에 필요한 요소는 별과 캐릭터를 그리는 것이 되겠습니다.
이것을 기본으로 하나하나 게임을 설계해 봅시다.
2-2. 캐릭터의 이동
while(1){
...
draw_player();
...
if (_kbhit()) {
/* 224 키보드 방향키값 제거 */
do { c = _getch(); } while (c != 224);
/* 기존 도형을 삭제*/
gotoxy(player_x, player_y);
printf(" ");
/* 이동 처리 */
move(_getch());
}
...
}
먼저 key를 어떻게 받느냐에 따른 이동처리를 해줘야 합니다.
위 키를 누르면 위로 이동하도록, 아래 키를 누르면 아래로 이동하도록 만들어 줘야겠습니다.
1. 먼저 방향키 값을 제거하고,
2. gotoxy를 통하여 플레이어의 위치로 이동한 뒤 공백을 출력하여 기존 플레이어 도형을 삭제합니다.
3. 이후 함수를 통하여 이동 처리를 한 뒤 반복문을 통하여 다시 플레이어를 그려줍니다.
void move(int input) {
switch (input) {
case DOWN:
player_y++;
break;
case UP:
player_y--;
break;
case LEFT:
player_x--;
break;
case RIGHT:
player_x++;
}
}
플레이어의 이동 처리를 하는 move 함수는 아주 간단합니다.
입력된 값에 따라서 플레이어의 좌표 값만 수정해주는 방식입니다.
다만 주의하여야 할 점은 일반적인 좌표계와 다르게 아래쪽이 증가하는 방향입니다.
(옜날 컴퓨터가 위에서 아래로 출력하는 것을 본적 있다면 쉽게 이해하실 겁니다.)
화면좌표계는 왼쪽 상단 위가 (0, 0) 이고 아래로 내려갈 수록 y좌표가 증가합니다.
따라서 DOWN, UP에 있어서는 일반적인 좌표계와 반대로 DOWN에서는 증가, UP에서는 감소를 시켜줍니다.
void draw_player() {
gotoxy(player_x, player_y);
printf("@");
}
캐릭터가 이동하였다면 그려줘야겠죠?
그냥 현재 플레이어의 좌표로 가서 플레이어의 캐릭터 모양인 "@"을 출력해줄 뿐입니다.
2-3. 별의 생성
void make_star() {
srand(time(NULL));
object_x = rand() % 20;
object_y = rand() % 20;
gotoxy(object_x, object_y);
printf("★");
}
별의 생성도 아주 간단합니다.
srand() 함수를 통하여 시간에 따른 시드를 부여한 뒤,
(0, 0) ~ (20, 20) 사이에 별의 값을 부여하고 그 위치에 별을 출력하면 끝입니다.
2-4. 점수 획득
void check() {
if (object_x - player_x > -2 && object_x - player_x < 2 && object_y == player_y) {
score++;
star = 0;
gotoxy(object_x, object_y);
printf(" ");
}
}
마지막으로 플레이어가 별에 다가가면 점수를 획득해야겠죠?
별의 크기가 화면에서 출력할 때 2칸정도 크기를 잡아먹습니다.
따라서 별의 x축과 플레이어의 y축의 차이가 2 이내일 경우,
별과 플레이어가 같은 높이에 있을 경우(y값이 같음)
점수를 올려줍니다.
star = 0;을 통하여 star 변수를 0으로 만들어 main함수에서 별을 다시 생성할 수 있도록 해줍니다.
또한 별의 위치로 이동하여 공백을 출력함으로 별을 지워줍니다.
2-5. 마무리
자 이제 필수 요소들을 모두 살펴봤으니 처음 봤던 소스코드를 다시 한번 살펴보도록 하겠습니다.
자잘한 것들은 주석을 달아놓을테니 확인해보세요.
#include<iostream>
#include<conio.h>
#include<WIndows.h>
// 방향키
#define UP 72
#define LEFT 75
#define RIGHT 77
#define DOWN 80
/* 아래 위치에 별과 플레이어, 점수 등을 표시하기 위하여 선언했습니다. */
#define POS 30
using namespace std;
/* 해당 좌표로 이동하는 함수입니다. */
void gotoxy(int x, int y) {
COORD pos = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
/* 플레이어와 별의 위치를 기억하기 위하여 선언한 변수입니다.*/
int player_x, player_y;
int object_x, object_y;
/* 점수와 게임 화면에 별이 있는지 확인하기 위한 변수입니다. */
int score = 0;
int star = 0;
/* 위에서 다루었던 별을 만드는 함수입니다. */
void make_star() {
srand(time(NULL));
object_x = rand() % 20;
object_y = rand() % 20;
gotoxy(object_x, object_y);
printf("★");
}
/* 위에서 다루었던 플레이어의 위치를 표시하는 함수입니다. */
void draw_player() {
gotoxy(player_x, player_y);
printf("@");
}
/* 위에서 다루었던 입력에 따른 플레이어 좌표 변환 함수입니다.*/
void move(int input) {
switch (input) {
case DOWN:
player_y++;
break;
case UP:
player_y--;
break;
case LEFT:
player_x--;
break;
case RIGHT:
player_x++;
}
}
/* 위에서 다루었던 플레이어가 별을 획득했는지(별에 닿였는지) 여부를 확인하는 함수입니다. */
void check() {
if (object_x - player_x > -2 && object_x - player_x < 2 && object_y == player_y) {
score++;
star = 0; /* 별 상태를 0으로 만들어 다시 별이 생성되게끔 합니다. */
gotoxy(object_x, object_y);
printf(" ");
}
}
int main(void) {
/* 초기 플레이어 위치는 20으로 설정했으나 얼마로 설정하든 상관없습니다. */
player_x = player_y = 20;
int c;
while (1) {
/* 플레이어와 별, 점수를 나타내기 위한 출력문입니다. */
/* POS의 위치에서 차례대로 출력합니다. */
gotoxy(POS, POS);
printf("player : (%d, %d) \n", player_x, player_y);
gotoxy(POS, POS-1);
printf("star : (%d, %d) \n", object_x, object_y);
gotoxy(POS, POS-2);
printf("score : %d", score);
/* 플레이어를 그립니다. */
draw_player();
/* 별을 획득하여 별이 없을 경우 별을 그립니다. */
if (!star) {
make_star();
star = 1; // 별을 그리고 별 상태를 1로 바꿉니다.
}
if (_kbhit()) {
/* 224 키보드 방향키값 제거 */
do { c = _getch(); } while (c != 224);
/* 기존 도형을 삭제*/
gotoxy(player_x, player_y);
printf(" ");
/* 이동 처리 */
move(_getch());
}
check();
}
}
3. 실행 화면
점수도 잘 오르고 플레이어와 별의 위치 또한 잘 나타내고 있는 모습이 보입니다.
다만 아쉬운 점은 소스코드에 종료 버튼을 넣지 않아서 컨트롤+C를 통한 콘솔 종료를 해야한다는 점이네요 ㅜ
커서도 많이 신경쓰일 수 있구요!
이 부분에 대해서는 각자 숙제로 맡기겠습니다~
'게임 프로젝트 > 기본기' 카테고리의 다른 글
키값 확인 및 키가 입력되었는지 확인하기(getch(), kbbit()) (0) | 2021.06.28 |
---|---|
커서이동 gotoxy 함수와 입력대기 (0) | 2021.06.27 |