탄막슈팅 시리즈 - 1
"슈팅 게임" 이라는 장르와 게임 컨텐츠 관점의 설명은 생략합니다.
보편적인 내용일 뿐더러 슈팅 게임을 접해본 사람이면 피부로 느낄 수 있는 내용을 앞으로도 큰 설명없이 생략합니다.
게임 개발 관점에서 필요한 내용 위주로 작성합니다.
"게임" 은 어떻게 구성될까요?
컴퓨터 프로그래밍에서는 하나의 목적을 가진 내용을 수행 ( function 과 같음 ) 을 하고 종료합니다.
다만, 긴 시간을 두고 유저 ( 클라이언트 ) 와 상호작용을 하는 프로그램도 존재합니다.
게임도 같은 맥락입니다. 게임 한판의 컨텐츠는 시작과 끝이 명확하지만 게임 프로그램 자체는 유저가 시작하고 종료하기 전까지 임의로 종료되지 않습니다.
그 말인 즉 프로그램은 종료되지 않고 끝나지 않는 루프 ( 반복 ) 을 가지게 됩니다.
여기서 우리는 GUI ( 그래픽 ) 환경의 게임을 다루기 때문에 일정 주기의 그림 ( render ) 를 반복해서 그려야 합니다.
보통 30 fps, 60 fps 라는 말은 frame per second, 1 초에 몇 번 화면이 갱신되냐는 말과 같습니다.
fps 를 지키기 위해서는 루프는 적어도 30 번, 60 번 반복되고 매 루프 마다 변경된 상태를 반영하는 화면은 갱신되어야 합니다.
위 내용까지 모두 합치면 하나의 루프안에서는 "변경 사항" ( 유저의 입력 / keyborad, mouse, joystick, 그리고 모든 object 의 update ) 가 이뤄지고, 이를 하나의 배경 ( 화면 ) 에 갱신해준 뒤 모니터 ( 또는 buffer ) 에 그려주는 작업을 진행합니다.
위 변경 사항에서는 ui, ux 적인 업데이트가 포함될 수도 네트워크 및 DB 의 갱신이 다른 job ( task, 멀티 쓰레드 ) 에서 이뤄질 수도 있습니다.
멀티 쓰레드 개념이 잠깐 등장했지만 보통 동시 접근을 정리하기 위해 게임 루프 ( thread ) 는 별도로 처리되고 언제 작업이 완료될 지 모르는 기타 작업 ( network, db, ui / ux ) 통신은 비동기로 처리하기 위해 또 다른 thread 로 진행 됩니다. 이렇게 job 을 분리하면 최소한의 갱신 주기 ( 30, 60 fps ) 를 지켜주는 루프는 지연을 최소한으로 받아 안정성을 얻을 수 있습니다.
당장은 "게임 루프" 안에서 처리되어야 할 내용만 다루겠습니다.
가장 기본이 될 골자는 아래와 같습니다.
game_loop {
update ();
render ();
}
javascript 에서는 interval api 가 존재하므로 timer 에 적절한 interval 을 입력하여 루프를 작성할 수 있습니다.
다만, 고정 fps 보다는 가변 fps 를 두고 희망하는 frame 값에 맞추어 지연을 처리하는 것이 좋을 것 같습니다.
주석. 과거 javascript 로 게임 framework 프로젝트 를 진행한 내용이 있으나.. 오랫동안 관리가 되지 않아 다시 작업을 진행합니다
과거에는 setInterval(0) 을 사용했네요. 이번에는 다른 방법이 뭐가 좋을까 parserjs 를 조금 찾아봤는데.. 더 좋은 loop 생성이 있다면 좋을 것 같네요.
아니면 timer 자체를 미리 만들어 두고 main timer 로부터 game 업데이트를 처리해도 괜찮을 듯 싶습니다.
class timer {
this.interval = 16 // 1 / 60
this.fn = fn // job
_invoke(fn) { ...fn(); }
register() {
timer_manager.register(this);
}
}
빠르게 넘어가서 buffering 개념도 나오는데 말 그대로
render buffer 에 내가 그리고 싶은 모든 내용을 그리고 이를 output buffer ( 보통 모니터에 바로 전달 되는 buffer ) 로 옮기는 작업을 말합니다.
buffer change 가 없다면 화면에 점진적으로 변경되는 어색함이 보일 수 있으니 그리고 싶은 내용을 다른 공간에 미리 그려서 한번에 바꾸는 내용입니다.
저희는 canvas ( HTML 5 ) 를 사용할 것이니 위 내용은 알아서 해결해 줄 겁니다.
간단한 game loop 구조를 만들고 "hello world!" 를 canvas 에 그려봅시다.