kubawal Temat założony przez niniejszego użytkownika |
[SFML, Box2d] Piłka przelatuje przez statyczną krawędź (b2EdgeShape) » 2014-01-22 20:24:58 Witam! W przerwie pisania mojego frameworka Box2d-SFML'owego, dla treningu napisałem sobie prostego pinballa. Jednak, nie wiem czemu piłka przelatuje przez świat niczym nie zważając na krawędzie. #define SCALE 0.05
Vector2f XLine( float len, float w = 1.0f ) { return Vector2f( len, w ); }
Vector2f YLine( float len, float w = 1.0f ) { return Vector2f( w, len ); }
inline Vector2f getCenter( const FloatRect & r ) { return Vector2f( r.width / 2, r.height / 2 ); }
inline Vector2f getCenter( Shape & o ) { return getCenter( o.getGlobalBounds() ); }
inline b2Vec2 SFtoB2( Vector2f vec ) { return b2Vec2( vec.x * SCALE, vec.y * SCALE ); }
inline Vector2f B2toSF( b2Vec2 vec ) { return Vector2f( vec.x / SCALE, vec.y / SCALE ); }
template < typename Other > inline Other SFtoB2( Other val ) { return val * SCALE; }
template < typename Other > inline Other B2toSF( Other val ) { return val / SCALE; }
struct Object { Shape * objSF; b2Body * objB2; string name; void update(); void draw( RenderWindow & win ); };
void Object::draw( RenderWindow & win ) { win.draw( * objSF ); }
void Object::update() { { objSF->setPosition( B2toSF( objB2->GetPosition() ) - getCenter( * objSF ) ); objSF->setOrigin( getCenter( * objSF ) ); objSF->setRotation( RDtoDG( objB2->GetAngle() ) ); objSF->setOrigin( 0.0f, 0.0f ); } }
Object * createBall( b2World * world, RenderWindow * win ) { Object * obj = new Object; obj->name = "ball"; float objRad = 10.0f; Vector2f objPos( 200.0f, 0.0f ); float objDen = 1.0f; obj->objSF = new CircleShape( objRad ); obj->objSF->setPosition( objPos ); obj->objSF->setFillColor( Color::Red ); b2BodyDef objDef; objDef.position = SFtoB2( objPos + getCenter( * obj->objSF ) ); objDef.type = b2_dynamicBody; objDef.bullet = true; b2CircleShape objSh; objSh.m_radius = SFtoB2( objRad ); obj->objB2 = world->CreateBody( & objDef ); obj->objB2->CreateFixture( & objSh, objDen ); return obj; }
vector < Object *> createGameEdges( b2World * world, RenderWindow * win ) { vector < Object *> edges; float edW = 2.0f; Object * top = new Object; top->name = "top edge"; edges.push_back( top ); float topLen = 500.0f; Vector2f topPos( 100.0f, 100.0f ); top->objSF = new RectangleShape( XLine( topLen, edW ) ); top->objSF->setPosition( topPos ); top->objSF->setOutlineColor( Color::Black ); top->objSF->setFillColor( Color::Black ); b2BodyDef topDef; topDef.position = SFtoB2( topPos + getCenter( * top->objSF ) ); topDef.type = b2_staticBody; b2EdgeShape topSh; topSh.Set( b2Vec2(), b2Vec2( SFtoB2( topLen ), 0.0f ) ); top->objB2 = world->CreateBody( & topDef ); top->objB2->CreateFixture( & topSh, 1.0f ); Object * left = new Object; left->name = "left edge"; edges.push_back( left ); float leftLen = 400.0f; Vector2f leftPos( 100.0f, 100.0f ); left->objSF = new RectangleShape( YLine( leftLen, edW ) ); left->objSF->setPosition( leftPos ); left->objSF->setOutlineColor( Color::Black ); left->objSF->setFillColor( Color::Black ); b2BodyDef leftDef; leftDef.position = SFtoB2( leftPos + getCenter( * left->objSF ) ); leftDef.type = b2_staticBody; b2EdgeShape leftSh; leftSh.Set( b2Vec2(), b2Vec2( SFtoB2( edW ), SFtoB2( leftLen ) ) ); left->objB2 = world->CreateBody( & leftDef ); left->objB2->CreateFixture( & leftSh, 1.0f ); Object * right = new Object; right->name = "right edge"; edges.push_back( right ); float rightLen = 400.0f; Vector2f rightPos( 600.0f, 100.0f ); right->objSF = new RectangleShape( YLine( rightLen, edW ) ); right->objSF->setPosition( rightPos ); right->objSF->setOutlineColor( Color::Black ); right->objSF->setFillColor( Color::Black ); b2BodyDef rightDef; rightDef.position = SFtoB2( rightPos + getCenter( * right->objSF ) ); rightDef.type = b2_staticBody; b2EdgeShape rightSh; rightSh.Set( b2Vec2(), b2Vec2( SFtoB2( edW ), SFtoB2( rightLen ) ) ); right->objB2 = world->CreateBody( & rightDef ); right->objB2->CreateFixture( & rightSh, 1.0f ); Object * g = new Object; g->name = "ground"; edges.push_back( g ); float gLen = 800.0f; Vector2f gPos( 0.0f, 750.0f ); g->objSF = new RectangleShape( XLine( gLen, edW ) ); g->objSF->setPosition( gPos ); g->objSF->setOutlineColor( Color::Black ); g->objSF->setFillColor( Color::Black ); b2BodyDef gDef; gDef.position = SFtoB2( gPos + getCenter( * g->objSF ) ); gDef.type = b2_staticBody; b2EdgeShape gSh; gSh.Set( b2Vec2(), b2Vec2( SFtoB2( gLen ), 0.0f ) ); g->objB2 = world->CreateBody( & gDef ); g->objB2->CreateFixture( & gSh, 1.0f ); return edges; }
int main() try { RenderWindow win( VideoMode( 800, 800 ), "SFBall" ); b2World world( b2Vec2( 0.0f, 9.8f ) ); vector < Object *> objs; vector < Object *> edges; edges = createGameEdges( & world, & win ); objs.push_back( createBall( & world, & win ) ); cout << "Objs created ->" << endl; for( Object *& e: objs ) { cout << "name: " << e->name << endl << "size: " << e->objSF->getGlobalBounds().width << " " << e->objSF->getGlobalBounds().height << endl << "pos: " << e->objSF->getPosition() << "(SF), " << B2toSF( e->objB2->GetPosition() ) << "(B2)" << endl << "center(local): " << getCenter( * e->objSF ) << endl; } cout << "Total: edges: " << edges.size() << ", objs: " << objs.size() << endl; while( win.isOpen() ) { world.Step( 1.0f / 100.0f, 6, 2 ); for( Object * o: objs ) { o->update(); } for( Object * o: edges ) { o->update(); } } return 0; }
(wiem, że mechanizm tworzenia obiektów jest długi i nieelastyczny, ale w końcu po to pisze frameworka, a to jest gra dla zabawy) PS. sprawdziłem i do świata też jest podpięte 5 obiektów, więc Box je symuluje... |
|
kubawal Temat założony przez niniejszego użytkownika |
» 2014-01-23 19:53:46 Myślałem, że na tym forum więcej osób używa Box'a... |
|
DejaVu |
» 2014-01-23 21:24:17 |
|
MrPoxipol |
» 2014-01-23 21:58:30 Myślałem, że na tym forum więcej osób używa Box'a... |
No. Obraź się, bo nikt nie chce Ci odpowiedzieć ;> Pamiętasz co Ci kiedyś napisałem? Nie każdemu chce się szukać w obcym kodzie błędów, każdy ma swoje projekty (no może większość), czas też jest tu ważnym czynnikiem - mało go. (Pozdrawiam serdecznie.) |
|
DejaVu |
» 2014-01-23 22:09:50 Wklej ten krótki kod konsolowy sobie do projektu i sprawdź jak działa. Zmień go na kulkę i sprawdź czy nadal działa, a potem porównaj różnice ze swoim projektem. Tamten kod który wklejałem działał poprawnie, więc nie wiem czemu widzisz problem w analizie przysłowiowych 30 liniek, prezentujących poprawne działanie kolizji biblioteki Box2D. Dokumentacja jest znacznie dłuższa i jak się przez nią przebijałem rok/dwa lata temu to musiałem przeczytać co najmniej 20 stron, aby uzyskać te 30 linijek działającego pod konsolą kodu. |
|
SeaMonster131 |
» 2014-01-23 22:37:14 Dokumentacja jest znacznie dłuższa i jak się przez nią przebijałem rok/dwa lata temu to musiałem przeczytać co najmniej 20 stron, aby uzyskać te 30 linijek działającego pod konsolą kodu. |
Wystarczy skopiować podany kod od strony 7 - Chapter 2 Hello Box2Dhttp://box2d.org/manual.pdfTak czy inaczej, @kubawal, zerknij do tego manuala i może wpadniesz na pomysł co jest nie tak. |
|
kubawal Temat założony przez niniejszego użytkownika |
» 2014-01-24 17:03:23 W chromie ten adres wyświetla mi się już po wpisaniu b :) (dla użytkowników Mozilli: bardzo często wchodziłem na ten adres) Zaraz spróbuję jeszcze zrobić debugowe wyświetlanie pozycji obiektu według Box'a i zobaczymy co wyjdzie... musiałem przeczytać co najmniej 20 stron, aby uzyskać te 30 linijek działającego pod konsolą kodu |
Tak apropo, ten kod @DejaVu jest dokładnie taki sam, jak ten w manualu |
|
pekfos |
» 2014-01-24 17:13:32 Tak apropo, ten kod @DejaVu jest dokładnie taki sam, jak ten w manualu |
W 100% identyczny? Nie robiłeś żadnych modyfikacji? Huh, jeszcze jedna przeglądarka? Ja tam używam Firefoxa i mi też podpowiada strony po jednym znaku ;) |
|
« 1 » 2 3 4 |