제 2 장 게임개발을위한첫걸음 이장의주요내용게임의규칙과체계결정하기게임스테이지정의하기기본적인 HTML 작성하기첫번째자바스크립트모듈구현하기웹폰트를이용한스플래시화면구성하기
20 1 부 HTML5 시작하기 제1장에서학습했던 HTML5에대한배경및기술적인지식을토대로이제는본격적인게임개발을시작해보자. 그러나코드를작성하는것보다더욱중요한것은먼저이프로젝트를이해하는것이다. 이번장의첫번째파트에서는우리가구현할게임의규칙과목적, 그리고각종체계에대해설명한다. 또한게임의주요스테이지들을정의하고게임을구성할화면의각영역들을설계한다. 게임에필요한내용들이명확하게정리되면비로소코드의작성을시작한다. 기본적으로게임을지원하기위한간단한구조를가진 HTML 페이지를구성한다. 그런후우선적으로필요한 CSS 코드를작성하고 Modernizr 라이브러리를이용하여자바스크립트파일을로드하는방법을보여줄것이다. 또한두개의자바스크립트모듈을구현할것인데, 하나는게임의스테이지를변환하는매우간단한프레임워크이며다른하나는 DOM 객체조작을손쉽게하는모듈이다. 마지막으로게임의첫번째스테이지를구현하며, 웹폰트를이용하여예쁘장한로고가표시되는스플래시 (splash) 화면을구성할것이다. HTML 게임의이해 이책을통해구현할게임은세개의블록을일치시켜없애는퍼즐게임으로, PopCap 게임즈가개발한캐주얼게임인비주얼드 (Bejeweled) 덕분에유명해진형식의게임이다. 필자는이게임의제목을주얼워리어 (JewelWarrior) 라고정했지만, 더괜찮은제목이있다면여러분이직접다른제목을붙여도무방하다. 실제로게임을구현하기에앞서게임의구성요소와절차에대해소개하고자한다. 이게임의핵심체계와규칙은무엇이며, 각스테이지의차이점은무엇일까? 게임을처음시작할때부터종료할때까지사용자들은서로다른스테이지를보게될것이다. 우선은게임의체계부터살펴보고주요스테이지와메뉴및로딩화면같은나머지컴포넌트들은차후에살펴보도록하자. 블록맞바꾸기 이게임의핵심은 8x8 크기의격자에서로다른보석모양과색상을가진블록을채우고이것들을돌려서같은모양과색상을가진블록을모으는것이다. 게임이시작
제 2 장게임개발을위한첫걸음 21 되면 64개의격자는임의의보석블록으로채워진다. 게임의목적은세개이상의동일한보석블록을모아서점수를쌓아가는것이다. 플레이어는하나의보석블록을선택한뒤인접한다른보석블록을선택함으로써보석들의위치를맞바꿀수있다. 세개의블록맞추기 보석블록을맞바꾸는것은반드시세개이상의동일한색상을가진보석블록이일치되었을때만유효하다. 만일보석블록을맞바꾸었지만인접한보석블록중같은색상을가진보석블록이세개가되지않는다면원래상태로되돌아간다. 플레이어가보석블록을맞바꾸어인접한보석블록의색상이일치하게되면그보석블록들은화면에서사라진다. 보석블록들이사라지면서생긴공간은위쪽에위치한보석블록들이내려와채워지며, 그렇게해서생긴상단의빈공간에는새로운임의의보석블록들이채워진다. 가장간단한것은특정보석블록을세개모으는것이지만, 네개혹은다섯개의보석블록이모아질수도있다. 한행이나한열에동일한보석블록을많이모을수록더많은점수를얻을수있다. 연속적으로일치되는보석블록들이생겨난다면추가점수를얻을수있다. 보석블록을세개이상모아보석블록이없어진후위쪽에있던보석블록들이내려오면서계속해서동일한보석블록들이모아질수있으며, 이런경우점수는배가된다. 게임보드를유심히살펴보면의도적으로이러한연속동작을발생시켜더많은점수를얻을수있을것이다. 게임이진행되는동안플레이어는더이상움직일보석블록이없는상황에맞닥뜨릴수있다. 최소한세개의일치하는보석블록을더이상만들수없는경우에는게임보드를다시구성해야한다. 이경우현재게임보드의모든보석블록이제거되고처음게임을시작할때와동일한방법으로임의의보석블록들을채우게된다. 게임레벨의증가 게임의긴박감을더하기위해천천히카운트다운하는타이머를게임에적용할예정이다. 이타이머가 0이되면게임은끝나게된다. 플레이어는타이머가종료되기전까지일정수준의점수를획득하면다음스테이지로이동하게된다. 다음스테이지로이동하면게임보드가다시그려지고, 타이머가초기화되며, 다음레벨의스테이지로이동
22 1 부 HTML5 시작하기 하기위해필요한점수가더높아진다. 이렇게되면플레이어는점점바빠지겠지만숙련된플레이어는계속해서게임을플레이할수있다. 시간이지나면서게임이점점어려워지도록하기위해각레벨사이의점수간격은플레이어가스테이지를이동할때마다증가한다. 결국아무리뛰어난플레이어도할당된시간내에필요한점수를채우기가어려워질것이다. HTML 게임스테이지정의하기 각각의게임스테이지는점점더복잡해져서플레이어가더많은시간을할애하게된다. 그러나플레이어의흥미를돋구기위해몇가지추가스테이지를구성하는것이좋다. 스플래시화면 플레이어가가장먼저보게되는화면은스플래시화면이다. 이화면을제공하는목적은두가지이다. 첫째로, 이화면은게임의로고를화면에보임으로써플레이어에게게임을소개하는역할을한다. 둘째로, 진행막대를추가하여게임의실행이어느정도준비되어가는지플레이어가쉽게알수있도록해준다. 게임을구성하는모든항목들이미리로드될필요는없지만, 스테이지가활성화된후다음스테이지에필요한그래픽요소들이미리준비되어로드된다면플레이어에게더좋은인상을줄수있다. 그림 2-1은스플래시화면의모습을그려본것이다. 주메뉴 플레이어가스플래시화면을클릭하면주메뉴를보게된다. 주메뉴는필요한몇가지메뉴로만간단하게구성한다. 가장중요한것은이메뉴를통해실제게임을시작하는것은물론최고점수를보여주거나게임에대한상세한정보를제공하거나혹은게임을종료할수있는기능들을제공하게된다. 만일플레이어가새게임이나이전게임이어하기를선택하면게임은곧바로시작된다. 온라인을이용한멀티플레이어게임의경우는다른플레이어를만나서게임을준비하는로비 (lobby) 가필요하기때문에게임시작을위한몇가지단계가더필요하다. 이에대한자세한내용은제11장에서온라인플레이를위한옵션을구현할때설명하도록한다. 그림 2-2는주메뉴를그려본것이다.
제 2 장게임개발을위한첫걸음 23 그림 2-1 스플래시화면을그려본모습 그림 2-2 주메뉴의모습 게임플레이하기 실제로게임이시작되면게임보드와플레이어이름, 현재점수등게임을구성하는요소들이화면의대부분을차지하게되지만, 플레이어입장에서는주메뉴로돌아갈수있는기능이필요하다. 이를위해게임화면의일부를상태막대나도구막대를만들수있도록남겨두었다. 그림 2-3은게임화면을그려본것이다. 그림 2-3 게임이실행중인화면의모습
24 1 부 HTML5 시작하기 최고점수목록 게임이종료되면애플리케이션은최고점수와플레이어의이름을나열하는화면으로전환된다. 플레이어가최고점수를달성하게되면이름을묻는화면이나타나며, 플레이어가이름을입력하면현재점수가목록에추가된다. 이게임은최고점수목록을저장하기위해웹저장소를활용한다. 그림 2-4는최고점수목록화면을그려본것이다. 그림 2-4 최고점수목록화면의모습 HTML 애플리케이션의뼈대구현하기 이게임을구현하기위해서는특별한도구나애플리케이션이필요하지않다. 제13장에서웹소켓에대해알아볼때는웹서버에 Node.js 프레임워크를설치할필요가있을뿐이다. 그러나그외에는여러분에게익숙한텍스트편집기와이미지편집기만있으면된다. 많은웹개발자들은 jquery나 Prototype과같은라이브러리를이용하므로 DOM 요소를선택하거나조작하는것같은웹개발의사소한부분들은문제가되지않을것이다. 간혹이런라이브러리들이그다지필요하지않은기능들을포함하고있을수있다. 따라서정말 50~100KB 용량의라이브러리가필요한지, 아니면그보다작고간단한무엇이필요한지스스로판단해야한다. 필자는가능한라이브러리를사용하지않을예정이지만, 필요에따라매우작지만유용한라이브러리들은활용할것이다. 이미브라우저의기능이지원되는지여부에
제 2 장게임개발을위한첫걸음 25 따라자바스크립트파일을동적으로로드하는 Modernizr 라이브러리에대해언급한바가있다. 어쨌든이책에서는여러분이문서객체모델 (DOM, Document Object Model) 을다루는방법에대해서는이미충분히알고있다는것을가정한다. DOM 객체를처리하는코드를최소화하기위해 jquery나 Prototype처럼강력하며빠르게동작하는 CSS 스타일의 DOM 객체탐색엔진인 Sizzle을이용한다. Sizzle을이용하면 DOM 객체를매우편리하게다룰수있다. 예를들어, ID 특성값이 #gameboard 인 div 요소에서 class 특성에 jewel이라는값이지정된모든요소를선택하려면다음과같이코드를작성하면된다. var jewels = Sizzle("div#gameboard.jewel"); jquery나 Prototype과같은라이브러리를사용해본경험이있다면 CSS 선택자를이용하여 DOM 객체를선택하는방법에매우익숙할것이다. http://microjs.com/ 웹사이트를살펴보면웹개발의특정영역에초점을맞춘작은크기의다양한라이브러리들을찾아볼수있다. Modernizr와 Sizzle 라이브러리는모두 MIT와 BSD 오픈소스라이선스가적용되어있으므로거의제한없이여러분의게임프로젝트에서자유롭게활용할수있다. 이두라이브러리는이번장의내용에필요한기능들을포함하고있으며, http://www. modernizr.com/ 과 http://sizzlejs.com/ 웹사이트에서최신버전을다운로드할수있다. 자, 이제시작할시간이다. 게임프로젝트를위한빈폴더를생성하고그아래에 scripts와 styles라는이름의하위폴더를각각생성하자. 향후에몇개의폴더를더추가하게되겠지만지금당장은이두개의폴더로충분하다. 이제 scripts 폴더에 modernizr.js와 sizzle.js 파일을추가하자. 이두파일은예제로부터복사해도되며, 최신버전을다운로드했다면압축을해제하여해당폴더에복사하면된다.
26 1 부 HTML5 시작하기 HTML 구성하기 이게임의기초는보통의 HTML 문서이다. 프로젝트폴더에새파일을생성하고파일이름을 index.html로지정하자. 예제 2.1은 index.html 파일에작성할기초코드를보여준다. 예제 2.1 빈 HTML 문서 <!DOCTYPE HTML> <html lang="en-us"> <head> <meta charset="utf-8"> <title>jewel Warrior</title> </head> <body> <div id="game"> <!-- 여기에게임을구현한다. --> </div> </body> </html> 문서의타입선언이매우간단하다는것에주목하자. 이부분을 HTML 4.01 Strict 버전의정의와비교해보면아래와같다. <!DOCTYPE HTML PUBLIC " -//W3C//DTD HTML 4.01//EN" "http://www.w3.org/tr/html4/strict.dtd"> 이제더이상이런구시대적유물을보지않아도된다. DOCTYPE 키워드는이제사람이기억할수있을정도로쉬워졌다. meta 태그는예전과마찬가지로문자의인코딩형식을지정하기위해사용되었다. 역시간단한것이좋은것이다! 이제 HTML 문서로되돌아가보자. div 태그는게임을구성할다른요소들을포함하게된다. 즉, 게임에필요한나머지마크업코드는이태그의하위태그로작성될것이다. 이후에작성할마크업코드는앞서설명했던다양한게임화면을구성하게된다. 새로추가할 div 태그에는 screen이라는 CSS 클래스가지정되며, 이들은각각유일한 id 값을가지고각각의게임화면을구성하게될것이다. 예제 2.2는게임에서사용할몇개의화면을구성하는 div 태그들을보여준다.
제 2 장게임개발을위한첫걸음 27 예제 2.2 게임에화면요소들추가하기 <div id="game"> <div class="screen" id="splash-screen"></div> <div class="screen" id="main-menu"></div> <div class="screen" id="game-screen"></div> <div class="screen" id="high-scores"></div> </div> 스플래시화면을구성하는것은잠시미루고지금은게임의개발을시작하는데필요한몇가지 CSS 코드를작성해보자. 스타일추가하기 이책에서는두개의서로다른스타일시트를소개한다. 먼저 main.css 파일은게임애플리케이션의전체적인구조를위한스타일규칙을정의한다. 예제 2.3은 head 태그에정의된스타일코드를보여준다. 예제 2.3 main.css 스타일시트를페이지에로드하는코드 <head> <meta charset="utf-8"> <title>jewel Warrior</title> <link rel="stylesheet" href="styles/main.css" /> </head> Remember HTML5에서는 link 태그의 rel 특성에 stylesheet라는값을지정하면기본적으로 type 특성에 text/css 값을추가한다. 따라서더이상개발자가이값을명시적으로지정할필요가없어졌다. 현재로서는이페이지가참조하는스타일시트는데스크톱브라우저만을지원한다. 제3장에서는모바일브라우저에대한지원과다양한장치의다양한해상도를지원하기위해, 서로다른스타일코드를로드하기위한 CSS 미디어쿼리사용법을보여준다.
28 1 부 HTML5 시작하기 기본적으로 main.css 파일에는몇개의간단한규칙만정의하면된다. 예제 2.4는 main.css 파일에정의된 CSS 코드를보여준다. 예제 2.4 main.css 파일의기본코드 body { margin : 0; #game { position : absolute; left : 0; top : 0; width : 320px; height : 480px; background-color : rgb(30,30,30); #game.screen { position : absolute; width : 100%; height : 100%; display : none; z-index : 10; #game.screen.active { display : block; body 스타일은브라우저가기본적으로문서에지정하는여백값을없앤다. #game 스타일은게임보드를구현할 div 태그의배경색을회색으로지정하고, 우리가구현하는것과같은스타일의게임에적합하며 iphone과같은모바일장비에도적합한크기인 320x480 크기로지정한다. 제7장에서는 canvas 요소를이용하여보다보기좋은배경을만드는방법을보여준다. 또한 screen이라는클래스가지정된모든 div 요소에는 display 속성값을 none으로지정한다. 이렇게하면게임이처음로드될때는해당요소들이보이지않게되며, 경우에따라필요한요소만보이게할수있다. screen 클래스가지정된 div 요소가화면에보여야할때는 display 속성값을 block
제 2 장게임개발을위한첫걸음 29 으로지정하면된다. 스크립트로드하기 최근들어스크립트의효율적인로딩이라는주제에대한관심이지속적으로증가하면서스크립트를로드하는방법도하나의기술이되어가고있다. 이경우특정기능에대한지원가능여부를판단할수있는 Modernizr 라이브러리를이용하면이처럼중요한기능을여러분이스스로제어할수있게된다. 예전처럼 script 태그를이용해서로드해야하는라이브러리는 Modernizr 라이브러리와 loader 스크립트파일이며, 나머지는스크립트의로드순서를지정해주기만하면된다. loader.js 파일은잠시후에작성하기로하자. 예제 2.5는 head 태그에추가된 script 태그들을보여준다. 예제 2.5 Modernizr 와 loader 스크립트로드하기 <head>... <script src="scripts/modernizr.js"></script> <script src="scripts/loader.js"></script> </head> 만일최신버전의 Modernizr 라이브러리를다운로드하고자한다면 http://www. modernizr.com/download/ 페이지에서다운로드할스크립트를마음대로정의할수있다. 이페이지에서는 Modernizr 라이브러리가지원가능여부를판단할수있는기능중여러분의프로젝트에서필요한기능만선택할수있으며, 따라서불필요한코드는다운로드하지않을수있다. 이책에서구현할프로젝트를위해서는모든기능을선택하는것은물론 Modernizr.load() 기능과 Modernizr.addTest() 기능을함께선택해주어야한다. 이렇게생성된라이브러리파일의이름은 modernizr.custom. 12345.js와같은형식으로만들어지며, 예제 2.5에서사용한것과동일한이름으로변경해주면된다.
30 1 부 HTML5 시작하기 Remember 스타일시트를참조하는 link 태그와마찬가지로 script 태그역시 type 특성을명시적으로지정할필요가없다. type 특성을지정하지않으면기본값으로 text/javascript 값이사용된다. loader.js 스크립트파일에는 Modernizr.load() 함수를이용하여필요한스크립트를로드하는코드가작성된파일이다. 먼저 Sizzle 라이브러리파일및 game.js와 dom.js 라는두개의새로운스크립트파일을로드하도록하자. 또한 jewel이라는네임스페이스객체를생성하여이객체를통해필요한모든게임모듈을사용할수있도록한다. 예제 2.6은 loader.js 스크립트파일의초기코드를보여준다. 예제 2.6 loader.js 파일의코드 var jewel = {; // 현재문서가완전히로드될때까지기다린다. window.addeventlistener("load", function() { // 동적로딩을시작한다. Modernizr.load([ { // 항상로드되는파일들 load: [ "scritps/sizzle.js", "scritps/dom.js", "scritps/game.js" ], // 모든파일의로드및실행이완료되면호출된다. complete: function() { // console.log(" 모든파일이로드되었습니다!"); ];, false);
제 2 장게임개발을위한첫걸음 31 예제에서보듯이먼저페이지가처음필요한스크립트를로드하고나면 Modernizr 라이브러리가나머지스크립트들을로드한다. 지정된모든파일의로드및실행이완료되면 Modernizr 라이브러리는 complete() 함수를자동으로호출하므로이함수는애플리케이션의로직을구현하기위한적합한함수라고할수있다. 웹애플리케이션의디버깅 이번세션에서는여러분이최신의브라우저들이제공하는다양한디버깅도구에이미익숙하다는것을가정한다. 파이어폭스 (Firefox), 크롬 (Chrome) 및 IE9은매우강력한콘솔과요소검사도구를제공하며, 대부분 F12 키를누르면실행할수있다. 대부분의브라우저들은거의표준화된콘솔출력 API를제공하며, 여러분은아래와같이필요한 API들을호출하여디버깅용메시지를콘솔에출력할수있다. console.log(" 로그메시지 "); console.warn(" 경고메시지 "); console.error(" 에러메시지 "); 이러한 API들덕분에수년전부터웹개발자들이디버깅을위해 alert() 함수를사용했던것에비해훨씬깔끔하고명료하게디버깅을수행할수있다. 다만이책에서는디버깅방법이나에러를처리하는코드에대해많은지면을할애하지는않으며, 우리가현재활용할수있는새로운기능과기법에대해소개하는것에더욱초점을맞출것이다. 그러나원한다면여러분스스로얼마든지디버그메시지를추가할수있다. DOM 핼퍼모듈작성하기 sizzle.js 스크립트파일은제공되는소스코드에서찾거나 Sizzle 라이브러리의웹사이트 (http://sizzle.js.com/) 에서최신버전을다운로드할수있다. Sizzle 라이브러리는 DOM 객체모델을탐색하는기능을제공하지만 DOM 요소를조작하기위해서도사용할수있다. dom.js 파일이바로이런기능을제공한다. 예제 2.7은첫번째핼퍼메서드가구현된 dom.js 파일의코드를보여준다.
32 1 부 HTML5 시작하기 예제 2.7 DOM 핼퍼모듈 jewel.dom = (function() { var $ = Sizzle; function hasclass(el, clsname) { var regex = new RegExp("(^ \\s)" + clsname + "(\\s $)"); return regex.test(el.classname); function addclass(el, clsname) { if (!hasclass(el, clsname)) { el.classname += " " + clsname; function removeclass(el, clsname) { var regex = new RegExp("(^\\s)" + clsname + "(\\s $)"); el.classname = el.classname(regex, " "); return { $ : $, hasclass : hasclass, addclass : addclass, removeclass : removeclass ; )(); 모든게임모듈은 jewel 네임스페이스에구현되며, 기본적으로몇개의공용메서드를가진객체다. 여러분이모듈패턴 (module pattern) 이라고알려진패턴을직접사용해본적이있다면이메서드는매우익숙할것이다. 모든기능은외부에노출될함수를참조하는객체를리턴하는익명함수내부에구현된다. 이익명함수는곧바로호출되며, 리턴값이 jewel 네임스페이스객체의속성에대입된다. 이러한모듈화된접근법을활용하면애플리케이션의코드를자바스크립트의전역범위에서분리하며, 따라서향후서드파티스크립트모듈들을보다쉽게통합할수있다. 익명함수를이용한캡슐화는명시적으로외부에노출되도록설정되지않은모든변수와함수를효과적으로숨길수있다.
제 2 장게임개발을위한첫걸음 33 jewel.dom 모듈은초기에는 CSS 클래스를다루기위한몇개의함수만을가지고있다. 또한 Sizzle() 함수를참조하는 $() 함수를노출하고있다. hasclass() 함수는주어진요소의 classname 특성값에지정된클래스이름이존재하면 true를리턴한다. addclass() 함수와 removeclass() 함수는각각의이름에서알수있듯이요소에지정된 CSS 클래스이름을추가하거나제거하는역할을한다. 게임모듈작성하기 game.js 스크립트파일에는게임스테이지를변경하는등의기본적인애플리케이션로직이구현된 jewel.game이라는모듈을구현한다. 예제 2.8은 game.js 파일에구현된게임로직의코드를보여준다. 예제 2.8 기본적인게임모듈 jewel.game = (function() { var dom = jewel.dom, $ = dom.$; // 현재활성화된스크린을보이지않게하고지정된 ID 를가진스크린을보이게한다. function showscreen(screenid) { var activescreen = $("#game.screen.active")[0], screen = $("#" + screenid)[0]; if (activescreen) { dom.removeclass(scree, "active"); dom.addclass(screen, "active"); // 공용메서드를정의한다. return { showscreen : showscreen ; )();
34 1 부 HTML5 시작하기 Remember Sizzle 라이브러리는지정된조건을만족하는요소가단하나뿐이라하더라도항상요소의배열을리턴한다. 따라서특정요소하나를선택하고자할때는배열자체를사용하는것이아니라배열의첫번째요소를사용해야한다. 현재버전의 jewel.game 모듈은 showscreen() 이라는단하나의함수를제공한다. 이함수는단순히지정된 ID를가진 screen 요소를화면에보이게한다. 이미다른요소가화면에보여지고있는상태라면이요소는더이상보이지않도록한다. 이제 index.html 파일을브라우저를통해로드하면게임의배경으로사용될회색사각형을볼수있을것이다. 이파일이올바르게로드되었는지테스트해보려면 loader.js 파일의 complete 함수에서아래와같이 alert() 함수나 console.log() 함수를호출해보면된다. Modernizr.load([ {... complete : function() { alert(" 로드성공!"); ]); 이게임의네임스페이스계층구조가복잡한것은아니지만, 함수를호출하기위해모듈의경로전체를입력하는것은매우짜증나는작업이다. 타이핑하는양을줄이기위해예제 2.8에서와같이모듈참조에대한경로를단축시킬수있다. 예제 2.8의경우 jewel.game 모듈에서는 jewel.dom 모듈및 $() 함수에손쉽게접근하기위한지역참조변수를상단에선언하고있다. 또한지역참조변수를사용하면자바스크립트엔진이필요한네임스페이스객체를찾기위해전체객체구조를조회하지않아도되므로전체적인자바스크립트코드의실행성능을향상시키는데도움이된다. 스플래시화면출력하기 이제게임의화면을바꿀수있게되었으므로 loader.js 스크립트파일에서필요한파일을로드하는동안스플래시화면을보이도록하는코드를추가해보자. 예제 2.9에
제 2 장게임개발을위한첫걸음 35 서와같이 complete 함수에서 showscreen() 함수를호출하도록하면된다. 예제 2.9 loader.js 에서스플래시화면을보이도록하는코드 Modernizr.load([ {... complete : function() { // 스플래시화면을보이게한다. jewel.game.showscreen("splash-screen"); ]); 이코드는스플래시화면이아직완성되지는않았지만해당요소가화면에보여질것인지에대한여부를토글방식으로결정할수있다. 다음파트에서는웹폰트를이용하여멋진게임로고를가진스플래시화면을구성해보자. HTML 스플래시화면만들기 스플래시화면은게임의로고와함께 계속하려면탭하세요 라는메시지를보여주는간단한화면이다. Jewel Warrior 로고는단순한게임의이름을보여주며재미있는글꼴로표현된다. 이제는내장된웹폰트는 HTML과 CSS만으로도제법보기좋은로고를만들수가있다. 예제 2.10은스플래시화면을구현할 div 태그의코드를보여준다. 예제 2.10 스플래시화면의마크업 <div id="game"> <div class="screen" id="splash-screen"> <h1 class="logo">jewel <br/>warrior</h1> <span> 계속하려면탭하세요.</span> </div>... </div>
36 1 부 HTML5 시작하기 웹폰트사용하기 웹에서안전하게사용할수있는웹폰트는아직많지않으며충분히외울수있을정도이다. 웹에서표준형식으로보다미려한글꼴를사용하고자하는노력은예전부터지속되어왔다. CSS의 @font-face 규칙을이용하면대부분의브라우저에서글꼴을지정할수있다. W3C는새로운웹폰트표준인웹오픈폰트포맷 (WOFF, Web Open Font Format) 을위한작업을수행하고있으며, 현대의모든데스크톱브라우저는이형식을지원한다. 그러나최상위수준의브라우저호환성을지원하려면다양한형식의글꼴을사용할수있어야한다. 예를들어, iphone이나 ipad와같은애플의단말기들은 ios 4.2 버전부터트루타입폰트 (TTF, TrueType Font) 형식을지원하기는하지만아직 WOFF 형식을지원하지는않는다. Tip WOFF 웹글꼴형식은 HTML5의일부가아닌독자적인형식이다. W3C의웹폰트작업그룹 (Web Font Working Group) 은아직이형식의스펙을정의하고있지만, 2011년중최종권고안이발표될예정이다. Jewel Warrior 게임에서는 Slackey 글꼴과 Geo 글꼴을사용한다. 이두글꼴은모두구글의웹폰트디렉토리 (http://www.google.com/webfonts) 페이지에서무료로사용이가능하다. 구글웹폰트사이트에서원하는글꼴을찾아 Add to Collection 버튼을클릭하고필요한글꼴을모두마련했다면우측상단의 Download your collection 링크를클릭하여선택된 TTF 파일들을압축한 ZIP 파일을다운로드할수있다. 만일다른글꼴을사용하고싶다면직접웹을검색해볼것을권한다. 구글웹폰트사이트는웹을위한글꼴을모아둔유일한사이트이다. FontSquirrel(http://www. fontsquirrel.com/) 사이트에서는필요한글꼴파일과 CSS 파일을미리묶어둔무료글꼴들을제공한다. 또한 TTF 글꼴파일을업로드하면 @font-face 코드를생성해주는손쉬운온라인생성기도제공한다. 필자는이웹사이트를통해구글웹폰트사이트에서다운로드한 TTF 파일을 WOFF 파일로변환했다. 프로젝트폴더에 fonts라는새폴더를생성하고제2장의예제코드에서글꼴파일을
제 2 장게임개발을위한첫걸음 37 복사하자. 글꼴을위한 CSS 코드는새로운 fontfaces.css 파일에정의하여 styles 폴더에보관한다. 이새로운스타일시트파일의코드는예제 2.11과같다. 예제 2.11 fontfaces.css 파일의코드 @font-face { font-family: "Slackey"; font-weight: normal; font-style: normal; src: url("../fonts/slackey.woff") format("woff"), url("../fonts.slackey.ttf") format("truetype"); @font-face { font-family: "Geo", font-weight: normal, font-style: normal, src: url("../fonts/geo.woff") format("woff"), url("../fonts/geo.ttf") format("truetype"); @font-face 규칙을설정하기란어렵지않다. font-family 속성값은나머지 CSS 코드에서글꼴을참조할때사용할이름이다. font-weight와 font-style 속성은글꼴파일에내장된서로다른두께와스타일 ( 굵은글꼴, 기울임글꼴등 ) 을지정하기위한것이다. 앞서예제에서는보통글꼴만을사용한다. 브라우저는 @font-face 규칙을만나면소스파일의목록을읽어지원가능한첫번째글꼴을다운로드한다. 애플의 ios 단말기들은 WOFF 파일을아직지원하지않기때문에그냥무시하고대신 TrueType 글꼴파일을다운로드한다. Tip WOFF와 TTF 글꼴파일은 IE9은물론크롬, 오페라, 파이어폭스, 사파리등브라우저의최신버전이라면모두지원한다. 이전버전브라우저들을지원하고자한다면더많은형식의글꼴이필요하며, @font-face 선언이더욱복잡해지게된다. 보다견고한크로스브라우저환경을원한다면폴아이리시 (Paul Irish) 가작성한 견고한 @font-face 문법 이라는제목의글 (http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/) 을읽어보기를권한다.
38 1 부 HTML5 시작하기 스플래시화면에스타일적용하기 전체적으로이게임에서는기본글꼴로 Geo 글꼴을사용할것이므로 main.css 파일에서게임이구현될요소에해당글꼴을지정해보자. 이렇게하면각각의게임화면을구성하는모든요소들이자동적으로같은값을상속하게된다. 예제 2.12는새로운글꼴속성을게임요소에지정하는코드이다. 예제 2.12 내장된글꼴에대한참조를추가하는코드 #game {... font-family: Geo; color : rgb(200, 200, 100); 또한 index.html 파일의 head 요소에 fontfaces.css 파일을참조하는 link 태그도추가해야한다. <head>... <link rel="stylesheet" href="styles/fontfaces.css" /> </head> 이제스플래시화면을조금더예쁘게꾸밀수있는글꼴을페이지에포함할수있게되었다. 스플래시화면의텍스트들에는이미 Geo 글꼴이상속되어적용되어있지만, 이프로젝트에서는로고의경우 Slackey 글꼴을사용하도록할예정이다. 예제 2.13은 main.css 파일에추가된 CSS 코드를보여준다. 예제 2.13 스플래시화면에스타일적용하기 #splash-screen { text-align: center; padding-top: 10px; #splash-screen.continue { cursor: pointer, font-size: 30px;
제 2 장게임개발을위한첫걸음 39.logo { font-family: Slackey; font-size: 60px; line-height: 60px; margin: 0; text-align: center; color: rgb(70, 120, 20); text-shadow: 1px 1px 2px rgb(255, 255, 0), -1px -1px 2px rgb(255, 255, 0), 5px 8px 8px rgb(0, 0, 0); 이제로고에는초록색의 Slackey 글꼴이적용되었으며, 모든요소는화면가운데에정렬된다. text-shadow 속성은두가지목적을가지고있다. 먼저위의두라인의코드는두개의밝은노란색외곽선을양쪽에위치시킨다. 마지막라인의코드는텍스트에그림자효과를만들어낸다. 사실 IE의경우아직텍스트에대한그림자효과를지원하지않는다. 그러나다음과같은코드를 main.css 파일에추가하면 IE의풍부한필터효과를이용하여유사한효과를나타낼수있다..no-textshadow.logo { filter: dropshadow(color=#000000,offx=3,offy=3); 이제브라우저를이용하여 index.html 파일을열어보자. 페이지가로드되면자동으로스플래시화면이먼저나타날것이다. 이스플래시화면의모습은그림 2-5와같다.
40 1 부 HTML5 시작하기 그림 2-5 지금까지구현한스플래시화면의모습 HTML 요약 이번장에서필자는 Jewel Warrior 게임의컨셉을설명하는것에초점을맞추었다. 즉, 게임의규칙과보석블록을회전하는기법및플레이어가점수를얻을수있는방법등을설명하였다. 그런후에는게임을처음시작할때보여지는스플래시화면을비롯하여메뉴와실제게임화면, 게임이종료되었을때보여질최고점수화면등게임의다양한스테이지를소개하였다. 이후에는 HTML과약간의 CSS를이용하여게임의기초를구현하였다. 그과정에서 Modernizr 라이브러리에포함된 yepnope.js 라이브러리를이용하여자바스크립트파일을동적으로로드하는방법도살펴보았다. 또한게임의각스테이지를구성하고이들을전환하기위한기본적인프레임워크도소개하였다. 이번장의후반부에서는웹폰트와 CSS의 @font-face 선언을이용하여페이지에글꼴을포함하는방법과포함된글꼴을이용하여스플래시화면에게임로고를구현하는방법을알아보았다.