2010-08-02 38 views
0

所以我一直在尋找,對Box2D的你的物理信息不應該是你的渲染信息Box2D的和XNA渲染數據

所以你不能做這樣的事情

spriteBatch.Draw(mazeBox,mazeBody。位置/ 0.01f,顏色。白色)

相反,您應該創建物理信息的變換並將其用作渲染。

那究竟是什麼意思?我一直在試圖找到如何使用變換和渲染的信息,但我得到空白。

回答

0

這意味着物理可以像您希望的那樣呈現:更大,更小,旋轉,翻譯等等。你只需要找出你的渲染器(在我們的例子中是XNA)將會繪製你的物理實體的比例。只需做下一步:在地面位置畫一條線,用「hello box2d」應用程序在球/盒位置畫一個1x1的盒子(這根本不存在,但你可以簡單地創建一個新的box2d應用程序,它什麼都不做但模擬球/盒落在地板上,不要忘記踩你的物理!)。

如果你有興趣,這裏是我的SFML應用與Box2D的一些角色管理基礎知識:

#include <stdio.h> 

#include <Box2D/Box2D.h> 
#include <SFML/Window.hpp> 
#include <SFML/Graphics.hpp> 

#include "Animation.h" 

#pragma comment(lib, "Box2D.lib") 
#pragma comment(lib, "sfml-system.lib") 
#pragma comment(lib, "sfml-window-s.lib") 
#pragma comment(lib, "sfml-graphics.lib") 

#define M_PI 3.14f 

#define PIXELS_PER_METER 64.f 
#define METERS_PER_PIXEL (1.f/PIXELS_PER_METER) 

#define PPM PIXELS_PER_METER 
#define MPP METERS_PER_PIXEL 

#define x_cor 2.f * METERS_PER_PIXEL 
#define y_cor METERS_PER_PIXEL 

// Thanks to bobasaurus =) 
class DebugDraw : public b2DebugDraw 
{ 
public: 
    DebugDraw(sf::RenderWindow *renderWindow) 
    { 
     window = renderWindow; 
    } 

    void DrawPolygon(const b2Vec2 *vertices, int32 vertexCount, const b2Color &color) 
    { 
     sf::Shape polygon; 

     for (int32 i = 0; i < vertexCount; i++) 
     { 
      b2Vec2 vertex = vertices[i]; 
      polygon.AddPoint(vertex.x * PIXELS_PER_METER, window->GetHeight() - (vertex.y * PIXELS_PER_METER), sf::Color(0, 0, 0, 0), B2SFColor(color)); 
     } 

     window->Draw(polygon); 
    } 

    void DrawSolidPolygon(const b2Vec2 *vertices, int32 vertexCount, const b2Color &color) 
    { 
     sf::Shape polygon; 

     for (int32 i = 0; i < vertexCount; i++) 
     { 
      b2Vec2 vertex = vertices[i]; 
      polygon.AddPoint(vertex.x * PIXELS_PER_METER, window->GetHeight() - (vertex.y * PIXELS_PER_METER), B2SFColor(color)); //need transparant outline? 
     } 

     window->Draw(polygon); 
    } 

    void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) 
    { 
     sf::Shape circle = sf::Shape::Circle(center.x * PPM, window->GetHeight() - (center.y * PPM), radius * PPM, sf::Color(0, 0, 0, 0), 1.0f, B2SFColor(color)); 
     window->Draw(circle); 
    } 

    void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) 
    { 
     sf::Shape circle = sf::Shape::Circle(center.x * PPM, window->GetHeight() - (center.y * PPM), radius * PPM, B2SFColor(color)); 
     window->Draw(circle); 
    } 

    void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) {} 

    void DrawTransform(const b2Transform& xf) {} 

private: 
    sf::RenderWindow *window; 

    sf::Color B2SFColor(const b2Color &color) 
    { 
     sf::Color result((sf::Uint8) (color.r * 255), (sf::Uint8) (color.g * 255), (sf::Uint8) (color.b * 255)); 

     return result; 
    } 
}; 

int main() 
{ 
    sf::RenderWindow *App = new sf::RenderWindow(sf::VideoMode(800, 600, 32), "SFML + Box2D Test"); 
    App->UseVerticalSync(true); 

    // ================= Init Physics ==================== 
    b2World *world = new b2World(b2Vec2(0.0f, -10.0f), true); 

    DebugDraw *debugDraw = new DebugDraw(App); 
    debugDraw->SetFlags(b2DebugDraw::e_shapeBit); 
    world->SetDebugDraw(debugDraw); 

    // Define the ground body. 
    b2BodyDef groundBodyDef; 
    groundBodyDef.position.Set(0.0f * x_cor, 0.0f * y_cor); 

    b2Body* groundBody = world->CreateBody(&groundBodyDef); 
    b2PolygonShape groundBox; 
    groundBox.SetAsBox(500.f * x_cor, 10.0f * y_cor); 
    groundBody->CreateFixture(&groundBox, 0.0f); 
    // ==================================================== 

    // ==================================== 
    /*b2PolygonShape shape; 
    shape.SetAsBox(5.f * x_cor, 5.f * x_cor); 

    b2FixtureDef fd; 
    fd.shape = &shape; 
    fd.density = 1.0f; 
    fd.friction = 0.3f; 
    fd.restitution = 0.7f; 

    b2BodyDef bd; 
    bd.type = b2_dynamicBody; 
    bd.angle = M_PI/4.f; 
    bd.position.Set(10.f * x_cor, 80.f * x_cor); 
    b2Body* body = world->CreateBody(&bd); 

    body->CreateFixture(&fd);*/ 

    b2BodyDef bd; 
    bd.position.Set(3.0f, 5.0f); 
    bd.type = b2_dynamicBody; 
    bd.fixedRotation = true; 
    bd.allowSleep = false; 

    b2Body* body = world->CreateBody(&bd); 

    b2PolygonShape shape; 
    shape.SetAsBox(0.25f, 0.25f); 

    b2FixtureDef fd; 
    fd.shape = &shape; 
    fd.friction = 20.0f; 
    fd.density = 20.0f; 
    body->CreateFixture(&fd); 
    // ==================================== 

    sf::Image Image; 

    if (!Image.LoadFromFile("moo.jpg")) 
     return 1; 

    //Image.Copy(Image, 0, 0, sf::IntRect(0, 0, 67 * 5, 68)); 

    sf::Animation Sprite(Image, 45, 50, 5); 
    Sprite.SetLoopSpeed(20); 
    Sprite.Play(0, 4); 
    Sprite.SetBlendMode(sf::Blend::Alpha); 
    Sprite.SetCenter(Sprite.GetSize().x/2, Sprite.GetSize().y/2); 

    while (App->IsOpened()) 
    { 
     sf::Event Event; 
     static std::vector<sf::Vector2f> points; 
     static sf::Color cl; 
     bool nonConvex = false; 

     while (App->GetEvent(Event)) 
     { 
      if (Event.Type == sf::Event::Closed) 
       App->Close(); 

      if (Event.Type == sf::Event::KeyPressed) 
      { 
       if (Event.Key.Code == sf::Key::Escape) 
        App->Close(); 

       if (Event.Key.Code == sf::Key::W && abs(body->GetLinearVelocity().y) < 1.0f) 
        body->ApplyLinearImpulse(b2Vec2(0, 5 * body->GetMass()), body->GetWorldCenter()); 
      } 
     } 

     { 
      if (App->GetInput().IsKeyDown(sf::Key::A) && abs(body->GetLinearVelocity().x) < 5.0f) 
      { 
       body->ApplyForce(b2Vec2(-30 * body->GetMass(), 0), body->GetPosition()); 
      } 
      if (App->GetInput().IsKeyDown(sf::Key::D) && abs(body->GetLinearVelocity().x) < 5.0f) 
      { 
       body->ApplyForce(b2Vec2(30 * body->GetMass(), 0), body->GetPosition()); 
      } 

      if (App->GetInput().IsKeyDown(sf::Key::D)) 
      { 
       //if (Sprite.IsStopped()) 
       { 
        Sprite.FlipX(false); 
        Sprite.Play(0, 5); 
       } 
      } else 
      if (App->GetInput().IsKeyDown(sf::Key::A)) 
      { 
       //if (Sprite.IsStopped()) 
       { 
        Sprite.FlipX(true); 
        Sprite.Play(0, 5); 
       } 
      } else 
      //if (!Sprite.IsStopped()) 
      { 
       Sprite.Play(12, 22); 
      } 
     } 

     world->Step(App->GetFrameTime(), 1024, 1024); 
     world->ClearForces(); 

     App->Clear(); 

     // And draw all the stuff 
     world->DrawDebugData(); 

     Sprite.Update(); 
     Sprite.SetPosition(body->GetPosition().x * PPM, App->GetHeight() - (body->GetPosition().y * PPM)); 
     App->Draw(Sprite); 

     App->Display(); 
    } 

    return 0; 
} 
0

鑑於代表一個矩形體,下面的C#代碼會根據人體的物理渲染貼圖:

spritebatch.Begin(); 
spritebatch.Draw(texture, 
     Body.Position * Scale, 
     textureSourceRectangle, 
     Color.White, 
     Body.Rotation, 
     new Vector2(textureWidth/2f, textureHeight/2f), 
     1f, 
     SpriteEffects.None, 
     0); 
spritebatch.End(); 

量表是對我來說定義爲100.0f,這意味着與高度設定爲0.1F的主體是等於0.1F * 100.0f = 10個像素。 Body.Position也是如此。 (0.1f,0.1f)在屏幕座標中等於(10,10)。

繪製時,將「原點」設置爲矩形的中心也很重要。這樣的旋轉發生在你的紋理中心周圍。