Przykład intro w skryptach sqs

Ponieważ poprzedni poradnik tego typu okazał się pomocny postanowiłem stworzyć drugi. Tym razem intro (a więc również poradnik) jest krótsze choć nie oznacza to że nie wnosi nic nowego, gdyż użyłem jednego z bardziej zaawanosowanych trików tj. występuje "przyczepienie" kamery do pojazdu będącego w ruchu). Dzięki temu że filmik jest krótszy łatwiej będzie go ogarnąć i ewentualnie przerobić na swoje potrzeby.

Ten poradnik jest nieoficjalny (tzn. nie został wydany ani przez BIS ani przez Codemasters). Ponadto jego autor nie gwarantuje, że ustrzegł się błędów, a w związku z tym używasz informacji w nim zawartych na własne ryzyko.

Filmik przedstawiał będzie patrol oddziału US Army (jeepMG i M113) który kończy się w chwili gdy sowiecki RPG niszczy jadący na czele jeep. Akcja ma miejsce w południowej cześci Malden (sektor F7). Filmik będzie składał się z następujących "części":
1. Przejazd patrolu ze skrzyżowania (Gb68) do rejonu zasadzki (Fi70).
2. Zniszczenie jeepa przez sowieckiego żołnierza za pomocą RPG.
Ponieważ intro to nie wymaga za wiele pracy omówię je obie naraz.

Pierwsza część składa się z trzech ujęć. Najpierw satycznego ujęcia drogi, które pokazuje przejeżdzający patrol (grupa przejeżdża przez kadr). Następnie ujęcia z "żabiej perspektywy" (kamera znajduje się na środku drogi tak, że oba pojazdy po niej przejeżdzają). Na koniec kamera zaczyna towarzyszyć M113 znajdując się nieco za wieżyczką.

Druga część rozpoczyna się od przeniesienia kamery w miejsce w którym ukrywa się żołnierz z RPG. W pierwszej chwili nie widać go i kamera koncentruje się na odległym patrolu. Dzięki oddaleniu (unzoom) żołnierz pojawia się w kadrze już z wycelowaną w jeepa wyrzutnią. Oddaje strzał gdy jeep zwalnia przed przeszkądą znajdującą się na drodze (wrak samochodu). Ostatnie ujecie pokazuje płonącego jeepa po czym filmik się kończy.

By uzyskać ten efekt potrzebuję grupy pojazdów złożonej z jeepMG (dowódcy) - jeep i M113 - m113 oraz żołnierza z RPG - atank. Pojazdy muszą mieć szyk kolumny, zachowanie Bezpiecznie (po to by załoga wyglądała przez włazy) i punkt zerowy trasy, w miejscu gdzie ma nastąpić zasadzka. Żołnierz z RPG ma swój zerowy punkt trasy ustawiony na sobie (nigdzie nie będzie musiał chodzić) i ustawioną postawe Wstrzymaj ogień (żeby nie zaczął strzelać za wcześnie). Dodatkowo wpisuję mu w inicjacji this SetCaptive true, by zabezpieczyć się przed jego niespodziewaną śmiercią z rąk patrolu gdyby nie udało mu się trafić za pierwszym.
Oprócz wymienionych elementów wstawiamy na mapę dwa wyzwalacze - kończący intro, czyli typu koniec cz.1 z wpisanym w Warunku koniec i f0 umieszczonego tak jak to jest pokazane na obrazku i o następujących parametrach:

Nazwa f0, Oś a:50, Oś b:50, Aktywacja:Zachód,Obecny,Cyklicznie,Przy dezaktywacji: f0stop = true

Poza tym na mapie dodałem jeszcze nagrobek i wrak pojazdu dla klimatu. Poniżej ilustracja przedstawiająca widok w edytorze (kliknij aby powiększyć).

Czas zacząć tworzyć skrypt. Jeżeli wiesz jak utworzyć skrypt to możesz pominąć następny akapit i zająć się od razu jego treścią.

Skrypt jest po prostu plikiem tekstowym i możemy go napisać np. w notatniku (tzn. Notepaddzie). W tym celu uruchamiamy notatnik, a następnie wybieramy Plik->Zapisz. W polu Nazwa pliku wpisujemy np. Intro.sqs, po czym w polu Zapisz jako typ ustawiamy Wszystkie pliki(*.*) i zapisujemy w folderze z misją. Jeżeli nigdy nie oglądaliście skryptu w notatniku to będzie on miał domyślną ikonę windows - wystarczy na niego dwukrotnie kliknąć i w oknie Otwórz z wybrać notatnik jako aplikację (uprzednio zaznaczywszy opcję Do otwierania tego pliku zawsze używaj tego programu), którą użyjemy do otwarcia skryptu. Na razie nie robi on nic, bo nic nie zawiera, ale możemy zacząć wypełniać go treścią.

Skrypt odpowiedzialny za przebieg intro wygląda następująco:

;Intro.sqs

PlayMusic "track11"
TitleCut["Patrol NATO - Południowa część wyspy Malden","BLACK IN",5]
EnableRadio false
_camera = "Camera" CamCreate GetPos f0
_camera CamSetTarget f0
_camera CamSetRelPos [0,-25,1]
_camera CamCommit 0
_camera CameraEffect ["Internal","BACK"]

@f0stop

_camera CamSetTarget [(GetPos jeep Select 0),(GetPos jeep Select 1),-1]
_camera CamSetRelPos [-50,-12,0]
_camera CamCommit 0
~8

_i=0
#Loop
_camera CamSetTarget jeep
_camera CamSetPos [(GetPos m113 Select 0)+0.5,(GetPos m113 Select 1)+0.5,3.3]
_camera CamCommit 0
_i=_i+1
~0.01
?(_i<60): goto "Loop"

_camera CamSetPos [(Getpos atank Select 0)-1,(Getpos atank Select 1)-0.5,0.75]
_camera CamSetFOV 0.1
_camera CamCommit 0
atank DoTarget jeep ~3

_camera CamSetFOV 1 _camera CamCommit 3 @CamCommitted _camera atank DoFire jeep ~3
_camera CamSetTarget atank
_camera CamSetPos [(Getpos jeep Select 0)+10,(Getpos jeep Select 1)+10,1]
_camera CamCommit 0

@(getDammage jeep==1)
~3
5 FadeMusic 0
titlecut ["","BLACK OUT",5]
~5
koniec = true
enableRadio true
_camera CameraEffect["Terminate","BACK"]
CamDestroy _camera
Exit

Przejdźmy więc do objaśniania co powodują te wszystkie komendy. Linijka ;Intro.sqs jest po prostu komentarzem ignorowanym podczas wykonywania skryptu. Komenda PlayMusic "track11" powoduje rozpoczęcie odtwarzania ścieżki dźwiękowej numer 11. Komenda TitleCut["Patrol NATO - Południowa część wyspy Malden","BLACK IN",5] spowoduje, że ekran stopniowo (w czasie 5 sekund) przejdzie z czerni do "normalnego" obrazu z jednoczesnym wyświetleniem napisu "Patrol NATO - Południowa część wyspy Malden". _camera = "Camera" CamCreate GetPos f0 stworzy w punkcie w którym znajduje się wyzwalacz f0 kamerę o nazwie _camera (tak naprawdę to jest to zmienna lokalna _camera, z którą kamera jest skojarzona, ale nie komplikujmy). Jak łatwo się domyśleć kamerę można tworzyć więcej niż jedną, ale nie ma takiej potrzeby. Polecenie _camera CamSetTarget f0 nakazuje kamerze obserwować obiekt o nazwie f0 czyli wyzwalacz (może wydaje się nieco dziwne, że kamera obserwuje punkt w którym jest ale zaraz się to wyjaśni).Komenda _camera CamSetRelPos [0,-25,1] spowoduje, że kamera znajdzie się w pewnym miejscu względem obiektu, który obserwuje, a dokładnie znajdzie się 25 metrów na południe i jeden metr nad ziemią (wyzwalacze "leżą" na ziemi). Następnie dosyć istotna komenda _camera CamCommit 0, które spowoduje, że wszystkie polecenia wydane kamerze zostaną wykonane natychmiast (czyli w czasie 0 sekund). Na koniec _camera CameraEffect ["INTERNAL","BACK"] powoduje uruchomienie kamery. Za tą linijką znajduje się jeszcze zapis @f0stop, który zatrzymuje wykonywanie skryptu do chwili gdy zmienna f0stop przyjmie wartość true (prawda). Opisane linijki odpowiadają za pierwsze statyczne ujęcie drogi. Za zakończenie tego ujęcia odpowiada również wyzwalacz f0 (pełni podwójną rolę). Aktywuje się on mniej więcej w chwili gdy patrol wjedzie w kadr, natomiast dezaktywuje się gdy patrol opuści jego obręb. Wtedy zmiennej f0stop przypisywana jest wartość true co "popycha" akcję dalej.

Kolejne cztery linijki odpowiadają za drugie ujęcie. Komenda _camera CamSetTarget [(GetPos jeep Select 0), (GetPos jeep Select 1),-1] nakazuje kamerze wycelować w punkt w którym w danej chwili znajduje się jeep (ale nie w samego jeepa bo wtedy zaczęła by za nim podążać wzrokiem). Następnie polecenie _camera CamSetRelPos [-50,-12,0] ustawia odpowiednio kamerę względem punktu który obserwuje. Pozostaje tylko potwierdzić komendą _camera CamCommit 0 i dać 8 sekund (wielkość ustalona metodą prób i błędów) na wykonanie tego ujęcia za pomocą ~8.

Teraz pojawi się nieco trudniejszy element, a mianowicie pętla powodująca "przyczepienie" kamery do M113tki. Najpierw muszę zainicjować zmienną lokalną _i sterującą pętlą poprzez przypisanie jej wartości 0. Następna linijka to etykieta #Loop wyznaczająca miejsce do którego wracać będzie skrypt w wyniku działania komendy goto. Następne pięć linijek zostanie wykonane 60 razy w odstępach ok. 0.01 sekundy. Za każdym razem kamera wyceluje w jeepa dzięki komendzie _camera CamSetTarget jeep i zajmie pozycję przesuniętą względem miejsca, w którym jest M113tka o wektor [0.5,0.5,3.3] dzięki komendzie _camera CamSetPos [(GetPos m113 Select 0)+0.5,(GetPos m113 Select 1)+0.5,3.3]. Przy każdym wykonaniu pętli komendy te muszą być potwierdzane za pomocą polecenia _camera CamCommit 0. Przypisanie _i=_i+1 powoduje, że po każdym wykonaniu pętli wartość zmiennej sterującej pętlą (czyli _i) zwiększa się o jeden. Opóźnienie ~0.01 ma chatrakter kontrolny gdyż w rzeczywistości wykonanie pętli zajmuje komputerowi więcej czasu (ilość wykonań pętli dobiera się metodą prób i błędów ) i całe ujęcie nie trwa tylko pół sekundy. Ostatnia linijka zawierająca ?(_i<60): goto "Loop" sprawdza wartość zmiennej sterującej _i - jeżeli jest mniejsza od 60 to pętla jest wykonywana (następuje skok do etykiety #Loop). Jeżeli wartość zmiennej sterującej _i jest równa 60 lub większa pętla nie jest wykonywana i skrypt przechodzi do następnej linijki.

W tym miejscu rozpoczyna się część druga filmu. Za pomocą komendy _camera CamSetPos [(Getpos atank Select 0)-1,(Getpos atank Select 1)-0.5,0.75] kamera zostaje przeniesiona niedaleko żołnierza z wyrzutnią RPG, a komenda _camera CamSetFOV 0.1 powoduje zbliżenie czyli "zoom" (dzięki czemu mimo iż znajduje się ona za nim to nie jest on widoczny w kadrze). Zmiana następuje natychmiastowo dzięki _camera CamCommit 0 po czym kamera obserwuje patrol przez trzy sekundy. W między czasie żołnierz atank otrzymuje poleceniem atank DoTarget jeep wycelowania w jeepa (ponieważ ma postawę Wstrzymaj ogień ograniczy się do wycelowania).

Następnie następuje oddalenie unzoom. Następuje ono stopniowo w czasie trzech sekund dzięki użyciu komendy _camera CamCommit 3. Komenda @CamCommitted _camera powoduje wstrzymanie działania skryptu (czyli wykonywania następnych komend) do czasu dokonania się wcześniej nakazanych zmian (czyli w tym przypadku zamiany stopnia zbliżenia obrazu) bez względu na to ile by one trwały. Następnie pojawia się brzemienna w skutkach komenda atank DoFire jeep która powoduje, że żołnierz atank strzela z RPG do jeepa (żołnierz jest już w polu widzenia kamery). Trzy sekundy opóźnienia pozwalają zobaczyć eksplozję.

Ostatnie ujęcie pokazuje trafionego jeepa (albo jego ostatnie chwile). Kamera zostaje umieszczona za jeepem za pomocą komendy _camera CamSetPos [(Getpos jeep Select 0)+10,(Getpos jeep Select 1)+10,1] i wycelowana w sprawcę jego nieszczęścia czyli atank (jeżeli nie trafił za pierwszym razem to mamy szansę zobaczyć nadlatującą rakietę). Wszystko jak zwykle wymaga potwierdzenia za pomocą _camera CamCommit 0. Komenda @(getDammage jeep==1) daje nam pewność że filmik nie zakończy się jeżeli jeep nie ulegnie zniszczeniu (teoretycznie możliwe jest, że żołnierz trzykrotnie chybi i film się nie skończy, ale w praktyce trafienie nieruchomego celu nie stwarza mu problemu). Po zniszczeniu jeepa widzimy go jeszcze trzy sekundy dzięki opóźnieniu ~3.

Pozostaje zakończyć filmik. W tym celu wyciszam stopniowo w czasie pięciu sekund muzykę komendą 5 FadeMusic 0 i ściemniam ekran komendą titlecut ["","BLACK OUT",5]. Oczywiście muszę dać pięciosekundowe opóźnienie na dokonanie tych zmian. Następnie przypisuję zmiennej koniec wartość true, dzięki czemu aktywuje się wyzwalacz kończący. Za pomocą komendy enableRadio true przywracam działanie radia. Na koniec wyłączam kamerę komendą _camera CameraEffect["Terminate","BACK"], niszczę ją komendą CamDestroy _camera i kończe działanie skryptu za pomocą Exit. Ostatnie trzy linijki wydają się zbędne gdyż filmik zakończył się z chwilą aktywacji wyzwalacza kończącego, ale są potrzebne by uwolnić procesor od konieczności utrzymywania kamery i skryptu.

Jeżeli macie jakieś wątpliwości, to zawsze możecie obejrzeć jak misja została zrobiona w edytorze, a poza tym pisać pytania na Forum OFP Center PL w dziale "Edytor".

Napisał: ALDEROUS



Wejdź na forum Wejdź na stronę Armed Assault Center PL