Skocz do zawartości

Pierwsze wprawki mp_potential_move


Barsztik

Rekomendowane odpowiedzi

Cześć,

 

W ramach wstępnej nauki GM stworzyłem postać obj_gracz składa się z 2 spritów (nogi i tors). Sprite tors ma 8 klatek: 4 klatki to ruch bez broni (same ręce) i 4 klatki (w rękach jakiś hipotetyczny gun).

Animację wymyśliłem tak, że klatki w ruchu przewijają się od 1-4, a jeśli ma broń to od 5-8, do tego celu wprowadziłem zmienną jaka_bron, przyjmującą wartości jaka_bron=0 (bez broni) i jaka bron=1 (z bronią). Póki co niczego specjalnie to nie służy, ale założyłem, że gracz może mieć bron 0,1,2,3.... itd, dlatego wprowadziłem zmienną mn_klatki.

 

W obj_gracz (mój ludzik) w evencie Create wpisałem:

 

klatka=0; //klatka "gracza" wyświetlana na starcie

licz_klatki=0; //timer spowalniający animację

global.jaka_bron=0; //zmienną jaka bron zrobiłem jako global (na przyszłość bo zdefiniowanie jej w create spowodowało by wyzerowanie przy zmianie rooma - tak przynajmniej sądzę)

mn_klatki=global.jaka_bron*4; // sprawia ze z bronią animacja dzieje się w klatkach 5-8, bez broni 1-4, z na przyszłośc z 2 bronia np w klatkach 9-12 itd...

xx=x; // wstępne zdefiniowanie zmiennych do wskazania myszką

yy=y;

 

W Global left pressed:

xx=mouse_x; // przypisanie wartości xx to położenia kursora myszki przy kliknięciu

yy=mouse_y;

 

 

 

W Step:

 

mp_potential_step(xx,yy,4,false)

 

if mp_potential_step(xx,yy,4,false)=false // gdy postać się porusza to...

{

 

licz_klatki+=1; //timer odlicza

if licz_klatki>=5 // jak odlicz do 5

{

klatka +=1; // zmienia klatka

licz_klatki =0; //zeruje timer

if klatka = 4 {klatka = 0;} // 'przewija' animację gdy dojdzie w konca wyznaczonego fragmentu

}

}

 

a w Draw:

 

mn_klatki=global.jaka_bron*4; //mn_klatki to zmienna która odsyła do odpowiedniej klatki (1+0=0 dla bez broni, ale 1+4=5 dla z bronią)

draw_sprite_ext(spr_gracz_nogi,klatka+mn_klatki,x,y,1,1,direction,c_white,1);

draw_sprite_ext(spr_gracz_gora,klatka+mn_klatki,x,y,1,1,direction,c_white,1);

 

Kod działa, mimo, że znajdowanie drogi na mp_potential_move jest dość kulawe, ale na razie nie porywam się na własne.

Moje pytanie brzmi, czy w tych kodach widzicie jakieś kardynalne błędy, które na razie się nie objawiają, ale w przypadku rozwiniętego kody wszystko by się wywaliło lub znacznie utrudniło.

 

Na przykład początkowo nie używałem zmiennej mn_klatki=jaka.bron*4, tylko od razu robiłem jaka_bron=4 (przy kolizji ze skrzynią z bronią) a w draw draw_sprite_ext(spr_gracz_nogi,klatka+jaka.bron,x,y,1,1,direction,c_white,1);, ale doszedłem do wniosku, że gdyby nie były to wprawki, a jakaś "prawdziwa" gra było by to kłopotliwe i ułatwiało by pomyłkę przy większej ilości broni.

 

Drugie pytanie. Chciałem by przy ruchu gracza odgrywała się animacja i wstawiłem if mp_potential_step(xx,yy,4,false)=true {...}

Ale wtedy animacja działała gdy gracz się nie poruszał, a gdy był w ruchu to się animacja się zatrzymywała. Rozwiązanie było proste, zamieniłem =true na =false i pomogło. Ale dla czego?

Rozumiałem to tak if mp_....=false (czyli nie porusza się), a okazało się odwrotnie. Stąd mój wniosek, że nie rozumiem polecenia mp_potential_move. Dlaczego false w tym przypadku to ruch, a true to brak ruchu?

 

Mam nadzieję, że mój post jest chodź w części zrozumiały :).

 

Pozdrawiam

B.

Odnośnik do komentarza
Udostępnij na innych stronach

Ta funkcja zwraca czy instancja osiągnęła pozycję xgoal i ygoal a nie czy się rusza.

 

No i do poruszania instancją nie używa vspeed, hspeed, speed tylko po prostu od razu przenosi instację na wolną pozycję o krok określony w parametrze "speed" dlatego mimo że instancja się rusza to jej zmienna speed nadal jest równa 0.

 

 

W ten sposób powodujesz że instancja rusza się podwójnie i podwójnie wylicza czy pozycja do której ma zamiar się udać jest wolna

GML
mp_potential_step(xx,yy,4,false)

 

if mp_potential_step(xx,yy,4,false)=false // gdy postać się porusza to...

{

Odnośnik do komentarza
Udostępnij na innych stronach

Po za tym to można uprościć

GML
licz_klatki+=1; //timer odlicza

if licz_klatki>=5 // jak odlicz do 5

{

klatka +=1; // zmienia klatka

licz_klatki =0; //zeruje timer

if klatka = 4 {klatka = 0;} // 'przewija' animację gdy dojdzie w konca wyznaczonego fragmentu

}

}

 

GML
klatka += 1;

animacja1 = klatka mod 5; // będą się odgrywać klatki z zakresu 0 do 4

animacja2 = ( klatka mod 7 )+4; // będą się odgrywać klatki z zakresu 4 do 10

itd

 

 

Ale gdy nie używałem warnuku if... postać animowała się cały czas, nawet gdy stała w miejscu.

 

No tak bo musisz sprawdzać czy postać się rusza ale za pomocą speed > 0 tego nie zrobisz bo speed = 0 więc możesz np wyznaczyć sobie wektor z pozycji aktualnej do pozycji poprzedniej, są takie zmienne jak xprevious, yprevious użyj ich z funkcjmi trygonometrycznymi, bodaj tan2(y,x) sry arctan2(y,x) powinien tutaj pomóc

A nie co za głupoty gadam, arctan2() wyliczy kierunek wektora a ty musisz znać jego długość więc z pitagorasa wyliczysz.

Odnośnik do komentarza
Udostępnij na innych stronach

Ok, dziękuję :)

 

Musze to wszystko przetrawić, więc pewnie odezwę się za kilka dni jak opanuje to co napisaliście :)

 

Ostatnio pisałem cokolwiek z dobre 10 lat temu we flashu 5, a przedtem na cpc464 w basicu, więc mam sporo do nadrobienia :)

 

*** back ***

 

Zrozumiałem dlaczego warto zamienić if mp_potential_move(....)=false na sumę wartości abs lub sumę kwadratów. Jak miałem mp_potential_move w warunku, to działało to 2 krotnie, i ludzik zasuwał za szybko. Aż wstyd, że nie wpadłem na wykorzystanie xprevious. Pamiętam, jak w basicu samodzielnie pisałem coś w stylu "xprevious", by magazynować tam poprzedni x właśnie do porównania z obecnym, a tu jest jak na tacy! Ponadto używałem tego do zatrzymywania ludka przy kolizji ze scianą, skrzynią (przy sterowaniu z klawiatury).

 

 

Ale mam pewne zastrzeżenie do:

GML
klatka += 1;

animacja1 = klatka mod 5; // będą się odgrywać klatki z zakresu 0 do 4

animacja2 = ( klatka mod 7 )+4; // będą się odgrywać klatki z zakresu 4 do 10

itd

 

Wykorzystanie reszty z dzielenia rzeczywiście jest w tym wypadku prostsze, ale czy nie wymagało by dodawania kolejnych linijek kodu przy każdej kolejnej broni?

W moim przykładzie w step mam:

GML
if ( predkosc > 0 )

{

licz_klatki+=1;

if licz_klatki>=5

{

klatka +=1;

licz_klatki =0;

if klatka = 4 {klatka = 0;}

}

}

Kod jest faktycznie dłuższy, ale nie wymaga ingerencji nawet jak ilość broni (wyglądów górnej części gracza), była by bardzo duża, bo pętla kręci się w wartościach 0-4 (dokładnie to w 0-3, bo 4 odsyła do 0).

 

Dalej kod w Draw:

GML
mn_klatki=global.jaka_bron*4;

draw_sprite_ext(spr_gracz_nogi,klatka+mn_klatki,x,y,1,1,direction,c_white,1);

draw_sprite_ext(spr_gracz_gora,klatka+mn_klatki,x,y,1,1,direction,c_white,1);

 

Również jest przygotowany na bardzo dużą ilość wariantów broni, poprostu numer broni 0,1,2,....15.... odeśle automatycznie do kokretnych klatek z zakresu 1-4, 5-8, 9-12,....60-64.... i również nie wymaga dopisywania żadnej linijki kodu w przypadku wiekszej ilości wariantów. Czy pod tym względem takie rozwiązanie nie jest lepsze? Wydaje mi się, że przy 2 rodzajach broni Twój kod jest faktycznie krótszy, ale gdybym dodał jeszcze kilka, to mógłby urosnąć znacznie.

 

Ciekawa rzecz jaką zauważyłem, to pewnego rodzaju "zawijanie" animacji. Otóż spr_gracz_nogi ma tylko 4 klatki, a mój kod (przypadkowo, bo skopiowałem go z draw_sprite_ext(spr_gracz_gora... odsyła "nogi" do klatek 5-8 (przy broni 1),ale wszystko działa, animacja jakby się zwijała i w przypadku animacji z klatkami 1-4 "wirtualna" nieistniejąca klatka 5 = klatce 1, 6=2, 7=3 itd... jeśli dobrze to rozumiem, to podoba mi się takie rozwiązanie :)

 

Z innej beczki. Podoba mi się, że w gml nie trzeba predefiniować zmiennych i definiują się przy pierwszym nadaniu wartości. Niemniej część zmiennych chciałbym sobie predefiniować na starcie w taki sposób, że same by się nie zresetowały. Np, jak wpiszę global.jaka_bron w Create w obj_gracz, to przy zmianie room'a obj_gracz zostanie utworzony na nowo i global.jaka_bron dostanie ponownie domyślną wartość. Chciałbym gdzieś wpisać początkowy kod, który zadziała tylko przy uruchomieniu aplikacji lub bezpośrednim odesłaniu do tego kodu, niezależnie jakie obiekty, room'y zostaną stworzone. Gdzie wpisać taki kod? W scripts?

Odnośnik do komentarza
Udostępnij na innych stronach

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ę...