『ActionScript: The Definitive Guide』의 저자 콜린 무크
플래시에서 프리로더는 요청된 데이터 본문의 일부가 다운로딩을 끝낼 때까지 무비의 재생을 보장하면서 무비를 잠시 중단 시키는 코드 모듈이다. 예를 들어 프리로더는 플레이 하기 전에 애니메이션이나 사운드가 충분히 버퍼되도록 보장해 주며 조작되고 보여지기 전에 일련의 변수들을 전송하도록 해준다. 이러한 데이터 형식 하나하나를 위해 서로 다른 기술들이 프리로더에 대응하는 것을 구축하는데 사용된다. 이 기사에서 우리는 이러한 기술에 대해 살펴볼 것이며 가장 간단한 싱글 무비를 위한 프리로더로부터 시작할 것이다. 이 기사에서 제공되는 코드 예제는 모두 플래시 5 액션스크립트 구문을 사용한 것임을 명심하라.
샘플 다운로드
이 기사에서 기술된 프리로더 예제는
여기서 다운로드할 수 있다. 뮤직 플레이어 예제는 드래그할 수 있는 플레이해드로 확장되어졌다는 것을 명심해라(단, 이 기사에서는 다루지 않음).
싱글 무비 프리로더
싱글 플래시 .swf 파일은 자급식 단위로 되어있다. 그 파일의 컨텐츠인 그래픽, 사운드, 무비 클립, 버튼 및 스트립트 등은 메인 타임라인의 프레임 위에 분산되어 있다. 메인 타임라인 프레임의 다운로드 진행상황을 모니터함으로써 무비의 컨텐츠가 적절하게 실행되기 전에 플레이 하는 것을 방지할 수 있다. 그 결과 충분한 프레임이 전송된 후에야 무비를 플레이 할 수 있다. 기본적인 싱글 무비 프리로더를 만들기 위해 아래의 사항을 단계별로 따라 해보자.
- 새로운 무비를 만든다.
- 디폴트 Layer 1 층에 100개의 프레임을 추가한다(실재로 15개 이상만 되면 사용할 수 있으나 이 예제를 위해 꼭 100개를 추가하는 것이 좋겠다.).
- Layer 1 층의 프레임 15에 공백 Keyframe을 추가한다(삽입-->:Blank Keyframe).
- Layer 1 층의 프레임 15와 프레임 100 사이에 컨텐츠가 풍부한 Keyframe들을 추가한다(참고로 사운드와 비트맵은 컨텐츠 용량을 많이 차지하게 하는데 좋다).
- 메인 타임라인 위에 script라고 불리는 새로운 계층을 만든다.
- 메인 타임라인 위에 label이라고 불리는 새로운 계층을 만든다.
- Labels의 프레임 4에 공백 Keyframe을 추가한다.
- 변경한다.--> label에서 프레임으로 새로운 keyframe 전송
- label 층의 프레임 15에 공백 keyframe을 추가한다.
- 새로운 keyframe을 beginMovie라고 명명한다.
- Script 층의 프레임 5에 공백 keyframe을 추가하고 아래의 코드를 추가한다.
//플레이하기 전에 몇 개의 프래임을 전송할 것인지 명세해라.
var loadAmount = _totalframes;
//프래임의 요청된 숫자가 전송을 마치면…
if (_framesloaded == loadAmount) {
//…무비를 시작한다.
gotoAndPlay("beginMovie");
} else {
// ...otherwise, go back and check load progress again.
gotoAndPlay("loading");
}
|
이상으로 프리로더 작업을 마쳤다. 이제 여러분이 만든 것이 확실히 작동되는지 살펴볼 차례이다. 무비가 모뎀 속도와 상관없이 다운로드 되도록 하려면 테스트 무비 모드에서 사용할 수 있는 대역폭 프로파일러(Bandwidth Profiler)라고 불리는 테스트 도구를 사용해야 한다. 아래는 대역폭 프로파일러를 작동시키는 방법을 설명한 것이다.
- 여러분이 만든 무비를 편집하는 동안 Control을 선택한다. --> 테스트 무비
- 테스트 무비 모드에서 View를 선택한다. --> 대역폭 프로파일러
- 디버그 메뉴 아래에서 원하는 다운로드 속도를 선택한다.
- 선택한 속도에서 무비를 다운로드하기 위해 View를 선택한다. --> 쇼 스트리밍
대역폭 프로파일러 맨 위에 보이는 녹색 바를 주의해서 보아야 한다. 녹색 바는 무비의 다운로드 정도를 보여주기 때문이다. 무비가 전송되는 동안 프레임 4의 재생 포즈에 주목해야 한다. 만약 목표 속도에서 너무 오랫동안 지연되고 있다면 여러분이 작성한 무비를 조각 조각으로 분리해야 할 것을 고려해 보아야 하기 때문이다. 메인 무비 타임 라인에 다중 프리로더를 첨가하거나 컨텐츠를 여러분이 필요한 만큼만 전송하는 분리 .swf 파일로 분리시켜 보자(프리로딩 다중 .swf 파일에 대해서는 나중에 다루기로 한다). 대역폭 프로파일러는 오로지 싱글 무비 프리로더를 테스트 하는데 사용될 수 있다. 대역폭 프로파일러는 전송된 변수나 XML 또는 loadMovie()를 통해 전송된 무비의 진전상황을 보여주지 않기 때문이다.
프리로더에 대한 독창적인 예제들은 『ActionScript: The Definitive Guide』의 저자인 콜린이 그의 저서를 위해 최근 제작한
자매 사이트를 방문해 하면 볼 수 있다. 플래시 사이트 자체가 로딩 바를 네비게이션 메뉴에 있는 그래픽적 요소로 변형시키는 동안 이 책의 무비 예고편은 프리로더로서 알사탕(3차원 구들이 회전)을 사용한다(물론 플래시가 요구됨).
이제 대역폭 프로파일러와 함께 움직이고 있는 프리로더에 대해 살펴봤다면 프레임 5에 첨부한 코드를 조사함으로써 작동시키는 방법에 대해 생각해 보도록 하자. 첫 번째 문장에서 우리는 프리로드 할 프레임이 몇 개나 되는지 지시하는 변수와 loadAmount를 생성했다.
var loadAmount = _totalframes;
|
예제에서는 loadAmount를 _totalframes로 지정했으며 _totalframes은 무비 클립이나 메인 타임라인에 여러 개의 프레임을 저장하는 내장형 액션스크립트 속성이다. _totalframes을 사용함으로써 코드 일반(프리로드하기 원하는 프레임의 숫자는 액션스크립트에 의해 결정되는 타임라인에 있는 프레임의 숫자)을 유지할 수 있다.
어쨌든 간에 우리는 플래시가 컨텐츠를 스트림(플래시가 전송을 계속해서 사용하는 동안 무비를 전송할 수 있음)한다는 사실을 기억해 두어야 한다. 무비의 일부분만을 프리로드하고 유저가 쇼를 보고있는 동안 그 나머지 부분은 그냥 전송시킨다는 것은 현명한 생각이다. 무비의 일부분만을 프리로드 하기위해 우리는 _totalframes에 있는 숫자보다 더 작은 숫자로 loadAmount를 설정했다. 프리로드하기 적당한 부분을 결정하기 위해 사이트가 목표로 하는 모뎀 속도에서 대역폭 프로파일러를 사용해라.
몇 개의 프레임을 프리로드 해야 할지 결정한 후(우리의 경우에는 모두 프리로드 하는 것이겠지만), 그 결정한 양이 다운로딩을 끝낼 수 있는지 없는지를 점검해봐야 한다. 우리는 내장 프로퍼티 _framesloaded(몇 개의 프레임을 전송했는지 지시해 주는 것)와 loadAmount(무비가 플레이 되기 전에 몇 개의 프레임이 전송되어야 하는지 지시해 주는 것)를 비교해 보아야 한다.
if (_framesloaded == loadAmount) {
|
두 값이 같을 경우에만 요청된 프레임들이 전송되고 그 결과 무비 플레이를 실행할 수 있다.
gotoAndPlay("beginMovie");
|
그렇지만 두 값이 다를 경우, 요청된 프레임은 전송되지 않고 그 결과 우리는 플레이해드를 전송 프레임으로 보내야 한다(우리가 작성한 예에서는 프레임4).
거기서 무비는 다시 플레이를 시작하고 프레임 5로 다시 들어가서 몇 개의 프레임이 전송되었는지 다시 점검한다. 따라서 플레이해드는 안전하게 beginMovie 프레임으로 나아갈 수 있는 시점인 요청된 프레임의 숫자가 로드될 때까지 타임라인의 루프안에 빠져있게 된다. 간단하지만 효과적이다.
이러한 기술에 대한 몇 가지 주의 사항은 다음과 같다.
- 무비의 첫번째 프레임에 있는 스크립트는 아주 자주 플래시 플레이어가 생략하고 지나가기 때문에 프리로더는 프레임 1보다는 프레임 5에서 시작한다. 따라서 프리로더가 무비의 시작을 더 쉽게 해줄 새로운 컨텐츠를 추가하기 전에 약간의 여유 공간을 남겨두어야 한다.
- 프리로드 점검을 너무 자주 하지 않도록 하려면 프레임 4와 프레임 5 사이에 새로운 프레임을 추가해야 한다. 이러한 것은 특정 지점에서만 끝나야 하는 프리로드 애니메이션이나 사운드를 플레이 할 경우 아주 유용하다.
- 우리는 이제 프리로더에서 예전에 사용했던 ifFrameLoaded 선언을 더 이상 사용하지 않는다. 그것은 우리가 사용하는 코드보다 덜 유연하다.
저 기술: 층 전송 순서와 함께 프리로딩하기
프레임 5에서 시작하는 프리로더를 만든 후라면 여러분은 분명히 만약 프레임 1부터 프레임 4 사이에 컨텐츠가 있다면 무슨 일이 일어날지 궁금할 것이다. 만약 플래시가 프레임을 표현하려고 할 때 프레임이 충분히 전송되지 않을 경우 컨텐츠가 전송됨에 따라 한꺼번에 한 층에 그 컨텐츠가 보여질 것이다. 층들은 파일-->발행 설정-->플래시-->전송 순서 하에서 무비를 위한 전송 순서에 따라 하의상달 또는 상의하달 방식으로 전송한다.
우리는 "pre-프리로더"를 구축하기 위해 이러한 장점을 사용할 수 있다. 간단히 개별 층위에 로고를 분리시킴으로써 우리는 유저에게 초기 로드 진행 상황을 지시해주는 기본적인 애니메이션을 생성해낼 수 있다. [그림 1]에서 단어"moock"의 각 알파벳은 각각의 층마다 놓여져 있으며 애니메이션 결과는 [그림 2]에서 보는 바와 같다.
[그림 1] 층위에 컨텐츠 분리시키기
[그림 2] 층위에 있는 컨텐츠의 진행 상황 그림
이와 같이 층 전송 순서에 기반을 둔 간단한 애니메이션은 유저에게 무비가 다운로딩을 시작했지만 얼마나 기다려야 하는지에 대해서는 알려주지 않는다는 것을 알 수 있다. 얼마나 기다려야 하는지에 대해서는 다음에서 배우기로 하자.
전송 진행 상황 보여주기
앞에서 우리는 특정한 숫자의 프레임이 다운로드될 때까지 성공적으로 무비의 재생을 지연시킬 수 있었다. 이제는 무비가 전송되는 동안(그렇지 않으면 플래시 플레이어가 확실하게 작동하는 것처럼 보이는 동안) 유저에게 얼마나 기다려야 하는지를 보여주는 방법에 대해 알아보기로 하자. [그림 3]에서 보는 바와 같이 우리는 싱글 무비 프리로더에 다음과 같은 특징들을 추가할 것이다.
- 무비의 파일 사이즈를 킬로바이트로 보여주는 텍스트 영역
- 다운로드된 킬로바이트 숫자를 보여주는 텍스트 영역
- 무비 다운로드 진행상황을 퍼센트로 보여주는 텍스트 영역
- 무비의 다운로드 상태를 그래픽적으로 보여주는 프리로드 바
[그림 3] 전송 상황을 보여주는 스크린
플래시 작업을 해준 후에 프리로드 스크립트를 업데이트해야 한다. 진행상황 보여주는 컨텐츠를 위해 메인 타임라인 위에 층들을 생성하는 것부터 시작해보자.
- 메인 타임라인에 두 개의 새로운 층을 생성하고 하나는 바, 다른 하나는 텍스트 영역이라고 명명한다.
- 바와 텍스트 영역 층의 프레임4에 공백 keyframe을 추가한다.
- 바와 텍스트 영역 층의 프레임 15에 공백 keyframe을 추가한다.
다음은 두 개의 무비 클립으로 구성된 프리로드 바를 만드는 과정이다.
- loadBarHousing이라고 불리는 무비 클립 심볼을 만들어라.
- loadBarHousing에 높이 8픽셀 너비 140픽셀의 직사각형 모양의 아웃라인을 잡아준다(직사각형 안은 채우지 말 것).
- loadBarHousing에 있는 직사각형을 선택한 후 Window-->Panels-->Info을 차례로 실행한다.
- 클립의 등록 점에 직사각형의 왼쪽 끝을 X좌표는 0, Y좌표는 ?4에 오게 위치시켜라.
- loadBar라고 불리는 무비 클립 심볼을 만들어라.
- loadBar에 높이 8픽셀 너비 1픽셀의 직사각형을 만들어라(직사각형의 아웃라인은 잡아주지 말 것).
- loadBar에 있는 직사각형을 선택한 후 Window-->Panels-->Info을 차례로 실행한다.
- 클립의 등록 점에 직사각형의 왼쪽 끝을 X좌표는 0, Y좌표는 ?4에 오게 위치시켜라.
프리로드 바 클립이 완성이 되었다. 이제는 완성된 것을 Stage에 놓을 차례이다.
- 바 층의 프레임4에 loadBarHousing의 인스턴스를 놓는다.
- 인스턴스를 loadBarHousing이라고 명명한다(변경--> 인스턴스).
- 바 층의 프레임 4에 loadBar의 인스턴스를 놓는다.
- 인스턴스를 loadBar라고 명명한다.
- loadBarHousing과 loadBar 인스턴스를 선택한다.
- 일렬 패널(Window-->Panels-->Align)에서 일렬 왼쪽 버튼(패널의 왼쪽 최상위 버튼)과 일렬 바닥 버튼(패널의 오른쪽 최상위 버튼)을 선택한다.
마지막으로 프리로더를 위한 킬로바이트 및 퍼센트 정보를 나타내는 텍스트 영역을 만들어 보자.
- 텍스트 도구를 선택한다.
- 텍스트 영역 층의 프레임 4에 세자리 숫자를 써넣을 수 있을 정도로 충분한 텍스트 박스를 끌어낸다.
- Text-->Options를 선택한다.
- 텍스트 옵션 패널에서 정적 텍스트를 동적 텍스트로 바꾼다.
- 텍스트 옵션 패널에서 삽입 폰트 하에서 전체 폰트 아웃라인을 포함하도록 선택해라([…] 버튼). (단지 문자만을 삽입해야 하는 작업 상황이기 때문에 실제로 여러분은 텍스트 영역을 사용하는 것이다. 지금과 같은 경우에는 숫자와 퍼센트 표시)
- 변수 텍스트 영역에 bytesLoadedOutput을 타이핑한다.
- 위에서 말한 1번에서 6번을 반복해서 실행하여 bytesTotalOutput와 percentOutput이라고 명명되는 텍스트 영역을 두 개 더 만든다.
- 각각의 텍스트 영역 옆에 Loaded: , Total: , Percent: . 처럼 컨텐츠를 기술하는 정규 통계 텍스트를 추가한다.
이제 흥미롭게 보이는 파트가 프레임 5에 대한 코드로 새로이 업데이트 되었으며 다음과 같이 프로그램을 읽을 것이다(우리는 else절의 컨텐츠를 바꾸기만 했지만 코드는 온전히 다 보여짐).
// 플레이 하기 전에 몇 개의 프레임을 전송할 것인지 명세해라.
var loadAmount = _totalframes;
// 만약 요청된 프레임의 숫자가 전송을 끝낸다면…
if (_framesloaded == loadAmount) {
// 무비를 시작한다.
gotoAndPlay("beginMovie");
} else {
// 그렇지 않으면 전송 상태를 보여주고…
// 그런 후 되돌아가서 전송 진행상황을 다시 점검한다.
// 첫째, 전송된 킬로바이트와 총 킬로바이트를 결정한다.
loaded = Math.round(getBytesLoaded() / 1024);
total = Math.round(getBytesTotal() / 1024);
percent = Math.round((loaded/total) * 100);
// 텍스트 영역에
// 전송된 킬로바이트, 총 킬로바이트, 전송된 킬로바이트의 퍼센트를 보여주어라.
bytesLoadedOutput = loaded;
bytesTotalOutput = total;
percentOutput = percent + "%";
// loadBar의 폭에 해당하는 부분에
// loadBarHousing의 퍼센트를 설정해라
loadBar._width = loadBarHousing._width * (percent / 100);
// 이제 되돌아 가서 전송 진행상황을 점검한다.
gotoAndPlay("loading");
}
|
프리로더를 테스트하기 위해 대역폭 프로파일러를 사용해라. 타임라인에 컨텐츠가 많으면 많을수록 프리로드 바가 작동하는 것을 더 잘 볼 수 있다.
프레임 5에서 우리가 작성한 코드의 변경사항을 점검해보자. 위에서처럼 전송된 프레임의 숫자와 요청된 loadAmount가 맞아 떨어지면 무비를 시작할 것이다.
if (_framesloaded == loadAmount)
|
그렇지만 이번에 만약 요청된 프레임의 숫자가 아직 전송되지 않았다면 전송 프레임으로 플레이해드를 되돌려 보내기 전에 스크린위에 보이는 텍스트 영역과 프리로드를 업데이트 시켜야 할 것이다. 우선 우리는 몇 킬로바이트가 전송되었는지 계산해야 한다. getBytesLoaded() 무비 클립 메소드는 몇 바이트가 전송되었는지 말해준다(킬로바이트로 변환하기 위해 1,024로 반환값을 나누었음). 출력 결과를 읽어보기 쉽게 하기위해 우리는 Math.round()를 사용한 결과를 반올림 하였다.
loaded = Math.round(getBytesLoaded() / 1024);
|
다음에 할 일은 전체 무비가 몇 킬로바이트인지 계산해보는 것이다. 무비의 사이즈를 바이트로 환산하기위해 getBytesTotal() 메소드를 사용했다. 1,024로 나누고 반올림하여 다시 킬로바이트로 변환하였다.
total = Math.round(getBytesTotal() / 1024);
|
전체 무비의 몇 퍼센트나 다운로드 되었는지 알아보기 위해 현재 전송된 양을 전체로 나누고 그 결과에 100을 곱했다. Math.round()를 사용해 그 결과를 반올림하여 보기 쉽게 정수로 환산해 내었다.
percent = Math.round((loaded/total) * 100);
|
계산값을 스크린 위에 나타내기 위해 우리는 전송량, 전체량, 텍스트 영역에 상응하는 퍼센트를 할당하였다.
bytesLoadedOutput = loaded;
bytesTotalOutput = total;
percentOutput = percent + "%"; // 디스플레이 목적으로 % 기호를 더해라
|
마지막으로 우리는 프리로드 바의 너비를 설정하였다. 무비가 완전히 전송되었을 때 loadBar의 너비가 loadBarHousing의 너비 만큼은 되어야 한다는 사실은 알고 있다. 무비가 계속해서 전송하고 있을 때 loadBar의 너비가 loadBarHousing 너비의 일부분을 차지해 나감으로 두 너비의 최대 폭은 같아야 한다. 우리는 이미 무비의 전송된 퍼센트를 계산해 놓았기 때문에 퍼센트 변수값에 따라 loadBar의 _width 프로퍼티를 loadBarHousing 퍼센트의 _width 프로퍼티에 적절하게 설정하기만 하면 된다.
loadBar._width = loadBarHousing._width * (percent / 100);
|
전송 진행상황 보여주기가 업데이트 되었다면 프리로드 점검을 실행하고 플레이 할 지점인 전송 프레임으로 무비를 다시 돌려보낸다.
독자 연습: 이론상으로 무비가 전송되는 동안 우리는 사용자의 관심을 알사탕 그래픽이나 이야기, 게임의 서두 또는 다른 장난감 같은 것으로 전환시켜야 한다. 프레임 4에 있는 오락 무비 클립에 이러한 것들은 추가할 수 있는지 한 번 살펴보자. 사용자의 관심을 분산시킬 이러한 작은 소품들을 빨리 전송할 수 있게 작게 만들어야 함을 명심해라. 만약 너무 크게 만들경우 프리로더를 프리로드 해아만 하는 사태가 발생 할지도 모른다.
멀티플 무비 프리로더
loadMovie()를 사용해서 외부 .swf 파일을 무비 클립(타겟이라 불림)이나 문서 수준으로 전송할 수 있다. 외부로 전송된 .swf 파일은 싱글 플래시 무비처럼 정확하게 프리로드 될 수 있다. 예를 들어 세 가지 섹션(제품, 연락처, 회사소개)으로 링크될 메인 메뉴가 있는 플래시 사이트를 생각해보자. 각각의 섹션에는 분리 .swf 파일(products.swf, contact.swf, aboutus.swf)이 있다. 사이트의 홈페이지인 menu.swf는 레벨1로 각 섹션을 전송하는 버튼을 아래와 같이 제공한다.
on (release) {
loadMovie("products.swf", "_level1");
}
|
제품 섹션을 프리로드하기 위해 우리는 products.swf의 메인 타임라인 위에 정확하게 싱글 무비 프리로더를 놓았다. products.swf가 레벨 1로 전송되는 동안 프리로더는 다운로드를 관리할 것이다.
그렇지만 이와 같은 접속이 비능률적일 때가 있다. 예를 들어 우리가 멀티플 사운드트랙 .swf 파일을 호스트라고 불리는 싱글 타겟 인스턴스로 전송하는 뮤직 플레이어를 구축한다고 가정해보자. 이 경우에는 모든 .swf 파일을 위해 분리 프리로더를 만드는 것보다 호스트로 전송된 파일이라면 모두 다운로드 되도록 관리하는 싱글 일반 프리로더를 만드는 것이 훨씬 더 낫다. 그렇다면 이러한 작업을 어떻게 하는지 살펴 보도록 하자. 사운드트랙 무비를 호스트 클립으로 전송하는 일련의 버튼을 만드는 것부터 시작하도록 한다. 첫 번째 버튼에 대한 코드는 아래와 같다.
on (release) {
host.loadMovie("soundtrack1.swf");
}
|
soundtrack1.swf를 호스트로 전송하면 호스트가 자동적으로 파일을 프리로드 되는 것이 사용하기 편리하다. 이 때문에 우리는 호스트 클립에 약간의 조작을 해줄 필요가 있다. 무비가 호스트 클립으로 전송될 때 다운로드를 다룰 커스텀 preload() 함수를 호출해야 한다. 필요시 _root.preload()를 호출하고 호스트에 있는 파일을 모니터하기 위해 아래의 enterFrame 무비 클립 이벤트를 사용할 것이다.
onClipEvent (enterFrame) {
// 호스트 클립이 외부 .swf 파일을 갖고 있다면…
if (this._url != _root._url) {
// 전송 .swf 파일의 다우로드 진행상황을 보여주는
// preload() 함수를 호출한다.
_root.preload(this);
}
}
|
각각의 프레임을 통과함에 따라 호스트의 enterFrame 핸들러에 있는 코드들이 실행된다. 만약 호스트의 파일명 (this._url)이 메인 뮤직 플레이어의 파일명 (_root._url)과 맞지 않으면 외부 무비는 호스트 내에 있어서 우리가 preload() 함수를 실행해야 한다. preload() 함수는 전송 진행 상황을 보여줄 것이며 호스트 내에 있는 무비를 플레이 할 때를 선택적으로 결정할 것이다.
preload()가 어떻게 작동하는지 살펴보기 전에 금방 보여졌던 enterFrame 핸들러가 이 상황에서 사용하기 가장 좋은 핸들러가 아닌 것은 확실하다. 이론상으로는 데이터가 무비 클립으로 전송될 때만 실행하는 데이터 이벤트에서 preload()를 호출하는 것이 더 낫다. 하지만 불행하게도 나는 데이터 이벤트가 항상 빠르게 접속(DSL, Cable, T1)하는 것이 아리라는 것을 발견했다. 이것은 아직 확실히 검증된 버그는 아니지만 preload() 호출을 enterFrame 핸들러로 이동시키기 충분한 문제를 야기시킨다. 나는 이 사항을 이미 매크로미디어에 보고하였으며
나의 웹 사이트에서 이에 대한 해결책을 보고할 것이다.
이제 preload() 함수로 돌아가보자. 아래의 사항들을 대충 훑어보면서 그 함수가 어떻게 작동하는지 익힌 후 이에 대해 상세히 분석해 보자.
function preload (theClip) {
if (!theClip.doneLoading) {
// 모든 프레임을 갖고 있다면
// 다운로드가 완료되었다는 메시지를 만들어라.
if (theClip._framesloaded > 0
&& theClip._framesloaded == theClip._totalframes) {
theClip.doneLoading = true;
// 일단 전송이 완료되면 선택적으로 클립을 시작한다.
// 클립은 theClip.play();
} else {
// 전송이 될 때까지 선택적을 클립을 일시 중지한다.
// 클립은 theClip.stop();
}
// 텍스트 영역에 있는 로딩 바이트 카운트를 보여주어라.
bytesLoadedOutput = theClip.getBytesLoaded();
bytesTotalOutput = theClip.getBytesTotal();
// 클립으로 전송되고 있는 .swf 파일명을 빼내어 와서
// 그것을 텍스트 영역 내에 보여주어라.
var lastSlash = theClip._url.lastIndexOf("/");
clipURLOutput = theClip._url.substring(lastSlash + 1,
theClip._url.length);
// 로딩 바의 너비를 설정하자.
var percentLoaded = (theClip.getBytesLoaded()
/ theClip.getBytesTotal());
preloadBar._width = preloadBarBG._width * percentLoaded;
}
}
|
[
편집자 주: 라인 20번과 22번은 우리 웹 사이트의 포맷 형식에 맞게 각각 두 줄로 확장되었다. 이 기사 전체에서 코드 라인이 두 라인으로 쪼개지는 경우 두 번째 라인은 의도적으로 이와 같이 설정된 것임을 기억하기 바란다.]
preload() 함수는 theClip이라는 하나의 매개변수만을 갖으며 그것은 클립을 프리로드 하기위한 참조이다(하나 이상의 호스트 클립의 가능성을 허용하는).
function preload (theClip) {
|
외부의.swf 파일이 호스트에게 있는 한 preload() 함수가 프레임마다 한 번씩 호출되는 것을 생각해보자. 파일이 완전히 전송된다면 프리로딩 코드를 실행시키는 것은 시간 낭비이기 때문에 preload()의 첫 번째 역할은 theClip이 전송을 끝냈는지 그렇지 않은지를 점검하는 것이다.
if (!theClip.doneLoading) {
|
전송이 완료되면 변수 doneLoading은 theClip내에 설정될 것이다. 만약 변수가 존재하지 않는다면 프리로딩 코드를 실행시킬 필요가 있다. 프리로딩 코드 자체로는 큰 변화가 많지는 않을 것이다. 지금까지 전송된 프레임의 숫자가 무비의 총 프레임 숫자와 일치하는지 체크하는 것부터 시작했지만 여기서는 적어도 하나 이상의 프레임이 있어야 한다는 사실을 잊어서는 안된다.
if (theClip._framesloaded > 0
&& theClip._framesloaded == theClip._totalframes) {
|
전송되지 않은 클립의 컨텐츠는 _totalframes를 0으로 설정하기 때문에 타겟 클립으로 무비 전송 작업을 할 때에는 _framesloaded > 0 이라는 안전장치가 필요하다. 그러므로 _framesloaded == _totalframes의 아주 느린 접속 비교는 전송된 프레임이 전혀 없을 때에도 참 값이 될 수 있다(왜냐하면 _totalframes과 _framesloaded이 모두 0이 될 수도 있기때문). theClip내에 있는 모든 프레임들이 전송되었다는 것을 알게되면 더 이상 프리로딩 코드를 실행시킬 필요가 없다는 것을 알려주는 플래그를 설정한다.
theClip.doneLoading = true;
|
이 시점에서 우리는 간단히 실행시켜 주는 것만으로도 무비(안전하게 전송되었는지 알려주는)를 플레이할 수 있다.
그렇지만 뮤직 플레이어 예제에서 우리는 MP3 플레이어처럼 전송이 되자마자 막 바로 무비가 플레이를 시작하도록 설정했기 때문에 theClip.play()를 호출할 필요는 없다.
만약 theClip에 있는 모든 프레임들을 아직 전송하지 않았다면 우리는 다음과 같이 작성함으로써 너무 빨리 플레이 하는 것을 방지할 수 있다.
} else {
theClip.stop();
}
|
그렇지만 우리의 예제에서는 무비를 중지시킬 필요까지는 없다. 우리는 뮤직이 플래시 플레이어로 스트리밍 되어 나오는 동안 무비가 플레이 되도록 놓아두어도 된다. 어떤 이벤트이든 간에 우리는 텍스트 영역과 프리로드 바의 업데이트 상황을 항상 보고 싶어한다. 이번에는 이전 예제에서 우리가 조작했던 것처럼 킬로바이트로 변환하는 것보다는 원래의 바이트로 그 결과를 보고싶어 할 것이다.
// 텍스트 영역에 로딩 바이트 카운트를 보여주어라.
bytesLoadedOutput = theClip.getBytesLoaded();
bytesTotalOutput = theClip.getBytesTotal();
// 클립으로 전송되는 .swf 파일명을 빼내어 와서
// 그것을 텍스트 영역내에 보여주어라.
var lastSlash = theClip._url.lastIndexOf("/");
clipURLOutput = theClip._url.substring(lastSlash + 1,
theClip._url.length);
// 로딩 바의 너비를 설정하여라.
var percentLoaded = (theClip.getBytesLoaded()
/ theClip.getBytesTotal());
preloadBar._width = preloadBarBG._width * percentLoaded;
|
theClip._url에서 마지막 슬래시 뒤에 오는 모든 것을 뽑아 냄으로써 전송중인 무비의 파일명을 보여주었다는 것을 명심해 두어야 한다. 이것이야말로 프리로더를 커스터마이즈하는 끊임없는 방법 중 하나이다. _alpha 프로퍼티를 설정하여 무비 전송으로서 클립을 사라지게 하거나 사운드의 크기를 증가시키거나 파일을 전송하는 데 걸리는 시간과 남은 시간 환산을 계산할 수도 있다. 뮤직 플레이어 예제를 위한 소스 파일에서 우리는 무지가 얼마나 전송되었나를 보여주었을 뿐만 아니라 얼마나 플레이 정도 까지도 보여주었다.
첨부된 사운드 프리로딩
이제 타겟 클립으로 전송된 무비를 위한 프리로더를 만들 차례이다. 우리는 그것을 전송 첨부 사운드로 쉽게 사용할 수 있다. 첨부된 사운드는 실행시간에 무비에 역동적으로 첨부되는 사운드이다. 사운드를 첨부하기 위해 우리는 우선 그것을 (옵션-->링크 하에 있는) 라이브러리로부터 가져온 후 사운드를 생성, 첨부, 플레이하기위해 내장 사운드 클래스의 인스턴스로 사용한다. 예를 들어 아래의 코드는 사운드 객체 bang에 사운드와 심볼 링크 식별자 loudBang을 덧붙이는 코드이다. 이것은 bang 사운드를 시작하고 중지시키는 코드이다.
// _root 타임라인의 범주에 드는 새로운 사운드 오브젝트를 생성해라.
bang = new Sound(_root);
// 라이브러리로부터 loudBang 사운드를 검색하고
// 그것을 bang에 첨부해라.
bang.attachSound("loudBang");
// bang 사운드를 시작해라.
bang.start();
// bang 사운드만 정지해라.
bang.stop("loudBang");
|
무비의 라이브러리에서 나온 사운드는 무비 시작 전에 전송 지연을 야기시키면서 무비의 첫 번째 프레임에서 다운로드되어야 한다. 이러한 전송 지연을 방지하기위해 필요할 경우(우리가 뮤직 플레이어 예제에서 무비를 전송했던 것과 똑같이) 타겟 클립으로 우리가 전송하는 분리 .swf 파일에 있는 외부로 나가는 사운드를 내놓을 수도 있다. 예를 들어 linkedSounds.swf에 외부로 나가는 사운드를 저장했다고 가정해 보자. 우리는 호스트 무비 클립으로 linkedSounds.swf를 전송하기위해 멀티플 무비 프리로더를 사용한다. 파일이 완전히 전송되면 우리는 다음과 같이 안전하게 외부로 나가는 사운드를 첨부하고 플레이할 수 있다.
// 호스트의 타겟으로 새로운 사운드를 생성해라.
host.bang = new Sound(host);
host.bang.attachSound("loudBang");
host.bang.start();
|
첨부된 사운드는 사운드 객체가 지정한 타켓(우리의 경우에는 호스트)의 라이브러리 내에서 이용할 수 있어야 한다. 전송된 무비 내에서 사운드 객체를 구축할 때 타겟 인자를 생략하는 것은 흔히 저지를 수 있는 실수이다. 타겟 인자가 제공되지 않으면 타겟은 _level0으로 초기설정이 되어 사운드가 검색될 수 없다. 예를 들어 호스트에서 사운드를 플레이하려는 아래의 시도는 _level0의 라이브러리에서 사운드 loudBang을 이용할 수 없기 때문에 실패할 것이다.
// _level0의 의도적인 타겟과 함께 새로운 사운드를 생성해라.
host.bang = new Sound();
// 이 실행결과는 실패한다. "loudBang"이 _level10의 라이브러리에 존재하지 않는다.
host.bang.attachSound("loudBang");
//사운드가 성공적으로 첨부되지 않았기 때문에 사운드는 시작되지 않을 것이다.
// host.bang을 구축할 때 타겟을 명세하는 것을 잊어버리는 실수를 했다.
host.bang.start();
|
XML과 전송된 변수들 프리로딩
XML과 변수들을 전송하는 것은
『ActionScript: The Definitive Guide』에서 완벽하게 다루었기 때문에 여기서 다시 반복하지는 않겠다. 아래에 제시한 요약 설명은 내가 쓴 책이나 매크로미디어의 문서와 관련된 정보를 찾아내는데 도움을 줄 것이다.
XML 문서를 프리로드하기 위해 우리는 XML 계열의 onLoad() 콜백 핸들러를 사용한다. 플래시가 XML.load()나 XML.sendAndLoad()를 통해 요청된 XML 문서의 전송이나 파싱을 끝냈을 때 onLoad() 핸들러는 자동적으로 실행한다. 대개의 구현에서 우리는 XML.load()를 호출한 후에 전송 메시지와 함께 프레임으로 무비를 보낸다. 그리고 재생을 다시 시작해도 안전하다는 것을 알려주는 onXML() 핸들러를 기다린다(예, 데이터를 가공하고 보여주는 것).
XML 객체에 의해 전송된 원래의 데이터를 절편하기위해서 우리는 문서화되지 않은 onData() 핸들러를 사용할 수 있다. 불행하게도 그것은 Flash 5에서 검색되고 있는 XML 문서의 전송 진행 상황을 결정할 수는 없다. 더 자세한 정보는 『ActionScript: The Definitive Guide』의 언어 참조편에 있는 XML.send(), XML.sendAndLoad(), XML.onData(), XML.onLoad()를 참조하기 바란다(관련
샘플 챕터는 나의 웹 사이트에 올려놓았음). 또한 매크로미디어의
Flash XML primer에서도 이와 관련된 정보를 얻을 수 있다.
전송된 변수에 대해서 프리로딩을 다루기 위해 이벤트 핸들러를 사용했다. 우리는 변수를 서버측 스크립트나 텍스트 파일에서 무비 클립의 타임라인으로 끌어들이는 loadVariables() 함수를 호출함으로써 시작했다. 변수를 기다리고 있는 동안 전송 프레임을 보여줄 수 있었다. 변수가 도착하면 클립 데이터 이벤트가 유인되고 무비와 함께 실행할 수 있다. 데이터 핸들러에 대한 가장 흔한 대체안(플래시 4와 친근한)은 가장 마지막으로 전송된 변수의 값을 반복해서 검색하거나 변수가 정의될 때에만 계속 진행하도록 하는 것이다. 두 경우 모두다 불행하게도 변수의 전송 진행 상황을 결정 할 수는 없다. 단지 완전히 전송된 때만을 감지할 수 있을 뿐이다.
변수 전송에 대한 단계적인 튜토리얼 전 단계를 보고 싶다면 『ActionScript: The Definitive Guide』의 챕터 17을 참고하기 바란다. 프리로딩 끝!!
콜린 무크(Colin Moock)는 1995년 이후로 웹 개발 및 디자인 리서치 작업을 하고 있다. 1997년 까지는 HoTMetaL PRO의 제작자인 SoftQuad Inc에서 웹마스터로 근무했었다. 지금은 ICE(Integrated Communications & Entertainment)에서 웹 전문가로 활동하면서 웹에 대한 기사를 쓰고 컨퍼런스에서 강연자를 활동하고 있으며 소니, 리바이스, 노르텔, 에어 캐나다 및 휴렛 패커드와 같은 기업체의 대화식 컨텐츠를 만들었다. 콜린이 플래시 개발자들을 위해 만든 유명한 지원 사이트와 수상한 적이 있는 플래시 작품 덕택에 플래시 개발자 커뮤니티에서는 아주 유명한 인사가 되었다. 매크로미디어는 그의 플래시 기술과 이 두 작품을 플래시 자문 위원회의 멤버로 임명하면서 매크로미디어의 사이트에서 공식적으로 인정했다. 그는 또한 『The Flash 4 Bible』(1999, IDG Books)과 『The Flash 5 Bible』(2001, IDG Books)의 협력 저자이자 오라일리에서 출간한 『ActionScript: The Definitive Guide』의 저자이다. 콜린 무크에 대한 더 자세한 정보는 그의 웹 사이트(http://www.moock.org/asdg/)에서 볼 수 있다.