메뉴 바로가기

서브메뉴 바로가기

본문 바로가기

logo

MFC테트리스 만들기
조회 수 27,894 추천 수 0 댓글 37
?

단축키

Prev이전 문서

Next다음 문서

위로 아래로 댓글로 가기 인쇄 첨부 목록
?

단축키

Prev이전 문서

Next다음 문서

위로 아래로 댓글로 가기 인쇄 첨부 목록
?
  • 소마 2011.11.02 04:35

    이렇게 소스를 보다보니 변수를 선언하실때 int나 bool 이렇게 나누시는데

    이건 앞의 함수의 선언에 따라 함수 내부 변수를 달리하신건가요....

    그리고.. 변수를 이렇게 정의 내리신 이유는 무엇때문이죠....

  • WhiteAT 2011.11.02 11:32 글쓴이

    소마 님에게 달린 댓글

    모두 int 로 해도 상관은 없습니다.^^

     

    bool 은 TRUE, FALSE 로 2가지의 상태만 가질수 있고,

    int 는 32비트일 경우 4294967296 가지의 상태를 가질수 있는 겁니다.

     

    단순히, '했다/안했다' 를 판단하려는 변수가 필요한데,

    int 처럼 메모리를 많이 잡아 먹는 형태를 사용할 필요는 없겠죠..

     

    반대로, 0 부터 1000까지의 숫자를 저장할 변수가 필요할때는

    bool 로 사용하면 0 과 1만 표현할 수 있기 때문에 꼭 int 를 사용해야 합니다.~~

     

     

  • 소마 2011.11.02 05:15

    선생님 제가 너무 기초가 없어서 그런데요...

    return true,false에 대한 개념이 안잡혀서 그런데요..

    이것이 함수에서 어떻게 작용 하는지 가르쳐주세요....

    그리고

        if(IsGameEnd()) 함수에서요 IDYES랑 MB_YESNOCANCEL 이 무엇이죠//// 

  • WhiteAT 2011.11.02 11:40 글쓴이

    소마 님에게 달린 댓글

    변수 선언에 대한 개념을 먼저 잡으셔야 하는데,

     

    C 언어 책 앞 쪽에 보시면, bool, int, long....  등의 데이터 타입이 있습니다.

    그것을 먼저 보시는게 좋을거 같네요.^^

     

    IDYES 나 MB_YESNOCANCEL 등은 MFC 에서 제공하는 숫자(?) 입니다.

    헤더 파일 다 뒤져 보면 아시겠지만, 미리 선언되어 있습니다.

    #define IDOK                1
    #define IDCANCEL            2
    #define IDABORT             3
    #define IDRETRY             4
    #define IDIGNORE            5
    #define IDYES               6
    #define IDNO                7

     

     

    #define MB_OK                       0x00000000L
    #define MB_OKCANCEL                 0x00000001L
    #define MB_ABORTRETRYIGNORE         0x00000002L
    #define MB_YESNOCANCEL              0x00000003L
    #define MB_YESNO                    0x00000004L
    #define MB_RETRYCANCEL              0x00000005L

     

     

     

     

     

     

     

    IDYES  는 메세지 박스의 리턴값인데,,

    YES 버튼이 눌렀을 경우의 값입니다.

     

    NO 를 누르게 된다면 IDNO 값이 리턴되지요..

     

     

     

    MB_YESNOCANCEL 에 대해서는

    http://www.functionx.com/bcb/functions/msgbox.htm 를 먼저 보시고 (그림 만이라도 보세요.^^)

     

    Constant Integer Button(s)
    MB_OK
    MB_OKCANCEL
    MB_ABORTRETRYIGNORE
    MB_YESNOCANCEL
    MB_YESNO
    MB_RETRYCANCEL
    MB_CANCELTRYCONTINUE
    MB_HELP
     

    MB_YESNOCANCEL  를 사용하게 되면

    다이어로그 창에    의 3개의 버튼이 사용됩니다.

     

     

     

  • WhiteAT 2011.11.02 11:52 글쓴이

    소마 님에게 달린 댓글

    궁금증이 이제 좀 해결 되셨나요?^^

     

    많은 댓글 올려 주셔서 감사합니다.~~

  • 소마 2011.11.08 01:37

    선생님!!! 이제 기본적인건 공부했다고 생각이드는것 같아요...아직 많이 부족하겠지만요...

    이제부터 본격적인 소스공부에 들어갈려고합니다... 선생님 많이 도와주세요 ㅠ.ㅠ....

    정말 기초적인것 부터 묻고 들어갈것 같아요 그래도 꼭 가르쳐주실거라 믿어요...

  • WhiteAT 2011.11.08 09:46 글쓴이

    소마 님에게 달린 댓글

    궁금한 점은 언제라도 글 남겨 주세요.^^

  • 소마 2011.11.09 01:35
    CWATTetrisView::CWATTetrisView()
    : CFormView(CWATTetrisView::IDD)
    선생님 요 클래스에는 class에다가 변수를 추가시켜주면 .cpp파일에 이 밑에 자동적으로 추가시킨 변수가 뜨던데요...
    그런데 선생님이 여기다 보드정보를 선언하시고 또 GameStart() 함수에도 보드 정보를 선언하셨던데 둘다에다 보드 정보를 선언해야하나요/
  • WhiteAT 2011.11.09 09:09 글쓴이

    소마 님에게 달린 댓글

    먼저 메소드가 언제 사용하는지를 설명 드리겠습니다.
     
    CWATTetrisView::CWATTetrisView() 는 프로그램이 시작할때 한번만 실행되며 (단 1번)
    게임 전체에 관련된 변수를 초기화 합니다.
     
    GameStart()는 게임을 시작할때마다 실행되며.  (여러번 실행)
    게임 하나에 대한 변수를 초기화 합니다.
     
    두 메소드의 기능을 정확히 이해하시면
    2군데 겹치는 것을 정리하셔도 됩니다.
     
     
     
     
    그리고, 변수 선언은 한번만 하고,
    각 메소드에는 변수 값을 설정한 것이지요^^
     
  • 소마 2011.11.09 01:47
    void CWATTetrisView::GameStart()?//게임 함수 일부분을 복사해봤어요 ㅎㅎ;;;
    {
    SetTimer(1,1000,NULL); // 1번 타이머를 1000mS(즉,1초)마다 동작
        srand( (unsigned)time( NULL ) ); ?//이거는 난수를 발생시키기 위한 선언이죠///
    m_iNowBlockShape = rand()%7;?//그렇다면 위의 선언이 없다면 계속 똑같은 패턴의 rand함수가 발생하기에
    m_iNextBlockShape = rand()%7;?//srand( (unsigned)time( NULL ) ); ?넣어주고 다른 패턴을 만들기위해
         //넣어주죠...헌데... srand를 넣지 않은 rand함수의 패턴이 따로 알려져있나      //요............////
         


  • WhiteAT 2011.11.09 09:54 글쓴이

    소마 님에게 달린 댓글

    srand() 와 rand() 는

    http://whiteat.com/zbxe/53877 에 정리해 두었습니다.

     

    참고하세요.~~

  • 소마 2011.11.09 02:28

    선생님 소스를 이리저리 조작해봤어요... Game start()와 연계된게 GameEnd함수도 관련 되있구... 초기화 클래스(CWATTetrisView::CWATTetrisView(): CFormView(CWATTetrisView::IDD))랑도 연결되있던데요... 

    GameStart 함수같은 경우는 보니깐 제일 처음 내려오는 벽돌은 GameStart내의 벽돌설정에 따르고 

    그리고 다음부터는 On Timer함수에서 입력된 블록설정 값을 받고 내려오던데요.. 

  • WhiteAT 2011.11.09 09:56 글쓴이

    소마 님에게 달린 댓글

    벽돌 내려오는 것은 y++ 변수에만 상관 있습니다.~

  • 소마 2011.11.09 03:23
    ??혹시 rand()%7의 패턴은 전에 벽돌회전 댓글에 달아놓으신 이것과 관련있는가요///

    int 의 나누기와 % 연산자를 간단하게 설명해 드릴게요~~

     

    int 로 나누기를 하면 소수점이 나오지 않습니다.

    1/4  = 0.25 인데, 1보다 작기에 0 입니다.

    2/4  = 0.50 인데, 1보다 작기에 0 입니다.

    3/4  = 0.75 인데, 1보다 작기에 0 입니다.

    4/4  = 1.00 이라                           1 입니다.

    5/4  = 1.25 인데, 2보다 작기에 1 입니다.

    즉 소수점 이하는 버리게 됩니다.

     

     

    그리고 % 는 나머지 연산자인데 나머지값이 입력됩니다.

    1%4  일때 몫은 0 이고 나머지는 1 입니다.

    2%4  일때 몫은 0 이고 나머지는 2 입니다.

    3%4  일때 몫은 0 이고 나머지는 3 입니다.

    4%4  일때 몫은 1 이고 나머지는 0 입니다.

    5%4  일때 몫은 1 이고 나머지는 1 입니다.

    즉 %4 연산을 하면 0, 1, 2, 3, 0, 1, 2,3,.... 이 반복되는 겁니다.^^


    컴파일을 시작하면 똑같은 패턴으로 나와야하지 않을까요/// 그런데 계속 다른 모양으로 나오기는 하지만 비슷한 패턴이 자주 계속 반복되는 것 같아요///

     

    ?

  • WhiteAT 2011.11.09 09:58 글쓴이

    소마 님에게 달린 댓글

    rand()%7  는

    0부터 6 까지의 숫자중 랜덤하게 나오며,

    이 의미는 벽돌 모양이 7가지 중 랜덤하게 나온다는 내용입니다.^^

     

    랜덤 수라고 해서 모든 수가 1번씩 나온다는 보장은 없습니다.^^

    같은 모양이 연속으로 나올 때고 있고, 모양이 잘 나올 때도 있습니다.~~

     
    같은 모양이 약간은 반복될 수 있습니다.
  • 소마 2011.11.09 05:35 SECRET

    "비밀글입니다."

  • WhiteAT 2011.11.09 10:01 글쓴이

    소마 님에게 달린 댓글

    벽돌이 바닥에 닿았을 때 해당 줄을 없앨지를 검사하는 부분입니다.~~

    주먹구구식으로 작업 한 것이라 좀 정리를 해야 하는 부분입니다.;;

     

    범위가 너무 많으니 이해 안되는 부분만 집어 주시고.

    이 부분은 소마님께서 새로 작성하시는게 좋을 듯 합니다.~~

     

     

  • 소마 2011.11.09 17:16

     (0!=g_BoardInfo[m_iNowBlockY+iTempBlockY][m_iNowBlockX+iTempBlockX])

    g_BoardInfo[][][이거 자체가 하나의 변수라고 취급 하는데 [m_iNowBlockY+iTempBlockY]

    되어있는데 iTempBlockY는 어디서 온거죠////

  • WhiteAT 2011.11.09 19:41 글쓴이

    소마 님에게 달린 댓글

    iTempBlockY 은 0부터 3까지의 범위를 갖습니다.^^

     

    현재 위치에 있는 벽돌을 보드의 좌표로 계산하는 것입니다.~

  • 소마 2011.11.09 17:49

    아 temp 뜻이 임시라는 거지..


  • 견황 2011.11.24 22:07

    선생님

    이 소스를 기반으로 헥사(1*3)로 고치고 있거든요.

    벽돌이 바닥에 닿았을때 남아있는 그 벽돌의 색상을 유지하는 방법 좀 알려주세요..

     

  • WhiteAT 2011.11.25 07:39 글쓴이

    견황 님에게 달린 댓글

    벽돌의 색상 정보를 보드에 전달하고,

    그 정보를 출력해 주면 됩니다.~~

     

    현재 보드가 0인지 1인지만 처리되는데,

    그것을 0부터 255 또는 그 이상으로 표현 하면 됩니다.~

  • 견황 2011.11.29 12:18 SECRET

    "비밀글입니다."

  • WhiteAT 2011.11.29 20:00 글쓴이

    견황 님에게 달린 댓글

    이런 경우는 브레이크 포인트(F9 ) 잡아 놓고, 스텝바이스텝으로 한줄 실행할때마다

    변수의 변화를 지켜 봐야 합니다.

     

    소스만 봐서는 알기 힘들고요~;

  • 견황 2011.11.30 19:41

    WhiteAT 님에게 달린 댓글

    자세한 사용법을 알려주시면 고맙겠습니다 ㅠ

    F9로 찍으면 빨간볼에 생기는데

    한줄 실행할때마다 보는것은 어떻게 하나요

  • 견황 2011.11.29 13:21

    게임이 종료될때 0.3초마다 한 라인씩 검은색벽돌로 바꿔줄 때,

    타이머를 어떤식으로 이용하면 되나요....

  • WhiteAT 2011.11.29 20:02 글쓴이

    견황 님에게 달린 댓글

    게임 종료할때 타이머를 생성하고( 예를 들어, SetTimer(5,300,NULL))

    해당 타이머마다 라인을 증가하면서 벽돌의 값을 변경해 주면 됩니다.~

  • 저 하다 하다 안되서 질문 합니다 ㅠㅜㅜㅜ

    소스 다 맞는대 실행이 안되요

    소스문제라고는 안뜨는대 확인좀요 ㅠㅠㅜ

     

  • WhiteAT 2011.12.01 19:57 글쓴이

    김민재 님에게 달린 댓글

    IDC_BUTTON1 만들었다가 제거하신거죠?

     

    IDC_BUTTON1  클릭하였을 때의 함수를 만들었다면,

    IDC_BUTTON1 를 제거할때는 그 함수를 먼저 제거한 후에

    IDC_BUTTON1 를 제거해야 합니다.

     

    OnButton1 이 들어간 줄을 모두 제거하세요.

    찾아 보니 아래처럼 2줄이 있네요.^^

     

     

    \W200702461KMT_Project_TetrisView.cpp(227): ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
    \W200702461KMT_Project_TetrisView.h(83): afx_msg void OnButton1();

     

     

  • 김민재 2011.12.04 02:25

    김민재 님에게 달린 댓글

    너무 너무 감사합니다 이렇게 자세히 가르쳐주셔서

    공부하는대 너무 큰도움이 됬습니다 ^^

    만들고나니 너무 뿌듯하네요 ㅎ

    근대 여기에 오른쪽에 점수나

    시간 같은거는 나오게 할 수 없나요 ㅎ

    만들다 보니 욕심이 생겨서요

    ㅎㅎ좋은 답변부탁드릴게요 ㅎ

  • WhiteAT 2011.12.05 06:50 글쓴이

    김민재 님에게 달린 댓글

    이 게시판을 한번 쭉 보시면 점수출력하는 예제도 있습니다.~

     

    시간출력은 점수 출력을 약간 변경하시면 됩니다~~

  • 아코 2013.06.04 14:30

    선생님! 질문입니다...^^;;


    게임 끝인지 체크하는 함수 부분이 이해가 안되서요..ㅠ


    BOOL CWATTetrisView::IsGameEnd(){

                     for(int tempY = 0;tempY<2 ;tempY++){

                                      for(int tempX=3; tempX<7; tempX++)

                                       {

                                                         if(0 != g_BoardInfo[tempY][tempX]){

                                                                           return TRUE;

                                                        }

                                       }

                     }

     

                      return FALSE;

    }



     tempY 는 0,1

     tempX 는 3,4,5,6


    인데 왜 저렇게 for문을 돌리는지 이해가 안되구요..


    0 != g_BoardInfo[tempY][tempX]


    이부분은 0이 아니라는건 벽돌이 들어있따는 뜻이 맞나요?


    그럼 저부분 체크를 할 때 어느부분에 벽돌이 생기게 되면


    게임 끝인지 모르겠습니다..ㅠ

  • WhiteAT 2013.06.08 11:28 글쓴이 Files첨부 (1)

    아코 님에게 달린 댓글

    아래 그림의 빨간색으로 표시한 부분을 검사하는 것입니다. ~

    다음 벽돌이 나와야 하는데, 그 위치가 0이 아니라면(즉, 다른 벽돌이 있다면) 게임이 끝난게 되겠죠^^?



    제목 없음.png

  • 냐하 2014.02.21 17:57

    안녕하세요.

    테트리스 강의를 처음부터 하나씩 따라해서 방법1까지 해봣는데요.

    제가 따라한 소스와 여기서 다운로드한 소스랑 비교하면서 찾아봣는데,

    모르겟는게 제 소스를 실행 시키면 윈도우창이 테트리스 블록을 전부다 표시해주지 못해서

    창을 일일이 확대시켜야하는데 다운 받은 소스는 실행시키자마자 테트리스 게임에 맞게 

    창이 만들어 지더군요.

    어떻게 창크기를 그렇게 바꿀수 있나요?

  • WhiteAT 2014.02.21 18:05 글쓴이

    냐하 님에게 달린 댓글

    요즘 MFC를 사용하지 않아서 기억이 가물가물 하네요.^^


    App 클래스의 Init 메소드에서

    ShowWindows(SW_SHOWMAXIMIZED); 를 추가하시면 됩니다.


    여기서는 App 클래스가 CWATTetrisApp 일겁니다 ;;




  • WhiteAT 님에게 달린 댓글

     윈도우창을 최대화하지 않고 처음 실행시 창의 크기가 틀려지게 할수 없을까요?

    제가 만든 소스는 처음 창 크기에 테트리스게임이 잘려서 나오기때문입니다.

    스크린 샷을 첨부합니다.포맷변환_noname01.jpg

    이게 제가 만든것이고

    포맷변환_noname010.jpg

    이게 여기서 다운 받고 실행시킨 초기 화면 입니다.

  • WhiteAT 2014.02.27 11:05 글쓴이

    냐하 님에게 달린 댓글

    답변이 많이 늦었네요 ;;


    윈도우 크기는  MoveWindow()로 변경할 수 있습니다. 

    MoveWindow(0,0, 640, 320); // 0,0 위치에 640, 320 크기의 윈도우 크기를 생성

    0,0 에  윈도우 위치를 넣으시면 됩니다.~