Forumet - Enkel kollision, problem vid flyttalsvariabler

Enkel kollision, problem vid flyttalsvariabler

135 0 11
Jag försöker koda en enkel fysikmotor med hjälp av vanliga bounding boxes (alltså, ingen rotation och sånt avancerat).

När jag gör allt med heltal är det inga problem, då jag enkelt hela tiden kan kolla om pixeln under sig själv kolliderar med något annat. Men när jag kör med flyttal så vill jag gärna få bättre precision, problemet är bara det att när två boxar kolliderar så hamnar de helt enkelt i varandra.

Kort sagt, så fort boxen som simulerar "spelaren" nuddar en box så sitter spelaren fast i boxen.

Är det någon som har tips på hur jag bör lösa detta på ett bra sätt?
k1337oris:

Är det någon som har tips på hur jag bör lösa detta på ett bra sätt?


Själv har jag lärt mig C++ och håller på och lär mig fortfarande. Jag är ingen erfaren programmerare men jag har håller på och lär mig programmera enklare spel med 2D grafik då jag kopplar av från mina studier. Jag har läst något om bounding boxes också så jag har stött på begreppet. Kan du visa de relevanta delarna av koden här så är det lättare att sätta sig in i programmeringsproblemet och hitta en lösning.

Ifall det finns brist på kunniga här på forumet så rekommenderar jag
Matte och fysik forumet på gamedev.se , där borde väl finnas kunniga personer, ifall du inte redan råkar tänka på det:
http://www.gamedev.se/forum/viewforum.php?f=2

Spana också in:

k1337oris:

http://ungd.pastebin.com/f80597ed


Det där borde ju inte fungera alls, varken med flyttal eller heltal. Eftersom en kolliderande box får hastigheten satt till 0 så kommer den vara kvar på exakt samma ställe vid nästa iteration, och då kommer det bli en kollision igen, och så vidare.

Dessutom verkar din kollisionskod bara kolla två hörn på boundingboxen, vilket inte är tillräckligt för att detektera kollisioner. Egentligen borde du kolla åtta punkter, först ifall något av B:s hörn är inuti O, och sedan om något av O:s hörn är inuti B, för att täcka alla specialfall.
k1337oris:

Men hur bör jag göra? Ska jag kolla om nästa iteration kommer att kollidera, och sätta hastigheten till 0 om nästa iteration kommer att kollidera?


Jo, det borde fungera bättre. Det kan ju ge konstiga resultat om hastigheten hos objekten är hög, men så länge du har tillräckligt snabba iterationer (och därmed låg hastighet) så borde det fungera okej.
Hm, problemet är att om jag exempelvis trycker kuben åt vänster eller höger så kommer gravitationen och trycker ner kuben så att den kolliderar och därför inte kan röra sig.

Dessutom, om man är i luften med kuben och trycker mot en annan kub så kan man "trycka fast" sig i kuben, vilket ser lite konstigt ut... hm. Känns som att man borde kolla varje dimension för sig eller nått.

Exempel:
Image
Låt säga att man styr den gröna kuben och trycker åt vänster. Man kommer då att fastna i den röda kuben. Gravitationen kommer ju inte att trycka ner den då den kolliderar.
k1337oris:

Hm, problemet är att om jag exempelvis trycker kuben åt vänster eller höger så kommer gravitationen och trycker ner kuben så att den kolliderar och därför inte kan röra sig.


Det är för att du sätter x-velocity till 0 så fort den kolliderar.
Du kan prova invertera y-velocityn vid kollision istället (b.v.y = -b.v.y) och ta bort: b.v.x = 0

Sedan istället för att resetta x-velocityn så kan du hantera den speciellt för inputten. Om man rör blocket till höger så kollar den först att det inte blir kollision. Samma för vänster, något i denna stil:

if (Key_Left && !collided) // kollar även om man kan göra det
// flytta block vänster
if (Key_Right && !collided)
// flytta block höger

Detta borde även lösa:

k1337oris:

Dessutom, om man är i luften med kuben och trycker mot en annan kub så kan man "trycka fast" sig i kuben, vilket ser lite konstigt ut... hm. Känns som att man borde kolla varje dimension för sig eller nått.

Låt säga att man styr den gröna kuben och trycker åt vänster. Man kommer då att fastna i den röda kuben. Gravitationen kommer ju inte att trycka ner den då den kolliderar.

sylar:

Du kan prova invertera y-velocityn vid kollision istället (b.v.y = -b.v.y)


Då får jag ju "studs"? Det är inte jag vill ha just nu.

Problemet med din kod är att man hela tiden måste kolla om man "får" addera hastighet. Jag vill helst hålla de delarna separata; spelarens knapptryckningar adderar hastighet till boxen, och om boxen sedan kolliderar så ändras hastigheten.
k1337oris:

Jag vill helst hålla de delarna separata; spelarens knapptryckningar adderar hastighet till boxen, och om boxen sedan kolliderar så ändras hastigheten.


Då kan det bli lite knivigt. Måste kunna skilja på alla olika fall. Då måste du nog dela upp spelarblocket i olika delar som den kollar mot och se vilken del som kollideras.

Exempelvis den undre delen av blocket för kollision när man landar på ett block (fast inte hörnen)
Högra delen för rörelse åt höger (fast inte hörnen)
etc...