所以我发现对于Box2D你的物理信息不应该是你的渲染信息
所以你不能做像
这样的事情spriteBatch.Draw(mazeBox,mazeBody.Position / 0.01f,Color.White)
相反,您应该创建物理信息的变换并将其用作渲染。
那究竟是什么意思呢?我一直试图找到有关如何使用变换和渲染的信息,但我得到了空白。
答案 0 :(得分:0)
这意味着可以按照您的意愿渲染物理:更大,更小,旋转,平移等等。你只需要找出你的渲染器(在我们的例子中它是XNA)将绘制你的物理体的比例。只需执行下一步:使用“hello box2d”应用程序在地面位置画一条线并在球/盒位置画一个1x1的盒子(这个根本不存在,但你可以简单地创建一个新的box2d应用程序,它什么都不做但是模拟球/盒落在地板上。不要忘记踩踏你的物理!)。
如果您有兴趣,这是我的带有box2d的SFML应用程序和一些角色控制器基础知识:
#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;
}
答案 1 :(得分:0)
给定一个表示矩形的Body,下面的c#代码将根据Body的物理渲染纹理:
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的Body等于0.1f * 100.0f = 10像素。 Body.Position也是如此。 box2D中的(0.1f,0.1f)在屏幕坐标中等于(10,10)。
绘图时将原点设置为矩形的中心也很重要。这样,旋转就会发生在纹理的中心周围。