Skocz do zawartości
  • 0
LolikZabijaka

Lengthdir - Nie ogarniam

Pytanie

Witajcie, zdaję sobie sprawę, iż temat był maglowany setki razy, mimo przetrzepania forum i wuja google, nie jestem w stanie uzyskać zadowalającego efektu. Przejdę do meritum:

Próbuję stworzyć coś, w rodzaju prymitywnego ragdolla, w rzucie 2D (Top-Down). Sama mechanika zachowania ciała nie sprawia większej trudności, poza jedną sprawą:

Jak wiadomo, aby uzyskać taki efekt, musiałem podzielić ciało na osiem segmentów(nie licząc korpusu). Efekt ten uzyskuję przy "instance_create" Tutaj pojawia się problem, ponieważ poszczególne segmenty "uciekają od siebie" przy zmianie kąta/kierunku, przykładowo, podczas obracania korpusu z już gotowymi "nogami" owe odnóża w czasie obrotu nie pozostają idealnie w punktach pierwotnego tworzenia. Wiem, iż w takim przyadku należy użyć funkcji lengthdir. Tutaj kilka pytań z mojej strony:

 

1. Wiem, że należy użyć twierdzenia pyta-golasa, aby obliczyć tę przeciwprostokątną, to pamiętam ze szkoły, ale czy orientacja sprite'a (poziom/pion) ma tu jakieś znaczenie? 

2. Jeśli orgin korpusu jest centralny, to czy dane do twierdzenia wyliczać od orginu, czy od wielkości tekstury?

3. Największa bolączka - kąt - z matmy nigdy nie byłem orłem, mimo zdania matury na 50%, nie zmienia to faktu, że tego kąta za cholerę nie mogę wyliczyć, nie wiem jakie dane i w jakiej kolejności podstawić, prosiłbym o łopatologiczne wyjaśnienie mi tego zagadnienia, bez zbędnej matematycznej terminologii :) Będę wdzięczny, ponieważ wczoraj kilka godzin z tym wojowałem i wyszedł jeden wielki(TU WIADOMO CO)

Oto grafika poglądowa korpusu:

Korpus

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

13 odpowiedzi na to pytanie

Rekomendowane odpowiedzi

  • 0

No właśnie cała specyfika lenghtdira polega na tym, ze nie musisz pitagorasów/tangensów liczyć, tylko podajesz od razu długość przeciwprostokątnej.

 

Patrzysz zatem na swój sprite który ma się obracać względem pierwszego i na to, jaki ma origin x. To będzie ten width.

 

x + lengthdir_x(w, 0) i y + lengthdir_y(w,0), powinny ustawić origin sprita drugiego, względem origina sprita pierwszego (gdzie x i y to pozycja pierwszego, a w to jest origin x drugiego).

 

Przypominam - 0 to w prawo, 90 w górę, 180 w lewo, 270 w dół, 360 == 0.

 

Zatem jak chcesz następny obrazek ustawić nie względem origina, a prawego końca, to musisz policzyć lengthdira z całej szerokości. Jak kolejny sprite ma origin na środku, ale ma nie zaczynać się na prawej stronie, ale na środku wzgledem tej strony, to kolejny raz liczysz od ostatniego punktu lenghtira o długosci origina.

 

Nie mam żadnego fajnego painta na linuxie żeby to narysować :P

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Nadal średnio to łapię :) Zróbmy inaczej, wrzucę grafikę poglądową korpusu jego mać. Żółty, to orgin. Teraz, czy posiłkować się trójkątem nr.1, czy nr.2 ? Jak to nie trzeba bawić się Pitagorasem,  wybacz, ale nadal nie do końca wiem jak to robić:D

 

Korpus jego mać

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Ja z kolei nie rozumiem twojego rysunku.

 

Dobra, inaczej, mamy dwa sprite. Każdy ma origina na środku, więc jak robisz draw_sprite(spr_A, 0, x, y), no to origin tego sprita jest właśnie na pozycji x i y. To wiemy.
Teraz mamy drugi sprite, on też ma origina i działa to na tej samej zasadzie.

Jak napiszesz, zeby środek pierwszego sprite był 20px od środka drugiego, to robisz tak:

draw_sprite(spr_B, x+lengthdir_x(20, dir), y+lengthdir_y(20, dir));
oczywiście za dir podkładasz kierunek, np. dla kierunku 0 i kierunku 45 będzie to tak (sorry za jakośc, to jakiś onlinowy edytor grafiki):

image.png

 

Oczywiście spr_B nie jest tutaj obracany, jakbyś chciał, żeby zawsze się obracał względem siebie, to musisz o to zadbać sam. Fioletowa linia to jest te 20px.

Oczywiście jak origin bedzie gdzie indziej, to sie wszystko zmienia:

image.png

 

Mniej wiecej tak (tutaj jeden spite ma origin w 0,0, a drugi ma w np. 20,0). Będzie wrażenie, że ten sprite ucieka i się zbliża. Dlatego najlepiej, jak masz origin na środku (albo środku przynajmniej jednego boku i obracać dobrze).

 

Po prostu zawsze na początku i końcu linii jest origin, a sprite się rysuje o tyle przesunięty (jak masz origin 30,40, to sprite będzie się zaczynał -30px w lewo i -40 w górę od punktu wynikowego).

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Udało mi się w miarę dobrze wyrysować nogę na korpusie, ale przy obracaniu obydwu części, noga gdzieś ucieka, wnika w korpus, oto kod ze step nogi:

 

image_angle=direction
x=o_korp.x+lengthdir_x(-6, -30)
y=o_korp.y+lengthdir_y(32, -30)

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

OK, a weź daj screena tych obrazków, ale ze sprite editora, żeby origin było widać (i coś na około, nie przycinaj tak dokładnie).

 

Mały hint - możesz robić ctrl+v obrazka w poście :)

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Inaczej, zacząłem bawić się z Animacją szkieletową od Psyhixa, podczas ruchów, nadal rozłączają się kończyny :/ Oto kod z draw: Gdzie jest babol ?

 



// lewe udo
d3d_transform_set_identity()
d3d_transform_add_rotation_z(kr_udo1) // pierw obracamy uklad wzgledem kierunku ramienia
d3d_transform_add_translation(-6,16,0) // potem przesuwamy uklad o 14 pixeli wstecz aby znalesc sie tam gdzie ma konczyc sie ramie (kosc ramienia rowna 14 pixeli)
d3d_transform_add_rotation_z(kr_tw)
d3d_transform_add_translation(x,y,0)
draw_sprite(s_udo,0,0,0)
// lewa łyda
d3d_transform_set_identity()
d3d_transform_add_rotation_z(kr_lyda1) // obrot ukladu wzgledem kierunku reki
d3d_transform_add_translation(0,0,0) // przesuniecie reki o 8 pixeli (dlugosc reki)
d3d_transform_add_rotation_z(kr_udo1)
d3d_transform_add_translation(-6,48,0)
d3d_transform_add_rotation_z(kr_tw)
d3d_transform_add_translation(x,y,0)
draw_sprite(s_lyda,0,0,0)

// tulow
d3d_transform_set_identity() // resetujemy transformacje
d3d_transform_add_rotation_z(kr_tw) // obracamy uklad wzgledem kierunku tulowia
d3d_transform_add_translation(x,y,0) // przesuwamy uklad na pozycje obiektu
draw_sprite(s_korp,0,0,0) // rysujemy przetransformowanego sprajta
// nga

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Wybaczcie double-posta. Udało mi się stworzyć ów silnik :D Mam tylko jeszcze jedno małe pytanie. Jak ustawić losowy zakres wartości np. Prędkość (od -15 do 15), jak taki random zamknąć w kodzie ?

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

starsze GM: value = -15 + round(random(30.1))

nowsze GMS: value = irandom_range(-15, 16);

 

random zawsze losuje liczbę  a <= value < b, więc nigdy nie dostaniesz b, dlatego piszemy 16 (i 30.1 w przypadku pierwszym) :)

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
7 godzin temu, Uzjel napisał:

Nie no, pokaż jak działa ;)

koszmar początkujących w tym dziale

  • Haha (+1) 1

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

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

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

Zaloguj się tutaj

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników, przeglądających tę stronę.

×