컴공과컴맹효묘의블로그

c언어로 게임을, c언어 좌표계 gotoxy()함수 본문

컴퓨터/C언어

c언어로 게임을, c언어 좌표계 gotoxy()함수

효묘 2019. 10. 1. 20:54
반응형
C언어 콘솔창으로 테트리스, 오목을 만들 수 있다.

c언어를 처음 배우는 분들이 c언어 콘솔창으로 게임을 만들고 싶을 때가 있을겁니다.

테트리스, 스네이크게임, 오목, 바둑 등 여러 게임을 만들때는 보통 좌표계를 이용합니다. 왜냐하면 좌표계를 이용하면 굉장히 편리하기 때문이죠.

c언어 콘솔창 테트리스 /출처 : https://www.a-mean-blog.com/ko/blog/Text-Game-Maker-JS/Games/Tetris

 

Windows.h

Windows.h 헤더파일은 윈도우 개발자들이 필요한 모든 메크로들, 다양한 함수들과 서브시스템에서 사용되는 모든 데이터 타입들 그리고 윈도우 API의 함수들을 위한 정의를 포함하는 윈도우 C  C++ 헤더 파일이다.

출처 : 위키백과

콘솔창에서 좌표계를 사용하고 싶다면, Windows.h를 인클루드 해야합니다.

#include<Windows.h>//#include<windows.h> 소문자로도 가능

 

좌표계를 설정해주는 함수 만들기
#include<stdio.h>
#include<Windows.h>

void gotoxy(int x, int y);

int main(void){
	
    return 0;
}

void gotoxy(int x, int y){
	COORD pos = {x,y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

위 함수 gotoxy()를 추가해줌으로써 콘솔 좌표계에 '점'을 찍을 수 있습니다. gotoxy(3,3);을 하면 '커서'가 콘솔의 3,3으로 가고, 이 상태에서 printf("1");을 해주면 3,3에 1이 찍히는 것을 볼 수 있습니다.

 

3,3에찍은 1 // 개발환경 dev c++

 

그런데 좀 이상하죠... 분명 3,3에 찍은 것 같은데, -3, 2정도에 찍힌 것으로 보입니다..

사실 이 함수는 우리가 평소에 알던 좌표계와는 다르게 y축이 아래쪽으로 향해있습니다.

 

그러면 왜 x좌표는 3에 가있지 않는 것인가요?

그 이유는 알파벳의 크기에 있습니다. 예를 들어 'a'는 높이가 1이라 하면, 가로가 0.5이기 때문에 알파벳 두 개가 연속적으로 있어야 정사각형 인 것을 알 수 있습니다. 모든 알파벳의 크기가 1x0.5이며, 한글이나 한자는 1x1입니다.

 

즉, 테트리스 블럭같은 경우 크기가 1x1이므로 좌표계를 재설정 할 필요가 있습니다.

 

#include<stdio.h>
#include<Windows.h>

void gotoxy(int x, int y);

int main(){
	gotoxy(3,3);
	printf("1");
	return 0;
}

void gotoxy(int x, int y){
	COORD pos = {x*2,y};//여기만 바뀜
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

 

다시 설정한 함수로 3,3을 찍음

이제 좀 원하는 대로 나온 것 같네요. 이제 저 1을 테트리스 블럭으로 바꿔주기만 하면 될 것 같네요.

 

#include<stdio.h>
#include<Windows.h>

void gotoxy(int x, int y);

int main(){
	gotoxy(3,3);
	printf("□");//한글 ㅁ을 누르고 한자키를 누르면 2번째 페이지에 있음
	return 0;
}

void gotoxy(int x, int y){
	COORD pos = {x,y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

 

저 'ㅁ'은 특수 문자로써 알파벳의 두 칸을 차지하므로, 1x1크기 입니다.

ㅁ을 찍자.

이제 블럭을 지우는 일만 남았네요.

 

 

블럭을 지우는 방법 / 화면을 초기화 하는 방법

 

제 기준으로 블럭을 나누는 방법은 크게 두 가지가 있다고 생각합니다.

 

첫 번째로 gotoxy함수로 지울 위치에 간 후에 printf("  ");로 지우기.

두 번째는 system("cls");로 지우는 방법이 있습니다.

 

위 두가지 방법은 서로 장단점이 있습니다. 하지만 저는 첫 번째 방법을 선호합니다.

 

첫 번째 방법:

printf("  ");//스페이스 두 칸입니다.

이 방법은 gotoxy로 블럭을 지울 위치에 가서 블럭을 하나 지워줍니다. gotoxy로 직접 가야한다는 불편함이 있지만, 속도가 빠릅니다.

 

두 번째 방법:

system("cls");입니다. 이 방법은 cmd에서 cls명령어를 치는 것과 똑같습니다. 화면 전체를 지웁니다. 첫 번째 방법보다는 번거로움이 덜 하지만, 매우 느린 속도로 작동하므로, 화면의 블럭(혹은 알파벳, 무엇이든)들이 깜박거리는 것을 볼 수 있습니다.

 

깜박거리는 커서 없애기

c언어로 코드를 짜고 실행시켜보면, 입력을 받을 때, 입력하는 부분이 깜박거리는 것을 볼 수 있습니다. 하지만 테트리스나 오목같은 게임에서 이런 지저분한 커서는 필요가 없습니다. 다행이도 거슬리는 커서를 없앨 방법이 있습니다. 코드 4줄로 해결이 가능합니다.

 

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

void gotoxy(int x, int y);

int main(){
	CONSOLE_CURSOR_INFO cursorInfo = { 0, };
	cursorInfo.bVisible = 0;
	cursorInfo.dwSize = 1;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);

	gotoxy(3,3);
	printf("□");
	getch(); 
	return 0;
}

void gotoxy(int x, int y){
	COORD pos = {x*2,y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

이러면 커서가 깔끔하게 지워진 것을 볼 수 있습니다.

 

이제 간단한 게임을 만들 때 필요한 것은 모두 같췄습니다. 물론 진짜 할만한 게임을 만들려면 훨씬 복잡한 코드를 짜야겠지만, 조금만 생각하면 오목 정도는 쉽게 만들 수 있습니다.

 

 

 

반응형
Comments