티스토리 뷰

Project

#001 : Mole Catch

BaeMinCheon 2018. 1. 28. 19:20

Project Note #001


Mole Catch

  • Window API를 활용해 만든 게임, Mole Catch에 대해 알아봅니다.
  • 참고
    ※ https://youtu.be/quCLlsKS_uU (플레이 영상)
    ※ https://github.com/BaeMinCheon/mole-catch (Github)

환경

  • Visual Studio 2015 Community
  • Windows 10 Home
  • Window API (C/C++)

소개

  • 주어진 생명력이 0으로 떨어질 때까지, 두더지를 최대한 많이 잡아 고득점을 획득하는 것이 목표인 게임입니다.
    ※ 두더지를 잡을 때마다 게임점수 1을 획득하며, 놓칠 때마다 생명력 1을 잃습니다. 점수가 높아질수록 두더지들이 빠르게 사라집니다.
  • 학술동아리에서 Window API를 공부하고, 이를 적용해보자 만든 게임입니다.
    ※ https://goo.gl/cNTKwY (많은 부분을 해당 링크에서 참고했습니다)

분석

  • 화면 분리
    /
    ① 각 화면들의 이름을 열거형으로 구분하고, 클래스로 구현합니다.
    ex)
    enum Sequence { Title = 0, Start = 1, Help = 2, Gameover = 3 };
    namespace Scene { class Title { ... } }
    /
    ② 기본적으로 4가지의 함수를 가지고, 해당 화면에 필요한 객체들을 별도로 포함합니다.
    Initialize() : 해당 화면의 객체들을 동적할당하는 기능
    Release() : 해당 화면에 동적할당되었던 객체들을 해제하는 기능
    Update() : 사용자의 입력을 받는 기능
    Draw() : 화면을 출력하는 기능
    ex)
    namespace Scene { class Title { public: static Button* B1; static Button* B2; static Button* B3; static VOID Initialize(HWND hWnd); static VOID Release(VOID); static VOID Update(VOID); static VOID Draw(HDC hDC); }; }
    /
    ③ 각 화면들은 사전에 Initialize()를 통해 미리 생성되고, 초기화가 필요한 경우 Release()와 Initialize()를 순서대로 실행합니다.
    Scene::Start::Release(); Scene::Start::Initialize(hWnd);
    /
    ④ 현재 화면을 열거형으로 저장하고, 이를 통해 현재 화면에서만 입력과 출력을 수행합니다.
    ex)
    Sequence nSeq = Sequence::Title;
    switch(nSeq) { case Sequence::Title: ... break; ... }

  • 화면 출력
    /
    ① Window API는 메시지기반으로 동작하지만, 게임은 프레임기반으로 동작해야합니다. 따라서, 메시지가 없거나 메시지가 WM_PAINT인 경우에 출력을 하는 방식을 채용합니다.
    while(true) { if(PeekMessage(pMsg, nullptr, NULL, NULL, PM_REMOVE) && pMsg->message != WM_PAINT) { ... } else { hResult = OnPaint(hWnd); ... } }
    /
    ② 빠른 속도를 내기 위해 BYTE 배열로 화면을 편집합니다.
    BYTE* pMem = reinterpret_cast<BYTE*>(malloc(800 * 600 * 4));
    memset() 또는 memcpy()를 통해 pMem를 편집합니다.
    /
    ③ 화면 내 객체는 각자의 Draw() 함수를 사용합니다.
    ex)
    B1->Draw(hDC); B2->Draw(hDC); B3->Draw(hDC);

  • 입력 처리
    /
    ① 키보드 입력 처리 : WndProc 내에서 WM_KEYDOWN 메시지로 처리합니다.
    case WM_KEYDOWN: if(p_wParam == VK_ESCAPE) { ... } ... break;
    /
    ② 마우스 입력 처리 : 객체마다의 Update() 함수에서 처리합니다.
    해당 윈도우에 대한 클릭인지 검사 if((GetKeyState(VK_LBUTTON) & 0x8000) && (GetActiveWindow() == hWnd))
    새로운 입력인지 검사 if(!bClick && !bPrevClick)
    맞다면 새로운 입력에 대한 처리 진행, 아니라면 연이은 입력에 대한 처리 진행
    해당 윈도우에 대한 클릭이 없을 경우 if((GetKeyState()...)) { ... } else { [HERE] }
    이전에 클릭이 있었는지 검사 if(bClick) { ... }
    맞다면 클릭이 끝났을 때에 대한 처리 진행, 아니라면 bClick = FALSE; bPrevClick = FALSE; 실행 후 마침

이상으로 노트를 마칩니다.


'Project' 카테고리의 다른 글

#006 : Unlight Copycat [DAY #05]  (0) 2018.02.26
#005 : Unlight Copycat [DAY #04]  (0) 2018.02.25
#004 : Unlight Copycat [DAY #03]  (0) 2018.02.25
#003 : Unlight Copycat [DAY #02]  (0) 2018.02.23
#002 : Unlight Copycat [DAY #01]  (0) 2018.02.22
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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
글 보관함