저자: 가레스 노이스, 역 전순재
컴퓨터 게임은 엄청난 산업이다. 10명에서 20명이 한 팀이 되어 문을 걸어 잠그고 1~2년 동안 철야 작업과 같은 열정적으로 작업을 하고서도 최종적으로 (여러분의 선택을 받아) 히트작이 되어야 겨우 세상의 빛을 본다. 이와 같은 개발에 드는 평균 예산은 수 만 달러에 이른다. 물론 이 비용은 마케팅 비용을 포함하기 전의 비용이다! 게임 개발과 관련된 위험과 비용을 고려해 볼 때, 오늘날 수 많은 게임들이 진화와 도태 사이에서 위험한 줄타기를 하고 있다는 것은 별로 놀란 만한 일이 아니다.
많은 경영주들이 개발 회사들을 통합정리하고 황금 수갑
[1]을 제공하면서 앞서가는 정보 제공업자(IP)들을 특정한 제조업자의 하드웨어로 독점적으로 모시고 있다. 게임 개발 산업에 대한 진입 장벽은 너무나 커서 그저 한 사람만으로는 컴퓨터 게임을 만들 수 없다.
그렇지만 여러 사람이라면?
도구들은 이미 나와 있다!
솔직히 이야기해서 상업적인 게임 산업에 진입하기 위한 장벽은 높다. 필자의 개인적인 생각으로도 너무 높다. 밥(Bob)과 조(Joe)가 다음에 히트할 플레이스테이션 2 타이틀을 만들어야 한다면 6개월 동안 각자의 침실에 앉아, 굉장한 아이디어를 창조해내기 위해 부지런히 일하려고 하지는 않을 것이다. 그렇다고 해서 그들이 할 수 있는 일이 겨우 선술집에 앉아 훌륭한 게임을 만드는 방법에 대해 토론하는 것 뿐이라는 것도 아니다. 밥(Bob)과 조(Joe)는 많은 이점들을 가지고 있다! 그들에게는 걱정해야 할 마감시간이나 제한이 없다. 훌륭한 아이디어가 있으며, 자유로운 시간이 있고, 아무것도 잃어버릴 것이 없다. 더욱 중요한 사실로 밥과 조에게는 자유 소프트웨어(free software)가 있으며 그들의 배움에 도움을 주기위해 기꺼이 지식을 나누어 줄 네트워트에 연결된 사람들이 있다는 것이다. 이 뿐만 아니라 청중들은 더욱 많은 게임을 요구한다. 비용이 얼마이든 상관없이 말이다. 초보 게임 개발자의 군수창고에는 강력한 무기들이 있다.
우리 같은 프로그래머, 예술가나 음악가는 1회 다운로드에 해당하는 비용만 들이면 상업적 등급의 도구를 사용할 수 있다. 이 도구는 우리 모두의 일상생활에 도움을 준다. 특히 밥과 조 같은 초보 개발자들에게는 더욱 도움을 준다. 그들은 바위처럼 견고한 운영 체제를 자유롭게 선택하고 개발할 수 있으며, 가장 산뜻하면서도 배우기 쉬운 프로그래밍 언어,
파이썬을 사용할 수 있다.
거인의 어깨위에 걸터 앉아서
언어 개발자들은 초보 프로그래머가 배우기 쉬우면서도 게임을 개발할 정도로 충분히 강력한 언어를 만들기 위해 수많은 시도를 해왔다. 블릿츠 베이직(
Blitz Basic)과 같은 언어들은 어느 정도는 성공적이라고 보여질 수도 있으나 이 모든 언어들은 여러 영역에서 실패한다.
- 언어들은 특정 OS에 묶여있거나, 더욱 나쁠 경우 특정 머신에 묶여있다.
- 그 언어 안에서 "게임"에 관련되지 않은 작업을 하는 것은 더욱 어렵다.
- 기본적인 실행흐름-제어 메커니즘을 넘어서서, 사용자들은 "실제 세계의" 프로그래밍 경험을 할 기회가 많지 않다.
파이게임(
Pygame)을 눌러보아라, 아직 깨야 할 판이 남아 있다.
"파이게임(Pygame)이 뭐야?"라는 웅얼거리는 소리가 들린다. 필자는 이 질문에 대해 기쁜 마음으로 대답해 주겠다.
파이게임(Pygame)이란 Simple DirectMedia Layer(
SDL)를 살짝 포장한 래퍼(wrapper)이다. 또한 윈도우, 리눅스, 맥 OS, 및 BSD (다른 운영체제들)에서 사용할 수 있는 플랫폼에 구애받지 않는 라이브러리로서 저수준 그래픽 프로그래밍 루틴에 접근할 수 있다. "DirectX"를 고려해 본다면 대충은 이해할 수 있을 것이다. 물론 SDL의 매력인 자유로우며, 비독점적이고, 아주 강력하다는 점은 빼고 말이다.
파이게임(Pygame)을 사용하면 SDL의 기능을 꺼내 쓸 수 있다. CD 디바이스, 키보드와 조이스틱, 팔레트의 섬세한 조절과 하드웨어-가속 그래픽 원자 명령들에 접근할 수 있다. 물론 "믹서(mixer)" 모듈에 접근하면, MP3에서부터 WAV 샘플까지 무엇이라도 연주할 수 있다. 파이게임(Pygame)은 컴퓨터 게임을 만들기 위해 필요한 모든 것을 담고 있다.
그러나 왜 Py인가?
"파이썬이 게임 개발을 할 수 있을 만큼 충분히 빠른가?"라는 질문에 의문을 품을 것이다. 내가 파이게임 프로젝트에 초기부터 관여하면서, 얼마나 파이게임이 빠를 수 있는지를 알게 되었을 때의 느낌은 놀라움 그 이상이었다. 물론, C는 아니지만 전혀 느리지 않다. 파이게임에 움터 오른 헌신적이고 활동적인 개발 공동체와 피트 쉬너스(Pete Shinners) 덕분에, 파이게임은 계속해서 진보할 것으로 예상된다. 공헌된 모듈로 성장하고 있는
라이브러리가 있어서 프로젝트에 포함시킬 수 있고, 문제를 가진 사람들을 기쁜 마음으로 도와줄 따뜻하고 우호적인 개발자 메일링 리스트도 있다. 물론 IRC 채널(#Pygame on irc.openprojects.net)도 있어 IRC 채널에 가면 "파이게임 프로젝트" 개발자의 대부분을 만날 수 있다. 답변 없이 지나가는 문제는 전혀 없어 보인다.
"실제" 개발을 처음으로 공격하기 시작하는 게임 개발자들은 방대한 아이디어 모음과 아이디어를 실현하는 방법과 관련된 몇몇 "단서들"로 무장하고 개발을 시작한다. 프로젝트 초기에 선택한 개발 언어의 복잡함에 사로잡힌다면 의욕이 상실될 것이다. 그리고 프로젝트를 땅에서 띄워 올리기 위해 방대한 "도구화 작업" 시간이 필요하다는 것을 깨닫게 되면 다시 의기소침해진다. 이 사람들이 원하는 것은 결과이다! 게다가 빨리 얻기를 원한다! 그래픽 아티스트는 자신이 만든 캐릭터 디자인이 배경과 잘 조화를 이루어 작동하는지 보기를 원한다. 사운드를 맡은 사람은 자신이 만든 음악이 적절히 "느껴지는지"를 알기를 원한다. 그리고 코드를 작성하는 사람은 특정 크기의 화면 주위에 계획된 개수만큼 객체(스프라이트)들을 바꾸기 위해 정확하게 얼마나 많은 화면이 갱신되는지(초당 프레임의 개수) 알기 원한다.
파이썬과 파이게임의 매력 덕택에 개발자들은 C와 같은 "저 수준" 언어에 딸려 오는 하찮은 허드렛일들에서 벗어날 수 있다. 여러분은 "메모리에 관하여 걱정할 필요가 없고, 컴파일 주기, 등등 같은 것은 전혀 없다"는 주장이 무엇을 의미하는지 이미 다 알고있을 것이다. 그러나 그 차이는 컴퓨터 게임의 영역을 고려해 볼 때 진짜로 확연히 드러난다. 파이썬 구문의 기초는 몇 일이면 이해할 수 있고, 파이게임의 핵심 기능도 몇 일만 더 공부하면 알 수 있다. 초보 게임 프로그래머라고 할지라도 충분히 일주일 안으로 작은 테스트 애플리케이션 하나를 완성하여 실행할 수 있다. 믿지 못하겠는가? 그렇다면 잠깐 이것부터 살펴 보자.
스프라이트(움직일 수 있는 이미지)를 적재하는 간단한 작업틀 하나를 작성하고, 화면을 설정한 후 그 스프라이트를 화면에 비트 블록으로 전송할 것이다 (또는 복사 ? 이 용어는 "bit block transfer"으로부터 파생됨)
# 간단한 파이게임 예제...
# SDL을 초기화하라, 이미지를 출력하라...
# 파일이름을 처리하기 위해...
import os
# 파이게임 모듈 그 자체를 위해...
import pygame
# 이미지 처리를 위해...
import pygame.image
# 파이게임에 대한 중요한 상수 정의,
# 이 예제에서는: "이중 버퍼" 화면을
# 설정하는데 사용된다...
from pygame.locals import *
# 다음으로부터 이미지를 가져오라: ./images/sprite1.gif
sprite_file = os.path.join("images", "sprite1.gif")
# 화면을 열고, 적재된 이미지를 화면에 그려라
# -- ESC를 점검하라; 만약 눌리면, 종료하라...
#
def main():
# SDL 환경을 초기화하라
pygame.init()
# 640x480 화면을 설정하라...
screen = pygame.display.set_mode((640,480), HWSURFACE|DOUBLEBUF)
# 화면과 똑같은 크기의 "표면(surface)"을 만들어라...
background = pygame.Surface(screen.get_size())
# 이 배경 표면을 흰 색으로 만들어라
# (note: R,G,B tuple):
background.fill((255,255,255))
# 스프라이트를 적재하라:
sprite = pygame.image.load(sprite_file)
# 스프라이트의 초기 위치를 획득하라,
sprite_position = sprite.get_rect()
# 그 위치를 화면 정중앙에 설정하라...
sprite_position.bottom = (480 / 2)
sprite_position.left = (640 / 2) - 100
# 이제 배경과 스프라이트를 화면에
# "비트블록 전송하라(blit)"...
screen.blit(background, (0,0))
screen.blit(sprite, sprite_position)
# 이제 우리가 비트블록 전송한
# 화면 버퍼를 표시하라...
pygame.display.flip()
# ESC 또는 "창 닫기(Close Window)" 위젯이 눌려질 때까지
# 창을 열어 놓고
# 무한 회돌이를 계속하라...
while 1:
# 발생하는 모든 "사건들(Events)"을 획득하라.
pygame.event.pump()
# 키보드 입력을 점검하라...
keyinput = pygame.key.get_pressed()
# ESC 또는 "QUIT" 사건이 발생하면, 종료하라...
if keyinput[K_ESCAPE] or pygame.event.peek(QUIT):
break
# 다음과 같이 CLI(명령어 라인 인터프리터)으로부터 직접 실행할 수 있다...
if __name__ == "__main__":
main()
"Hello World" 같은 단어조차 포함하지 않는 아주 간단한 애플리케이션이다! 타이핑 해넣는 수고를 덜려면 이
예제들을 다운로드 받아라. 실행하면, 예제 코드는 아래와 같은 화면을 보여준다.
먼저 화면을 가로로 640 픽셀 세로로 480 픽셀만큼 설정한다. 또 (가능하다면) 하드웨어 가속과 "이중 버퍼" 화면출력을 선택한다. (더블 버퍼링(Double Buffering)으로 여러분은 가상 화면을 그릴 수 있다. 가상화면은 숨어 있다가 화면을 전환하던가 "살짝 뒤집으면" 나타난다.)
다음으로 표면을 만든다(표면을 이해하려면 그 위에 그림을 그릴 수 있는 투명 플라스틱 조각으로 생각하라.). 표면 크기는 화면 크기와 똑같다. 그리고 이 표면을 흰색으로 채운다 ? 이 표면은 배경처럼 작동할 것이다.
이제 스프라이트를 적재한다.
get_rect() 메소드를 사용하여, 스프라이트의 현재 매개 변수들을 열람한다. 이렇게 하여
bottom과
left 속성을 통하여 스프라이트의 위치를 설정할 수 있다. (다른 유용한 것들 역시 설정할 수 있다!). 이 속성들은 정수 값으로 설정할 수 있다 - 또는 기존의 값들을 동적인 변경자
[3]들을 위한 기초로 사용할 수 있다.
스프라이트의 위치가 설정되면 (이 예제에서는 화면의 정중앙에 설정된다), 우리는 배경과 스프라이트를 화면 버퍼에 비트블록 전송한다.
pygame.display.flip()를 사용하면, 숨겨진 버퍼를 볼 수 있다.
위의 예제는 상당히 간단하다. 그러나 이것을 확장하여 스프라이트를 화면주위로 쉽게 이동시킬 수 있다. 우리가 이미 가지고 있는 무한 루프(loop)는 탈출(Escape) 키가 눌려지는지를 점검한다. 만약 이것을 확장하여 커서 키들을 점검한다면, 스프라이트의 위치를 적절하게 변경할 수 있으며 새로운 위치에 표시할 수도 있다. 아래와 같이 말이다.
while 1:
# 발생하는 모든 "사건들(Events)"을 획득하라.
pygame.event.pump()
# 키보드 입력을 점검하라...
keyinput = pygame.key.get_pressed()
# 만약 ESC 또는 "QUIT" 사건이 발생하면, 종료하라...
if keyinput[K_ESCAPE] or pygame.event.peek(QUIT):
break
# 오케이, ESC키가 눌려지지 않았으므로, 커서 키를 점검하라...
if keyinput[K_RIGHT]:
sprite_position.left = sprite_position.left + 4
if keyinput[K_LEFT]:
sprite_position.left = sprite_position.left - 4
if keyinput[K_UP]:
sprite_position.bottom = sprite_position.bottom - 4
if keyinput[K_DOWN]:
sprite_position.bottom = sprite_position.bottom + 4
# 위치에 변화가 있으면,
# 새로운 위치에 모든 것을 다시 그려라...
screen.blit(background, (0,0))
screen.blit(sprite, sprite_position)
pygame.display.flip()
만세! 스프라이트가 움직인다!
여기서 선보인 예제가 복잡해 보이는가? 보시다시피 파이게임(Pygame)은 복잡한 작업들을 우아하게 처리한다.
더욱 더 흥미진진한 사실! 파이썬 자체에는 표현 방법이 수 없이 많다. 게임에 네트워크 기능이 필요한가? 이것도 문제 없다!
>>> import socket
게임에서 사용자 매개변수들에 대하여 XML 환경설정 파일을 사용하고 싶은가? 물론 이것도 할 수 있다.
>>> import xml
밥과 조는 파이썬의 능력를 최대한으로 사용하고 표준 모듈들을 마음대로 사용하였다. 그리고 그 파워 덕분으로 전통적인 독점적 형태의 개발의 필요성 또는 컴퓨터 게임에 일반적으로 관련된 관습적 개발의 필요성이 제거되었다.
게다가, 파이썬은 분산 게임을 위한 훌륭한 플랫폼을 제공한다. 초기의 울티마 온라인 2(Ultima Online 2) 개발에서 볼 수 있듯이 말이다. 또한 파이썬이 제공하는 수단으로 플레이어들은 게임을 입맛에 맞출("mod") 수 있다, 이것은 Doom이 히트한 이래로 유행하여 온 것이다. 게임을 입맛에 맞추는 기능은 최근 "절단, 어둠의 칼(
Severance, Blade of Darkness)"에서 철저하게 채택되었다. 이 게임의 특색은 파이썬 인터프리터를 자체에 내장한 것이다!
파이썬과 파이게임으로 개발자들은 아이디어에 집중할 수 있다. 여러분은 신속하게 메일을 통해 논의한 바를 코드로 만들 수 있다. 코드는 아주 조금의 변경을 거치거나 전혀 변경을 거치지 않고 최종 배포본이 될 수도 있다. (약간만 생각해 보고 평범한 소프트웨어 공학적 관행을 따르기만 한다면) 갱신 또는 수정을 하는 작업은 별거 아니다. 파이썬은 초보자가 다른 사람들의 코드에서부터 쉽게 배울 수 있는 언어이지만, 반면에 극도로 달성하기 어려운 아이디어를 구현하기에 충분할 만큼 강력한 언어이기도 하다. 파이썬과 파이게임(Pygame) 그리고 SDL을 결합하면 진짜 플랫폼에 구애받지 않는 개발 능력을 가진다는 것은 말할 필요도 없다 - 현대 게임 산업의 성배(Holy Grail)
[2]를 실질적으로 가질 수 있다.
여러분이 또 요구할 만한 것은 무엇인가?
무한한 삶
일주일 내에 개발할 수 있는 간단한 예제 게임 뿐만 아니라 수 년간의 작업 후에도 여전히 개발을 해야 하는 방대한 프로젝트들이 있다. 파이게임은 그들 모두와 함께 성장해 왔다. 그리고 계속해서 새로운 기능들을 추가하면서 개발자들의 삶을 편하게 해주고 새롭고 흥미로운 특징들이 추가될 것으로 기대된다. 파이썬으로 하는 게임 개발은 쉬우면서도 유연하다.
극소수의 상업적 개발자들만이 위험을 무릅쓰고 혁명적인 타이틀들을 시장에 내놓을 수 있기 때문에 아마도 지금이 몸소 게임 개발을 고려해 볼 적기가 아닐까 한다. 그들의 감시망 아래로 은밀하게 침입해 들어가기에 지금처럼 쉬운 적은 없었다.
가레스 노이스(Gareth Noyce)는 낮에는 XML 아키텍트로 일하고 밤에는 자유 소프트웨어 프로젝트를 위해 독립적으로 활동하는 그래픽 아티스트이다.
[1] golden handcuffs : 실제로 처분할 수 없는 스톡옵션. 인재를 묶어두기 위한 방편으로 수갑이 풀려야만 부자가 될 수 있음
[2] Monty Python and the Holy Grail : 엑스칼리버를 받아 브리튼의 왕이 된 아서 왕이 원탁의 기사들과 성배를 찾아나선다는 내용의 1975년작 코미디 영화
[3] dynamic modifier : 동적으로 메소드를 정의하거나 실행하는 코드