Zdravím,
Chci se zeptat, jak nastavit pohyb objektu podle rotace, aby se mi objekt pohyboval určitým směrem (samozřejmě tam, kde má postava obličej a ne stále po ose Y). Pro úplnost, používám JigLibX engine, ale bohatě mi postačí 2D návod.
Díky.
Pohyb podle rotace
-
Tomáš Slavíček
- častý přispěvatel

- Posts: 264
- Joined: Wed Aug 19, 2009 7:09
- Zařízení: Nexus 5, Galaxy S3, Nokia X, iPad mini
Pohyb podle rotace
Základní idea se dá najít například tady: http://www.berecursive.com/...
Obecně, pokud už znáš úhel natočení objektu (v radiánech), můžeš si z něho určit směrový vektor (o kolik se má objekt posunout v ose X a Y), tj. něco jako Vector2 increment = new Vector2(Math.Cos(angle), -Math.Sin(angle));
Tento směrový vektor můžeš získat i tak, že si odečteš tvoji aktuální pozici, od pozice kam se díváš (increment = position - lookPosition), nebo obráceně ;). Na tento increment by se pak mělo zavolat ještě increment.Normalize() (v tom odkazovaném článku to dělají zbytečně složitě, převádí to na úhel a znovu zpátky).
Když už máš normalizovaný vektor přírustku (tj. vždycky bude mít délku jedna), můžeš ho přičíst k pozici:
position += increment * SPEED * (float)gameTime.ElapsedTime.TotalMilliseconds;
SPEED je zde nějaká konstanta typu float, která udává rychlost. Z objektu gameTime si bereš počet ms od minulého snímku, aby animace běžela vždy stejně rychle.
Kdyžtak se ještě ptej. Ten tvůj objekt si stejně nejspíš bude pamatovat pozici svého středu + úhel natočení, příp. i tu rychlost posunu. Bude ti tedy stačit jen z úhlu určit vektor přírustku, ten vynásobit koeficientem rychlosti a o tuto vzdálenost posunout objekt. Předpokládáme tady otočení jen podle jedné osy (jako ve 2D). Pokud bys chtěl něco obecnějšího (navigovat raketu ve 3D prostoru podle všech 3D os), je to už složitější. Pro víc informací si můžeš najít informace o pojmu gimbal lock a takzvaných quaternionech.
---
Jinak, koukám ten JigLibX vypadá zajímavě... Máš s ním už nějaké zkušenosti? Jak je na tom s výkonem? Zkoušel jsi na telefonu, kolik zvládne řešit najednou kolizí apod.?
Obecně, pokud už znáš úhel natočení objektu (v radiánech), můžeš si z něho určit směrový vektor (o kolik se má objekt posunout v ose X a Y), tj. něco jako Vector2 increment = new Vector2(Math.Cos(angle), -Math.Sin(angle));
Tento směrový vektor můžeš získat i tak, že si odečteš tvoji aktuální pozici, od pozice kam se díváš (increment = position - lookPosition), nebo obráceně ;). Na tento increment by se pak mělo zavolat ještě increment.Normalize() (v tom odkazovaném článku to dělají zbytečně složitě, převádí to na úhel a znovu zpátky).
Když už máš normalizovaný vektor přírustku (tj. vždycky bude mít délku jedna), můžeš ho přičíst k pozici:
position += increment * SPEED * (float)gameTime.ElapsedTime.TotalMilliseconds;
SPEED je zde nějaká konstanta typu float, která udává rychlost. Z objektu gameTime si bereš počet ms od minulého snímku, aby animace běžela vždy stejně rychle.
Kdyžtak se ještě ptej. Ten tvůj objekt si stejně nejspíš bude pamatovat pozici svého středu + úhel natočení, příp. i tu rychlost posunu. Bude ti tedy stačit jen z úhlu určit vektor přírustku, ten vynásobit koeficientem rychlosti a o tuto vzdálenost posunout objekt. Předpokládáme tady otočení jen podle jedné osy (jako ve 2D). Pokud bys chtěl něco obecnějšího (navigovat raketu ve 3D prostoru podle všech 3D os), je to už složitější. Pro víc informací si můžeš najít informace o pojmu gimbal lock a takzvaných quaternionech.
---
Jinak, koukám ten JigLibX vypadá zajímavě... Máš s ním už nějaké zkušenosti? Jak je na tom s výkonem? Zkoušel jsi na telefonu, kolik zvládne řešit najednou kolizí apod.?
Pohyb podle rotace
Mnohokrát díky, až budu u VS, tak dám vědět.
JigLibX šlape skvěle, kolize jsou přesné (je možné nastavit automatický výpočet kolizních hranic (to z vlastní zkušenosti nedoporučuji, prakticky to sníží FPS okolo 50%, nebo ručně, to sice zabere nějaký čas, ale rozdíly jsou pak pro oko minimální a s FPS to téměř nic nedělá. Je také možné nastavit hmotnost objektu a podobně. Port aplikace do Windows je též bez problému. Já naházel na plochu okolo stovky koulí a FPS nešlo pod 30. S zvýšenou hranicí FPS jsem nezkoušel.
A ještě jednou díky, bez tvého seriálu bych programování v XNA asi vzdal.
JigLibX šlape skvěle, kolize jsou přesné (je možné nastavit automatický výpočet kolizních hranic (to z vlastní zkušenosti nedoporučuji, prakticky to sníží FPS okolo 50%, nebo ručně, to sice zabere nějaký čas, ale rozdíly jsou pak pro oko minimální a s FPS to téměř nic nedělá. Je také možné nastavit hmotnost objektu a podobně. Port aplikace do Windows je též bez problému. Já naházel na plochu okolo stovky koulí a FPS nešlo pod 30. S zvýšenou hranicí FPS jsem nezkoušel.
A ještě jednou díky, bez tvého seriálu bych programování v XNA asi vzdal.
Pohyb podle rotace
Tak jsem to zkusil, objekt se mi však stále kroutí stále dokola, místo toho, aby šel rovně:
public void MoveFront(GameTime gameTime)
{
Quaternion q = Quaternion.CreateFromRotationMatrix(body.Orientation);
Vector2 increment = new Vector2((float)Math.Cos(q.Z), (float)-Math.Sin(q.Z));
increment.Normalize();
Vector3 newPosition = new Vector3(increment.X * 2 * (float)gameTime.ElapsedGameTime.TotalMilliseconds, increment.Y * 2 * (float)gameTime.ElapsedGameTime.TotalMilliseconds, 0);
PhysicsBody.Position = newPosition;
}
Jsem z toho poměrně zoufalý, nebotˇ chci hru stihnout na Game Expo 2012 a tento problém mi stále vrtá hlavou... Co přesně dělám špatně?
Pak bych samozřejmě hru prezentoval tu...
public void MoveFront(GameTime gameTime)
{
Quaternion q = Quaternion.CreateFromRotationMatrix(body.Orientation);
Vector2 increment = new Vector2((float)Math.Cos(q.Z), (float)-Math.Sin(q.Z));
increment.Normalize();
Vector3 newPosition = new Vector3(increment.X * 2 * (float)gameTime.ElapsedGameTime.TotalMilliseconds, increment.Y * 2 * (float)gameTime.ElapsedGameTime.TotalMilliseconds, 0);
PhysicsBody.Position = newPosition;
}
Jsem z toho poměrně zoufalý, nebotˇ chci hru stihnout na Game Expo 2012 a tento problém mi stále vrtá hlavou... Co přesně dělám špatně?
Pak bych samozřejmě hru prezentoval tu...
-
Tomáš Slavíček
- častý přispěvatel

- Posts: 264
- Joined: Wed Aug 19, 2009 7:09
- Zařízení: Nexus 5, Galaxy S3, Nokia X, iPad mini
Pohyb podle rotace
Na první pohled... Ten přírustek by se měl nejspíš přičítat k pozici, ne jen přiřazovat, tj. dát tam += do:
PhysicsBody.Position += newPosition; Ale možná, že to bude ještě něčím jiným. Zkus to...
PS. to Game Expo, to je myšleno to v Bratislavě? To vypadá zajímavě
PhysicsBody.Position += newPosition; Ale možná, že to bude ještě něčím jiným. Zkus to...
PS. to Game Expo, to je myšleno to v Bratislavě? To vypadá zajímavě
Pohyb podle rotace
Tak jsem to zkoušel i v čistým JigLibX projektu, zkoušel jsem jiné osy, zkoušel jsem Velocity a nic...
Jestli budeš mít chvílku čas, nekoukl bys na to?
http://jiglibx.codeplex.com/workitem/14784" onclick="window.open(this.href);return false;
PS: Jo, v BA.
Jestli budeš mít chvílku čas, nekoukl bys na to?
http://jiglibx.codeplex.com/workitem/14784" onclick="window.open(this.href);return false;
PS: Jo, v BA.
-
Tomáš Slavíček
- častý přispěvatel

- Posts: 264
- Joined: Wed Aug 19, 2009 7:09
- Zařízení: Nexus 5, Galaxy S3, Nokia X, iPad mini
Pohyb podle rotace
No, teď na tom moc s časem dobře nebudu... Pak se na to možná kouknu. Ale nejspíš tam bude dělat nějaký bordel ta knihovna. Pokud jsem někdy využíval simulaci fyziky apod., vždycky jsem to dělal raději na druhém objektu, pak si z toho vzal např. jen informaci o rychlosti, ostatní jsem si řešil po svém.
Zkus si tenhle algoritmus naprogramovat někde ve vedlejším projektu, úplně bez JigLibX, aby ti tam chodil (jestli v něm nemáš chybu). Pak se případně podívej, co ti tam vrací ta metoda CreateFromRotationMatrix(), jestli je to opravdu úhel v radiánech a jestli opravdu odpovídá správné ose (a tomu, co bys tam čekal). Pak si zkontroluj, jestli tomu objektu PhysicsBody vůbec můžeš nastavovat pozici, kdo ví, jakého je typu... A zkontroluj, jestli si tu pozici on potom ještě nemění někde po svém, např. v nějaké metodě IntegratePhysics().
Zkus si tenhle algoritmus naprogramovat někde ve vedlejším projektu, úplně bez JigLibX, aby ti tam chodil (jestli v něm nemáš chybu). Pak se případně podívej, co ti tam vrací ta metoda CreateFromRotationMatrix(), jestli je to opravdu úhel v radiánech a jestli opravdu odpovídá správné ose (a tomu, co bys tam čekal). Pak si zkontroluj, jestli tomu objektu PhysicsBody vůbec můžeš nastavovat pozici, kdo ví, jakého je typu... A zkontroluj, jestli si tu pozici on potom ještě nemění někde po svém, např. v nějaké metodě IntegratePhysics().
Who is online
Users browsing this forum: No registered users and 1 guest
