게임프로그래머가 되기위해 3 본문

Programming/프로그래밍 일반

게임프로그래머가 되기위해 3

쩡호 2017. 4. 13. 12:46

3. 재사용과 유지보수를 위한 "C++"
 
C언어를 넘어서 C++로 가기 위한 워밍업
 
C 언어이후에 배워야할 언어는 무엇이냐고 묻는다면 C++이라고 많은 사람들이 그럴것이다.
 
우선 다른 방법론을 소개 하고자 한다. 윈도우 프로그래밍은 현재 게임을 만들려면 거의 반드시 배워야 하는것이니, Win32 API를 먼저 공부해도 좋다. 이유는 차차 넘어가면서 설명해보자.
 
C언어로 자신이 Linked List - Inser, Delete 포함 - 한 구조를 함수화 시켜서 잘짰다면, C++로 넘어와도 좋다. 물론 C++로 넘어오기 전에 Visual C++ 디버거도 부담없이 사용할수 있어야 한다.
 
현재까지 짜왔던 프로그래밍은 절차적 프로그래밍이였다. 여기서 말하는 '절차적' 의 의미를 곰곰히 생각해보자.
 
C에서 C++로 (혹은 절차지향에서 객체지향으로)
 
C언어와 C++의 차이는 겉모양으론 없다. 실제로 C++언어를 쓰더라도, C언어에서 기본적으로 지원해주는 모든 함수들을 전혀 문제 없이 쓸수 있다.
 
그러나 근본적으로 다른 언어가 이 두가지 언어일것이다. 이것은 패러다임의 문제이다.
 
C언어는 순수하게 절차지향적인 언어이다. 작동하는 함수와 변수는 따로 존재하며, 일정한 함수들이 하나씩 Process를 해서 결과를 도출해가는 방식이다.
 
즉, 하나의 문제를 볼때 해결을 하는 루틴과 그것을 가지고 있는 데이터가 따로 존재하는구조이다.
 
C++은 객체 지향적 언어이다. 클래스라는 오브젝트를 중심으로 진행되어지는 프로그래밍을 뜻한다.
 
클래스란 무엇이냐? 라는 질문에 간단하게 답하면 은닉성, 상속성, 다형성을 가진 함수+변수의 묶음 이라고 표현 할 수 있다.
 
이런 클래스들의 집합으로 문제를 해결하려는 프로그래밍 방식식을 객체지향프로그래밍이라고 한다.
 
이런 내용들은 책에서 정확하게 이해 할수 있을것이다.
 
 
그렇다면 우리는 왜 객체지향(OOP)를 해야 하는것인가?
 
OOP의 목적은 재사용, 유지보수의 수월함일것이다. 절차 지향 방식 역시 여러 사람이 같이 작업할수 있지만, 객체 지향방식에서는 좀더 수월하기떄문이기도 하다.
 
지금 단순하게 이런 이야기를들으면 이해하기 힘들다. 코드의 재사용과 유지보수라는것은 직접 프로그래밍을 많이 해보지 않고서는 쉽게 느끼기 힘들다.
 
그런데, 잠깐 다른이이기를 해보자. 이 글을 읽고있는 당신은 프로그래밍이 뭐라고 생각하는가?
 
갑자기 철학적인 주재라고 생각하지만 당연히 프로그래밍은 컴퓨터 프로그램을 만드는 것이다.
 
컴퓨터 프로그램은 무엇인가? 컴퓨터 프로그램은 조금 단순하게 말하면 우리가 손으로 하는것을 컴퓨터를 이용해서 하려고 하는 도구다.
 
그러니까 다른 이야기로 하면 프로그래밍이라는것은 우리가 일상생활에서 사용하는 것들을 컴퓨터에 구현해 내려는것이다.
 
그렇기에 일상생활과 비슷하면 비슷할수록 좋다.
 
간단하게 생각하면 절차적 프로그램이 가장 합리적인 프로그램이라고 생각할수도 있다. 우리의 행동은 지극히 절차적이다.
 
간단한 예를 들어보자, 우리가 회사에서 돈 결제를 받으려고 한다. 약간 큰회사라면 경리과가 당연히 있을것이고, 당신은 서류를 준비한후, 경리과에 가서 결제를 받는다.
 
자 얼마나 절차적인가? 그러나 조금더 생각해보면  단순하게 절차적이다. 라고 설명하기에는 무리인 구석이있다.
 
'경리과' 라는 존재이다. 경리과에서는 분명 그 서류를 가지고 지지고 볶고 해서 이 결제 서류가 정확한지, 또 결제를 해줘야 하는것인지에 대해서 판단한다. 경리과에서 일어나는 일은 당신은 전혀 모르지만 결제가 가능하다.
 
또 생각해보면 단순한 서류라고 해도 그것을 쓰려면 종이와 컴퓨터, 워드프로세서, 프린터 등이 필요하지 않은가?
 
궁극적인 부분까지 간다면 모든일은 반드시 절차적일수 밖에 없지만 사람은 그 절차적임을 알지 않고 일을한다.
 
OOP는 이와 같다. 즉 일상생활에 더 가까운 프로그래밍 방법론이라는 것이다. 그렇기때문에 많은 부분에서 강력한 힘을 발휘한다.
 
너무 막연하다고 생각이 들면 어떤 부분에서 강력한지 예를 들어보자. 이런식에 Object로 나누어서 작업을 하는 우리 일상생활에서 만약 회사가 생겼을때 경리과를 만들었는데 이것이 너무 오래된 방식이고 부패 했다면, 회사의 오너는 경리과에 대한 인사나 시스템의 수정으로 그것을 수정 할 수 있다.(유지보수)
 
이 회사가 다른 작은 회사를 인수했다. 이 인수한 회사는 다른부분은 볼것이 없는데 마케팅 팀만든 현재 있는 마케팅팀보다 훨씬더 파워풀 하다면 약간의 시스템적 수정을 거쳐 바로 그 회사에서 사용할수 있다.(재사용)
 
물론 약간 무리가 될수 있는 인용이지만 '그냥 그렇다' 정도로 받아드리자.(한마디로.. 딴지 걸지 말자!)
 
 
 
그렇다면 어떻게 해야 이런 강력한 힘을 발휘할수 있을까?
 
OOP란 크게 추상화, 다형성, 은닉화, 상속성을 가지고 있다. 최대한 추상화된, 최대한 다형성에 맞게 최대한 은닉화 시켜서, 적절하게 상속해서. 이런 것을 지키면 된다.
 
물론 위에 내용들은 책에 아주 자세하게 나와있다. 그러나 강좌 밑에 예전에 써놨던 간단한 예들을 추가하도록하겠다.
 
 
 
무엇을 가지고 연습하면 좋을까?
 
우선 처음에 OOP를 맞닥드리면 참 난감하다. 한가지 방법을 소개하자면 위에 말한것 처럼 윈도우 프로그래밍을 했다면 간단한 테트리스 같은 게임을 만들어보자. "무조건 Class" 로 OOP답지 않아도 좋다. Class를 써보는거다.
 
윈도우 프로그래밍을 공부하지 않았다면 작은 프로그램을 OOP화 시켜보자. 무조건!(잘 못해도 좋다.)
 
프로그램을 완성시킨후 그것에대한 냉정한 평가를 내려보자. 과연 이 Class 하나 하나가 독립적인지, 재사용할수 있을지, 새로운 기능을 추가시키기 좋은지. 천재가 아닌이상 분명 위에 말한것중 거의 지켜지지 않을것이다. 그렇다면 또 다른 프로그램을 선택한후 짜보자.
 
이런 과정을 반복하면서 스타크래프트같은 유명게임은 어떻게 만들어졌을가 곰곰히 생각해보면 좋다.
 
이런 과정을 반복하게되면 최소한의 OOP는 가능해지게된다.
 
 
 
무언가 좋은 예 없을까?
 
그렇지만 확실히 저런일을 하고 있다보면 답답할것이다. 좋은 예를 보고 싶다는 생각도 할것이고.. 이때 매우 좋은 예가 있는데, 그건 바로 MFC다.
 
MFC가 뭔지 모르면 찾아봐라-_-; MFC는 나름대로 잘되어있는 객체 지향 구조를 가지고 있다. MFC는 처음에 배우기 난감하지만 배우고 나면 굉장히 쓸만하다.(이걸 라이브러리라고 해야 할지 프레임워크라고 해야할지-_-; )
 
특히 처음에 Operater Overloding 등을 어떻게 사용하는지 정확하게 알기 위해서 CString 클래스를 분석해보면 좋다.
 
또 은닉화가 어떻게 이루어지면 좋은지에 대해선 CArray나 CList 등을 분석해보면 좋다.
 
다형성은 전체적인 MFC 구조를 분석해보면 꽤 좋은 성과를 낼수 있다.
 
MFC를 공부하는데는 하나 하나 분석해볼필요 없이, 그냥 따라해보기 좋은 책을 선택한다음 기능 별로 차근 차근 따라해보자. 그후 전체적인 구조를 익히면 그만이다.
 
물론 MFC는 안해도 좋다. 일종의 추천이다.
 
 
이 글을 쓰는 나도 객체지향 프로그래밍을 잘하느냐고 묻는다면 단호히 잘 못한다고 말한다. 객체지향에는 정답은 없다. 위에 말한 객체지향의 요건들을 더욱더 극대화 시켜야할것이냐에 대한 고민을 계속한다.
 
그런 계속된 고민이야 말로 OOP의 '정도(正道)'이다.
 
다음은 가장 많이 쓰이는 게임 개발 SDK "DirectX" 이다.
 
---------------------------------------------------------------------------------------
 
OOP의 기본 계념들.
 
1. 추상화(Abstraction)
추상화란 자세한 사항은 무시하고 본질적인 특징에 집중하는것이다. 예를 들어 우리가 '컴퓨터'라는 단어를 들었을때 우리는 컴퓨터 프로세스가 무슨일을 어떻게 하는지 보단 컴퓨터를 가지고 할 수 있는일들을 떠올리고 또 하려고 한다. 또한 조지 부시라는 이름을 들었을때 우리는 그 자체를 생각하는 떠올리는 것이 아니라 원숭이 같은 외모나 무식쟁이나 악의 축이나 이런것들을 떠올려서 기억하는 것과 같은 것이다.
컴퓨터 언어에서는 약간 여러 과정을 거쳐서 추상화를 하는데 그것은 다음 강좌에 자세히 쓰도록 하겠다.

2. 은닉화(Encapsulation)
은닉화란 관련된 정보를 관련된 함수가 하나의 단위로 묶어서 처리하는 것을 말한다. 이때 데이터들은 외부에 들어나지 않는다. 우리는 흔히 은닉화를 설명할때 회사 경리 시스템으로 설명한다. 
"당신은 회사에 어떤 결제를 해야 한다. 그 결제를 하려고 당신은 경리과에가서 그에 맞는 서류를 쓰고 제출한다. 그럼 경리과에서는 알아서 처리 하게 된다. 당신은 경리과의 데이터를 알 필요도 알 수도 없다."
생각해보면 실생활에 있는 모든 데이터는 어떤 연산에 의해서 노출 된다. 우리가 누군가의 이름을 알려고 해도 우리는 그의 이름이 적힌 무언가를 보거나(See라는 연산) 혹은 그에게 물어봐야 한다.(Talk라는 연산) 그러면 그에 대한 결과로 우리는 그의 이름을 알 수 있는것이다. (참고로 연산은 여기서 함수라고 할 수 있다.)

3. 상속성(Hierarchy)
은닉화 하나가지곤 어떤 오브젝트(정보와 함수의 단위)를 설명하는데 부족함이 있다. 오브젝트들은 다른 오브젝트들과 어떤 연관을 맺고 있는데, 그중 서로가 서로를 참조하는 관계(함수를 부를수 있는 관계)뿐만아니라 조금 다른 관계도 있는데 그것이 바로 상속이다.

사람은 포유류이다. 포유류는 생명체이다. 사람은 포유류의 특성을 가지고 있고, 포유류는 생명체의 특성을 가지고 있다. 이것은 독립적으로 가지고 있다기보다는 '상속' 받은 것이다. 모든 포유류가 숨을 쉬듯 사람도 숨을쉬고, 모든 생명체가 세포로 이루어 져있듯 사람도 세포로 이루어 져있다. 어떤 오브젝트의 특성을 그대로 받아오는것이다.

4. 다형성(Polymorphism)
다형성의 원래 의미는 하나 의미의 띠는것이라고 한다. OOP에서 의미는 같은 메세지에 달느 행동을 하는것이다. 자 여기서도 실생활에 예를 들어보자. 사회화를 거친 사람은 대부분 글을쓴다. 헌대 같은 사람이 글을써도 어떤사람은 잘쓰고 어떤 사람은 잘 못쓴다. 또 어떤 사람은 빨리 쓰고 어떤사람은 늦게 쓴다. 같은 사람이고 글을 쓴다는 동일한 행동이라고 명명할수 있지만 각각의 사람들은 전혀 다른 방식으로 행동을 한다.
Comments