StageXL 1.0
StageXL 1.0
HTML5와 Dart를 위한 빠른 2D 렌더링 엔진 StageXL 1.0이 출시됐어요.
출처: 원문
본문
4년 넘는 개발 기간과 Dart의 초기 베타 버전부터 사용 가능했던 StageXL, 그 1.0 릴리스를 발표하게 되어 자랑스러워요. StageXL은 웹에서 게임과 애플리케이션을 위한 빠르고 보편적인 2D 렌더 엔진이에요. 이 글은 이 라이브러리의 가장 중요한 기능과 활용 분야에 대해 다뤄요.
거인의 어깨 위에 서서: Adobe Flash
몇 년 전에 Adobe Flash가 HTML5의 능력으로 대체될 것이 분명해졌어요. 비디오 스트리밍 플랫폼은 Flash 플레이어를 HTML5 플레이어로 교체했고, Google의 AdWords 네트워크는 최근 Flash 기반 디스플레이 광고를 모두 금지했어요. 웹에서 Flash 애플리케이션의 마지막 큰 거점은 게임이에요. 오늘날에도 facebook의 대부분 게임은 Flash로 만들어져요.
과거에 게임 개발자들은 게임에 Flash를 쓰는 것 외에 선택의 여지가 없었어요. DOM의 능력은 게임에 적합하지 않았고, canvas 요소가 도입된 후에도 성능 문제와 호환성 문제, 그리고 마지막으로 JavaScript(특정 Flash/ActionScript 개발자에게 묻는다면 지옥에서 태어난 언어)를 처리해야 했어요. CreateJS나 PixiJS처럼 Flash와 유사한 API와 개발자 경험을 제공하는 라이브러리가 도입되면서 상황이 나아졌어요. TypeScript, Haxe, CoffeeScript 같은 언어의 부상도 고통을 줄여줬어요.
전직 Flash/ActionScript 게임 개발자로서 저는 위에 언급한 모든 것을 직접 겪었어요. 하지만 Dart의 초기 버전과 접촉한 순간 그것이 ActionScript의 가치 있는 후계자라는 게 분명했어요. Dart는 ActionScript와 아주 비슷하게 생기고 느껴지면서도, 동시에 장황한 문법을 피하는 훨씬 더 현대적인 언어예요. 하지만 Flash는 언어 그 이상이에요. Flash는 디스플레이 트리(display tree) 기반 렌더 엔진, 사운드 엔진, 벡터 그래픽, 텍스트 렌더링 등을 제공해요. 이것이 StageXL의 토대가 됐어요. 이 새 라이브러리는 Dart와 HTML5를 결합해 Flash의 기능을 제공해야 했어요. 개발자는 이전에 Flash로 했던 것과 같은 방식으로 Dart와 StageXL로 게임을 작성할 수 있어야 했죠. 더 쉽게 만들기 위해 StageXL의 API는 Flash의 것과 대부분 동일해요.
Flash 개발자라면 이런 StageXL 코드에 익숙할 거예요.
**Sprite** createContainer(**BitmapData** bitmapData) {
var bitmap = new **Bitmap**(bitmapData);
var sprite = new **Sprite**();
bitmap.**x** = -bitmapData.**width** / 2;
bitmap.**y** = -bitmapData.**height** / 2;
sprite.**addChild**(bitmap);
sprite.**alpha** = 0.5;
return sprite;
}
ActionScript에서 와서 Dart를 배우는 것은 쉽다. 두 언어 모두 클래스 기반이고, 단일 상속이며, 객체지향이다… — ActionScript에서 오는 개발자를 위한 StageXL 비교 문서.
StageXL 한눈에 보기
StageXL의 API는 광범위한 기능을 다뤄요. 이 라이브러리의 주요 목적은 빠르고 사용하기 쉬운 렌더 엔진이지만, 게임이나 애플리케이션을 작성하려면 그보다 더 많은 게 필요해요.
그래픽(Graphics): 디스플레이 트리는 추상 DisplayObject 기본 클래스를 확장하는 노드로 구축돼요. 트리에서 노드의 위치가 그 디스플레이 객체가 다른 객체보다 앞에 있는지 뒤에 있는지를 정의해요. 트리에 가지를 만들려면 DisplayObjectContainer라는 두 번째 추상 기본 클래스를 사용해요. 두 기본 클래스 중 하나를 확장해서 커스텀 디스플레이 객체를 만들거나, Sprite, Bitmap, TextField, Shape 같은 내장 클래스 중 하나를 사용할 수 있어요. 이 모든 클래스는 Flash와 같고, 유사한 개념이 다른 렌더 엔진에서도 사용돼요.
상호작용(Interaction): EventDispatcher 클래스는 이벤트를 발송하고 특정 이벤트에 리스너를 구독하는 기능을 제공해요. 모든 디스플레이 객체는 EventDispatcher 클래스를 확장하므로 이벤트를 발송할 수 있어요. 그 이벤트는 게임 로직이 발송하는 커스텀 이벤트일 수도 있고, StageXL 런타임이 발송하는 마우스·터치·키보드 상호작용용 이벤트일 수도 있어요. 모든 디스플레이 객체가 디스플레이 트리 안에 살기 때문에, 이벤트는 루트 노드에서 대상 노드까지 모든 노드 위로 전파된 다음 다시 돌아와요(이벤트의 capturing, target, bubbling 단계).
오디오(Audio): 모든 게임에는 적절한 사운드 효과가 필요해요. StageXL은 오디오 샘플을 별다른 번거로움 없이 로드하고 재생할 수 있는 인프라를 제공해요. Sound 클래스는 메모리에 로드된 오디오 샘플을 나타내요. Sound 클래스에서 play 메서드를 호출하면 오디오 샘플 재생이 시작되고, 재생을 제어할 수 있는 SoundChannel 클래스 인스턴스를 반환해요. 같은 Sound의 여러 인스턴스를 동시에 재생할 수 있어요. 예를 들어 폭발 사운드의 여러 인스턴스를 재생할 수 있죠.
리소스(Resources): StageXL은 서버에서 이미지, 오디오 파일, 기타 리소스를 로드하기 쉽게 만들어요. 그런 파일을 로드하는 건 비동기 작업이므로 Future 기반 API를 제공해요. 이미지 로드는 BitmapData.load 메서드가 반환하는 Future가 완료되길 기다리는 것만큼 쉽고, Sound.load나 TextureAtlas.load 메서드가 반환하는 Future도 마찬가지예요. 여러 리소스를 한 번에 로드하는 걸 더 편리하게 하려면 ResourceManager 클래스를 사용할 수 있어요. 이 클래스는 지정된 모든 리소스를 로드하고, 로드 과정이 끝나면 그 리소스들에 쉽게 접근하게 해줘요. ResourceManager는 Flash의 내장 리소스(embedded resources)를 대체하는 것으로 볼 수 있어요.
애니메이션(Animation): StageXL에는 Juggler라는 애니메이션 프레임워크도 포함돼 있어요. Juggler 프레임워크는 Flash 개발자들에게 잘 알려진 Starling 렌더 엔진이 도입했어요. Juggler는 두 렌더 프레임 사이에 경과한 시간을 기준으로 소위 Animatables를 제어하는 데 사용돼요. 그 Animatable 중 하나가 Tween 클래스인데, 어떤 디스플레이 객체의 위치, 회전, 크기, 투명도를 애니메이션하는 데 사용돼요. Juggler는 또한 게임 로직에서 값을 제어하도록 시간 기반 Stream도 제공해요. 자세한 내용은 Juggler 문서에서 확인할 수 있어요.
무대 뒤의 StageXL
StageXL의 렌더 엔진은 최고의 성능과 유연성을 위해 WebGL 위에 구축됐어요. 물론 개발자가 StageXL을 사용하기 위해 WebGL에 대해 알 필요는 없어요. 그래도 디스플레이 객체는 WebGL 셰이더 프로그램으로 렌더링된다는 점을 언급할 가치가 있어요. 기본 셰이더를 사용하거나 BlurFilter, DropShadowFilter, ColorMatrixFilter 등 필터 효과용 더 고급 셰이더를 사용하죠. 더 고급 사용 사례에서는 개발자가 자신만의 WebGL 셰이더 프로그램 코드를 구현해서 커스텀 필터를 사용할 수 있어요.
최상의 렌더링 성능을 얻으려면 소위 텍스처 아틀라스(texture atlas)를 사용하는 게 필수적이에요. 모든 이미지 에셋을 하나의 큰 이미지로 결합해서 GPU의 메모리에 업로드하는 방식이에요. 그래서 StageXL은 가장 흔한 텍스처 아틀라스 형식을 기본으로 지원해요. 좋아하는 텍스처 아틀라스 생성기(TexturePacker를 적극 추천해요)로 텍스처 아틀라스를 만들면 나머지는 StageXL이 내부적으로 처리해요. 특별한 보너스로 StageXL은 폴리곤 스프라이트 메시(polygon sprite meshes)와 폴리곤 패킹 알고리즘 같은 고급 텍스처 아틀라스 기능도 지원해요.
StageXL의 사운드 엔진은 WebAudio API 위에 구축됐어요. WebGL과 마찬가지로 개발자가 이 API에 대해 알 필요는 없어요. 오디오 샘플을 재생하려면 모든 무거운 작업을 대신 처리하는 Sound와 SoundChannel 클래스를 사용하기만 하면 돼요. 다른 브라우저에서 오디오를 재생할 때 흔한 고통은 특정 오디오 코덱 지원이 없다는 거예요. 아마 오디오 샘플을 mp3 파일로 인코딩하겠지만, mp3가 모든 플랫폼에서 지원된다는 보장은 없어요. 다른 파일 형식으로 인코딩해도 마찬가지예요. StageXL은 브라우저의 능력에 따라 올바른 오디오 형식을 자동으로 로드해서 이 문제를 해결해요.
JavaScript용 다른 2D 렌더 엔진들은 종종 자기가 가장 빠르고 유연하다고 주장해요. 물론 그 주장은 벤치마크나 사용 사례에 크게 좌우되고 검증하기 매우 어려워요. StageXL을 설계하고 개발하는 동안 우리는 그 성능과 유연성을 다른 엔진과 지속적으로 비교했어요. 결국 두 품질 요소 모두 가장 좋다고 주장하는 다른 엔진과 맞먹거나 능가해요. 이 점에서 StageXL의 큰 장점 중 하나는 Dart 프로그래밍 언어를 사용한다는 거예요. 이 언어는 매우 깔끔한 API 설계를 허용할 뿐 아니라, 특정 패턴을 JavaScript에서 손으로 구현하기는 사실상 불가능한 방식으로 최적화하는 뛰어난 JavaScript 컴파일러를 제공해요. 컴파일된 JavaScript는 예쁠 필요가 없고 빨리 실행되기만 하면 돼요. 컴파일러는 함수 인라이닝, 죽은 코드 제거, 상수 폴딩, 타입 추론 등의 최적화를 수행해요. 컴파일러는 또한 현대 JavaScript 엔진에서 빠르게 실행되도록 JavaScript가 어떻게 생겨야 하는지도 알고 있어요. 이는 code가 JavaScript로 컴파일되지 않고 단지 트랜스파일만 되는 TypeScript 같은 다른 언어와는 아주 다르답니다. 마지막으로, 네이티브 ES5와 ES6 JavaScript로 컴파일하기 위해 코드 한 줄이라도 바꿀 필요가 없어요.
StageXL BunnyMark — 가능한 한 많은 토끼를 렌더링하세요!
StageXL은 계속됩니다
StageXL 1.0에 도달하는 데 4년 넘게 걸렸어요. 그렇게 오래 걸린 이유는 항상 개선하거나 추가할 게 있고, 프로젝트가 끝났다고 느끼는 일이 없기 때문이에요. 버전 1.0도 마찬가지예요. 앞으로 새 기능이 정기적으로 추가될 거예요. 커뮤니티의 피드백은 매우 소중하고, 기능 요청은 언제나 환영해요. 버그 리포트도 어느 정도는요 ;)
아마 우리가 지평선에서 보는 가장 큰 기능은 Flutter 지원일 거예요. Dart와 StageXL로 Android와 iOS용 모바일 게임을 작성할 수 있게 되는 거죠. Flutter의 초기 버전은 매우 유망해 보여요. 아쉽게도 그 플랫폼은 아직 StageXL을 그 위에 구축하는 데 필요한 OpenGL API를 노출하지 않아요. 우리는 개발을 계속 주시하고, StageXL이 모바일 기기에서 보이는 날이 너무 오래 걸리지 않길 바라요.
Flutter: 최고의 모바일 개발 경험과 더 재미있어진 모바일 개발에 관한 글.
확장 라이브러리
StageXL 라이브러리는 그래픽 렌더링, 오디오 재생, 리소스 파일 로드, 애니메이션 등을 위한 모든 것을 제공해요. 하지만 게임이나 애플리케이션에 필요할 수 있는 다른 기능도 있어요. 그래서 StageXL은 추가 패키지로 제공되는 더 전문화된 기능으로 확장될 수 있어요. 다음 확장은 GitHub와 Pub 양쪽에서 구할 수 있어요.
- StageXL_Spine: Spine은 2D 골격 애니메이션에 특화되어 있어서, 놀라운 애니메이션을 만들고 그것을 게임에 통합하는 효율적인 워크플로를 제공해요. Spine은 2D 애니메이션을 다듬고 정련하는 수많은 도구를 제공해요. 메시 스키닝/가중치로 이미지를 구부리거나 변형하고, dopesheet로 타이밍을 조정하고, ghosting으로 움직임을 시각화하고, 역운동학으로 캐릭터를 포즈를 취하게 하고, 유사 3D 효과를 만들고, 그 외 훨씬 더 많은 일을 할 수 있어요. (데모)
- StageXL_DragonBones: DragonBones는 Flash와 Starling 개발자 사이에서 매우 인기 있는 오픈소스 2D 골격 애니메이션 솔루션이에요. 편집기는 Mac과 Windows에서 사용할 수 있고 Adobe Flash가 필요 없어요. DragonBones는 Spine만큼 기능이 풍부하지는 않지만 대부분의 사용 사례에 충분한 기능을 제공해요. (데모)
- StageXL_GAF: GAF는 Generic Animation Format을 뜻해요. GAF는 Flash 애니메이션을 개방형 크로스 플랫폼 형식으로 저장해서 후에 재생할 수 있게 설계됐어요. GAF는 아티스트와 애니메이터가 Adobe Flash로 복잡한 애니메이션을 만들고 그 애니메이션을 StageXL에서 매끄럽게 사용할 수 있게 해줘요. (데모)
- StageXL_BitmapFont: 비트맵 폰트는 전문화된 도구로 만들거나 PhotoShop에서 디자인해서 멋진 텍스트를 렌더링해요. 글리프는 텍스처에 저장되어 런타임에 텍스트를 매우 효율적으로 렌더링해요. StageXL 비트맵 폰트 라이브러리는 텍스트를 확대·회전할 때 날카로운 가장자리를 위한 distance fields 같은 기능도 지원해요. (데모)
StageXL로 렌더링한 Spine 애니메이션 모습.
링크
- StageXL: GitHub의 StageXL, GitHub의 StageXL 예제, StageXL API 참조, StageXL 포럼
- 런타임(Runtimes): StageXL Spine 런타임, StageXL DragonBones 런타임, StageXL GAF 런타임, StageXL 비트맵 폰트
- 게임(Games): Memory(소스), Escape(Flash에서 포팅, 소스), Supersonic(Flash에서 포팅, 소스)
- 벤치마크(Benchmarks): Bunny Mark, Starling
- 커뮤니티 프로젝트: Flash/ActionScript에서 StageXL/Dart로의 변환기, Rockdot 프레임워크(UI 외 더 많은 것)
더 알아보기
- StageXL — GitHub 저장소
- StageXL API 참조 — 라이브러리 API 문서
- StageXL 문서 — 소개와 예제