kubawal Temat założony przez niniejszego użytkownika |
[SFML + Box2d]Obracanie sprite'a » 2014-02-24 13:05:54 Witam! Po pewnej przerwie wracam do programowania mojej gry SFML + Box2d i mam funkcję wyświetlającą podane tekstury w pozycjach poszczególnych fixtur ciała: void Body::displayBody( RenderWindow & win, b2Body * b, Texture ** fillTexture )
{ bool autoInterpolate = true; int i = 0; for( b2Fixture * f = b->GetFixtureList(); f; f = f->GetNext(), i++ ) { b2Shape * sh = f->GetShape(); b2AABB aabb = f->GetAABB( 0 ); Transform st = Transform::Identity; st.rotate( RDtoDG( b->GetAngle() ), B2toSF( aabb.GetCenter() ) ); if( fillTexture[ i ] && autoInterpolate ) fillTexture[ i ]->setSmooth( true ); switch( sh->GetType() ) { case b2Shape::e_polygon: { b2PolygonShape * s = dynamic_cast < b2PolygonShape *>( sh ); Sprite sp( * fillTexture[ i ], IntRect( 0.0f, 0.0f, B2toSF( aabb.upperBound.x - aabb.lowerBound.x ), B2toSF( aabb.upperBound.y - aabb.lowerBound.y ) ) ); sp.setPosition( B2toSF( aabb.lowerBound ) ); win.draw( sp, st ); break; } case b2Shape::e_circle: { b2CircleShape * s = dynamic_cast < b2CircleShape *>( sh ); Sprite sp( * fillTexture[ i ], IntRect( 0.0f, 0.0f, B2toSF( aabb.upperBound.x - aabb.lowerBound.x ), B2toSF( aabb.upperBound.y - aabb.lowerBound.y ) ) ); sp.setPosition( B2toSF( aabb.lowerBound ) ); win.draw( sp, st ); break; } case b2Shape::e_edge: { b2EdgeShape * s = dynamic_cast < b2EdgeShape *>( sh ); VertexArray va( sf::Lines, 2 ); va[ 0 ].position = B2toSF( b->GetWorldPoint( s->m_vertex1 ) ); va[ 0 ].color = Color::White; va[ 1 ].position = B2toSF( b->GetWorldPoint( s->m_vertex2 ) ); va[ 1 ].color = Color::White; win.draw( va ); break; } case b2Shape::e_chain: { b2ChainShape * s = dynamic_cast < b2ChainShape *>( sh ); for( int32 i = 0; i < s->GetChildCount(); ++i ) { b2EdgeShape edge; s->GetChildEdge( & edge, i ); VertexArray va( sf::Lines, 2 ); va[ 0 ].position = B2toSF( b->GetWorldPoint( edge.m_vertex1 ) ); va[ 0 ].color = Color::White; va[ 1 ].position = B2toSF( b->GetWorldPoint( edge.m_vertex2 ) ); va[ 1 ].color = Color::White; win.draw( va ); } break; } } } }
Problem jest taki, że niby wszystko jest na dobrych miejscach, ale sprite/y zamiast się obracać po prostu rozciągaję się do wielkości aabb. |
|
maly |
» 2014-02-24 13:45:05 Jeśli ten Sprite( sp( * fillTexture[ i ],... to sf::Sprite to on zawsze jest prostokątny. Wrzucę ogólny przykład jak ja to robię z shape-ami. void drawPolygonShape( sf::RenderWindow & window, sf::Texture & tex, b2Body * body ) { b2PolygonShape * PolygonShape =( b2PolygonShape * ) body->GetFixtureList()->GetShape(); sf::ConvexShape ConvexShape( PolygonShape->GetVertexCount() ); for( int i = 0; i < PolygonShape->GetVertexCount(); i++ ) { sf::Vector2f v( PolygonShape->GetVertex( i ).x, PolygonShape->GetVertex( i ).y ); ConvexShape.setPoint( i, v ); } ConvexShape.setPosition( body->GetPosition().x, body->GetPosition().y ); ConvexShape.setRotation( rad2deg( body->GetAngle() ) ); ConvexShape.setTexture( & tex ); window.draw( ConvexShape ); } |
|
kubawal Temat założony przez niniejszego użytkownika |
» 2014-02-24 14:00:58 Też próbowałem ze shape'ami, ale tekstura w środku nich się nie obraca razem z nimi. to on zawsze jest prostokątny. |
No i co z tego? Tak jest elastyczniej, bo mogę sobie zrobić teksturę z przezroczystością która kształtem będzie podobna lub taka sama do fixtury. |
|
maly |
» 2014-02-24 14:15:38 |
|
kubawal Temat założony przez niniejszego użytkownika |
» 2014-02-24 15:00:29 To jaki sposób jest prawidłowy? |
|
maly |
» 2014-02-24 15:07:21 Cytuje Laurent-a. Since the rotation is already applied when you create your shape, SFML doesn't know that it is rotated. To have the texture follow the rotation, you would have to rotate the SFML shape. I don't know if it's possible in your context (i.e. if you can access the unrotated points + rotation angle, rather than the final points). |
Mój sposób właśnie tak działa. |
|
kubawal Temat założony przez niniejszego użytkownika |
» 2014-02-24 17:11:11 No a mi nie :) sam shape się obraca, ale tekstura jest cały czas w tej samej osi. |
|
maly |
» 2014-02-24 17:20:05 #include <SFML/Graphics.hpp> #include <Box2D/Box2D.h> #include <cstdio>
float rad2deg( float rad ) { return rad *( 180.0f / b2_pi ); } float deg2rad( float deg ) { return deg *( b2_pi / 180.0f ); }
b2Body * addShape( b2World & world, const std::vector < b2Vec2 > & vertices, const sf::Vector2f & center );
void drawPolygonShape( sf::RenderWindow & window, sf::Texture & tex, b2Body * body ) { b2PolygonShape * PolygonShape =( b2PolygonShape * ) body->GetFixtureList()->GetShape(); sf::ConvexShape ConvexShape( PolygonShape->GetVertexCount() ); for( int i = 0; i < PolygonShape->GetVertexCount(); i++ ) { sf::Vector2f v( PolygonShape->GetVertex( i ).x, PolygonShape->GetVertex( i ).y ); ConvexShape.setPoint( i, v ); } ConvexShape.setPosition( body->GetPosition().x, body->GetPosition().y ); ConvexShape.setRotation( rad2deg( body->GetAngle() ) ); ConvexShape.setTexture( & tex ); window.draw( ConvexShape ); }
int main() { sf::RenderWindow Window( sf::VideoMode( 640, 480, 32 ), "Hello b2World" ); Window.setFramerateLimit( 60 ); b2World World( b2Vec2( 0.f, 0.f ) ); sf::Texture Texture; Texture.loadFromFile( "cb.bmp" ); const float size = 90.0f; const float ofs = 20.1f; std::vector < b2Vec2 > Vertices; Vertices.push_back( b2Vec2( - size, - size ) ); Vertices.push_back( b2Vec2( 0, - size - ofs ) ); Vertices.push_back( b2Vec2( size, - size ) ); Vertices.push_back( b2Vec2( size + ofs, 0 ) ); Vertices.push_back( b2Vec2( size, size ) ); Vertices.push_back( b2Vec2( 0, size + ofs ) ); Vertices.push_back( b2Vec2( - size, size ) ); Vertices.push_back( b2Vec2( - size - ofs, 0 ) ); b2Body * Actor = addShape( World, Vertices, sf::Vector2f( 640 / 2, 480 / 2 ) ); Actor->ApplyAngularImpulse( 100000000.0f, true ); float r = 0; while( Window.isOpen() ) { sf::Event Event; while( Window.pollEvent( Event ) ) { if(( Event.type == sf::Event::KeyPressed && Event.key.code == sf::Keyboard::Escape ) || Event.type == sf::Event::Closed ) Window.close(); } World.Step( 1.f / 60.f, 16, 8 ); Window.clear( sf::Color( 80, 80, 80, 255 ) ); drawPolygonShape( Window, Texture, Actor ); Window.display(); } return 0; }
b2Body * addShape( b2World & world, const std::vector < b2Vec2 > & vertices, const sf::Vector2f & center ) { std::vector < b2Vec2 > verts = vertices; b2BodyDef BodyDef; BodyDef.position.Set( center.x, center.y ); BodyDef.type = b2_dynamicBody; b2PolygonShape PolygonShape; PolygonShape.Set( & verts[ 0 ], verts.size() ); b2FixtureDef FixtureDef; FixtureDef.density = 1.0; FixtureDef.restitution = 0.5; FixtureDef.shape = & PolygonShape; b2Body * Body = world.CreateBody( & BodyDef ); Body->CreateFixture( & FixtureDef ); return Body; } |
|
« 1 » 2 |