2.7. 애셋 관리(Asset Management)

한 가지 분명한 사실은 모든 응용 프로그램의 자원에서 텍스처가 차지하는 비중이 가장 크다는 것입니다. 특히 게임에는 많은 그래픽이 필요합니다. 사용자 인터페이스에서 문자 항목 배경 등으로 변환할 수 있습니다. 하지만 그것이 전부는 아닙니다. 사운드 및 구성 파일을 관리해야 할 수도 있습니다.

이러한 애셋을 참조하려면 몇 가지 옵션이 있습니다.

  • 애플리케이션 내부에 바로 임베드합니다 ([Embed] 메타 데이터를 통해).

  • 디스크에서 로드하기 (AIR 응용 프로그램에서만 가능).

  • URL에서 로드하기 (예: 웹 서버에서).

모든 옵션에는 애셋 유형 및 로드 메커니즘에 따라 다른 코드가 필요하기 때문에 일관된 방식으로 애셋에 액세스하기가 어렵습니다. 고맙게도 Starling에는 AssetManager와 함께 도움이 되는 클래스가 있습니다.

다음 유형의 애셋을 지원합니다:

  • 텍스처 (비트 맵 또는 ATF 데이터에서)

  • 텍스처 아틀라스

  • 비트맵 폰트

  • 사운드
  • XML 데이터

  • JSON 데이터

  • 바이트 어레이(ByteArrays)

이를 달성하기 위해, AssetManager는 3단계 접근법을 사용합니다:

  1. 애셋에 대한 포인터를 대기열에 추가합니다. (예: 파일 오브젝트 또는 URL)

  2. 대기열을 처리하도록 AssetManager에 지시합니다.

  3. 대기열에서 처리가 완료되면 해당 ‘get’메소드를 사용하여 모든 에셋에 액세스할 수 있습니다.

AssetManager에는 자세한 정보가 들어 있습니다. 사용하도록 설정하면 대기열에 포함되고 로드되는 모든 단계가 콘솔로 추적됩니다. 이는 디버깅에 유용하거나 특정 애셋이 왜 보이지 않는지 이해하지 못하는 경우에 유용합니다! 이러한 이유로 Starling 최신 버전에서는 기본적으로 활성화되어 있습니다.

2.7.1. 애셋을 대기열에 넣기

첫 번째 단계는 사용하려는 모든 애셋을 큐에 넣는 것입니다. 그것이 어떻게 완료되었는지는 각 애셋의 유형과 출처에 따라 다릅니다.

디스크 또는 네트워크의 애셋

디스크 또는 원격 서버에서 파일을 대기열에 넣는 것은 다소 간단합니다:


1
2
3
4
5
6
7
8
9
// 원격 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가 나중에 아틀라스를 만들 때 찾을 것이기 때문입니다.


1
2
assets.enqueue(appDir.resolvePath("textures/atlas.xml"));
assets.enqueue(appDir.resolvePath("textures/atlas.png"));

비트맵 폰트는 동일하게 작동합니다. 이 경우 XML (.fnt 파일)의 파일 특성이 올바르게 설정되어 있는지 확인해야 합니다.


1
2
assets.enqueue(appDir.resolvePath("fonts/desyrel.fnt"));
assets.enqueue(appDir.resolvePath("fonts/desyrel.png"));
임베디드 애셋

임베디드 애셋의 경우 모든 임베드 명령문을 하나의 전용 클래스에 넣는 것이 좋습니다. public static const로 선언하고 명명 규칙을 따릅니다:

  • 삽입된 이미지의 클래스는 확장자가 없는 파일과 완전히 동일한 이름이어야 합니다. 이것은 XML (atlas, bitmap font)의 참조가 깨지지 않도록 하기 위해 필요합니다.

  • 아틀라스 및 폰트 XML 파일은 파일 이름으로 절대 참조되지 않으므로 임의의 이름을 가질 수 있습니다.

다음은 그러한 클래스의 샘플입니다:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}

해당 클래스를 큐에 넣으면 나중에 애셋 관리자가 포함된 모든 애셋을 인스턴스화 합니다.


1
2
var assets:AssetManager = new AssetManager();
assets.enqueue(EmbeddedAssets); (1)

(1) 새(bird) 텍스처, 폭발음 및 텍스처 맵을 큐에 넣습니다.

애셋 별 구성

Texture.from…() 팩토리 메소드를 통해 수동으로 텍스처를 생성하면 생성 방법을 미세하게 조정할 수 있습니다. 예를 들어 텍스처 형식이나 축척 비율을 결정할 수 있습니다.

해당 설정의 문제점: 일단 텍스처가 생성되면 더 이상 변경할 수 없습니다. 따라서 텍스처가 생성될 때 올바른 설정이 적용되었는지 확인해야 합니다. 애셋 관리자는 이러한 종류의 구성도 지원합니다:


1
2
3
4
var assets:AssetManager = new AssetManager();
assets.textureFormat = Context3DTextureFormat.BGRA_PACKED;
assets.scaleFactor = 2;
assets.enqueue(EmbeddedAssets);

애셋 관리자는 자신이 생성한 모든 텍스처에 대해 이러한 설정을 준수합니다. 그러나 이것은 모든 로드된 텍스처에 대해 하나의 속성 집합만 허용하는 것으로 보입니다. 사실은 아닙니다: 각 호출을 대기열에 넣기 전에 올바른 설정을 지정하고 여러 단계로 대기열에 넣기만하면 됩니다.


1
2
3
4
5
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. 애셋 로딩

애셋이 대기열에 추가되었으므로 이제 모든 애셋을 한꺼번에 로드할 수 있습니다. 적재중인 애셋의 수와 크기에 따라 다소 시간이 걸릴 수 있습니다. 이러한 이유로 사용자에게 진행률 막대 또는 로드 표시기를 표시하는 것이 좋습니다.


1
2
3
4
5
6
7
8
assets.loadQueue(function(ratio:Number):void
{
    trace("Loading assets, progress:", ratio);

    // when the ratio equals '1', we are finished.
    if (ratio == 1.0)
        startGame();
});

startGame 메서드는 직접 구현해야 하는 것입니다. 여기서 로딩 화면을 숨기고 실제 게임을 시작할 수 있습니다.

활성화된 자세한 속성을 사용하면 에셋에 액세스 할 수있는 이름이 표시됩니다:


1
2
3
4
5
[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… 메소드를 사용하여 에셋에 액세스할 수 있습니다. 각 애셋은 애셋의 파일 이름 (확장자 없음) 또는 포함 된 개체의 클래스 이름으로 참조됩니다.


1
2
3
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이라고 가정 할 때)를 호출하여 게임의 어느 곳에서나 내 애셋에 쉽게 액세스할 수 있습니다.