본문 바로가기

Try Programs

솔플 테트리스를 만들어보자 1

테트리스를 만들어보자 1

- 기반이 될 변수들과 맵, 블록을 그리는 함수 -



예전부터 한번은 만들자고 생각해왔던 간단한 프로젝트인 테트리스를 시작하겠다.

오픈소스들과 모르는 함수같은 부분들을 많이 찾아보며 공부하며 이미 다른 분들이 만들어놓은 소스들을

뜯어보며 실행하며 얻은 것들로 재구성해보았다.


오늘의 포스팅은 테트리스에서 가장 기초가 될 변수들과 맵, 블록을 그리는 함수들을 설명하겠다.

(우선 쓰인 헤드파일들과 정의, 기본 windows 함수들)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h> 
 
#define COL GetStdHandle(STD_OUTPUT_HANDLE)        //주요 핸들(텍스트 색상 변경 시 쓰임)
 
enum  Color { BLUE = 9, YELLOW = 14, RED = 12, WHITE = 15, PURPLE = 5, SKYBLUE = 3, GREEN = 2 };
 
void gotoxy(int x, int y)
{
    COORD Pos = { x - 1, y - 1 };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}
void CursorUtil_Hide(){        //커서 숨기기
    CONSOLE_CURSOR_INFO cursorInfo;
    cursorInfo.dwSize = 1;
    cursorInfo.bVisible = FALSE;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
cs


1. 여러 변수들


(1) block 관련 변수

테트리스에서 가장 기초는 역시 블록이 된다.

테트리스에서 블록은 총 4개의 정사각형으로 이루어져있는 블록들이 있는데 종류는 7종으로

I, O, L, J, S, Z, T 이 알파벳 모양의 블록들이 있다.

이 블록들은 3차원 배열로 구성할 것이다.


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
int block[7][4][4= {
    {
        { 0000 },
        { 0000 },
        { 1111 },
        { 0000 }
    },
    {
        { 0000 },
        { 0001 },
        { 0111 },
        { 0000 }
    },
    {
        { 0000 },
        { 0011 },
        { 0110 },
        { 0000 }
    },
    {
        { 0000 },
        { 0110 },
        { 0011 },
        { 0000 }
    },
    {
        { 0000 },
        { 0010 },
        { 0111 },
        { 0000 }
    },
    {
        { 0000 },
        { 0100 },
        { 0111 },
        { 0000 }
    },
    {
        { 0000 },
        { 0110 },
        { 0110 },
        { 0000 }
    }
};
cs


테트리스를 만들면서 실제로 3차원 배열을 처음 사용해봤다.

int block[7][4][4]에서 앞의 [7]은 블록의 종류를 나타낼 것이다. (7종류의 블록들)

그리고 0, 1로 모양을 찍어 나타낸다.

그럼 1일 때 블록을 ■으로 출력시키면 블록모양이 나올 것이다.


1
2
int originalBlock[7][4][4= { 0 };
int randBlock = 0;
cs


originalBlock은 모든 종류의 블록들을 저장해놓을 변수이고 (나중에 꺼내 쓸 것임)

randBlock은 0~6의 숫자들로 랜덤으로 블록들의 모양을 결정해 줄 변수이다.


1
int newBlock = 0;
cs


newBlock은 새로운 블록들이 생성될 때 그 사실을 체크해줄 변수이다.


(2) 맵 관련 변수

다음으로 게임을 플레이 할 장소인 Map을 만들어보자

테트리스는 기본적으로 가로 10칸, 세로 20칸의 맵을 주로 쓴다.

그러기 위해서는 테두리를 포함해야 하므로 가로 12칸, 세로 22의 공간이 필요하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int map[22][12= {                            //MAP = 가로 10칸, 세로 20칸
    { 111111111111 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 100000000001 },
    { 111111111111 }
};
cs


&


1
2
int collisionMap[22][12= { 0 };
int immutabilityMap[22][12= { 0 };
cs


collisionMap은 이름 그대로 맵 테두리에 블록이 충돌이 되었나 안 되었나를 확인할 변수로

블록이 바닥에 떨어질 것과 블록이 맵 밖으로 나가지 못하게 할 변수이다.

immutabilityMap은 Map의 데이터를 저장시켜 필요할 때 꺼내쓸 변수이다.


(3) 그 밖의 변수들


1
2
3
int nowHeight = 0;
int score = 0;
int x, y, px, py, Move, Move2;
cs


nowHeight는 블록이 쌓여있을 때 최고 높이를 저장할 변수로

이 변수를 이용해 게임오버 조건을 설정할 수 있다.

score 변수는 1줄을 클리어했을 때 100점씩 점수를 받을 변수이다.

x, y, px, py는 말 그대로 좌표를 받을 변수이고

Move, Move2변수는 블록의 움직임을 받을 변수이며 2개로 변수를 생성한 이유는

양방향을 그냥 알아보기 쉽게 하려고 이렇게 해보았다. (꼭 2개로 만들 필요는 없을것이다.)



2. 그리기 함수들


맵과 블록을 그리는 함수들이다.


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
void drawBoard()
{
    int i, j;
    gotoxy(53);
    for (i = 0; i<12; i++)
        printf("■");
    for (i = 0; i<21; i++)
        printf("\n    ■");
    gotoxy(524);
    for (i = 0; i<12; i++)
        printf("■");
    for (i = 0; i<21; i++)
    {
        gotoxy(274 + i);
        printf("■");
    }
    gotoxy(405);
    printf("-TETRIS-");
    gotoxy(406);
    printf("  슬기로운 코딩생활");
    gotoxy(4010);
    printf("SCORE : 0");
}
void drawBlocks(int m)
{
    int i, j;
    int color = 12;
    static int num = 1;
 
    for (i = 0; i<22; i++)
    {
        for (j = 0; j<12; j++)
            collisionMap[i][j] = immutabilityMap[i][j];
    }
    for (i = 0; i<4; i++)
    {
        for (j = 0; j<4; j++)
        {
            if (block[randBlock][i][j] == 1)
            {
                color = setColor(num);
                SetConsoleTextAttribute(COL, color);
                map[y + i][x + j] = num;
                gotoxy(px + j * 2, py + i);
                printf("■");
                if (num == 7)
                    num = 1;
                else if (NewBlock == 1)
                    num++, NewBlock = 0;
                if (m == 1)
                    collisionMap[y + i + 1][x + j] = 0;
                else if (m == 2)
                    collisionMap[y + i][x + j - 1= 0;
                else if (m == 3)
                    collisionMap[y + i][x + j + 1= 0;
            }
        }
    }
}
cs