2.7. 애셋 관리(Asset Management)
한 가지 분명한 사실은 모든 응용 프로그램의 자원에서 텍스처가 차지하는 비중이 가장 크다는 것입니다. 특히 게임에는 많은 그래픽이 필요합니다. 사용자 인터페이스에서 문자 항목 배경 등으로 변환할 수 있습니다. 하지만 그것이 전부는 아닙니다. 사운드 및 구성 파일을 관리해야 할 수도 있습니다.
이러한 애셋을 참조하려면 몇 가지 옵션이 있습니다.
애플리케이션 내부에 바로 임베드합니다 ([Embed] 메타 데이터를 통해).
디스크에서 로드하기 (AIR 응용 프로그램에서만 가능).
URL에서 로드하기 (예: 웹 서버에서).
모든 옵션에는 애셋 유형 및 로드 메커니즘에 따라 다른 코드가 필요하기 때문에 일관된 방식으로 애셋에 액세스하기가 어렵습니다. 고맙게도 Starling에는 AssetManager와 함께 도움이 되는 클래스가 있습니다.
다음 유형의 애셋을 지원합니다:
텍스처 (비트 맵 또는 ATF 데이터에서)
텍스처 아틀라스
비트맵 폰트
사운드
XML 데이터
JSON 데이터
바이트 어레이(ByteArrays)
이를 달성하기 위해, AssetManager는 3단계 접근법을 사용합니다:
애셋에 대한 포인터를 대기열에 추가합니다. (예: 파일 오브젝트 또는 URL)
대기열을 처리하도록 AssetManager에 지시합니다.
대기열에서 처리가 완료되면 해당 'get'메소드를 사용하여 모든 에셋에 액세스할 수 있습니다.
AssetManager에는 자세한 정보가 들어 있습니다. 사용하도록 설정하면 대기열에 포함되고 로드되는 모든 단계가 콘솔로 추적됩니다. 이는 디버깅에 유용하거나 특정 애셋이 왜 보이지 않는지 이해하지 못하는 경우에 유용합니다! 이러한 이유로 Starling 최신 버전에서는 기본적으로 활성화되어 있습니다.
2.7.1. 애셋을 대기열에 넣기
첫 번째 단계는 사용하려는 모든 애셋을 큐에 넣는 것입니다. 그것이 어떻게 완료되었는지는 각 애셋의 유형과 출처에 따라 다릅니다.
디스크 또는 네트워크의 애셋
디스크 또는 원격 서버에서 파일을 대기열에 넣는 것은 다소 간단합니다:
// 원격 URL에서 에셋 대기열에 넣기
assets.enqueue("http://gamua.com/img/starling.jpg");
// 디스크에서 에셋을 대기열에 포함 (AIR에만 해당)
var appDir:File = File.applicationDirectory;
assets.enqueue(appDir.resolvePath("sounds/music.mp3"));
// 재귀적으로 디렉토리의 모든 내용을 큐에 넣습니다 (AIR 만 해당).
assets.enqueue(appDir.resolvePath("textures"));
텍스처 아틀라스를 로드하려면 XML 파일과 해당 텍스처를 모두 대기열에 추가하기만 하면 됩니다. XML 파일의 imagePath 속성에 올바른 파일 이름이 포함되어 있는지 확인하십시오. AssetManager가 나중에 아틀라스를 만들 때 찾을 것이기 때문입니다.
assets.enqueue(appDir.resolvePath("textures/atlas.xml"));
assets.enqueue(appDir.resolvePath("textures/atlas.png"));
비트맵 폰트는 동일하게 작동합니다. 이 경우 XML (.fnt 파일)의 파일 특성이 올바르게 설정되어 있는지 확인해야 합니다.
assets.enqueue(appDir.resolvePath("fonts/desyrel.fnt"));
assets.enqueue(appDir.resolvePath("fonts/desyrel.png"));
임베디드 애셋
임베디드 애셋의 경우 모든 임베드 명령문을 하나의 전용 클래스에 넣는 것이 좋습니다. public static const로 선언하고 명명 규칙을 따릅니다:
삽입된 이미지의 클래스는 확장자가 없는 파일과 완전히 동일한 이름이어야 합니다. 이것은 XML (atlas, bitmap font)의 참조가 깨지지 않도록 하기 위해 필요합니다.
아틀라스 및 폰트 XML 파일은 파일 이름으로 절대 참조되지 않으므로 임의의 이름을 가질 수 있습니다.
다음은 그러한 클래스의 샘플입니다:
public class EmbeddedAssets
{
/* PNG texture */
[Embed(source = "/textures/bird.png")]
public static const bird:Class;
/* ATF texture */
[Embed(source = "textures/1x/atlas.atf",
mimeType = "application/octet-stream")]
public static const atlas:Class;
/* XML file */
[Embed(source = "textures/1x/atlas.xml",
mimeType = "application/octet-stream")]
public static const atlas_xml:Class;
/* MP3 sound */
[Embed(source = "/audio/explosion.mp3")]
public static const explosion:Class;
}
해당 클래스를 큐에 넣으면 나중에 애셋 관리자가 포함된 모든 애셋을 인스턴스화 합니다.
var assets:AssetManager = new AssetManager();
assets.enqueue(EmbeddedAssets); (1)
(1) 새(bird) 텍스처, 폭발음 및 텍스처 맵을 큐에 넣습니다.
애셋 별 구성
Texture.from...() 팩토리 메소드를 통해 수동으로 텍스처를 생성하면 생성 방법을 미세하게 조정할 수 있습니다. 예를 들어 텍스처 형식이나 축척 비율을 결정할 수 있습니다.
해당 설정의 문제점: 일단 텍스처가 생성되면 더 이상 변경할 수 없습니다. 따라서 텍스처가 생성될 때 올바른 설정이 적용되었는지 확인해야 합니다. 애셋 관리자는 이러한 종류의 구성도 지원합니다:
var assets:AssetManager = new AssetManager();
assets.textureFormat = Context3DTextureFormat.BGRA_PACKED;
assets.scaleFactor = 2;
assets.enqueue(EmbeddedAssets);
애셋 관리자는 자신이 생성한 모든 텍스처에 대해 이러한 설정을 준수합니다. 그러나 이것은 모든 로드된 텍스처에 대해 하나의 속성 집합만 허용하는 것으로 보입니다. 사실은 아닙니다: 각 호출을 대기열에 넣기 전에 올바른 설정을 지정하고 여러 단계로 대기열에 넣기만하면 됩니다.
assets.scaleFactor = 1;
assets.enqueue(appDir.resolvePath("textures/1x"));
assets.scaleFactor = 2;
assets.enqueue(appDir.resolvePath("textures/2x"));
이렇게 하면 1x 및 2x 폴더의 텍스처가 각각 1 및 2의 축척 비율을 사용하게 됩니다.
2.7.2. 애셋 로딩
애셋이 대기열에 추가되었으므로 이제 모든 애셋을 한꺼번에 로드할 수 있습니다. 적재중인 애셋의 수와 크기에 따라 다소 시간이 걸릴 수 있습니다. 이러한 이유로 사용자에게 진행률 막대 또는 로드 표시기를 표시하는 것이 좋습니다.
assets.loadQueue(function(ratio:Number):void
{
trace("Loading assets, progress:", ratio);
// 비율[ratio]이 '1'이면, 작업 종료.
if (ratio == 1.0)
startGame();
});
startGame 메서드는 직접 구현해야 하는 것입니다. 여기서 로딩 화면을 숨기고 실제 게임을 시작할 수 있습니다.
활성화된 자세한 속성을 사용하면 에셋에 액세스 할 수있는 이름이 표시됩니다:
[AssetManager] Adding sound 'explosion'
[AssetManager] Adding texture 'bird'
[AssetManager] Adding texture 'atlas'
[AssetManager] Adding texture atlas 'atlas'
[AssetManager] Removing texture 'atlas'
알아 차렸나요? 마지막 줄에서는 텍스처 아트라스를 생성한 직후에 아트라스 텍스처가 실제로 제거됩니다. 왜 그런가요?
아틀라스가 만들어지면 더 이상 아틀라스 텍스처에 관심이 없으며 텍스처 텍스처에만 포함됩니다. 따라서 실제 아틀라스 텍스처가 제거되어 다른 텍스처를 위한 슬롯이 해제됩니다. 비트맵 폰트에서도 마찬가지입니다.
2.7.3. 애셋에 액세스하기
끝으로: 대기열이 처리를 마쳤으므로 AssetManager의 다양한 get... 메소드를 사용하여 에셋에 액세스할 수 있습니다. 각 애셋은 애셋의 파일 이름 (확장자 없음) 또는 포함 된 개체의 클래스 이름으로 참조됩니다.
var texture:Texture = assets.getTexture("bird"); (1)
var textures:Vector.<Texture> = assets.getTextures("animation"); (2)
var explosion:SoundChannel = assets.playSound("explosion"); (3)
(1) 먼저 명명 된 텍스처를 검색 한 다음 아틀라스를 찾습니다.
(2) 위와 같지만 주어진 문자열로 시작하는 모든 (서브) 텍스처를 반환합니다.
(3) 사운드를 재생하고 사운드를 제어하는 사운드 채널을 반환합니다.
도중에 비트맵 폰트를 대기열에 추가하면, 이미 등록되어 사용할 준비가 되었을 것입니다.
내 게임에서는 일반적으로 정적 속성을 통해 액세스할 수있는 루트 관리자에 자산 관리자에 대한 참조를 저장합니다. 따라서 Game.assets.get...() (루트 클래스가 Game이라고 가정 할 때)를 호출하여 게임의 어느 곳에서나 내 애셋에 쉽게 액세스할 수 있습니다.