C언어 기초/C언어 연습

C언어 공룡 점프 게임

한 면만 쓴 종이 2021. 8. 31. 02:28

C언어 공룡 점프 게임

 

 

/* 공룡게임
 * z 누르면 점프
 * 공룡 발 번갈아 가면서 출력
 * 장애물 생성
 * 충돌 처리
 */

// 헤더
#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#include <time.h>
#include <stdbool.h>

#define DINO_BOTTOM_Y 12
#define TREE_BOTTOM_Y 20
#define TREE_BOTTOM_X 45

// 함수 선언

void SetConsoleView();
bool isCollision(const int treeX, const int dinoY);
void GotoXY(int x, int y);
int GetKeyDown();
void DrawDino(int dinoY);
void DrawTree(int treeX);
void DrawGameOver(const int score);


// main 함수
int main(void)
{
	SetConsoleView();

	while (true)
	{
		// 게임 시작시 초기화
		bool isJumping = false;
		bool isBottom = true;
		const int gravity = 3;

		int dinoY = DINO_BOTTOM_Y;
		int treeX = TREE_BOTTOM_X;

		int score = 0;
		clock_t start, curr;     // 점수 변수 초기화  /  시간 관련 함수 clock_t 시작, current
		start = clock();         // 시작시간 초기화 ( start 지점과 curr지점을 clock()로 지정하면 초 단위로 시간 계산

		while (true)
		{
			// 충돌 검사. 트리의 x값과 공룡의 y값으로 판단
			if (isCollision(treeX, dinoY))
				break;

			if (GetKeyDown() == 'z' && isBottom)  // z를 누르고 바닥일 때 점프
			{
				isJumping = true;   // 점프 중
				isBottom = false;   // 바닥이 아님
			}

			// 점프중이면 Y감소 점프중이 아니면 Y 증가
			if (isJumping)
				dinoY -= gravity;
			else
				dinoY += gravity;

			// Y가 계속 증가하는 것을 막기 위해 바닥을 지정
			if (dinoY >= DINO_BOTTOM_Y) {
				dinoY = DINO_BOTTOM_Y;
				isBottom = true;
			}

			// 나무가 왼쪽으로 가도록 하고
			// 나무의 위치가 왼쪽 끝으로 가면 다시 오른쪽 끝으로 소환
			treeX -= 2;
			if (treeX <= 0)
			{
				treeX = TREE_BOTTOM_X;
			}

			// 점프의 맨 위를 찍으면 점프가 끝난 상황
			if (dinoY <= 3)
				isJumping = false;

			DrawDino(dinoY);
			DrawTree(treeX);

			curr = clock();        // 현재시간 받기
			if (((curr - start) / CLOCKS_PER_SEC) >= 1)   // 1초 이상이면
			{
				score++;
				start = clock();     // 시작 시간 초기화
			}
			Sleep(60);
			system("cls");

			// 점수를 계속해서 출력해있기
			GotoXY(22, 0);     // 콘솔창의 가장 왼쪽 = x값이 0, 가장 위쪽의 y값이 0이고 밑으로 내려갈수록 커짐
			printf("Score : %d ", score);
		}

		DrawGameOver(score);
	}
	return 0;
}


// 콘솔 창의 크기와 제목 지정
void SetConsoleView()
{
	system("mode con:cols=100 lines=25");
	system("title Dinosaurs Jumping Game");
}

// 충돌하면 true, 충돌하지 않으면 false
bool isCollision(const int treeX, const int dinoY)
{
	// 트리의 X가 공룡의 몸체쪽에 있을 때,
	// 공룡의 높이가 충분하지 않다면 충돌로 처리
	GotoXY(0, 0);
	printf("treeX : %d, dinoY : %d", treeX, dinoY);
	if (treeX <= 8 && treeX >= 4 && dinoY > 8)
	{
		return true;
	}
	return false;
}

// 커서의 위치를 x, y로 이동
void GotoXY(int x, int y)
{
	COORD Pos;      // COORD: 커서의 위치를 저장하는 구조체
	Pos.X = 2 * x;
	Pos.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
	// 커서의 위치를 이동시키는 함수((핸들값 반환), 핸들값을 Pos값으로 지정)
}

// 키보드의 입력을 받고, 입력된 키의 값을 반환하는 함수
int GetKeyDown()
{
	if (_kbhit() != 0)
		return _getch();
	return 0;
}

// 공룡을 그리는 함수
void DrawDino(int dinoY)
{
	GotoXY(0, dinoY);

	// 몸통
	static bool legFlag = true;      // static: 전역변수 특징과 비슷
	printf("        $$$$$$$ \n");
	printf("       $$ $$$$$$\n");
	printf("       $$$$$$$$$\n");
	printf("$      $$$      \n");
	printf("$$     $$$$$$$  \n");
	printf("$$$   $$$$$     \n");
	printf(" $$  $$$$$$$$$$ \n");
	printf(" $$$$$$$$$$$    \n");
	printf("  $$$$$$$$$$    \n");
	printf("    $$$$$$$$    \n");
	printf("     $$$$$$     \n");

	// 다리
	if (legFlag)
	{
		printf("     $    $$$    \n");
		printf("     $$          ");
		legFlag = false;
	}
	else
	{
		printf("     $$$  $     \n");
		printf("          $$    ");
		legFlag = true;
	}
}

// 나무를 그리는 함수
void DrawTree(int treeX)
{
	GotoXY(treeX, TREE_BOTTOM_Y);
	printf("$$$$");
	GotoXY(treeX, TREE_BOTTOM_Y + 1);
	printf(" $$ ");
	GotoXY(treeX, TREE_BOTTOM_Y + 2);
	printf(" $$ ");
	GotoXY(treeX, TREE_BOTTOM_Y + 3);
	printf(" $$ ");
	GotoXY(treeX, TREE_BOTTOM_Y + 4);
	printf(" $$ ");
}

// 충돌하면 게임오버
void DrawGameOver(const int score)
{
	system("cls");
	int x = 18;
	int y = 8;
	GotoXY(x, y);
	printf("===================================");
	GotoXY(x, y + 1);
	printf("==========G A M E O V E R==========");
	GotoXY(x, y + 2);
	printf("===================================");
	GotoXY(x, y + 5);
	printf("SCORE : %d", score);
	
	printf("\n\n\n\n\n\n\n\n\n");
	system("pause");
}

 

system 함수 사용 방법을 확실히 알게 되는 계기가 되었으며, 콘솔창에서 코드가 어떻게 출력될지를 많이 생각해 볼 수 있었습니다.

 

 

BlockDMask 님의 코드를 보고 만들었습니다.

 

[C언어 게임] 구글 공룡 게임 만들기 (충돌처리 추가) (tistory.com)

 

[C언어 게임] 구글 공룡 게임 만들기 (충돌처리 추가)

안녕하세요. BlockDMask 입니다. C언어나 C++을 책만보고 공부만하면 재미가 없잖아요. 그래서 제가 간단한 게임을 만들어서 소개해보려 합니다. 제가 만든 게임이 게임성이 없는 프로그램 일 수 있

blockdmask.tistory.com