안녕하세요. BlockDMask 입니다.
C언어나 C++을 책만보고 공부만하면 재미가 없잖아요. 그래서 제가 간단한 게임을 만들어서 소개해보려 합니다.
제가 만든 게임이 게임성이 없는 프로그램 일 수 있습니다. 순전히 예제, 연습용 게임들이니 너그럽게 이해해주시면 감사하겠습니다.
오늘은 "C/C++로 게임을 만들어보자" 그 첫번째 게임인 "구글 공룡 게임"을 만들어 보았습니다.
사실 게임이라고 하기도 좀 그런게, 충돌판정이나 게임오버 점수주기 이런게 아무것도 없이, 캐릭터 움직임, 점프, 장애물 이동하기 이 세개만 만들어 보았습니다.
이영상을 통해서 "아 C/C++을 이용해서 이렇게 간단히 게임을 만들 수 있구나"를 보여드리고 싶었습니다.
<목차>
1. 게임 이름 및 설명
2. 게임영상
3. C언어 구글 게임 소스 코드 v1.0 (공룡 움직임, 점프, 나무 움직이기 등 기본 세팅)
4. 공룡 게임 소스코드 v2.0 (충돌, 시간에따른 점수 추가)
1. 게임이름 및 설명
▶ C/C++로 만든 구글 공룡 게임
▶ 구글 공룡게임 v1.0
1. z를 누르면 점프를 할 수 있습니다.
2. 공룡의 발을 번갈아 가며 출력합니다.
3. 장애물이 생성 됩니다.
2. 게임영상 (v1.0)
3. 소스코드(v1.0)
코드에 주석을 최대한 자세히 달았으니, 주석을 보고도 이해가 가지 않는다면 댓글 달아주시면 답변 드리겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | //[C/C++ game] very simple google dinosaur. //BlockDMask. #include<stdio.h> #include<Windows.h> #include<conio.h> #define DINO_BOTTOM_Y 12 #define TREE_BOTTOM_Y 20 #define TREE_BOTTOM_X 45 //콘솔 창의 크기와 제목을 지정하는 함수 void SetConsoleView() { system("mode con:cols=100 lines=25"); system("title Google Dinosaurs. By BlockDMask"); } //커서의 위치를 x, y로 이동하는 함수 void GotoXY(int x, int y) { COORD Pos; Pos.X = 2 * x; Pos.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos); } //키보드의 입력을 받고, 입력된 키의 값을 반환하는 함수 int GetKeyDown() { if (_kbhit() != 0) { return _getch(); } return 0; } void DrawDino(int dinoY) { GotoXY(0, dinoY); static bool legFlag = true; 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(" $$ "); } int main(void) { SetConsoleView(); bool isJumping = false; bool isBottom = true; const int gravity = 3; int dinoY = DINO_BOTTOM_Y; int treeX = TREE_BOTTOM_X; while (true) { //z키가 눌렸고, 바닥이 아닐때만 점프가능. if (GetKeyDown() == 'z' && isBottom) { isJumping = true; isBottom = false; } //점프중 = y감소 //점프끝 = y증가 if (isJumping) { dinoY -= gravity; } else { dinoY += gravity; } //Y가 계속해서 증가하는걸 막기위해 바닥을 지정. //Y가 증가한다는 것은 공룡이 아래로 내려온다는 뜻. if (dinoY >= DINO_BOTTOM_Y) { dinoY = DINO_BOTTOM_Y; isBottom = true; } //점프의 맨 위를 찍으면 점프가 끝난 상황 if (dinoY <= 3) { isJumping = false; } //나무가 왼쪽으로 가도록 하고(x의 음수방향) //나무의 위치가 왼쪽 끝으로가면 다시 초기 위치로 소환 treeX -= 2; if (treeX <= 0) { treeX = TREE_BOTTOM_X; } DrawDino(dinoY); //draw dino DrawTree(treeX); //draw tree Sleep(80); system("cls"); //clear } system("pause"); return 0; } | cs |
1. 시간에 따라서 점수가 올라가도록 코드 추가하였습니다.
2. 충돌 처리를 넣어달라는 요청이 있어서 간단하게 한번 넣어 보았습니다.
▶ 충돌 처리 간단 설명
이해가 쑥쑥 가시죠..?
공룡의 머리 기준으로 출력하기 때문에 공룡이 평소에는 y가 12인데 점프를 뛰면 대략 3까지 올라가더군요
그래서 중간 정도인 6정도가 딱 바 에서 나무가 오면 부딪히는걸로 간주하겠다고. 코드를 작성한 것이고
나무의 위치를 보니 공룡쪽으로 오는 X가 4~8 정도가 적당하다고 판단했습니다.
그래서 생겨난 코드가 bool isCollision(const int treeX, const int dinoY) 이 함수입니다.
해당함수 내부를 보면
if (treeX <= 8 && treeX >= 4 && dinoY > 8)
만약에 X(나무)의 위치가 4~8 사이이고 공룡 머머리의 Y가 8보다 높을때(바닥에 가까울때) 충돌했다! 라고 판단하면됩니다.
공룡이 나무에 부딪히면 게임오버 하는걸 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | //[C/C++ game] very simple google dinosaur. (by. BlockDMask) //2019.12.03 (v2.0)점수 추가, 충돌처리 추가. #include<stdio.h> #include<windows.h> #include<conio.h> #include<time.h> #define DINO_BOTTOM_Y 12 #define TREE_BOTTOM_Y 20 #define TREE_BOTTOM_X 45 //콘솔 창의 크기와 제목을 지정하는 함수 void SetConsoleView() { system("mode con:cols=100 lines=25"); system("title Google Dinosaurs. By BlockDMask."); } //커서의 위치를 x, y로 이동하는 함수 void GotoXY(int x, int y) { COORD Pos; Pos.X = 2 * x; Pos.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos); } //키보드의 입력을 받고, 입력된 키의 값을 반환하는 함수 int GetKeyDown() { if (_kbhit() != 0) { return _getch(); } return 0; } //공룡을 그리는 함수 void DrawDino(int dinoY) { GotoXY(0, dinoY); static bool legFlag = true; 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(" $$ "); } //(v2.0) 충돌 했을때 게임오버 그려줌 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"); } //(v2.0) 충돌했으면 true, 아니면 false bool isCollision(const int treeX, const int dinoY) { //트리의 X가 공룡의 몸체쪽에 있을때, //공룡의 높이가 충분하지 않다면 충돌로 처리 GotoXY(0, 0); printf("treeX : %d, dinoY : %d", treeX, dinoY); //이런식으로 적절한 X, Y를 찾습니다. if (treeX <= 8 && treeX >= 4 && dinoY > 8) { return true; } return false; } int main() { SetConsoleView(); while (true) //(v2.0) 게임 루프 { //게임 시작시 초기화 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; //점수 변수 초기화 start = clock(); //시작시간 초기화 while (true) //한 판에 대한 루프 { //(v2.0) 충돌체크 트리의 x값과 공룡의 y값으로 판단 if(isCollision(treeX, dinoY)) break; //z키가 눌렸고, 바닥이 아닐때 점프 if (GetKeyDown() == 'z' && isBottom) { 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; } //나무가 왼쪽으로 (x음수) 가도록하고 //나무의 위치가 왼쪽 끝으로가면 다시 오른쪽 끝으로 소환. treeX -= 2; if (treeX <= 0) { treeX = TREE_BOTTOM_X; } //점프의 맨위를 찍으면 점프가 끝난 상황. if (dinoY <= 3) { isJumping = false; } DrawDino(dinoY); //draw dino DrawTree(treeX); //draw Tree //(v2.0) curr = clock(); //현재시간 받아오기 if (((curr - start) / CLOCKS_PER_SEC) >= 1) // 1초가 넘었을떄 { score++; //스코어 UP start = clock(); //시작시간 초기화 } Sleep(60); system("cls"); //clear //(v2.0) 점수출력을 1초마다 해주는것이 아니라 항상 출력해주면서, 1초가 지났을때 ++ 해줍니다. GotoXY(22, 0); //커서를 가운데 위쪽으로 옮긴다. 콘솔창이 cols=100이니까 2*x이므로 22정도 넣어줌 printf("Score : %d ", score); //점수 출력해줌. } //(v2.0) 게임 오버 메뉴 DrawGameOver(score); } return 0; } | cs |
'<토이프로젝트> > [C언어 게임]' 카테고리의 다른 글
[C언어 게임] 테트리스 게임 (Tetris Game with C) (200) | 2017.07.13 |
---|---|
[C언어 게임] 뱀 게임 (Snake Game with C) (131) | 2017.07.04 |