본문 바로가기

Starling

Starling - Introducing 번역 5 > Juggler, Button, TextField, RenderTexture



목차

First Flight ------------------------------------------------------------------------------------------------- 1

What Is Starling?

Why Starling?

Philosophy 

Intuitive 

Lightweight 

Free 

How 

Layering Restrictions 

Getting Started

Setting Up Your Scene

Wmode Requirements

Stage Quality

Progressive Enhancements

The Display List

Event Model

Event Propagation

Touch Events

Simulating Multi-touch

Texture

Image

Collision Detection

Drawing API

Flat Sprites

MovieClip

Texture Atlas

Juggler

Button

TextField

Embedded Fonts 

Native Display List Overlay

Bitmap Fonts 

RenderTexture

Tweens

Asset Management

Multi Resolution Development

Static Approach

Dynamic Approach

Handling Screen Resizes

Plugging Starling with Robotlegs

Plugging Starling with Box2D

Particles

-----------------------------------------------------------------------------------------------------------------


간만에 컴퓨터 켜서 이것저것 짜볼까 하다가 걍 미룬 번역이나 마무리 하기로.


언제나처럼 번역은 의역과 오역이 있을 수 있으며

굳이 한글로 번역하지 않는 것이 이해되기 편하다 생각되는 부분은 영어단어 그대로 썼다.


( 서술파일...보다는 description 파일 이라고 하는쪽이 이해가 팍! )


요샌 퇴근하여 집에 오면 컴퓨터를 잘안키게 된다. 20대 땐 하루종일 머릴 쥐어짜며 일해도

일은 일, 공부는 공부, 이렇게 분리될 수 있었는데 요샌 집에 오면 그냥 티비보며 책보고 겜하다 하루마감ㅠㅜ


벌써부터 이러면 더 나이들면 어쩌지;


일단 시작.




Juggler


Juggler 는 IAnimatable 인터페이스를 구현한 객체를 애니메이션 시킬 수 있도록 해준다.

MovieClip 객체는 IAnimatable 인터페이스를 구현하며

MovieClip 외에 Juggler 를 통해 애니메이션 될 당신만의 객체를 정의하기 위해 해야 할 일은

IAnimatable  인터페이스를 구현하고 advanceTime 메소드를 오버라이드 하는 것 뿐이다.


아래의 코드는 MovieClip 의 메인 로직이며 이를 통해 우린 MovieClip 이 어떤 방식으로 애니메이션 되는지 알 수 있다.

MovieClip 은 매 프레임마다 텍스쳐가 교체된다.

기존의 API 에서 매 프레임마다 Bitmap 객체의 bitmapData 를 변경 하는 것과 비슷한 매커니즘이다.





아래는 사용가능한 Juggler API 목록을 나타낸다.


• add :

저글러에 객체를 추가한다.


• advanceTime :

저글러의 메인루프를 수동으로 제어해야 할 때 호출 되는 API.


• delayCall :

특정 메소드를 지연 실행한다. 메소드를 대신 실행하는 프록시 객체가 반환된다. (DelayedCall  객체)

전달된 시간이 지날 때 까지 실행이 지연된다.


• elapsedTime :

저글러의 총 생명시간.......( 원문: The total life time of the juggler ) ... life time 을 뭐라해야 할까...

객체가 생성된 후 흐른 총 시간을 말한다. 


• isComplete :

저글러의 상태.


• purge

한번에 모든 객체를 제거.


• remove

저글러에서 객체 하나를 제거.


• removeTweens

특정 대상의 모든  타입의Tween 객체를 제거.




Juggler 가 가진 또다른 재미있는 기능엔 지연호출이 있다.


아래의 코드에서 우리는 Juggler 를 사용하여 자식이 부모로부터 제거되는 시기를 지연시키고 있다.



특정 상황에서,

예를 들어 게임의 메인 콘텐츠가 일시 정지 된 상태인 경우

당신은 애니메이션을 처리하기 위해 또 다른 Juggler를 만들어야 할 수도 있다.

또다른 Juggler를 사용하기 위해서 할일은 단 하나. 객체를 만든 뒤 해당 객체의 advanceTime API 를 호출하는 것이다.


이를 위해선,

당신은 당신의 게임의 주요 부분들이 각각의 Juggler 를 사용하도록 설계해야 한다.


사용자가 일시정지를 눌렀을 때 게임 전체가 멈추는 것은 원하지 않을 테지만

단순히 Starling 객체의 stop API 를 호출하면 모든 렌더링과 frame 이벤트가 멈추게 된다.


Starling.current.stop();


대신에,

게임의 각 주요 부분( 메뉴, 배경 등 ) 을 분리된 각각의 Juggler 의해 처리되도록 설계한다면

게임을 일시정지 해야하는 경우,

특정 Juggler 만 중지시키면 게임의 각 부분에 대하여 일지중지 또는 다시재생등의 기능을 다룰 수 있게 된다.


아래의 코드를 보자. 우리는 전투장면이 포함된 커스텀클래스 BattleScene을 정의했다.



이제 우리는 외부에서  EnterFrameEvent.EVENT 이벤트를 사용하여 advanceTime  를 호출 하고 경과시간을 전달 할 것이다.



게임이 일시정지 되면, 우리는 advanceTime API 의 호출을 중지하게 되고, 따라서 배틀신의 컨텐츠는 멈추게 된다.

물론 게임 위를 애니메이션되며 덮어씌울 메뉴는 필요하다. 이를 구현하려면 해당 구문을 여기에 추가하기만 하면 된다.



paused 값을 바꾸는 것만으로도 마법은 일어나게 된다..

이젠 스탈링의 상호작용을 위한 또다른 중요 API 인 Button 클래스를 살펴보자.





Button


스탈링은 기본적으로 버튼의 개념을 지원한다. Button 클래스 생성자는 아래와 같다.



기본적으로 버튼 클래스는  label ( 이하 라벨 ) 을 표시하기 위해 내부에 텍스트필드 객체를 만들며

텍스트는 버튼의 중앙에 위치한다.


아래의 코드에서 우리는 Embed 한 비트맵을 스킨으로 사용하는 간단한 버튼을 만들고 있다.



버튼객체의 스킨을 표현하는 텍스쳐를 만들기 위해 fromBitmap API 를 사용한 것에 주목하자.



이젠 간단한 반복문을 사용하여  Vector 의 데이터가 포함된 메뉴를 만들어 보자.




이 코드를 테스트 해보면, 그림 44와 같은 결과를 얻을 수 있다.


그림 44. 버튼으로 만들어진 간단한 메뉴.



여기서 잠깐!


우리는 버튼들의 스킨에 스프라이트시트를 활용하지 않았다.

단지 단 한개의 스킨을 임베드 시켜 Texture 클래스의 fromBitmap API 를 통해 GPU 에 업로드 했을 뿐이다.


만약 모든 버튼에 같은 스킨을 입힐 생각이라면 이 방법도 나쁘지 않다.

하지만 가장 좋은 방법은 이전에 두개의 무비클립(소년과 정육점아저씨)을 만들었을 때 처럼

한장의 텍스쳐아틀라스에 모든 스킨을 정의하는 것이다.



이젠 버튼클래스에서 사용가능한 속성들을 살펴보자.


• alphaWhenDisabled:

      버튼이 비활성화 되었을때 사용 될 투명도 값.


• downState:

버튼이 눌러졌을 때 사용될 텍스쳐.


• enabled: 

버튼이 트리거 될 수 있는지 없는지 (클릭,터치) 에 대해 결정한다.


• fontBold: 

버튼 라벨을 bold 처리 할 것인지 아닌지 결정


• fontColor: 

폰트의 컬러.


• fontName:

버튼의 라벨에 사용될 폰트. 시스템폰트를 사용하거나 비트맵 폰트를 등록할 수 있다.


• fontSize:

버튼의 라벨에 사용될 폰트의 크기.


• scaleWhenDown:

버튼이 터치되었을때 스케일 값. 만약 downstate  속성에 텍스쳐를 지정했다면 버튼의 크기는 조절되지 않는다.


• text:

버튼 라벨에 쓰일 텍스트. 


• textBounds:

버튼 라벨의 위치.


• upState: 

 버튼이 터치되지 않았을때 보여질 텍스쳐.




기존의 Flash API 와는 다르게 버튼 객체는 DisplayObjectContainer 의 서브 클래스 이고

이는 버튼의 스킨을 상태 속성에 따라 제한할 필요가 없다는 것을 의미한다.

당연히 다른 컨테이너들처럼 버튼도 당신이 원하는 방식으로 꾸밀 수 있다.


버튼 객체는 클릭 상태를 처리하는 Event.TRIGGERED 이벤트를 디스패치 할 수 있다.


Event.TRIGGERED 이벤트는 버블링된다.

만약 이벤트전파를 활용하기 원한다면 컨테이너에서 캐취된 이벤트에 의지해도 된다.




인터페이스에 스크롤되는 배경을 추가해보자.





이제 우린 스크롤되는 배경과 간단한 메뉴를 가지게 되었다.

그림 45는 그 결과이다.


그림 45. 메뉴와 스크롤되는 배경.



배경이 스크롤 될 때 모션의 움직임을 강조하기 위해 포토샵에서 이미지에 약간의 블러를 적용한 것에 주목하자. 




TextField



starling.text.TextField API 는 quad 객체를 다룰 때 잠시 사용한 적이 있다.

스탈링에선 텍스트 작업을 어떻게 해야하는지에 대해 잠시 시간을 할애 해보도록 하자.


당신은 GPU 에 어떻게 폰트를 렌더링하는지 궁금할텐데, 여기엔 약간의 꼼수가 있다.


화면 뒤에선 스탈링은 기존의 TextField 객체를 cpu 를 사용해 만든 뒤

폰트를 렌더링 하기 위한 오프스크린 버퍼 ( offscreen buffer ) 로써 사용한다.


일단 래스터화 되면 텍스쳐는 GPU 에  업로드되고 스크린엔 텍스트가 나타난다.

TextField API 는 사용할 때 마다 매번 flash.text.TextField 객체를 생성하지 않는다.

하나의 인스턴스가 캐쉬되며 모든 텍스트를 렌더링 할 때마다 재사용된다.


 * 역자주 ----

래스터화 (rasterized ) 란 벡터 또는 윤곽선 데이터를 비트맵으로 바꾸거나,

픽셀의 위치를 계산하여 화면에 표시하는 등의 과정을 의미한다.

여기서의 래스터화는 문맥 상 기존의 TextField 객체를 비트맵화 하는 과정을 의미하며

실제로 스탈링의 starling.text.TextField 클래스 내부에선 기존 TextField 객체를 하나 만든 뒤

비트맵데이터에 draw 하여 Texture.fromBitmapData 를 통해 텍스쳐를 만들어 upload 하는 방식을 사용한다.

원문의 말대로 매번  flash.text.TextField 객체를 생성하지 않고 하나의 객체를 캐쉬하여 사용하긴 하지만

정작 BitmapData 객체는 텍스트크기만큼의 매번 생성, draw 되며 이 BitmapData 객체는 dispose 되지 않는다. (-..-;;) 


그리고 당연히 starling.text.TextField 객체는 하나 사용할 때마다 드로우콜은 하나씩 올라간다.

이말은 버튼 역시 생성자에 문자열을 넘겨 label 을 표시해줄 경우 버튼 수 만큼 드로우콜은 오른다는걸 의미한다ㅋㅋ

Starling 은 훌륭한 프레임워크임에는 틀림없지만 완전무결하지 않은 오픈소스임을 잊지 말아야 한다.


실제 Starling 을 사용하여 모바일 프로젝트 개발을 하게 되면 만족스러운 퍼포먼스를 위해

많은 부분을 커스텀하거나 수정해야 할 필요가 있다. 


a.Daniel 은 나보다 똑똑할텐데... b.무언가 이유가 있겠지...

c.어련히 알아서 되어있겠지... d.고치다 프레임웤이 제대로 동작하지 않으면 어쩌지? 


등의 고민은 하지 말고 아니다 싶은 부분은 과감히 수정해야 한다.

Starling 내부엔 지금 보고 있는 e-book 에서 필자 스스로 지적했던 최적화 기법이 되어있지 않은 부분도 많다.

Starling 은 그 자체로도 분명 빠르다. 하지만 모바일에서 우리가 원하는 만큼의 효과를 넣기엔 충분히 빠르지 않다.

원하는 만큼의 퍼포먼스를 내기 위해선 Starling 은 반드시 Custom 할 필요가 있다.

이런 부분은 글이 길어지므로 나중에 시간이 나면 다루는 걸로....

----


아래의 코드에서, Verdana  시스템 폰트를 사용한 텍스트필드 객체를 만들어 화면에 표시한다.


그림 46 은 그 결과이다.


그림 46 몇개의 간단한 텍스트들.


지금 스크린에서 보여지는 것은 진짜 텍스트필드가 아니라

GPU 에 업로드 된 비트맵 텍스쳐가 그려진 스냅샷일 뿐라는 점을 잊지 말자.



이젠 TextField API 를 살펴보도록 하자.


• alpha:

텍스트의 투명도


• autoScale:

정의된 텍스트 블럭의 크기에 자동으로 크기가 맞춰질 것인지 에 대한 Bool 값.


• bold:

폰트의 라벨이 bold 처리되었는지 아닌지를 알려준다.


• border:

텍스트 필드 주위에 테두리를 표시할 수 있또록 해준다. 비주얼 디버깅에 유용하다.


• bounds: 

텍스트필드 내부 문자열의 실제 영역.


• color: 

텍스트의 색.


• fontName: 

사용된 폰트이름.


• fontSize: 

사용된 폰트의 크기.


• hAlign: 

텍스트의 수평 정렬 값.


• italic:

텍스트가 기울임 꼴인지 아닌지를 정의.


• kerning:

비트맵폰트(사용가능한 경우) 의 kerning 정보를 사용하도록 허용. 기본값은 true


• text:

표시될 텍스트.


• textBounds:

텍스트필드 내부 문자열의 실제 영역.


• underline:

텍스트에 밑줄을 그을지 아닌지를 정의.


• vAlign:

텍스트의 수직 정렬 값.



TextField 의 멋진 기능 중 하나는 곧 다룰 autoScale 속성이다.

하지만 그전에 먼저, 다른 몇가지 속성을 맛보도록 하자.

아래의 코드에서 우린 텍스트 주위에 테두리를 추가하고 bold 처리를 한 뒤 색상을 바꾸었다.



그림 47은 그 결과이다.


그림 47. 색깔이 입혀진 텍스트.


텍스트필드 객체는 기본적으로 HTML을 다루지 않는다.

하지만 이후의 버전에서 이러한 기능이 추가될 수 도 있다.

이런 기능이 추가되길 원한다면 스탈링 포럼에 당신의 목소리를 높히는 것을 주저하지 말아라.


그리고 스탈링은 오픈소스임을 기억하자.

당신 역시 이런 기능을 직접 구현하고 제공하여 커뮤니티의 확장을을 꿰할 수 있다.

(역자주: 실제 어려운 기능이 아님에도 추가하지 않는 건 이러한 기능을 추가해달라는 포럼의 글을 기다리고 있는 것 같다ㅋㅋ)

 

우리는 앞의 예제들에선 매우 일반적이고 유용한 시스템폰트만을 사용해 왔지만

대부분의 프로젝트에서는 포함된 글꼴을 사용해야 할 것이다.

예를 들어 게임환경에서 강력한 브랜드 경험을 제공하기를 원한다면 포함된 글꼴의 사용이 반드시 필요하다.



Embedded Fonts


스탈링의 TextField 는 기존 TextField API 처럼 embedFont 속성을 제공하지 않는다.

하지만 걱정하지 않아도 된다.


실제로 스탈링에서 포함된 글꼴을 사용하는 것은 매우 쉽다.

먼저, 당연하지만, 필요로 하는 글꼴을 포함하거나 런타임 때 로드해야 한다.

그리곤 TextField 의 생성자에 해당하는 폰트의 이름을 전달하기만 하면 된다.


아래의 코드에서, 우리는 폰트를 임베드 하고 , 인스턴트화 한다음

택스트필드의 생성자에 fontName 속성을 전달했다.



자동적으로, 텍스트필드객체는 자신의 이름과 맞는 포함된 글꼴을 찾아 사용하게 된다.

그림 48은 포함된 Abduction 폰트로 표현된 텍스트를 보여주고 있다.



그림 48. 포함된 폰트를 사용한 텍스트. 정말 쉽죠? 



어쩌면 컨텐츠 안에서 당신은 사용자 이름, 이메일, 기타정보의 입력을 위한 input text 를 제공하길 바랄 지도 모른다.


예상되겠지만, 텍스트 편집은 GPU 상에서는 까다로운 작업이다.

모바일을 포함한 대부분의 플랫폼에선 한가지 트릭을 사용하게 된다.


아이디어는 간단하다.

이러한 상황에서 우리는 항상 사용해 왔던 고전적인 네이티브 표시 객체를 사용한다.

스테이지3d 화면 위로 표시객체를 위치시켜 intput TextField 를 GPU 컨텐츠들 위로 표시할 수 있다.

이 작업을 위해 우린 스탈링의 매우 편리한 기능인 native overlay 를 사용한다.


예전에 우린 wmode 의 값이 잘못되었을때 스탈링이 에러 메세지를 표시했던 것을 본적이 있다. 

스탈링은 이 기본 오버레이 기능을 내부적으로 사용한다.

알다시피, 스탈링은 stage3d 상에서 구동된다.

native overlay 기능은 스탈링 객체에서 표시목록에 대한 접근 권한을 얻어

기존의 표시목록에 Flash 에서 항상 사용해온  video 나 text input 같은 객체를 추가할 수 있도록 해주며

이들은 스테이지3D 화면 위에 표시 된다.


스탈링은 잘못된 wmode 가 사용되었다는 것을 감지하면

Stage3d 의 화면위로 경고 메세지를 표시하기 위해 내부의 showFatalError  함수가 호출된다. 


물론 이 시나리오에선 렌더링할 GPU 표면이 없기 때문에

스탈링은 스테이지3d 위의 표시목록에 의지하게 된다.


이코드에서,

우리는 입력 텍스트필드를 만들고 스탈링 화면 위 표시목록 리스트에 추가하였다.




이것은 게임이 시작 될 때 여러가지 정보를 입력하기 위해 텍스트 입력이 필요한 경우 매우 유용할 수 있다. 

스탈링 객체의 nativeStage 속성을 사용하면

언제든지 기존의 stage (flash.display.Stage)에 접근할 수 있다는 점도 기억해두자.

(역자주: input text 이슈는 이방법외에 다른방식으로도 해결 가능하다)



이젠 최고의 성능을 위하여 비트맵폰트를 살펴 보도록 하자. 



Native Display List Overlay


Stage3D 가 포함된 어도비 AIR 의 베터버젼에서 Stage3D 위로 기존의 표시목록 리스트를 겹치는 것은

퍼포먼스에 영향을 미쳤었다.

하지만 AIR3.2최종 릴리즈 버전에서는 모든 렌더링 작업이 단일 패스로 결합되어 최적화 되어 있다.


Stage의 표면은 이젠 Stage3D 의 면(plane) 과 동시에 업데이트 된다.


동시 업데이트란

Stage3D 컨텐츠 위로 기존의 DisplayObjects 를 사용할 경우

Context3D.present() 메서드가 호출되기 전까지는 Stage 와 Stage3D 둘 모두 화면에 갱신되지 않는다는 것을 의미한다.


스탈링을 사용하는 유저는 Context3D.present() 의 호출에 대해 걱정할 필요가 없다.

스탈링은 화면 뒤에서 당신을 위해 이 작업을 대신 수행해준다.




Bitmap Fonts


텍스쳐는 화면 뒤에서 생성되기 때문에

가비지 컬렉터 로드, 적은 비용의 리소스,  최고의 퍼포먼스를 위해 비트맵폰트가 사용된 TextField API 를 사용할 수 있다.


아이디어는 동일하다.

모든 문자는 한장의 스프라이트시트에서 추출되고

이 텍스쳐가 각 문자가 렌더링할때 필요한 샘플이 된다.


그림 49는 Britannic Bold 폰트를 위한 스프라이트시트가 준비된 GlyphDesigner  툴을 보여주고 있다.


그림 49. MacOS 의 GlyphDesigner 


윈도우에서는 Bitmap Font Generator(AngelCode 에서 제작) 라는 이름의 유사한 기능을 가진 툴을 자유롭게 사용할 수 있다.


Figure 50. 윈도우의 Bitmap Font Generator.


( 이런 젠장 좋은 툴은 다 맥에 있어! )


물론 런타임 시 스프라이트시트에서 문자들을 뽑아내어 각 문자들이 포함된 텍스트필드를 사용하여

레이아웃에 맞게  BitmapData  API 를 사용해 그려도 상관없다.


플랫폼( 데스크탑 혹은 모바일 ) 에 따라 당신의 선택은 다를 수 있다.

런타임에서 활용하는 방법은 크기등의 이유로 가치가 있을 것이다.

반면 embedding 은 당신의 콘텐츠가 빠르게 시작되도록 해준다.


당신은 두개의 방법중에 하나를 선택해야 한다.



툴을 통해 폰트가 Export 가 되면

텍스쳐는 이미지와 이미지에 대한 서술이 담긴 파일로 저장이 되며

fnt 확장자를 가진 파일 (XML 혹은 text ) 에서  각 문자의 위치에 대한 디테일한 정보를 가져 올 수 있게된다.


이는 아래와 같다.



비트맵 텍스쳐와 .fnt 확장자로 이루어진  description 파일이 export 되면 이를 포함하여 사용할 수 있다.



이들을 사용하기 위해선 아래에 보이는 TextField 클래스의 정적 메소드를 사용해야 한다.


• registerBitmapFont: 비트맵 폰트를 등록한다.

• unregisterBitmapFont:  비트맵폰트를 제거한다.


BitmapFont 객체에 텍스쳐와  decription 파일을 전달 한 후 registerBitmapFont  API 를 통해 등록하자.



등록이 되면 TextField 객체를 생성할 때 폰트의 이름을 전달 할 수 있게 된다.

그림 51은 그 결과이다.




Figure 51. 비트맵폰트로 렌더링된 텍스트.


이젠 문자열을 조금 더 길게 바꾸면 어떤일이 일어나는지 보자.



예상대로,  텍스트필드의 경계상자는 모든 문자열을 담기에는 너무 작다.

그 결과 텍스트는 잘려 제대로 표시되지 않았다. ( 그림 52 )



Figure 52. 잘려진 긴 비트맵 텍스트.


다행스럽게도, 스탈링의 TextField 엔 autoScale 속성이 지원된다.



이 속성은 게임에서 로컬라이즈 작업을 위해 변화될 문자들이

명시된 박스안에 딱 맞춰야 할 필요가 있을 때 매우 유용하다.

대부분, 디자인상의 이유로

어떤 길이의 문자가 와도 레이아웃이 정확히 동일하게 유지될 수 있도록 텍스트는 조정이 되야할 필요가 있다.


그림 53은 autoScale 속성을 사용하여 문자열들이 조금 변화된 모습을 보여주고 있다.


그림53. 큰 텍스트들이 크기가 조절되어 박스안에 맞춰진 모습.


우리는 비트맵폰트를 사용하여 메뉴와 스크롤되는 배경을 가진 이전의 예제를 조금 더 그럴싸 하게 만들 수 있게 되었다.



그림 54는 그 결과이다.


Figure 54. 커스텀 폰트가 사용된 메뉴.


이젠 스탈링의 또다른 뛰어난 기능인 RenderTexture 를 살펴보도록 하자.


RenderTexture

starling.textures.RenderTexture API 는

지워지지 않는 드로잉을 구현할 수 있도록 해준다.


이 기능은 드로잉툴과 같은 프로그램에서

연덜아 그려야 하거나 이전의 그림을 유지해야 할 때 매우 유용할 수 있다.


아래의 코드에서 ,

우리는  BitmapData.draw 기능을 스탈링을 통해 GPU상에서 똑같이 구현하고 있다.



마우스를 누른채로 마우스를 이동하면 그림 55와 같은 결과를 얻을 수 있다.



Figure 55. 계속 유지되는 드로잉.


이제 우리는 플래시 개발자들에게 매우 잘 알려진 주제인 트위닝에 대해 이야기 할 것이다!

to be continued..



ps. 남은 분량을 보니 다음 번역글이 마지막이 될 것 같습니다.

아니면 Plugging 쪽에서 한번 끊고 갈 수도 있고...

언제가 될진 모르겠지만 --ㅋㅋㅋㅋ