티스토리 뷰
Project Note #002
Unlight Copycat DAY #01
개요
Window API
의 일종인pclaf
를 활용해 게임을 만드는 과정을 정리합니다.- 참고
※ https://github.com/BaeMinCheon/unlight-copycat (Github, "v0.1.0" 커밋)
환경
- Visual Studio 2015 Professional
- Windows 10 Home
- pclaf (C/C++)
Window API
를 활용해 어떤 게임을 만들어볼까 생각을 하던 도중, 최근에 서비스 종료를 한 Unlight
가 떠올랐습니다. 일관성 있는 디자인과 단순한 조작감으로 즐겨 했던 웹게임이었습니다(어떤 게임인지 궁금하신 분은 아래의 영상을 참고해주세요). 이 게임을 따라 만들어보는 것도 재미있을 것 같아 시작하게 되었습니다.
그리고 최근 접하게 된 pclaf
라는 Window API
라이브러리를 사용해보면서 굉장히 편리하다고 느껴, 본 프로젝트에 적용하게 되었습니다. 난해하고 복잡한 Window API
를 적당히 추상화시켜 정리한 것이 마음에 드는 라이브러리입니다. 또한 Visual Studio는 제한되는 기능에 걸리는 일이 종종 있어 기존 Community 에디션에서 Professional 에디션으로 변경했습니다(교내인증소프트웨어로 지원을 받았습니다).
그럼 본격적으로 시작해보겠습니다. 무엇부터 만들어야할지 생각해봅시다. 우선 pclaf
라이브러리는 Application
이라는 클래스를 지원하는데, 해당 클래스를 상속받으면 기본적인 윈도우의 속성을 갖춘 클래스를 얻게 됩니다. 메시지 루프, 프로시저 등의 복잡하고 반복되는 코드들에 대해서는 건너뛸 수 있습니다. 본 프로젝트에서는 GameWindow
라는 클래스를 만들어 사용하겠습니다(소스코드는 본문에 작성하기에는 비효율적이므로, Github을 참고해주세요).
pclaf
에서의 윈도우 생성
Application
을 상속받는 클래스 작성
※ 최소한 생성자는 구현해야 합니다.- 해당 클래스의 객체를
int mainLAF()
내에서 생성
※ 본 함수는 프로그램의 시작점입니다. - 해당 객체의
run()
을 호출
위의 과정은 GameWindow.h
와 GameWindow.cpp
에서 참고할 수 있습니다. 단순히 생성자만 구현해도, 적어도 빈 화면이 출력되는 윈도우를 만들 수 있습니다. 윈도우를 만드는 일은 벌써 끝냈군요. 그럼 다음으로 해야할 일을 생각해봅시다.
Unlight
는 메뉴가 없는 게임이 아니었습니다. 메인 화면에서 여러 가지 버튼을 눌러 해당 메뉴로 들어가 서로 다른 출력을 보고 작업을 수행할 수 있었습니다. 즉, 게임 내부의 시퀀스를 나눌 필요가 있습니다. 게임의 상태를 하나만 정의하고 그 안에 욱여넣는 것보다는 의미있게 분할하는 것이 만들기도 관리하기도 더 편하겠죠 ?
Sequence
라는 클래스를 만듭니다. 다형성을 살리기 위해, 모든 시퀀스들을 이 클래스의 자식 클래스로 작성하고 이 클래스의 포인터로 접근하는 것이 좋겠네요. 지금은 그리기와 마우스 입력에 대한 함수들만 작성합니다(draw()
leftClick()
doubleClick()
rightClick()
). 그리고 Sequence
를 상속받는 Main
Quest
Battle
클래스도 작성해줍니다.
위의 과정은 Sequence.h
와 Sequence.cpp
에서 참고할 수 있습니다. 그럼 이번에는 방금 만든 시퀀스들을 간단하게 변환시켜봅니다. 추후에는 버튼을 만들어서 시퀀스 변환을 구현하겠지만, 지금은 마우스 입력으로 처리해봅시다. 시퀀스 클래스들을 저장할 vector
를 GameWindow
의 정적 멤버변수로 작성하고, Sequence
클래스의 leftClick()
에서 시퀀스를 가리키는 인덱스값(sequenceIndex
)에 변화를 주는 내용을 작성합니다. 그리고 자식 클래스의 leftClick()
에서 부모 클래스인 Sequence
의 leftClick()
을 호출합시다(자식 시퀀스 클래스의 leftClick()
에 각각 정의하는 것이 정석이겠지만, 지금 작성하는 내용은 동일하기 때문에 굳이 그럴 필요는 없습니다).
pclaf
에서의 마우스 입력
mouseDown()
: 마우스 왼쪽 클릭이 입력되면 호출mouseMDown()
: 마우스 중간 클릭이 입력되면 호출
※ 휠 버튼 입력을 말합니다.mouseRDown()
: 마우스 오른쪽 클릭이 입력되면 호출doubleClick()
: 마우스 왼쪽에 대한 더블 클릭이 입력되면 호출
그럼 이제 각 시퀀스의 leftClick()
이 실행되면 시퀀스들을 담는 sequenceVector
의 인덱스값이 변경됩니다. 각 시퀀스의 leftClick()
을 호출하기 위해, Application
을 상속받은 GameWindow
의 mouseDown()
에 각 시퀀스의 leftClick()
을 호출하는 내용을 작성합니다. 이렇게 하면 마우스 왼쪽 클릭이 입력될 때마다 GameWindow
의 mouseDown()
이 호출되고 내부에서 각 시퀀스의 leftClick()
이 호출될 것입니다.
pclaf
에서의 화면 출력
Update()
: 기존 화면을 남긴 상태에서,paint()
를 호출clearAndUpdate()
: 기존 화면을 지우고(하얀 바탕으로 만들고),paint()
를 호출paint()
: 윈도우 생성 직후 및 위의 함수들이 사용되었을 때 호출
그러고 보니 별도의 출력을 하지않으면 시퀀스가 바뀌는 줄 모르겠군요. 지금은 간단하게 구분만 하기 위해 문구를 출력해봅시다. 각 시퀀스의 draw()
에 출력할 내용을 wout()
과 setpos()
을 이용해 작성합니다. 그 다음 GameWindow
의 paint()
에서 각 시퀀스의 draw()
를 호출하는 코드를 작성합니다.
pclaf
에서의 문자(열) 출력
wout()
:Application
을 상속받은 클래스의 객체에서 멤버함수로 사용가능setpos()
:wout()
으로 출력될 위치를 지정[윈도우객체].wout() << setpos(x, y) << TEXT("...");
의 구조로 사용
이제 paint()
가 호출될 때마다 각 시퀀스의 draw()
가 호출되어 구분할 수 있겠군요. 실제로 실행해보면 마우스를 클릭할 때마다 문구가 바뀌는 것을 확인할 수 있습니다. 이로써 시퀀스를 나누고 각 시퀀스마다의 입출력을 따로하는 구조를 완성했습니다. 이 다음으로는 버튼을 만드는 과정을 진행해보겠습니다. 이상으로 DAY #01
노트를 마칩니다.
'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 |
#001 : Mole Catch (0) | 2018.01.28 |
- Total
- Today
- Yesterday
- PopeTV
- csharp
- pclaf
- NOX
- Docker
- unreal
- cuDNN
- lib
- unity
- Anaconda
- ATOM
- visualstudio
- Python
- Game
- CUDA
- A.I.
- tensorflow
- shader
- git
- dll
- C/C++
- WindowAPI
- CAFFE
- Slack
- windows
- Hashtable
- JIT
- visual-studio
- DirectX
- vscode
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |