OK캐쉬백 앱용 HTML5 게임 개발기

HTML5 게임

HTML5의 다양한 새로운 기술들은 웹 브라우저에서 할 수 있는 작업을 더욱 폭넓게 만들어 주고 있습니다. 그 중에서도 그래픽 처리를 위한 Canvas API나 WebGL, SVG 등이 지원되기 시작하면서, 웹에서 이미지나 애니메이션을 표현할 수 있는 방법이 더욱 다양해졌으며, 특히 고속으로 렌더링되는 Canvas와 함께 Audio, Video 태그 그리고 Fullscreen API등을 조합하여 기존에는 구현하기 어려웠던 게임조차 어떠한 플러그인 하나 없이 PC뿐만 아니라 모바일 브라우저에서 즐길 수 있는 시대가 열리게 되었습니다.

이렇게 브라우저상에서 순수 웹 표준만으로 게임을 구현할 수 있다는 점은 생각보다 큰 파급력을 가집니다. 우선 진정한 의미의 n-screen 게임 플랫폼을 갖게 됩니다. 이미 그렇기도 하지만, 스크린이 장착된 대부분의 장치들에는 웹 브라우저가 포함되어 있고, 이는 곧 모든 화면에서 게임을 실행할 수 있다는 의미가 됩니다. 또한 게임을 장치에 다운로드 받아 설치를 할 필요가 없습니다. 불편한 설치 과정과 빈번한 업데이트 과정없이 간단하게 브라우저를 열고 접속만하면 되는 거죠. 개발자의 입장에서도 OS별로 다른 코드로 작성할 필요 없이 하나의 코드로 모든 플랫폼에 모두 배포할 수 있게 됩니다.

이러한 막강한 장점에도 불구하고 HTML5 게임은 여전히 장밋빛 희망만 남겨준 채 크게 성장하지 못하고 있습니다. 그 이유는 여러 가지가 있겠지만 Native 게임엔진에 비해 속도가 매우 느리고, 3D나 화려한 그래픽을 처리하기에 훨씬 비효율적이며 다양한 버전의 브라우저 환경을 모두 지원하기에는 실질적으로 구현시 고려해야 할 사항이 너무나도 많기 때문입니다. 그나마 PC에서는 월등한 HW성능으로 다양한 HTML5 게임들이 Chrome과 Firefox 브라우저를 대상으로 출시되고 있지만, 모바일에서는 PC 대비 큰 성능의 제약으로 n-screen의 장점을 극대화 할 수 있는 상품화 출시 사례가 전무합니다. 그렇지만 Web기술개발팀에서는 HTML5 게임의 모바일 단말에서의 가능성을 제대로 실험하고 증명하고자 OK캐쉬백 앱에 Embedding된 형태로 Android 2.3 및 iOS 6.0 이상을 동시에 지원하는 게임을 개발하고 성공적으로 상품화 출시하였습니다.

HTML5 게임을 어떻게 제공할까?

과제의 기획 단계부터 모바일 단말용 HTML5 게임은 현재 모바일 브라우저 및 WebView의 성능을 고려하여 1~5분 정도의 짧은 시간 동안 즐길 수 있는 어렵지 않고 단순한 캐주얼 게임의 형태가 적합하며 Branded game 즉, 당사 서비스나 제품의 Branding를 위한 요소들을 게임 내에 통합하여 제공하는 형태로 제공하는 것이 개발부터 상품화까지 가능하리라고 생각하였습니다. 따라서 독자적인 게임앱 개발보다는 이식성이 높은 특징을 이용해 다른 앱 내에 WebView를 통해서 임베딩시키자는 아이디어를 도출하였고 이를 구체화하여 OK캐쉬백 앱 내에서 실행하여 사용자에게 재미와 리워드를 제공함과 동시에 OK캐쉬백의 UV 제고도 함께 도모할 수 있는 게임 이벤트를 기획하였습니다.

OK캐쉬백 게임이벤트는 OK캐쉬백 모바일 앱 내에서 하나의 이벤트 피드의 링크를 따라 웹 게임 이벤트를 노출을고 이에 연결된 WebView 컨테이너내에서 게임을 구동하는 방식입니다. 앱의 커스텀스킴(Custom Scheme)을 통해 모바일 브라우저에서 직접 접근할 수 있는 방법도 제공합니다.

Branded Game은 어떤 장르로 개발할 것인가?

게임 이벤트를 개발하는 데는 몇 가지 고려해야 할 사항이 있었습니다. 우선 어떤 게임을 개발할지를 정해야 했습니다. 조작이 단순하면서 재미도 있고 사용자간의 경쟁심리를 유발할 수 있는 요소, 그리고 참여자에게 포인트를 부여하기 위하여 점수를 통한 순위 구분이 가능해야 했습니다. 1차 이벤트로 횡 스크롤 비행 슈팅게임이 선정되었습니다. 어린 시절 쌈짓돈을 모아 동네 오락실에서 한 번쯤 해보았을 법한 ‘갤러그’와 유사한 게임을 제공하기로 결정한 것이죠. 참여자들의 점수를 정렬하여 순위를 보여주고 고득점자에게 OK캐쉬백을 적립해주는 형태였습니다.

그림 1. OK캐쉬백 게임이벤트 (추억의 게임)

어떻게 개발할 것인가?

HTML5 게임 개발에는 아래와 같은 핵심 모듈들이 필요합니다.

  • 2D 그래픽 : 비트맵그래픽처리를 위해 Canvas API를 통해 게임 내 요소들을 그립니다.
  • 애니메이션 : 요소들의 속성을 시간의 흐름에 따라 변경하여 움직임을 표현합니다. Sprite Map 이미지를 재생시키기도 합니다.
  • 요소 관리 : 화면 내 배치될 요소들의 그룹핑하고 속성들을 관리합니다. 장면과 레벨에 대한 관리도 필요합니다.
  • 물리 엔진 : 요소들에 물리적 속성을 부여합니다.
  • 사운드 : 배경음악, 효과음을 재생합니다.
  • 입력 처리 : 사용자입력을 받아들여 게임 내 요소와 상호작용합니다.
  • 렌더러 : 요소들을 실행 환경에 맞게 주기적으로 화면에 그려냅니다.

requestAnimationFrame

Canvas기반의 HTML5 게임엔진의 핵심 로직을 요약하면 다음과 같습니다. 화면에 렌더링이 가능할 때마다 호출되는 requestAnimationFrame을 통해 각 요소들의 위치나 크기 같은 속성들을 계산하고 한 프레임씩 화면에 그려내는 것입니다.

var start = Date.now();

function render() {
	var now = Date.now();
	step(now - start); //시간에 따른 요소들의 속성들을 계산
	clearCanvas(); //Canvas를 지움
	drawCanvas(now - start); //계산에 따른 결과를 Canvas에 그려냄
	requestAnimationFrame(render); //애니메이션 프레임 재요청
}

render();

코드 1. requestAnimationFrame을 이용한 게임 렌더링

requestAnimationFrame은 컴퓨팅 성능이 충분하다면 16.6666ms(60fps) 마다 불리어지고 그렇지 않으면 가능한 가장 가까운 시간에 호출됩니다. requestAnimationFrame의 자세한 내용은 다음의 링크를 참고하시기 바랍니다.

충돌 감지

슈팅 게임을 만들기 위해서 가장 중요한 로직은 게임 내 요소간의 충돌을 감지하는 로직입니다. 각 요소는 사각형으로서 x, y좌표와 함께 너비와 높이 값을 가집니다. 두 개의 서로 다른 요소(o1, o2)가 충돌했는지는 다음과 같이 이 4가지 속성을 통해 확인할 수 있습니다.

function collision(o1, o2) {
    return (o1.x <= o2.x + o2.width && o1.y <= o2.y + o2.height &&
            o2.x <= o1.x + o1.width && o2.y <= o1.y + o1.height);
}

코드 2. 충돌 감지를 위한 collision 함수

하지만 실제 요소는 항상 직사각형의 형태가 아니기 때문에 충돌 감지시 정확도 문제가 생깁니다. 사각형이 아닌 형태의 적기와 총알이 충돌했는지를 세밀하게 판단하기 위해서 각 요소 별로 충돌 맵(Collision map)을 만들었습니다. 앞서 언급한 기본 충돌 함수를 통해 외곽의 충돌여부를 판단하고, 이를 통과했을 때는 충돌 맵을 순회하면서 요소의 형태에 맵핑된 박스에 충돌 했을 때에만 실제 충돌로 처리하였습니다.

그림 2. 충돌 맵 예제

저사양 단말에서의 Frame Skip

동일한 게임으로 다수의 사용자가 고득점을 경쟁하는 게임 방식인데, 모바일 단말의 성능에 따라 난이도가 달라진다면 사용자간 형평성에 어긋나는 설계라고 생각하였습니다. 따라서 렌더링 성능과 관계없이 프레임 레이트만 가변적으로 적용하고 처리속도가 느린 환경에서는 렌더링 과정을 자동 생략하도록 개발하였습니다. 성능이 낮은 단말에서는 화면이 약간 끊겨 보이지만 전체적인 게임 진행시간 및 기본적인 난이도는 최대한 동일하게 구성할 수 있었습니다.

한 가지 고려해야 했던 점은 생략되는 프레임으로 인해 충돌 감지 또한 생략된다는 것이었습니다. 예를 들면 날아오는 총알을 맞아야 되는 타이밍인데 마치 순간이동을 하듯이 뚫고 지나가는 버그가 발생하였습니다. 이러한 문제는 총알의 이동속도, 비행기의 최대 이동속도 등을 모바일 단말 상에서 조정하여서 해결할 수 있었습니다.

GC(Garbage Collection)을 최소화하기 위한 객체 풀(Object Pool)

자바스크립트는 GC에 의해 유휴 메모리를 관리합니다. 게임 내 요소들은 자바스크립트의 객체로 관리되며 각각의 라이프사이클에 따라 생성되고 삭제됩니다. 더 이상 참조되지 않거나 삭제된 객체에 대한 메모리는 언제 수행될지 모르는 GC에 의해 다시 가용 메모리로 전환되며 이 과정 동안 자바스크립트 엔진은 어떠한 다른 작업도 수행하지 못하여 게임의 렌더링이 일시 정지됩니다. 객체들의 라이프사이클 변화가 많은 게임에서는 이런 GC가 빈번하게 발생하여 일시적인 멈춤 현상을 일으킬 수 있습니다. 따라서 객체 풀을 만들어 두고 할당된 객체를 재사용하여 이런 현상을 최소화하였습니다.

오픈소스 HTML5 게임엔진

이러한 일련의 공통기능 혹은 재사용 가능한 코드를 게임 별로 일일이 개발하기는 상당히 복잡하고 비효율적입니다. 온라인 상에는 이런 필요를 충족시키기 위한 다양한 오픈 소스 HTML5 게임 엔진들이 있습니다.

그 중에서도 iOS용 네이티브 게임 엔진에서 시작한 cocos2d의 변형인 cocos2d-html가 사용자도 많고 커뮤니티도 활성화 되어있어 사용을 검토해 보았지만, 모바일 단말에서 사용하기에는 기능이 너무나 많고 용량이 1.2MB 정도로 너무 커서 특히 Android 2.3을 포함한 저사양 단말에 사용하기에는 적합하지 않았습니다. 또한 다른 게임 엔진들은 대부분 모바일 브라우저의 성능 최적화 측면에서 부족하고 사용자층이 없어 검증되지 않았거나 특정 게임장르, 예를 들면 슈퍼마리오 게임처럼 캐릭터를 맵 내에서 조작하고 점프하며 이동하는 플랫폼 게임(Platform game)에만 특화된 것도 있었습니다. 이렇게 많은 게임 엔진이 있는데도 계속해서 새로운 게임 엔진들이 만들어 지고 있다는 점 또한 기존 엔진들에 대한 의구심을 갖게 하는 요인이 되기도 하였습니다.

그림 3. 플랫폼 게임의 예) 슈퍼 마리오, 출처 : (http://en.wikipedia.org/wiki/File:Super_Mario_Bros_1985.png)

pwge (Planet web game engine)

우리가 추구하는 Branded 캐쥬얼 게임에 적합한 범용적이고 모바일 단말에서 충분한 성능의 확보가 가능한 엔진의 필요로 고민 끝에 자체 게임 엔진인 pwge(planet web game engine)을 개발하게 되었습니다.

타 HTML5 Canvas 게임 엔진 대비 pwge의 특징은 다음과 같습니다.

      • 모듈 기반 (AMD 모듈)
        • RequireJs를 이용한 모듈 구성
        • 공통 모듈을 제외한 추가모듈은 plug-in 방식으로 제공
      • 작은 용량 (압축시 32KB)
      • 모바일 브라우저에 특화
        • 저사양단말 지원 : Android 2.3이상. iOS 6이상
        • planet.webview 연동으로 Audio 지원 확장(예정) 및 저사양 단말의 성능향상
      • 렌더링 성능 최적화
        • 이전 프레임과 동일한 화면의 렌더링을 생략
      • JavaScript 기반의 verbose한 코딩스타일 강조
      • key/value 기반의 요소관리
      • 간단한 sprite와 animation 적용
      • 다해상도 지원 : 레티나를 포함한 3단계 해상도 지원
      • 여러 종의 템플릿 게임(기본 뼈대가 되는 게임 장르)을 토대로 쉬운 변형이 가능
        • 플랫폼 게임
        • 레이싱 게임
        • 퍼즐 게임
        • 캐논 슈팅 게임(예: 앵그리 버드)
        • 기타 등등

 게임 엔진의 성능은 요소들을 관리하고 페인팅을 얼마나 효율적으로 하는지에 따라 결정된다고 해도 과언이 아닙니다. Canvas를 지우거나 요소를 그려내는 페인팅 속도가  화면 해상도에 비례해서 증가하며 단말에 따라 천차만별이기 때문에 렌더링 성능을 최적화하는데 가장 중점을 두어 개발하고 있습니다. 현재는 이전 프레임과 비교해서 변경된 요소가 있을 경우에만 화면에 그려내도록 처리하였고, 추후에는 변경된 요소에 해당하는 최소영역만 다시 그려내도록 더욱 최적화 할 예정입니다.


planet.webview

저사양 단말의 WebView에서 Canvas엘리먼트의 페인팅속도를 향상시키기 위해서 Mobile S/W개발팀에서 개발한 planet.webview도 함께 적용하였습니다. Android WebView에서 제공하는 Canvas 엔진의 느린 렌더링 대신 Android의 OpenGL 렌더링을 이용해 성능을 한층 끌어올릴 수 있었고, 아직은 지원하지 않는 안드로이드 WebView의 사운드 지원을 위해 추후 planet.webview를 통해 게임 내 사운드 재생도 Web Audio를 통하여 지원할 예정입니다.

pwge로 개발한 OK캐쉬팡

OK캐쉬백 1, 2차 추억의 게임 이벤트에 이어서 pwge을 이용해 개발한 OK캐쉬팡 게임이벤트가  2014년 2월 20일부터 3월 20일까지 진행 중입니다. 모두에게 친근한 매칭 퍼즐게임이니 아직 해보지 않으신 분들은 OK캐쉬팡 게임 한번씩 참여해보시고 OK캐쉬백 10,000 포인트의 주인공에 도전하시기 바랍니다.

그림 4. OK캐쉬팡 이벤트

(모바일 브라우저에서 http://skpla.net/ocbgame3로 접속하세요)

맺음말

HTML5 게임에는 분명한 장단점이 존재합니다. 여전히 게임 플랫폼으로써의 브라우저는 무척이나 매력적인 타겟이 아닐까 생각합니다. 때문에 주요 브라우저들도 관련 기술의 최적화에 힘을 쏟고 있고 결국에는 그 입지를 다지게 될 것이라 믿습니다. 앞으로 계속해서 OK캐쉬백 앱 내 임베딩되는 형식의 게임을 확산 적용할 예정이며, 장기적으로는 pwge 게임 엔진의 오픈 소스화와 독립 게임서비스도 검토하고 있습니다. 관심을 갖고 지켜봐 주시면 고맙겠습니다.

참고자료

김준기 Web기술개발팀

JavaScript와 Front-end 기술에 관심이 많은 초보아빠 개발자입니다.

Facebook 

공유하기

  • ryu11

    안녕하세요~ 웹UI개발을 하고있는 종사자인데 항상 디자이너가 제공해준 psd 로 웹사이트만 만들다가
    취미로 html5 게임을 만들어보고 싶다는 생각이 들어 댓글을 남겨봅니다.
    혹시 추천해주실만한 국내 도서가 있을가요? 초보라 책피고 만들어야 할거 같아서 문의 드려봅니다^^
    스킬은 html5 /css3/ jquery 정도인데 게임개발이 가능할지도 궁금합니다.