r23-07.doc

(355 KB) Pobierz
Szablon dla tlumaczy

Rozdział 23.
Klipy filmowe jako obiekty złożone

W tym rozdziale:

·         Definicja kolizji

·         Właściwość _dropTarget

·         Użycie metody hitTest

·         Tworzenie labiryntu

·         Podstawy obiektów typu Smart Clips

 

W tym rozdziale omówimy szczegóły wykrywania kolizji obiektów typu Movie Clip. Jeśli chciałeś kiedyś opracować grę, w której statki wybuchały po zderzeniu z rakietą, tutaj znajdziesz opis, jak tego dokonać.

Wykrywanie kolizji klipu filmowego

Czy chciałeś kiedyś wykryć nałożenie się na siebie dwóch elementów filmu? Gdy dwa klony klipu filmowego nasuną na siebie, jak się tego dowiesz? Jak zlecić skryptowi wyszukiwanie nachodzących na siebie elementów? We Flashu 5 istnieją dwa rodzaje kolizji:

·         kolizja po przeciągnięciu elementu,

·         kolizja przy ruchu obiektu sterowanego przez skrypt lub animację.

Właściwość _dropTarget

Kolizja dwóch obiektów typu Movie Clip może wystąpić, gdy użytkownik przeciągnie jeden klip filmowy nad inny klip filmowy. W rozdziale 19., „Sterowanie klipami filmowymi” omówiliśmy akcję oraz metodę startDrag(). W filmie przedstawiającym psa użyliśmy właściwości _dropTarget obiektu typu Movie Clip do sprawdzania, czy na obszarze jednego klipu nie znalazł się inny. Reasumując, nałożenie na siebie dwóch klipów filmowych możesz sprawdzić za pomocą takiego skryptu:

on(press){

  this.startDrag(true);

}

 

on(release){

  this.stopDrag();

  if(eval(this._dropTarget) == _root.klonKlipu2){

    trace("Ten klon klipu filmowego najechał na klonKlipu2");

  } else {

    trace("Ten klon klipu nie najechał na klonKlipu2");

  }

}

Kod ten powinien zostać przypisany do klonu przycisku znajdującego się w pierwszym klonie klipu filmowego. Gdy użytkownik kliknie przycisk, zostanie wykonana metoda startDrag klipu filmowego i będzie można przeciągać klon klipu na obrazie. Kiedy użytkownik zwolni klawisz myszy, właściwość _dropTarget (która zwraca ścieżkę adresową w notacji ukośnikowej) konwertowana jest na ścieżkę adresową w notacji kropkowej. Gdy właściwość _dropTarget zwróci ścieżkę do innego klonu, warunek if sprawdzi, czy zwrócona ścieżka jest równa _root.klonKlipu2. Jeśli tak, akcja trace spowoduje wyświetlenie komunikatu o najechaniu na klonKlipu2. W przeciwnym wypadku wyświetlony zostanie komunikat o braku kolizji.

Odsyłacz! Aby zobaczyć właściwość _dropTarget w działaniu, zajrzyj do sekcji „Sprawdzanie miejsca upuszczenia: _dropTarget) z rozdziału 19., „Sterowanie klipami filmowymi”.

Wykrywanie kolizji za pomocą metody hitTest

Możesz także przeprowadzać bardziej zaawansowane wykrywanie kolizji, korzystając z metody hitTest obiektu typu Movie Clip. Metoda ta sprawdza, czy dwa elementy nałożyły się na siebie. Oto dwa formaty składni metody hitTest:

klonKlipu.hitTest(innyKlon);

lub

klonKlipu.hitTest(współrzędna X, współrzędna Y, obszarKolizji);

Druga metoda została zademonstrowana w rozdziale 19., „Sterowanie klipami filmowymi”, podczas wykrywania kolizji klonu klipu filmowego sliderBar. Przy użyciu tej metody możesz sprawdzić, czy punkt o podanych współrzędnych znajduje się w obszarze zajmowanym przez klon klipu. Detektor zdarzeń klipu filmowego w połączeniu ze zdarzeniem mouseMove pozwala stale sprawdzać, czy nie nastąpiło zderzenie:

onClipEvent(mousemove){

  if(this.hitTest(_root._xmouse, _root._ymouse, true)){

    trace("Nastąpiło najechanie");

  }

}

Ten skrypt będzie wykonywał akcję trace za każdym razem, gdy kursor myszy wykona ruch w miejscu zajmowanym przez grafikę klonu klipu filmowego zawierającego skrypt. Argument obszarKolizji metody hitTest określa rzeczywisty obszar brany pod uwagę przy kolizji. Jeśli znacznik ten jest równy true, wtedy współrzędne punktu dotyczą tylko obszaru zajmowanego przez grafikę z klonu klipu filmowego. Gdy jest ustawiony na false, sprawdzamy, czy punkt o podanych współrzędnych znajduje się w ramce otaczającej klon klipu. Na rysunku 23.1 w lewym kole używana jest metoda ze znacznikiem równym true, zatem zderzenie zostanie zarejestrowane tylko wtedy, gdy punkt znajdzie się wewnątrz kształtu koła (a nie ramki otaczającej). W prawym kole (używającym znacznika false) kolizja zostanie wykryta, gdy punkt znajdzie się wewnątrz ramki otaczającej.

Rysunek 23.1. Obszar kolizji określa obszar klonu klipu filmowego, jaki bierze pod uwagę metoda hitTest

Na CD-ROM-ie! Działający przykład znacznika kształtu oraz metody hitTest znajdziesz w pliku hitTest_xy.fla znajdującym się w katalogu ch23 na CD-ROM-ie.

Druga wersja metody hitTest jako argument przyjmuje po prostu ścieżkę adresową klipu, z którym chcemy sprawdzić kolizję. W tym wypadku nie możesz definiować obszaru kolizji; gdy ramki otaczające sprawdzanych klonów klipów nachodzą na siebie, sygnalizowana jest kolizja. Na przykład możesz zmodyfikować wcześniejszy skrypt, aby sprawdzał kolizję dwóch klonów, a nie kolizję z punktem:

onClipEvent(mousemove){

  if(this.hitTest(_root.klonKlipu2)){

    trace("Nastąpiło najechanie");

  }

}

W tym skrypcie zakładamy, że w innym miejscu została wywołana akcja startDrag. Pominęliśmy także drugą część warunku if w obydwu przykładowych skryptach. Gdy w warunku if nie porównujesz wartości, program wykonuje zagnieżdżone instrukcje wówczas, gdy zmienna (która musi być typu logicznego) w warunku jest równa true. Obydwa poniższe warunki if są identyczne:

klikniecie = true;

if (klikniecie){

  trace("Zmienna klikniecie jest równa true.");

}

if (klikniecie == true){

  trace("Zmienna klikniecie jest równa true.");

}

Jeśli chcesz użyć skróconego zapisu, testowana w warunku if zmienna (lub wartość zwracana przez metodę) musi być typu logicznego (true lub false). Metoda hitTest zwraca true (jeśli nastąpiła kolizja) lub false (jeśli nie nastąpiła). Pamiętaj, że w większości języków programowania częściej spotyka się pierwszy z zapisów z powyższego przykładu.

Na CD-ROM-ie! Przykład zastosowania metody hitTest do sprawdzania kolizji z klonem znajdziesz w pliku hitTest_target.fla znajdującym się w katalogu ch23 na CD-ROM-ie.

Szare tło!

Ćwiczenie eksperta
Użycie metody hitTest dla wielu obiektów
Autor: Dorian Nisinson

Dzięki temu ćwiczeniu nauczysz się strukturalnego tworzenia złożonych projektów. Poznasz także nową notację kropkową, nowy detektor zdarzeń onClipEvent oraz dołączenie skryptów do klipów filmowych. Dodatkowo poznasz metody hitTest oraz getBounds obiektu typu Movie Clip. Najlepiej jednak będzie, gdy przed rozpoczęciem czytania tego ćwiczenia załączysz Flasha 5, otworzysz plik redMaze.fla i wybierzesz polecenie Control/Test Movie, aby zobaczyć, jak działa ukończony film.

W tym ćwiczeniu na przykładzie pliku redMaze.fla pokażemy, jak możesz zaplanować film Flasha. Ukończony film znajdziesz w katalogu ch23\dorian_nisinson na CD-ROM-ie.

Planowanie struktury filmu

Gdy zaczynasz pracę nad projektem, warto utworzyć schemat zawierający elementy filmu i pokazujący ich zależności. Im bardziej złożony będzie film, tym bardziej przydatny stanie się schemat. Ten projekt jest wyjątkowo skomplikowany, więc poświęć trochę czasu na przestudiowanie schematów.

Poniższy rysunek zawiera schemat z symbolami i innymi elementami filmu. Na drugim schemacie znajdziesz opis skryptów oraz kierunki przepływu danych między nimi. Najpierw musisz się zastanowić nad tym, co ma robić film. Później zdecyduj się na najbardziej efektywną strukturę skryptów, która wykona wszystkie zadania.

Ogólny schemat filmu

Schemat struktury skryptów (na następnym rysunku) jest drugą rzeczą, jaką powinieneś wykonać w czasie projektowania struktury projektu. Dzięki tym dwóm schematom dalsza praca nad projektem będzie znacznie prostsza. Im bardziej szczegółowo określisz wszystko przed rozpoczęciem właściwej pracy, tym mniej czasu spędzisz na ewentualnych modyfikacjach filmu.

Schemat struktury skryptów

Definiowanie celów gry

Zanim zaczniemy tworzyć grę we Flashu, dobrze byłoby także określić podstawowe jej cele. Dla tego przykładu można podać następujące wskazówki:

1.       Użytkownik powinien sterować niewielkim klipem filmowym (piłką). Powinna się ona poruszać w górę, lewo, prawo i dół.

2.       Ruch piłki powinien być tak płynny, jak to tylko możliwe.

3.       Piłka nie będzie mogła przejść przez ścianki labiryntu, więc potrzebna jest pewnego rodzaju detekcja kolizji.

4.       Każde zderzenie musi zostać wykryte, aby zatrzymać ruch piłki w danym kierunku. Najważniejsze dla poprawnego działania gry jest to, by wiedzieć, z której strony ścianki uderzyła piłka. Ruch piłki w kierunku tej ścianki musi być zablokowany tak długo, aż zderzanie się w tym kierunku nie ustąpi.

5.       Gdy piłka przejdzie przez labirynt, powinno to zostać wykryte.

Przyjrzymy się teraz każdemu z wymienionych zadań, które trzeba rozwiązać, by ukończyć projekt.

Zadanie 1. Sterowana przez gracza piłka

Elementy graficzne:

·         małe kółko o promieniu wynoszącym cztery piksele znajdujące się w klonie klipu filmowego o nazwie ball;

·         przycisk strzałki; umieść cztery klony tego przycisku na scenie, obróć je tak, aby każda strzałka wskazywała inny kierunek: górę, dół, prawo oraz lewo;

·         prostokąt o wysokości czterech, a szerokości dwudziestu pikseli w klonie klipu filmowego o nazwie gridHn lub gridVn.

Każdy przycisk będzie zawierał skrypt powodujący ruch piłki. Jeśli dołączymy do przycisku kod poruszający piłką, będzie ona przesuwać się o jeden piksel w wybranym kierunku. Ponieważ chcemy, aby piłka przesuwała się tak długo, jak naciśnięty będzie przycisk, utworzymy zmienną, która w zależności od naciśnięcia przyjmuje dwa stany. Gdyby piłka mogła poruszać się tylko w jednym kierunku, zmienną moglibyśmy nazwać nacisniety. Musimy jednak wiedzieć, jaki przycisk kierunku został naciśnięty. Do tego celu użyjemy czterech zmiennych o nazwach oznaczających kierunki: up (w górę), down (w dół), right (w prawo), left (w lewo). Naciśnięcie przycisku ze strzałką w górę spowoduje ustawienie zmiennej up na true. Na początku gry wszystkie zmienne są inicjalizowane wartością false, ponieważ nie chcemy, aby piłka poruszała się, gdy użytkownik nie nacisnął jeszcze żadnego przycisku. Wszystkie cztery zmienne definiujemy na głównej listwie czasowej w pierwszym ujęciu warstwy actions:

up = false;

down = false;

left = false;

right = false;

Aby dodać jedną z powyższych linii do skryptu w trybie Normal Mode, musisz kliknąć dwukrotnie akcję evaluate z kategorii Action w edytorze skryptów. Poniższy rysunek przedstawia edytor skryptów w trybie Normal Mode z wpisanym już skryptem. Akcja evaluate pozwala na dodanie całej linii kodu bez bawienia się w wypełnianie kilku pól. W trybie Expert Mode możesz wszystkie linie napisać od razu w oknie skryptu.

Skrypt dla przycisku ruchu w górę jest następujący:

on (press) {

  up = true;

}

on (release, releaseOutside) {

  up = false;

}

Gdy przycisk ze strzałką w górę jest naciśnięty, zmienna up ma wartość true. Gdy gracz zwolni przycisk, zmienna przyjmie wartość false.

Powyższy skrypt różni się od kodu ActionScript z Flasha 4. Nadal istnieje detektor zdarzenia myszy, jak we Flashu 4, ale teraz akcje dotyczące zdarzenia zawarte są w nawiasach klamrowych. Tym, którzy znają JavaScript, ten sposób formatowania wyda się znajomy. Nawiasy klamrowe określają akcje odnoszące się do części skryptu wykonującej pewne zadanie.

Podobne skrypty zostały dołączone do pozostałych przycisków. Oczywiście nazwy zmiennych zostały odpowiednio zmodyfikowane. W ten sposób Flash otrzyma informację, który przycisk jest naciśnięty, a co za tym idzie, w którą stronę przesunąć piłkę. Teraz trzeba napisać skrypt, który spowoduje przesunięcie piłki w określonym kierunku.

Zadanie 2. Ruch piłki

Detektor zdarzeń onClipEvent:

Jak dotąd używaliśmy skryptów powiązanych z przyciskami oraz ujęciami. Obydwa rodzaje występowały we Flashu 4. Jednak dla ruchu piłki użyjemy nowości w języku ActionScript Flasha 5 — detektora zdarzeń klipu filmowego. Jeśli otworzysz plik redMaze.fla we Flashu i klikniesz prawym klawiszem myszy (PC) lub Control+kliknięcie (MacOS) piłkę, zobaczysz podręczne menu (następny rysunek), które poza znanymi poleceniami posiada także parę nowych. Jednym z nich jest Actions. Upewnij się, że poza piłką nie są zaznaczone na scenie inne elementy, ponieważ w takim przypadku podręczne menu będzie inne.

Podręczne menu zawierające polecenie Actions

Nowy detektor zdarzeń, czyli akcja onClipEvent, posiada zestaw zdarzeń, podobnie jak przyciski. Składnia tej akcji jest następująca:

onclipEvent(zdarzenieKlipuFilmowego)

Klip filmowy może wykryć dziewięć różnych zdarzeń:

1.       load,

2.       unload,

3.       enterFrame,

4.       mouseMove,

5.       mouseUp,

6.       mouseDown,

7.       keyDown,

8.       keyUp,

9.       data.

Uwaga autora. Detektor zdarzeń onClipEvent jest omawiany w rozdziale 19., „Sterowanie klipami filmowymi”. Zdarzenie data omawiamy w rozdziale 24., „Wyprowadzanie i pobieranie danych we Flashu”.

Umieszczenie skryptu w piłce umożliwia zastosowanie nowego detektora zdarzeń klipu filmowego i wykorzystanie zalet zdarzenia enterFrame.

Akcje wykonywane po wystąpieniu zdarzenia enterFrame znajdują się wewnątrz nawiasów klamrowych. Tylko akcje w nich zawarte będą wykonywane podczas każdego wystąpienia zdarzenia.

Skrypt dla klipu filmowego piłki jest następujący:

onClipEvent (enterFrame) {

  //  ruch piłki

  if (_root.right == true) {

    this._x+=1;

  }

  if (_root.left == true) {

this._x-=1;

  }

  if (_root.up == true) {

    this._y-=1;

  }

  if (_root.down == true) {

    this._y+=1;

  }

}

Analiza skryptu: 1. linia

onClipEvent (enterFrame){

Ten skrypt używa zdarzenia enterFrame. Powoduje ono wykonywanie zawartych w nim akcji przy każdym przejściu wskaźnika czasu do nowego ujęcia. Ponieważ klip filmowy posiada własną listwę czasową, jest odtwarzany niezależnie od głównej listwy czasowej. Zdarzenie enterFrame będzie powodowało ciągłe wykonywanie akcji, tak długo jak będzie odtwarzany film, a klip filmowy będzie się znajdował na głównej listwie czasowej. O to właśnie nam chodziło. Nie chcieliśmy, aby sprawdzenie, czy gracz nacisnął przycisk następowało tylko jeden raz. Musimy stale sprawdzać stan przycisków. Za pomocą zdarzenia enterFrame po każdym wejściu do nowego ujęcia będzie sprawdzany aktualny stan wszystkich przycisków.

Analiza skryptu: 2. linia

if (_root.right == true) {

Korzystając z warunku if, możemy testować, jaka jest wartość zmiennych określających nac...

Zgłoś jeśli naruszono regulamin