Skocz do zawartości

Falowanie sprite'a


Rekomendowane odpowiedzi

Zainspirowany gameplayem z gry Trip autorstwa propaganji (a dokładniej jednym z efektów) postanowiłem po raz kolejny wykonać prosty skrypcik dotyczący rysowania - tym razem dotyczący, jak w temacie, falowaniem sprite'a.

https://gmclan.org/up5655_14_falowanie.html

Skrypt działa w wersji Lite każdego GM-a posiadającego funkcję draw_sprite_part.

 

draw_sprite_wave:

GML
var w,h,sn;

w = sprite_get_width(argument0) //dla uproszczenia obliczeń

h = sprite_get_height(argument0) //to też

for(i = 0; i < h; i += argument4) //pętla dzieli sprite'a na kawałki przesunięte o daną wartość sn

{

sn = sin((current_time+i)*argument6*pi/180) //obliczamy, o ile trzeba przesunąć dany fragment sprite'a (efekt fali) [poprawka Sernata]

draw_sprite_part(argument0,argument1,0,i,w,argument4,argument2+(sn*argument5),argument3+i) //rysujemy i-ty fragment sprite'a

}

 

/*

Jest siedem argumentów:

-pierwsze cztery dokładnie takie same co w draw_sprite

-piąty oznacza wysokość danego kawałka (im mniejszy, tym gładsza fala, ale i tym wolniejszy skrypt będzie)

-szósty oznacza wychylenie fali na boki (czyli szerokość fali)

-siódmy to okres fali (1 to domyślny, im większy, tym większa częstotliwość fali (2 to dwa razy większa, 0.5 to dwa razy wolniejsza itd.)

*/

Odnośnik do komentarza
Udostępnij na innych stronach

Hehe, fajne w prostocie, tylko ciekaw jestem jak jest z wydajnością podczas rysowania co stepa każdego paseczka o wysokości jednego piksela ;) . GM 8.1, dlatego też nie przetestuję, aczkolwiek efekt jest oczywisty ;) .

 

Łapaj piąteczkę.

Odnośnik do komentarza
Udostępnij na innych stronach

Skrypt jest identyczny jak w przykładzie, wystarczy skopiować, bo w linku nie ma więcej kodu, tylko jedna linijka w Draw, sprite, obiekt i room : )

Tak, zdaję sobie z tego sprawę i nie muszę nawet niczego pisać od nowa tudzież kopiować, bo sam efekt mam w głowie ;) . Osobiście pokombinowałbym jeszcze z ewentualnym wygładzaniem obrazu i stworzył wersję z paskami o większej wysokości niż 1 piksel, co owocowałoby brzydszym efektem, ale większą wydajnością. Ale mówię: bardzo ciekawie sobie z tym poradziłeś. Powinieneś tylko dostać opiernicz za to, że w sinusie użyłeś niepotrzebnie funkcji degtorad: Zrozum, tutaj używamy sinusa nie do działań trygonometrycznych, a do opisu ruchu drgającego. To by było na tyle :) .

Odnośnik do komentarza
Udostępnij na innych stronach

hehe :thumbsup: kod praktycznie ten sam co w tripie tylko tam narzucone jako filtr + pare dodatkowych opcji :) Zadziwiajaco szybko to dziala, u siebie co prawda wole grac na mniejszych detalach bo wtedy fps nie spada ponizej 30 ale ja mam grata, za to w robocie pelne detale + nagrywajacy fraps + dziesiatki programow w tle i pelna predkosc a komputer tez nie jest jakas super maszyna z kosmosu.

Odnośnik do komentarza
Udostępnij na innych stronach

@Sernat: rzeczywiście, mogłem dzielić przez (180/pi), bo to właśnie robi funkcja degtorad. Ciekawe, czy byłoby to wtedy szybsze. Zrobię test i napiszę w edicie.

No i ta wersja pozwala na ustalenie wysokości paska : ) Generalnie im mniejsza amplituda i okres, tym większe paski można stosować, bo widocznej różnicy graficznej wtedy nie ma (lub jest na tyle mała, że nie przeszkadza gameplayowi).

@propaganja: no widzisz, ile można wywnioskować oglądając półminutowy gameplay : P

 

E: łoo, pi/180 jest 4x szybsze niż degtorad(1). Co prawda, w skrypcie da to widoczne przyspieszenie po > 1000000 wywołań, ale wypada poprawić.

Odnośnik do komentarza
Udostępnij na innych stronach

rzeczywiście, mogłem dzielić przez (180/pi), bo to właśnie robi funkcja degtorad

Nie oto Sernatowi chodziło. On chciał ci powiedzieć że tutaj nie jest ważne czy robisz to na radianach czy stopniach, kod mógł by wyglądać tak:

GML
var w,h,sn;

w = sprite_get_width(argument0)

h = sprite_get_height(argument0)

for(i = 0; i < h; i += argument4)

{

sn = sin((current_time+i)*argument6)

draw_sprite_part(argument0,argument1,0,i,w,argument4,argument2+(sn*argument5),argument3+i)

}

Wtedy w draw trzeba podać po prostu mniejszą liczbę jako 6 argument, efekt będzie ten sam tylko że bez konwersji.

 

Edit:

E: łoo, pi/180 jest 4x szybsze niż degtorad(1)

Dobrze wiedzieć. Tylko czemu natywna funkcja z GMa jest wolniejsza niż customowa : O

Odnośnik do komentarza
Udostępnij na innych stronach

Wiem, ale po prostu wygodniej jest wprowadzać argumenty niewymagające dalszej obróbki. Miałem o tym pojęcie od samego początku. Lepiej, żeby domyślną wartością nie było 57.8, tylko 1.

 

E: no, chyba można wysłać do GMLScripts.com : )

Odnośnik do komentarza
Udostępnij na innych stronach

Ale w skrypcie powinno być bez zamiany, jak ktoś by sobie chciał zrobić wygodniej to w funkcji draw by tą konwersjię wprowadził w 6 argumencie.

GML
draw_sprite_wave(zomggg,-1,x,y,5,16,degtorad(0.5))
i po sprawie.

Wprowadziłeś po prostu niepotrzebny wymóg dodatkowej konwersji gdyby ktoś chciał od razu jechać na radianach.

Odnośnik do komentarza
Udostępnij na innych stronach

Teraz to Ty zrobiłeś niepotrzebną konwersję. Nie ma znaczenia, gdzie tę konwersję się wsadzi, ale lepiej, by pojawiła się raz w całym kodzie gry, niż za każdym razem, gdy podaje się argumenty.

 

Okazało się, że jest już taki skrypt na GMLScripts.com, w dodatku praktycznie identyczny : (

Odnośnik do komentarza
Udostępnij na innych stronach

hmmm? ja tu widzę 1 konwersję

GML
var w,h,sn;

w = sprite_get_width(argument0)

h = sprite_get_height(argument0)

for(i = 0; i < h; i += argument4)

{

sn = sin((current_time+i)*argument6)

draw_sprite_part(argument0,argument1,0,i,w,argument4,argument2+(sn*argument5),argument3+i)

}

GML
draw_sprite_wave(zomggg,-1,x,y,5,16,degtorad(0.5))

 

a teraz nie ma wcale

GML
draw_sprite_wave(zomggg,-1,x,y,5,16, 0.00873)

 

Oto mi chodziło

 

E: hmm w sumie to wyjdzie na to samo :P

Odnośnik do komentarza
Udostępnij na innych stronach

To nie jest wygodne. A utrata szybkości minimalna. Myślisz, że jak Apple podbiło świat? Ich sprzęt nie jest demonem szybkości, ale jest wygodny - to jego główna zaleta.

 

E: no widzisz? : P

Ten post zawiera tyle błędów rzeczowych, że aż grzechem jest się nie przyczepić ;) . Falowanie sprite'a to nic innego jak ruch zmienny (drgający), który opisuje się w najprostszym wariancie następująco: y = sin( k * x + a ), gdzie k i a to dowolne współczynniki stałe. Nic do tego nie mają radiany, nic do tego nie mają stopnie, gdyż nie mówimy o trygonometrii, a po prostu zaczerpujemy niesamowitą właściwość tej jakże genialnej funkcji.

 

Nie widzę do końca wygody w twoim pomyśle i nie widzę potrzeby, by degtorad zamieniać na pi / 180. Nie chodzi o szybkość, a o samą estetykę, perfekcjonizm, który w tego typu minimalistycznych przykładach jest wskazany.

 

Od kiedy Apple nie jest demonem szybkości to nie wiem. iPad 2 w benchmarkach niszczy mojego PCta, a sama seria iPodów i iPhone'ów słynie z niezawodności i braku ścinek. Jak Apple zaszło tak daleko? Marketing.

 

To byłoby na tyle, peace and love ;) .

Odnośnik do komentarza
Udostępnij na innych stronach

No dobra, może co do Apple nieco się wygłupiłem : P Ale swojego zdania co do wygody nie zmienię. Nie widzę żadnego powodu na dalszą ingerencję w skrypt, toteż nie będę nic więcej zmieniał. Tak wg mnie jest idealnie.

 

dot

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy
-siódmy to okres fali (1 to domyślny, im większy, tym większa częstotliwość fali (2 to dwa razy większa, 0.5 to dwa razy wolniejsza itd.)

Nie zgodzę się ze stwierdzeniem że argument6 domyślnie ma wartość 1 :)

Odnośnik do komentarza
Udostępnij na innych stronach

No dobra, może co do Apple nieco się wygłupiłem : P Ale swojego zdania co do wygody nie zmienię. Nie widzę żadnego powodu na dalszą ingerencję w skrypt, toteż nie będę nic więcej zmieniał. Tak wg mnie jest idealnie.

 

dot

Nic nie zmieniasz, usuwasz degtorad i efekt jest nadal ten sam. Kropka.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 4 tygodnie później...

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...