HTML5 게임 엔진 - OK캐쉬백 게임이벤트 개발 사례

Post on 30-Nov-2014

1.168 views 10 download

description

 

Transcript of HTML5 게임 엔진 - OK캐쉬백 게임이벤트 개발 사례

HTML5 게임 엔진OK캐쉬백 게임이벤트 개발 사례

SK플래닛 김준기

HTML5

왜 HTML5 게임인가?• 게임은 플랫폼 확보가 최우선

• PlayStation / XBOX / Nintendo…

• 웹 브라우저가 깔려있지 않은 기기는 더 이상 없다

• 자연스럽게 모바일로 확산

• One Source Multi Use

• N-screen

• 개발 생산성 향상

HTML5 Features for Game• Graphics

• Canvas

• WebGL

• SVG

• Audio / Video

• <audio> / AudioContext

• <video>

• ETC

• FullScreen API

• Pointer Lock API

정말? 그냥 과시용이 아니고?

HTML5 게임의 한계

• 애초에 브라우저는 게임 플랫폼이 아니다.

• 입력장치

• 복잡한 연산에 특화되지 않은 환경

• 메모리 관리

• 사용자의 하드웨어의 사양에 무관한 게임?

그래도 합니다. 되는데 까지 해볼랍니다.

웹에 적합한 게임?

• 플레이타임 1~5분 이내

• 원버튼 캐주얼

• 특정 서비스, 제품 홍보를 위한 요소를 통합시킨 Branded 게임

https://github.com/cykod/AlienInvasion

• 코드

• ~450 LOC engine.js (12kb)

• ~300 LOC game.js (8kb)

• 이미지

• sprites.png (63kb)

HTML5 게임엔진의 필요기능

• 그래픽 제어

• Animation 재생

• Resource Loader

• BGM / 효과음 재생

• 사용자 입력 제어

HTML5 게임 엔진

• pㅔ

HTML5 게임 엔진

• pㅔ

cocos2d

• cocos2d for iphone

• http://www.cocos2d-iphone.org/

• cocos2d-x

• http://www.cocos2d-x.org/

cocos2d-html5

• cocos2d-html5 2.2.2 (2014. 1. 7)

• cocos2d-js 3.0a (2014. 3. 15)

• cocos2d-html5

• cocos2d-x javascript binding

cocos2d-html5

• cocos2d-html5 2.2.2 (2014. 1. 7)

• Cocos2d-html5-v2.2.2.min.js (1.2mb, minified)

• 웹 방식의 deploy 방식에는 부적합 (특히 모바일)

필요한 기능만 만들어 써보자!

HTML5 게임엔진의 필요기능

• 그래픽 제어

• Animation 재생

• Resource Loader

• BGM / 효과음 재생

• 사용자 입력 제어

HTML5 게임엔진의 필요기능

• 그래픽 제어 > Canvas 2D 그래픽

• Animation 재생 > Sprite Animation

• Resource Loader > <img> / <audio> / XHR

• BGM / 효과음 재생 > <audio> / AudioContext

• 사용자 입력 제어 > Touch event 처리

Canvas 제어

• Raster 이미지, Immediate mode

• 그려낼 객체의 관리가 핵심

• Canvas Drawing 성능이 웹 게임 성능의 키

• requestAnimationFrame을 이용한 Renderer 작성

Renderer

Renderer

Renderer

Scene / Board / Entity• Entity

• 화면에 표시될 최소 단위 객체

• 주로 스프라이트 애니메이션이나 static 이미지, 혹은 canvas.context로 그려냄

• Board

• Entity들을 리스트로 가지는 레이어

• Scene

• 게임내 장면전환을 위해 Board들의 단위로 장면을 구성

cocos2d의 장면/레이어 컨셉

Scene / Board / Entity

Sprite Animation

• Entity와 Sprite Animation의 맵핑

• 지정된 시간에 정의된 속성에 따라 애니메이션 재생

8 프레임 프레임당 24px x 22px

Static Object Pool

• JavaScript의 Garbage Collection중에 브라우저는 다른 어떤 동작도 할 수 없음

• Canvas에 그려낼 객체 중 반복해서 생성/삭제 되는 객체(Entity, Board)를 GC의 대상이 되지 않도록 Static Object Pool로 관리

Canvas Dimension• 단말별 화면의 CSS 크기가 다름

• 게임 디자인 해상도와 화면 해상도간의 변환로직 필요

• canvas.width / height

• 화면의 크기에 맞게 canvas내부의 모든 entitiy의 width / height 좌표들을 조절

• canvas.style.width / height

• 단순하게 canvas.style 크기만 변경

canvas.width320 px

!360 px!

320 px

canvas.width 360 pxcanvas.width

320 px

canvas.width 360 pxcanvas.width

320 px

Entity의 위치, 크기를 배율 1.125(360/320)로 변환해야함

canvas.style.width 360 pxcanvas.style.width

320 px

canvas.style.width 360 pxcanvas.style.width

320 px

Entity의 위치, 크기 변환 필요 없음

충돌 감지 방법• 바운딩 박스 (collision box)

• 하나의 바운딩 박스로만 감지

• 여러개의 박스로 맵을 만들어 순회하여 감지

• 다각형 (Polygon 내부의 점)

• 미리 다각형의 맵을 작성해두고 폴리곤 내부의 점인지 판단가능

• Pixel Perfect Collision Detection

• 화면에 보이지 않는 canvas에 두 객체를 그려보고 달라진 픽셀이 있는지 순회하여 검사 (성능 이슈)

Frame Skip

• 60 FPS를 그려내지 못하는 단말에서는 16~7ms 내에 renderer loop가 돌아오지 않음.

• Frame Skip or Slow Animation?

Frame Skip시 문제점

• 저사양 단말에서 비행기가 총알을 뚫고 지나가는 현상

• Interpolation 혹은 다른 보정 로직 필요

HiDPI 지원

• 일명 레티나 디스플레이

• CSS 해상도와 물리적인 해상도가 상이

• devicePixelRatio

• canvas.context.backingStorePixelRatio

320 px 320 px

CSS 크기

640 px 480 px

실제 단말 해상도 css 해상도 * devicePixelRatio(backingStoreRatio)

devicePixelRatio

2devicePixelRatio

1.5

!canvas.width

640 px!!

canvas.style.width 320 px

적용할 canvas와 canvas.style의 크기

!canvas.width

480 px !!

canvas.style.width 320 px

!canvas.width

640 px!!

canvas.style.width 320 px

적용할 canvas와 canvas.style의 크기

!canvas.width

480 px !!

canvas.style.width 320 px

(320 * 1.5이상) px 기준으로 제작한 이미지를 사용해야 효과

디자인 해상도 설정 문제• 지원할 최고 해상도로 게임을 디자인

• 1080 x 1350

• 720 x 900 (x 2/3)

• 360 x 450 (x 1/3)

• 지원할 최저 해상도로 게임을 디자인

• 360 x 450

• 720 x 900 (x 2)

• 1080 x 1350 (x 3)

객체의 크기가 45 x 45 인 경우(최고 해상도 기준)

• 지원할 최고 해상도로 게임을 디자인

• 45 x 45

• 30 x 30 (x 2/3)

• 15 x 15 (x 1/3)

• 지원할 최저 해상도로 게임을 디자인

• 15 x 15

• 30 x 30 (x 2)

• 45 x 45 (x 3)

객체의 크기가 50 x 50 인 경우(최고 해상도 기준)

• 지원할 최고 해상도로 게임을 디자인

• 50 x 50

• 33 x 33 (x 2/3)

• 17 x 17 (x 1/3)

• 지원할 최저 해상도로 게임을 디자인

• 17 x 17

• 34 x 34 (x 2)

• 51 x 51 (x 3)

디자인 해상도 Best Practice• 지원할 최고 해상도로 게임을 디자인

• 가로기준 720px 설정

• 이미지는 360px, 720px 기준 총 2벌 구성

• 가로기준 1080px 설정

• 이미지는 360px, 720px, 1080px 기준 총 3벌 구성

• 360px 배수인 이유는 국내 안드로이드 단말 이용자수가 가장 많기 때문

갤노트류 400px갤S2이상, 옵G 및 기타 360px

CSS 가로너비

아이폰 320px (갤S 320px)

CSS 가로너비

viewport 설정

• stretch to fit (종횡비 변경)

• 가로기준 늘이기 (상하 손실가능)

• 세로기준 늘이기 (상하 손실가능)

?

터치 좌표 계산

• 개발시 지정한 디자인 해상도를 기준으로 Canvas 크기조정값, viewport 설정값등을 토대로 계산

• 터치 좌표에 가상의 1x1 박스를 만들고 충돌하는 Entity를 탐색

Resource Loader• 게임중 끊김현상을 방지하려면 필요한 리소스들을 미리 로딩해두어야함

• image

• <img> 태그 이용

• <img> 태그의 src지정. onload 이벤트 사용

• sound

• <audio> 태그 이용 (주로 배경음악)

• <audio> 태그의 src지정. oncanplay / oncanplaythough 이벤트 사용

• AudioContext 이용 (주로 효과음)

• XHR을 이용

Sound 재생• <audio>

• 리소스 로딩이 완료되지 않아도 바로 재생가능

• 동시에 2개의 <audio> 재생불가

• AudioContext

• XHR arraybuffer 타입으로 로딩

• 로딩 완료후에 재생가능

• 여러 효과음 동시재생 가능

• 지원 커버리지가 넓지 않음 (현재 iOS 6+만 제대로 지원)

iOS의 audio 재생 정책

• 사용자의 액션(터치나 클릭) 없이는 어떤 소리도 재생되지 않음

• 심지어 <audio>는 src를 지정해도 로딩조차 하지 않음.

iOS의 audio 재생 정책

• 사용자의 액션(터치나 클릭) 없이는 어떤 소리도 재생되지 않음

• 심지어 <audio>는 src를 지정해도 로딩조차 하지 않음.

시작버튼을 만들어 lock을 해제시켜주어야함

iOS의 audio 재생 정책

• 사용자의 액션(터치나 클릭) 없이는 어떤 소리도 재생되지 않음

• 심지어 <audio>는 src를 지정해도 로딩조차 하지 않음.

시작버튼을 만들어 lock을 해제시켜주어야함

iOS에서는 AudioContext만 사용해서 preloading

디폴트 브라우저 문제

• 단말별 디폴트 브라우저의 특수기능

• iOS 좌우 스와이핑시 네비게이션 이동

• 멀티 터치시 확대/축소

디폴트 브라우저 문제

• 단말별 디폴트 브라우저의 특수기능

• iOS 좌우 스와이핑시 네비게이션 이동

• 멀티 터치시 확대/축소

WebView나 <iframe>으로 Wrapping 해야만 해결 가능

스펙 커버리지 문제• HTML5 스펙 지원범위 차이

• Feature Detection 불가

• 예: 특정단말 브라우저에서 webkitAudioContext가 정의되어있으나 스펙이 제대로 구현되어있지 않음

스펙 커버리지 문제• HTML5 스펙 지원범위 차이

• Feature Detection 불가

• 예: 특정단말 브라우저에서 webkitAudioContext가 정의되어있으나 스펙이 제대로 구현되어있지 않음 결국 User Agent Sniffing 해야함.

Canvas Drawing 성능문제• 안드로이드 2.x

• Custom Webview의 지원사격 필요

• ex) PhoneGap FastCanvas

• OK캐쉬팡에는 planet.webview 사내 라이브러리지원으로 canvas 성능향상 + 안드로이드 sound적용

Canvas Drawing 성능문제

• 안드로이드 4.4 kitkat webview

• 단순히 drawRect만 해도 30fps 이하의 성능

Canvas Drawing 성능문제

• 안드로이드 4.4 kitkat webview

• 단순히 drawRect만 해도 30fps 이하의 성능

어떻하죠… ㅠㅠ

http://skpla.net/cashpang2

앞으로의 계획• Canvas Drawing을 최적화

• 현재는 이전프레임과 비교하여 변경사항이 있을때만 drawing

• 영역별로 비교하여 dirty area만 다시 그리도록 개선

• 다양한 게임에 적용하여 엔진 개선

• 오픈소스화 (시기 미정)

참고자료• OK캐쉬백 앱용 HTML5 게임 개발기 (https://readme.skplanet.com/?p=7243)

• http://html5gameengine.com/

• cocos2d Basic Concepts (http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:basic_concepts)

• Static Memory Javascript with Object Pools (http://www.html5rocks.com/ko/tutorials/speed/static-mem-pools/)

• High DPI Canvas (http://www.html5rocks.com/en/tutorials/canvas/hidpi/?redirect_from_locale=ko)

• Playing Sounds with the Web Audio API (https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/PlayingandSynthesizingSounds/PlayingandSynthesizingSounds.html#//apple_ref/doc/uid/TP40009523-CH6-SW1)

• Improving HTML5 Canvas Performance (http://www.html5rocks.com/en/tutorials/canvas/performance/)

고맙습니다 :)