Gdzie się podział śnieg tej zimy? Razem z ekipą QA zadawaliśmy sobie to samo pytanie. Dlatego jbeta pomógł nam w napisaniu kolejnego tutoriala, prezentującego… śnieg!
Głównie jest to skrypt, który tworzy, a właściwie symuluje, śnieg wokół gracza, kiedy ktoś wpisze zwykłą komendę. Skrypt pozwala zmieniać obszar „opadu”, oraz jego intensywność, prędkość i wielkość samych płatków.

Przygotowania
Na samym początku stwórzmy tabelę:
Oraz kilka zmiennych globalnych (dostępnych w całym skrypcie):
height = 4 –Jak wysoko ma zaczynać się “opad”
snowing = false –Pada, czy nie pada? Oto jest pytanie ;)
Programowanie komendy
Nauczyliśmy się tydzień temu, że możemy użyć funkcji addEventHandler aby przypisać nasz własne funkcje do wydarzeń globalnych (tego, co się dzieje w grze). Ten skrypt jednak używa komendy pisanej w konsoli, aby uruchomić daną funkcję. Dlatego powstała funkcja addCommandHandler:
Teraz zaprogramujemy samo zdarzenie tak, aby można było określić w komendzie wszystkie (wypisane na początku) parametry.
Funkcja addCommandHandler domyślnie przekazuje dwie wartości funkcji, do której jest przypisana. Są to ‘player’ (gracz) i ‘commandname’ (nazwa komendy, tutaj snow). Wszystkie dodatkowe argumenty muszą zostać oddzielnie zaprogramowane jako zmienne.
Na przykład, jeżeli gracz wpisał „snow 4 3 2 1″ w konsoli, to komenda powinna przekazał funkcji takie dane (w oddzielnych wartościach: „snow”, 4, 3, 2, 1
Dobrze więc. Mamy zaprojektowanć komendę. Czas stworzyć sam śnieg po wpisaniu komendy.
snowing = true –najpierw jednak ustawiamy wartość na „true”
snow_CreateSnow ( player, radius, density, speed, size ) –Tworzymy śnieg za pomocą funkcji snow_CreateSnow!
outputChatBox ( ‘Snow started by ‘ .. getClientName ( player ) ) –Wysyłamy powiadomienie, że zaczął się opad
Jeżeli nie pada śnieg, tworzymy go za pomocą snow_CreateSnow. Należy również zauważyć, że funkcja getClientName zwraca nick gracza ją wywołującego
Czas pozwolić graczom na zatrzymanie “opadu”:
snowing = false –ustawiamy zmiennć na “nieprawda”
outputChatBox ( ‘Snow stopped.’ ) –powiadamiamy gracza, że śnieg przestał padać (co za odkrycie ;d – dop. Globi)
end
end
Tworzymy śnieg
Skrypt używa funkcji snow_CreateSnow. Nie jest to jedna z podstawowych funkcji MTA, jest raczej dodatkowa, warto ją zadeklarować:
Skrypt tworzy śnieg wokół gracza, który go wywołał. Musimy więc pobrać jego aktualną pozycję:
local px, py, pz = getElementPosition ( player )
Tydzień temu nauczyliśmy się korzystać z funkcji setElementPosition. Najczęściej jednak używa się jej do pobrania samej pozycji gracza – dlatego zdefiniowano ją wraz ze zmiennymi px, py, pz.
if not px or not py or not pz then
snowing = false
return
end
Ta część skryptu sprawdzi, czy gracz czasem się nie rozłączył (po co ma padać, gdy już go nie ma). Wystarczy sprawdzić, czy wartości px, py albo pz są nieprawidłowe. Jeżeli są – gracza nie ma w grze.
Następna część skryptu rozpoznaje, czy podano wszystkie parametry. Na przykład, jeżeli gracz po prostu napisze „snow” bez dokładniejszych wytycznych, wtedy zostaną one ustawione domyślnie.
if not radius then radius = 20 else radius = tonumber ( radius ) end
Jeżeli pole “opadu” nie istnieje, to zostanie ustawione automatycznie na 20. Jeżeli istnieje, konwertujemy go na numer (dane z konsoli są pobierane jako łańcuchy znakowe) używamy funkcji lua – tonumber.
Analogicznie, jeżeli w ogóle jej nie ustawiliśmy, to wartością domyślną będzie 3. Jeżeli jednak istnieje, konwertujemy ją na numer, oraz zaokrąglamy za pomocą funkcji lua math.ceil.
Dlatego używamy funkcji lua math.abs, żeby zwrócić dodatni, zaokrąglony numer.
Jeżeli nie zostanie określona, zostawiamy domyślną.
Następnie zastosujemy pętlę while, aby stworzyć tyle płatków, ile nam potrzeba (pętla będzie tworzyć dopóty, dopóki nie spełni się dany warunek). Warunkiem będzie intensywność, ustawiona wcześniej.
while counter = density do
–Dla x i y, nadal obliczana jest przypadkowa pozycja wokół gracza (z uwzględnieniem podanych parametrów ograniczających)
local angle = randInt ( 0, 359 )local fx = px + math.cos ( angle ) * radius * randFloat ()local fy = py + math.sin ( angle ) * radius * randFloat ()
local fz = pz + height
Użyjemy trygonometrii, aby umieścić płatek w przestrzeni. Najpierw zastosujemy funkcję lua randInt aby wygenerować przypadkowy numer między 0 a 359. Następnie stosujemy trygonometrię, pobieramy pozycję x i y, oraz mnożymy przez radius (obszar opadu: „jego promień”). Teraz mnożymy to przez dowolną liczbę dziesiętną między 0, a 1 (randFloat).
Mamy pozycję, stwórzmy więc sam płatek
Zastosowano funkcję createMarker. Tydzień temu używaliśmy jej, aby określić wygląd „cylindryczny” (owalny) tworząc marker. Tworzymy teraz obiekt „corona”, który czymś w rodzaju świecącej piłki. Dodajemy go również do tabeli, więc będziemy mogli się do niego odwołać później.
Ustawiamy liczniki
local time = 1000 * ( height + 1 ) / speed
–każemy skryptowi, aby zaktualizować obecną pozycję płatka, tyle razy, ile trzeba oraz zapisać ID licznika do tabeli
setTimer ( ‘snow_moveFlake’, updaterate, math.floor ( time / updaterate ), flakeID, speed )
–Niszczymy płatek, gdy minie czas
setTimer ( ‘snow_destroyFlake’, time, 1, flakeID )
Wreszcie przywołujemy funkcję, którą rozpoczniemy opad.
Ruch oraz niszczenie płatków
Teraz warto napisać funkcję snow_moveFlake.
local fx, fy, fz = getElementPosition ( snowflake[flakeID] )
setElementPosition ( snowflake[flakeID], fx, fy, fz – ( updaterate / 1000 * speed ) )
end
Pobiera ona pozycję płatku, sprawdzając w poprzednio stworzonej tabeli. Następnie go porusza w dół, odwołując się do prędkości i częstotliwości opadu. Jako, że będzie to wykonywane wielokrotnie (zmienna updaterate), będzie sprawiał wrażenie ruchu.
Wreszcie napiszmy ostatnią funkcją snow_destroyFlake, odpowiedzialną za niszczenie płatków, gdy skończy się ustawiony czas opadu.
destroyElement ( snowflake[flakeID] )
snowflake[flakeID] = nil
end
Jak widać, użyto tej samej funkcji, co w zeszłym tygodniu, destroyElement, (używanej wtedy, aby zniszczyć pole teleportacyjne). Nie inaczej jest ze śniegiem. Na sam koniec następuje czyszczenie tabeli i zwolnienie pamięci.
2010-09-03 13:15:06
gra wygląda ciekawie, chciałem w nia pograć, ale nikt nie dołącza do mojego serwera...