Haaldor Temat założony przez niniejszego użytkownika |
SFML + Box2D - uzyskiwanie pozycji ciała » 2014-03-15 19:07:32 Witam, Uczę się używać Box2D, a do graficznej oprawy używam SFMLa. Jednakże natrafiłem na problem, w którym po prostu nie wiem, co jest źle. Linijka, w której najprawdopodobniej jest błąd to: sZiemia.setPosition( wymiaryOkna.x / 2 +( ziemia->GetPosition().x * 100 ), wymiaryOkna.y / 2 -( ziemia->GetPosition().y * 100 ) ); gdzie sZiemia to prostokąt SFMLowy reprezentujący statyczny obiekt, a ziemia jest tym statycznym obiektem. Nie mam pojęcia, co jest źle, ale obiekt dynamiczny spadający na ziemię graficznie zatrzymuje się dokładnie na środku tego obiektu (zamiast na jego górze). Może ktoś wytłumaczyć o co chodzi lub co robię źle? Jeśli potrzebny to wklejam cały kod: #include <SFML/Graphics.hpp> #include <box2d/box2d.h>
#define DEGTORAD 0.0174532925199432957f #define RADTODEG 57.295779513082320876f
using namespace std; using namespace sf;
int main() { Vector2u wymiaryOkna( 1200, 800 ); string nazwaOkna = "box2D + SFML test 002"; sf::RenderWindow app( sf::VideoMode( wymiaryOkna.x, wymiaryOkna.y ), nazwaOkna ); Vector2u wymiaryZiemi( 1000, 100 ); unsigned int promien = 20; Clock ograniczenieKlatek; b2Vec2 gravity( 0.0f, - 10.0f ); b2World world( gravity ); b2BodyDef definicjaCiala; definicjaCiala.position.Set( 0, - 1 ); definicjaCiala.type = b2_staticBody; b2Body * ziemia = world.CreateBody( & definicjaCiala ); b2PolygonShape groundShape; groundShape.SetAsBox( wymiaryZiemi.x / 200, wymiaryZiemi.y / 200 ); ziemia->CreateFixture( & groundShape, 0 ); definicjaCiala.position.Set( 0, 2 ); definicjaCiala.type = b2_dynamicBody; b2Body * cialo = world.CreateBody( & definicjaCiala ); b2CircleShape bodyShape; bodyShape.m_p.Set( 0, 0 ); bodyShape.m_radius = promien / 100; b2FixtureDef fixtureDef; fixtureDef.shape = & bodyShape; fixtureDef.density = 1; fixtureDef.friction = 0.3; fixtureDef.restitution = 0.8; cialo->CreateFixture( & fixtureDef ); float32 timeStep = 1.0f / 60.0f; int32 velocityIterations = 8; int32 positionIterations = 3; RectangleShape sZiemia(( Vector2f ) wymiaryZiemi ); sZiemia.setOrigin( wymiaryZiemi.x / 2, wymiaryZiemi.y / 2 ); sZiemia.setPosition( wymiaryOkna.x / 2 +( ziemia->GetPosition().x * 100 ), wymiaryOkna.y / 2 -( ziemia->GetPosition().y * 100 ) ); sZiemia.setFillColor( Color::Black ); CircleShape kolko( promien ); kolko.setOrigin( promien, promien ); kolko.setFillColor( Color::Blue ); ziemia->SetTransform( ziemia->GetPosition(), 0 * DEGTORAD ); sZiemia.setRotation( ziemia->GetAngle() * RADTODEG *( - 1 ) ); while( app.isOpen() ) { if( ograniczenieKlatek.getElapsedTime().asMilliseconds() <( 100 / 6 ) ) continue; sf::Event event; while( app.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) app.close(); } world.Step( timeStep, velocityIterations, positionIterations ); app.clear( Color::White ); kolko.setPosition( wymiaryOkna.x / 2 +( cialo->GetPosition().x * 100 ), wymiaryOkna.y / 2 -( cialo->GetPosition().y * 100 ) ); app.draw( sZiemia ); app.draw( kolko ); app.display(); ograniczenieKlatek.restart(); } return 0; }
|
|
MrPoxipol |
» 2014-03-15 20:40:43 Używaj tych pozycji, które podaje Ci Box, a jak nie będzie działać to znaczy, że coś zepsułeś w ustawieniach świata (kodu nie sprawdzałem). |
|
Haaldor Temat założony przez niniejszego użytkownika |
» 2014-03-15 21:40:47 Doszedłem do tego, że to coś z punktem transformacji. Gdy wywołuję w powyższym programie funkcję SetOrigin używam połowy szerokości i połowy wysokości, by oznaczyć środek danego obiektu (tak, żeby punkty transformacji SFML pokrywały się z tymi z Boxa2D). Teraz przetestowałem i otrzymałem pożądany wynik dzięki ustawieniu punktu transformacji w SFML dynamicznego ciała na środek dolnej granicy obiektu, a dla statycznego dla górnej. Wiem, że to mało zrozumiałe, ale trudno to zrozumiale opisać :/ Ale jak ktoś chce sobie to wyobrazić, to punkty transformacji stykają się, gdy jedno ciało spadnie na drugie ( a tak nie powinno być) Stąd wynika moje pytanie: To ja coś źle wpisuję, to jakiś błąd, czy to po prostu mój błędny tok myślenia? Zmiany w kodzie: sZiemia.setOrigin( wymiaryZiemi.x / 2, 0 ); zamiast: sZiemia.setOrigin( wymiaryZiemi.x / 2, wymiaryZiemi.y / 2 ); i kolko.setOrigin( promien, promien * 2 ); zamiast: kolko.setOrigin( promien, promien ); |
|
maly |
» 2014-03-18 13:48:55 unsigned int promien = 20; b2CircleShape bodyShape; bodyShape.m_radius = promien / 100; m_radius jest równy zero dlatego wydaje Ci się że wpada głębiej niż powinien. kolko.setPosition( wymiaryOkna.x / 2 +( cialo->GetPosition().x * 100 ), wymiaryOkna.y / 2 -( cialo->GetPosition().y * 100 ) ); Jeśli chcesz coś mieć naśrodko ekranu to albo ustaw pozycję body albo użyj sf::View . |
|
« 1 » |