Sterowanie odtwarzaniem klipu filmowego

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

W programie Flash stosowana jest metafora osi czasu odzwierciedlająca animację lub zmiany stanu w czasie. Każdy element wizualny z osią czasu musi być albo obiektem klasy MovieClip, albo należeć do klasy, która ją rozszerza. Wprawdzie kod ActionScript może nakazać każdemu klipowi filmowemu zatrzymanie, uruchomienie odtwarzania lub przejście do wskazanego punktu na osi czasu, nie jest możliwe programowe utworzenie osi czasu ani dodawanie treści w konkretnych klatkach. Takie operacje są możliwe tylko w narzędziu Flash do tworzenia treści.

Podczas odtwarzania obiekt MovieClip przechodzi przez kolejne klatki osi czasu z prędkością wyznaczoną przez częstość klatek pliku SWF. Można również wymusić inną prędkość, nadając wartość właściwości Stage.frameRate w kodzie ActionScript.

Odtwarzanie klipów filmowych i zatrzymywanie odtwarzania

Metody play() i stop() pozwalają — w podstawowym zakresie — na sterowanie odtwarzaniem klipu filmowego na osi czasu. Załóżmy na przykład, że na stole montażowym znajduje się symbol klipu filmowego zawierający animowany rower przemieszczający się po ekranie, a nazwa instancji tego klipu to bicycle . Jeśli do klatki kluczowej na głównej osi czasu zostanie dołączony następujący kod,

bicycle.stop();

rower nie będzie się poruszał (animacja nie będzie odtwarzana). Ruch roweru może zostać zainicjowany np. w odpowiedzi na interakcję z użytkownikiem. Jeśli, na przykład, istnieje przycisk o nazwie startButton , to następujący kod w klatce kluczowej głównej osi czasu spowoduje, że odtwarzanie animacji rozpocznie się po kliknięciu przycisku:

// This function will be called when the button is clicked. It causes the  
// bicycle animation to play. 
function playAnimation(event:MouseEvent):void 
{ 
    bicycle.play(); 
} 
// Register the function as a listener with the button. 
startButton.addEventListener(MouseEvent.CLICK, playAnimation);

Przewijanie do przodu i do tyłu

Metody play() i stop() to nie jedyne narzędzia sterowania odtwarzaniem dostępne w klipie filmowym. Możliwe jest również ręczne przemieszczanie głowicy odtwarzania po osi czasu przy użyciu metod nextFrame() i prevFrame() . Wywołanie każdej z tych metod zatrzymuje odtwarzanie i przesuwa głowicę odtwarzania odpowiednio o jedną klatkę w przód lub wstecz.

Użycie metody play() jest równoważne wywoływaniu metody nextFrame() po każdym wystąpieniu zdarzenia enterFrame w obiekcie klipu filmowego. Korzystając z tego mechanizmu, możemy odtwarzać klip filmowy bicycle wstecz, tworząc detektor zdarzenia enterFrame i wewnątrz detektora nakazując obiektowi bicycle przejście do poprzedniej klatki:

// This function is called when the enterFrame event is triggered, meaning  
// it's called once per frame. 
function everyFrame(event:Event):void 
{ 
    if (bicycle.currentFrame == 1) 
    { 
        bicycle.gotoAndStop(bicycle.totalFrames); 
    } 
    else 
    { 
        bicycle.prevFrame(); 
    } 
} 
bicycle.addEventListener(Event.ENTER_FRAME, everyFrame);

W przypadku normalnego odtwarzania, jeśli klip zawiera więcej niż jedną klatkę, będzie odtwarzany cyklicznie, w sposób zapętlony. A zatem po przejściu za ostatnią klatkę wróci do klatki nr 1. W przypadku użycia metod prevFrame() lub nextFrame() takie zachowanie nie jest realizowane automatycznie (wywołanie prevFrame() , gdy głowica znajduje się na klatce nr 1, nie powoduje przeniesienia głowicy do ostatniej klatki). Warunek if w powyższym przykładzie sprawdza, czy głowica odtwarzania cofnęła się już do pierwszej klatki, i wówczas przenosi głowicę do ostatniej klatki, zapętlając klip odtwarzany wstecz.

Przeskakiwanie do innej klatki i korzystanie z etykiet klatek

Wymuszenie przejścia do konkretnej klatki jest prostą operacją. Wywołanie metody gotoAndPlay() albo gotoAndStop() powoduje przeskok do klatki o numerze podanym jako parametr. Można też jako parametr przekazać ciąg znaków równy etykiecie klatki. Każdej klatce na osi czasu można przypisać etykietę. W tym celu należy zaznaczyć klatkę na osi czasu i wprowadzić nazwę w polu Etykieta klatki w Inspektorze właściwości.

Zalety korzystania z etykiet klatek zamiast ich numerów ujawniają się zwłaszcza w skomplikowanych klipach filmowych. Operując na dużej liczbie klatek, warstw i animacji, warto nadać ważnym klatkom czytelne etykiety odzwierciedlające zmiany w zachowaniu klipu filmowego (np. „start”, „idzie” lub „biegnie”). Zwiększa to czytelność kodu i jego elastyczność, ponieważ kod ActionScript odwołujący się do etykiety nie zawiera wpisanego wprost numeru klatki. Gdy w przyszłości zdecydujemy się przenieść dany segment animacji do innej klatki, nie trzeba będzie zmieniać kodu ActionScript, o ile tylko w nowym miejscu analogiczne klatki będą miały te same etykiety, co dotychczas.

W języku ActionScript 3.0 dostępna jest klasa FrameLabel reprezentująca etykiety klas. Każda instancja tej klasy reprezentuje jedną etykietę klatki i ma właściwość name zawierającą etykietę podaną w Inspektorze właściwości oraz właściwość frame reprezentującą numer klatki, której ta etykieta jest przypisana.

Aby umożliwić dostęp do instancji klasy FrameLabel powiązanych z instancją klipu filmowego, w klasie MovieClip przewidziano dwie właściwości, które bezpośrednio zwracają obiekty typu FrameLabel. Właściwość currentLabels zwraca tablicę zawierającą wszystkie obiekty FrameLabel z całej osi czasu klipu filmowego. Właściwość currentLabel zwraca ciąg znaków zawierający etykietę ostatnio napotkaną na osi czasu.

Załóżmy, że mamy utworzony klip filmowy o nazwie robot , a różne stany animacji robota są opatrzone etykietami. Możemy sformułować warunek sprawdzający wartość właściwości currentLabel w celu określenia bieżącego stanu klipu robot , co ilustruje poniższy kod:

if (robot.currentLabel == "walking") 
{ 
    // do something  
}

W programie Flash Player 11.3 i środowisku AIR 3.3 dodano zdarzenie frameLabel do klasy FrameLabel. Można przypisać moduł obsługi zdarzeń do wystąpienia klasy FrameLabel reprezentującego etykietę klatki. To zdarzenie jest wywoływane, gdy głowica odtwarzania wchodzi do klatki.

Poniższy przykładowy kod tworzy wystąpienie klasy FrameLabel dla etykiety drugiej klatki w tablicy etykiet klatek obiektu MovieClip. Następnie rejestruje moduł obsługi zdarzeń frameLabel .

var myFrameLabel:FrameLabel = robot.currentLabels[1]; 
myFrameLabel.addEventListener(Event.FRAME_LABEL, onFrameLabel); 
 
function onFrameLabel(e:Event):void { 
    //do something 
}

Praca ze scenami

W środowisku Flash do tworzenia treści można korzystać ze scen do rozgraniczenia szeregu osi czasu, które będą odtwarzane w pliku SWF. Drugi parametr metod gotoAndPlay() i gotoAndStop() pozwala na określenie sceny, do której należy przesunąć głowicę odtwarzania. Wszystkie pliki FLA zawierają początkowo tylko jedną scenę, można jednak tworzyć nowe sceny.

Użycie scen nie zawsze jest najlepszym rozwiązaniem. Sceny mają szereg wad. Aktualizowanie dokumentu Flash zawierającego wiele scen może być uciążliwe, zwłaszcza gdy pracuje nad nim kilku autorów. Zastosowanie wielu scen powoduje nieoptymalne wykorzystanie przepustowości, ponieważ proces publikowania scala wszystkie sceny w jedną oś czasu. W rezultacie stopniowo pobierane są wszystkie sceny, nawet te, które nigdy nie będą odtwarzane. Z tego względu stosowanie scen nie jest zalecane poza przypadkami długich animacji z wieloma osiami czasu.

Właściwość scenes klasy MovieClip zwraca tablicę obiektów Scene reprezentujących wszystkie sceny w pliku SWF. Właściwość currentScene zwraca obiekt Scene reprezentujący aktualnie odtwarzaną scenę.

Klasa Scene ma kilka właściwości udostępniających informacje o scenie. Właściwość labels zwraca tablicę obiektów FrameLabel reprezentujących etykiety klatek w danej scenie. Właściwość name zwraca nazwę sceny jako ciąg znaków. Właściwość numFrames zwraca liczbę typu int równą łącznej liczbie klatek w scenie.