PDA

Prikaži potpunu verziju : Box2D, vektor refleksije...


Belphegor
11.3.2012, 20:02
Za one koji ne znaju, pravim klon stare igre Breakout. Posto koristim Box2D za fiziku, koje bas i nije dizajniran za ovakvu stvar, imam problem.

Po nekoj normalnoj logici kako fizika funkcionise, vektor "refleksije" kad loptica udari u "tablu" koju kontrolise igrac, izgleda otprilike ovako:

http://www.dodaj.rs/f/2G/JV/1UJvAw9n/reflectionvector.jpg

Da ne objasnjavam sliku, verujem da je logicna.

Medjutim kod ovakve igre to nije slucaj, taj vektor "refleksije" zavisi sa koje "polovine strane" je loptica udarila tablu, pa s'tim moram da je polu-rucno i kontrolisem:



// Kad loptica napravi kontakt sa "tablom"
float padd_half_sz = (player_sprite->getSize().x * 0.5f) / B2_PIXEL_RATIO; // polovina "table", skalirano u Bo2D jedinicama
float ball_pos = (*balls_it)->getBody()->GetPosition().x; // X pozicija Box2D "tela" trenutne loptice
float padd_pos = player_sprite->getBody()->GetPosition().x + padd_half_sz;// X pozicija polovine table
float x = ball_pos - padd_pos; // razlika od centra table
bool sign = x < 0.0f; // da sacuvam "znak" razlike
x = proportion(std::fabs(x), padd_half_sz, 1.0f); // razlika propocionalno 0 - 1
b2Vec2 vel = b2Vec2(sign ? -x : x, -(1.0f - std::fabs(x))); // Y samo u minus, a '1 - fabs(x)' da bih imao "unit vektor"
vel *= ball_speed; // da bi sa '*= ball_speed' imao brzinu koju mogu da kontrolisem
(*balls_it)->getBody()->SetLinearVelocity(vel); // dodeli vektor

...
template< typename T >
T proportion(T oldNum, T oldSz, T newSz)
{
oldNum *= newSz;
oldNum /= oldSz;
return oldNum;
}
Medjutim kad je ugao veliki, cini mi se da loptica ide mnogo sporije nego kad je recimo ravno na gore V(0, -1).
Ako neko vidi gde gresim, ili ima na umu neku drugo resenje neka kaze?

MG-RAY
11.3.2012, 20:40
Generalno bi trebalo da ti Velocity bude oblika Direction * Speed.

U tvom slučaju, izračunaj vektor smera kako želiš, normalizuj ga (svaka komponenta posebno / length , mada pretpostavljam da b2Vec vec ima normalize() [edit: proverio, ima]), i pomnoži sa brzinom.

Reference za kasnije, ako zatreba: :D


Reflect: v = i - 2 * n * dot(i•n)
i je ulazni vektor, n je normala.

Normalize: v = v / length(v)

Belphegor
11.3.2012, 20:50
Ali ako je vektor "unit vektor" onda nema potrebe za normalizacijom?
Sad sam samo dodao normalize odmah pre SetLinearVelocity za sad izgleda ok.

MG-RAY
11.3.2012, 20:55
Unit vektor je vektor dužine jedan (1)...

Možda ti je matematika bila pogrešna...? :)

Belphegor
11.3.2012, 20:57
EDIT: Izgleda da sam permutovao, duzina vektora nije abs(x) + abs(y) nego x*x + y*y
u tome mi je i greska.

VojaM
12.3.2012, 0:26
A da nije možda još i koren iz tog zbira kvadrata?

Belphegor
12.3.2012, 0:30
Jeste ide i koren, ali nisam upisao u post. :)

Belphegor
12.3.2012, 0:41
Reference za kasnije, ako zatreba: :D


Reflect: v = i - 2 * n * dot(i•n)
i je ulazni vektor, n je normala.

Normalize: v = v / length(v)


Super sto si stavio kod ali ovo je za vektor refleksije, samo sto sam ja napisao u mom prvom postu da kod Breakout-a ovo ne vazi kad loptica udari u "tablu" vec zavisi sa koje strane "sredine" je udarila.

http://www.dodaj.rs/f/2Q/Nn/1lfwj57l/greenshot2012-03-1123-44.jpg

MG-RAY
12.3.2012, 9:25
^ Razume se, ostavio sam to za slucaj da ti mozda zatreba za nešto... I ja sam pravio sličnu igru pre par godina kao projekat za fax, tako da znam sa čime se suočavaš... :)