Velocity - byaim i ustawianie.
KariiO
06.04.2012
kod który po wystrzeleniu ent leci tam gdzie celuje:
new Float: Velocity[3] VelocityByAim(id, 1500 , Velocity) entity_set_vector(Ent, EV_VEC_velocity ,Velocity)
rysunek:
Gość_21977_* 07.04.2012
///////////////////////////////////////////////////
///////// odpowiedź na pierwsze pytanie: //////////
///////////////////////////////////////////////////
new Float:Velocity[3];
VelocityByAim(id, 1500, Velocity);
for(new i=0;i<3;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów
entity_set_vector(Ent, EV_VEC_velocity ,Velocity);
///////////////////////////////////////////////////
/////////// odpowiedź na drugie pytanie: //////////
///////////////////////////////////////////////////
new Float:Velocity[3];
VelocityByAim(id, 1500, Velocity);
for(new i=1;i<3;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów płaszczyzny poziomej
Velocity[0]=0.0; // wyzerowanie wektora wysokości
entity_set_vector(Ent, EV_VEC_velocity ,Velocity);
Użytkownik benio101 edytował ten post 07.04.2012 00:39
DarkGL
07.04.2012
1. xs_vec_neg
jeśli chcesz poczytać o wektorach to z książek mogę ci polecić
http://helion.pl/ksi...ourg,fiprog.htm
w liceum też są omawiane wektory ale nie wszystkie aspekty
na alliedmoders widziałem tutek poszukaj
KariiO
07.04.2012
lib xs daje dużo funkcji do pracy z wektorami
1. xs_vec_neg
jeśli chcesz poczytać o wektorach to z książek mogę ci polecić
http://helion.pl/ksi...ourg,fiprog.htm
w liceum też są omawiane wektory ale nie wszystkie aspekty
na alliedmoders widziałem tutek poszukaj
xs_vec_neg(const Float:vec[], Float:out[]) { out[0] = -vec[0]; out[1] = -vec[1]; out[2] = -vec[2]; }Możesz mi objaśnić do czego mogę użyć tego ?
dasiek
07.04.2012
new Float:velocity[3]; VelocityByAim(id, 700, velocity); velocity[2] = random_float(265.0,285.0); entity_set_vector(identa, EV_VEC_velocity, velocity);
Gość_21977_* 07.04.2012
Z tego, co widzę, to ta funkcja odwraca wektor, odpowiedź na Twoje pierwsze pytanie.lib xs daje dużo funkcji do pracy z wektorami
1. xs_vec_neg
jeśli chcesz poczytać o wektorach to z książek mogę ci polecić
http://helion.pl/ksi...ourg,fiprog.htm
w liceum też są omawiane wektory ale nie wszystkie aspekty
na alliedmoders widziałem tutek poszukajxs_vec_neg(const Float:vec[], Float:out[]) { out[0] = -vec[0]; out[1] = -vec[1]; out[2] = -vec[2]; }Możesz mi objaśnić do czego mogę użyć tego ?
A dokładnie, to zmienia zwrot kierunku na przeciwny.
dasiek
07.04.2012
Odwraca współżędne vec[] do out[]
xs_vec_neg(const wsp,Float wsp2)
zmienna wsp2 będzie miała współżędne wsp tyle ze odwrotne
G[o]Q
07.04.2012
///////////////////////////////////////////////////
///////// odpowiedź na pierwsze pytanie: //////////
///////////////////////////////////////////////////
new Float:Velocity[3];
VelocityByAim(id, 1500, Velocity);
for(new i=0;i<3;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów
entity_set_vector(Ent, EV_VEC_velocity ,Velocity);
///////////////////////////////////////////////////
/////////// odpowiedź na drugie pytanie: //////////
///////////////////////////////////////////////////
new Float:Velocity[3];
VelocityByAim(id, 1500, Velocity);
for(new i=1;i<3;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów płaszczyzny poziomej
Velocity[0]=0.0; // wyzerowanie wektora wysokości
entity_set_vector(Ent, EV_VEC_velocity ,Velocity);
wektor wysokosci to Velocity[2] a nie [0] chyba
pozatym powinno wystarczyć takie cos
VelocityByAim(id, -1500, Velocity);
ale najlepiej zbudować swój wektor przy uzyciu xS'a
Gość_21977_* 07.04.2012
for(new i=1;i<3;++i)Velocity[i]*=-1;
Dokładnie z 1. robi się 2., tylko w trójwymiarze:
Btw. A odnośnie mojego 2. kodu, dopiero się zorientowałem,
że zeruję zły wymiar i nie uwzględniłem przesunięcia pionowego.
Ach te nocne postowanie.
Inaczej można tak (raczej):
1. Pobieramy kąt obrócenia gracza (np. pev_v_angle), pisałeś o tym poradnik, więc powinieneś sobie dać radę.
2. Tworzymy wektor (bodajże {0.0,1500.0,0.0}), nie pamiętam dokładnie który wymiar ma którą cyferkę.
3. Obracamy go z powrotem o kąt obrócenia gracza:
x' = x*cos(alfa) - y*sin(alfa) y' = x*sin(alfa) + y*cos(alfa)4. I ostatecznie odwracamy wektor (xs_vec_neg), gdyż chcemy uzyskać przeciwny kierunek.
edit. @G[o]Q. Napisałem post, zanim przeczytał Twój, wyprzedziłeś mnie
Masz rację, pomyliłem wymiary w wektorze.
A odnośnie samego VelocityByAim(id, -1500, Velocity); to nie działa ze względu na to, że wymiar pionowy się nie zeruje i patrząc wysoko w niebo, wbija nas w ziemię i odbija wysoko w górę, podobnie patrząc w ziemię, od razu nas wybija do góry, a problem polega na "wyzerowaniu" tego przesunięcia pionowego celownika. Testowałem i powiem Ci, że tak nie da rady.
Użytkownik benio101 edytował ten post 07.04.2012 10:47
KariiO
07.04.2012
new Float:Velocity[3];
VelocityByAim(id, 1500, Velocity);
for(new i=1;i<3;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów płaszczyzny poziomej
Velocity[2]=0.0; // wyzerowanie wektora wysokości
entity_set_vector(Ent, EV_VEC_velocity ,Velocity);
Ent poleci zza mnie + poleci prosto bo Velocity[2]=0.0; zeruje nawet jakbym celownik w niebo, tak ?
Co do prawej i lewej strony, jak to będzie ?
Velocity[1] ?
Gość_21977_* 07.04.2012
Najlepiej, żeby nie bawić się w cuda niewida, to myślę, żeby zapisać pozycję aimingu gracza, zmienić do wprost przed siebie, wtedy wywołać ww. algorytm i na końcu przywrócić stary aiming gracza.
edit. Aha.. no i nie
for(new i=1;i<3;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów płaszczyzny poziomej[/color][color=#000000]tylko
Velocity[2]=0.0; // wyzerowanie wektora wysokoci
for(new i=0;i<2;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów płaszczyzny poziomej[/color][color=#000000]bo musimy odwrócić wymiary szerokości i długości, a jedynie wysokość (2) wyzerować.
Velocity[2]=0.0; // wyzerowanie wektora wysokości
Krótki kod:
register_clcmd("say jump","jump");odpalony na serwerze pokazuje, że po wpisaniu na sayu "jump", gracz jest popychany do tyłu, jednak, jak wyżej napisałem, moc tego pchnięcia jest różna w zależności od wysokości, na jaką celuje / patrzy gracz.
public jump(id){
new Float:Velocity[3];
VelocityByAim(id, 1500, Velocity);
for(new i=0;i<2;++i)Velocity[i]*=-1;
Velocity[2]=0.0;
entity_set_vector(id, EV_VEC_velocity ,Velocity);
}
Użytkownik benio101 edytował ten post 07.04.2012 13:19
KariiO
07.04.2012
Okej, a jak mogę ustawić żeby ent leciał na tej samej wysokości tylko np. w lewo od gracza ?Też tak robiłem, wyrzuca w dobrym kierunku, lecz z różną siłą, zależną od kąta nachylenia osi pionowej celowania przez fgracza, tj. jeśli patrzy wprost przed siebie, to wyrzuca maksymalnie prawidłowo, lecz im większe odchylenie (ku podłodze lub niebu), tym mniejsza odległość wektora. I tutaj jest stricte fizyka, wzór bodajże ten, co podałem wyżej, lecz nie umiem go odnieść do amxxa.
Najlepiej, żeby nie bawić się w cuda niewida, to myślę, żeby zapisać pozycję aimingu gracza, zmienić do wprost przed siebie, wtedy wywołać ww. algorytm i na końcu przywrócić stary aiming gracza.
edit. Aha.. no i niefor(new i=1;i<3;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów płaszczyzny poziomej[/color][color=#000000]tylko
Velocity[2]=0.0; // wyzerowanie wektora wysokoci
for(new i=0;i<2;++i)Velocity[i]*=-1; // odwrócenie zwrotów wektorów płaszczyzny poziomej[/color][color=#000000]bo musimy odwrócić wymiary szerokości i długości, a jedynie wysokość (2) wyzerować.
Velocity[2]=0.0; // wyzerowanie wektora wysokości
Krótki kod:register_clcmd("say jump","jump");odpalony na serwerze pokazuje, że po wpisaniu na sayu "jump", gracz jest popychany do tyłu, jednak, jak wyżej napisałem, moc tego pchnięcia jest różna w zależności od wysokości, na jaką celuje / patrzy gracz.
public jump(id){
new Float:Velocity[3];
VelocityByAim(id, 1500, Velocity);
for(new i=0;i<2;++i)Velocity[i]*=-1;
Velocity[2]=0.0;
entity_set_vector(id, EV_VEC_velocity ,Velocity);
}
|
Gość_21977_* 07.04.2012
Na początku pokazuję, jak wygląda kod, który cofa gracza do tyłu (oczywiście to mogła być równie dobrze strzała)
Następnie celuję coraz niżej ziemi, pokazując, że "cofnięcie" gracza jest coraz słabsze.
Później robię to samo w stronę nieba z tym samym efektem: coraz słabsze "cofnięcia" gracza.
Na końcu pokazuję, że dla różnych kierunków odpycha zawsze dokładnie do tyłu,
starając się celować jak najbardziej poziomo, by :cofnięcie" było lepiej widoczne.
1. Problem zdaje się być rozwiązany: jest prawidłowy kierunek (a raczej zwrot)
2. Teraz pozostaje problem chwilowej zmiany aimingu gracza na maksymalnie poziomy.
3. Tutaj znowu będzie trzeba na podstawie kąta obrócenia gracza obliczyć, gdzie jest "lewo" i odpowiednio przesunąć obydwa wektory, wektor 0 i 1.Okej, a jak mogę ustawić żeby ent leciał na tej samej wysokości tylko np. w lewo od gracza ?
DarkGL
07.04.2012
z tego co mogę się zorientować wystarczy znormalizować wektor po wyzerowaniu przesunięcia wysokości i pomnożyć go przez scalar
Gość_21977_* 07.04.2012
// Vector Operations -------------------------------------------------------------------------------Jeśli mi się uda znormalizować, wykorzystując podaną tutaj funkcję, to podam na bieżąco dane.
public Float:getVecLen(Float:Vec[3]){
new Float:VecNull[3]={0.0,0.0,0.0}
new Float:len=vector_distance(Vec,VecNull)
return len
}
public Float:scalar_triple_product(Float:a[3],Float:b[3]){
new Float:up[3]={0.0,0.0,1.0}
new Float:Ret[3]
Ret[0]=a[1]*b[2]-a[2]*b[1]
Ret[1]=a[2]*b[0]-a[0]*b[2]
Ret[2]=a[0]*b[1]-a[1]*b[0]
return vectorProduct(Ret,up)
}
public normalize(Float:Vec[3],Float:Ret[3],Float:multiplier){
new Float:len=getVecLen(Vec)
copyVec(Vec,Ret)
Ret[0]/=len
Ret[1]/=len
Ret[2]/=len
Ret[0]*=multiplier
Ret[1]*=multiplier
Ret[2]*=multiplier
}
public rotateVectorZ(Float:Vec[3],Float:direction[3],Float:Ret[3]){
// rotates vector about z-axis
new Float:tmp[3]
copyVec(Vec,tmp)
tmp[2]=0.0
new Float:dest_len=getVecLen(tmp)
copyVec(direction,tmp)
tmp[2]=0.0
new Float:tmp2[3]
normalize(tmp,tmp2,dest_len)
tmp2[2]=Vec[2]
copyVec(tmp2,Ret)
}
public Float:vectorProduct(Float:Vec1[3],Float:Vec2[3]){
return Vec1[0]*Vec2[0]+Vec1[1]*Vec2[1]+Vec1[2]*Vec2[2]
}
public copyVec(Float:Vec[3],Float:Ret[3]){
Ret[0]=Vec[0]
Ret[1]=Vec[1]
Ret[2]=Vec[2]
}
public subVec(Float:Vec1[3],Float:Vec2[3],Float:Ret[3]){
Ret[0]=Vec1[0]-Vec2[0]
Ret[1]=Vec1[1]-Vec2[1]
Ret[2]=Vec1[2]-Vec2[2]
}
public addVec(Float:Vec1[3],Float:Vec2[3]){
Vec1[0]+=Vec2[0]
Vec1[1]+=Vec2[1]
Vec1[2]+=Vec2[2]
}
Gość_21977_* 07.04.2012
Kod będzie wyglądał następująco:
new Float:Velocity[3]; // Pojemnik na wektor
VelocityByAim(id, -1500, Velocity); // Ustalenie obrotu gracza wraz z odwróceniem wektora (Optymalizacja by G[o]Q)
Velocity[2]=0.0; // Wyzerowanie pionowego przesunięcia wektora, aby uzyskać proste przesunięcie (prosty strzał, a nie w górę, czy w dół)
normalize(Velocity,Velocity,1500.0); // Normalizacja wektora wraz ze zwiększeniem, czyli dostosowanie wielkości przesunięcia po usunięciu przesunięcia pionowego
entity_set_vector(Ent, EV_VEC_velocity ,Velocity); // przesunięcie właściwe
// gdzie id to ID gracza, Ent to ID bytu, np. właśnie strzały
public normalize(Float:Vec[3],Float:Ret[3],Float:multiplier){ // funkcja normalizująca znaleziona w kodzie źródłowym ESP
new Float:len=getVecLen(Vec)
copyVec(Vec,Ret)
Ret[0]/=len
Ret[1]/=len
Ret[2]/=len
Ret[0]*=multiplier
Ret[1]*=multiplier
Ret[2]*=multiplier
}
public copyVec(Float:Vec[3],Float:Ret[3]){ // funkcja pomocnicza do funkcji normalizującej
Ret[0]=Vec[0]
Ret[1]=Vec[1]
Ret[2]=Vec[2]
}
public Float:getVecLen(Float:Vec[3]){ // druga i ostatnia funkcja pomocnicza do funkcji normalizującej
new Float:VecNull[3]={0.0,0.0,0.0}
new Float:len=vector_distance(Vec,VecNull)
return len
}
I tym samym problem pytania 2. rozwiązany
Przykładowy kod, który po wykonaniu komendy "jump", odpycha gracza używającego tej komendy o 1500 do tyłu:
register_clcmd("say jump","jump");
public jump(id){
new Float:Velocity[3];
VelocityByAim(id, -1500, Velocity);
Velocity[2]=0.0;
normalize(Velocity,Velocity,1500.0);
entity_set_vector(id, EV_VEC_velocity ,Velocity);
}
// ponieważ za ent (numer bytu) w entity_set_vector daliśmy ID gracza (id), to gracz zostanie przesunięty,
// czyli dostanie kopniaka i z siłą 1500 poleci do tyłu, bez względu, czy patrzy się na górę, na dół, czy przed siebie
public normalize(Float:Vec[3],Float:Ret[3],Float:multiplier){
new Float:len=getVecLen(Vec)
copyVec(Vec,Ret)
Ret[0]/=len
Ret[1]/=len
Ret[2]/=len
Ret[0]*=multiplier
Ret[1]*=multiplier
Ret[2]*=multiplier
}
public copyVec(Float:Vec[3],Float:Ret[3]){
Ret[0]=Vec[0]
Ret[1]=Vec[1]
Ret[2]=Vec[2]
}
public Float:getVecLen(Float:Vec[3]){
new Float:VecNull[3]={0.0,0.0,0.0}
new Float:len=vector_distance(Vec,VecNull)
return len
}
Z wstawieniem za ent strzały chyba problemów nie powinieneś mieć
Ostatecznie odpowiedź na 2. pytanie została udzielona
PS. Załączam link do filmiku na YT, gdzie widać, że normalizacja się udała, gdyż bez względu na wysokość,
na jaką się patrzymy (czy to niebo, ziemia, czy poziome patrzenie), zawsze jesteśmy "kopani" o taką samą
wartość. Oczywiście dalej działa to dla wszystkich obrotów prawidłowo, więc funkcję uważam za prawidłową.
http://www.youtube.c...h?v=8iLpNboI2as
PPS. Przepraszam, ale nie mogłem edytować poprzedniego postu, proszę o scalenie tego z powyższym. Dziękuję.
Użytkownik benio101 edytował ten post 07.04.2012 16:09
KariiO
07.04.2012
Tworzę cztery byty, jeden leci wprost przed gracza drugi w tył, trzeci w lewo a czwarty w prawo i tylerozpisaliście się tak że nie wiadomo co czytać opisz jakoś krótko co chcesz uzyskać
z tego co mogę się zorientować wystarczy znormalizować wektor po wyzerowaniu przesunięcia wysokości i pomnożyć go przez scalar
PS. Nie wiem już z jakiego kodu skorzystać
DarkGL
07.04.2012
potrzebne ci angles gracza i funkcja angle_vector http://www.amxmodx.o...?go=func&id=366
wyciągasz za pomocą tej funkcji vector forward ( przód ) i vector right ( prawy )
teraz używasz xs_vec_neg ( zmiana zwrotu wektora ) aby uzyskać wektor do tyłu ( z tego do przodu ) i w lewo z tego w prawo
masz 4 wektory które są już znormalizowane ( składowe wektora są podzielone przez jego długość )
więc teraz używasz xs_vec_mul_scalar ( mnożenie wektora przez liczbe ) aby pomnożyć te wektory przez szybkość jaką mają mieć enty i otrzymane wektory ustawiasz jako velocity
potrzebny ci kod czy sobie poradzisz
KariiO
07.04.2012
new Angles[3],vecprosto[3],vectyl[3],vecprawo[3],veclewo[3] pev(id,pev_v_angle,Angles) angle_vector (Angles, ANGLEVECTOR_FORWARD, vecprosto) angle_vector (Angles, ANGLEVECTOR_RIGHT,vecprawo) xs_vec_neg(vecprosto,vectyl) xs_vec_neg(vecprawo,veclewo) //możesz pokazać jak dalej zrobić?
DarkGL
07.04.2012
xs_vec_mul_scalar( wektor , predkosc( jako float ) , ten sam wektor ); i tak 4 wektory
a potem juz tylko
set_pev( numer_enta , pev_velocity , wektor );