2019-02-03 22:38:39 +08:00
|
|
|
|
// Copyright (C) 2019 Nomango
|
|
|
|
|
|
|
|
|
|
|
|
#include "easy2d.h"
|
|
|
|
|
|
#include "Box2D/Box2D.h"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace easy2d;
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// Box2D <20>dz<EFBFBD><C7B3>õ<EFBFBD><C3B5><EFBFBD>Ӧ<EFBFBD><D3A6> <20><>/ǧ<><C7A7>/<2F><> <20>ĵ<EFBFBD>λ, <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB><EFBFBD>м<EFBFBD><D0BC><EFBFBD>.
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD> Box2D <20><> Easy2D <20><><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>ʱ, <20><>Ҫ
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>һЩת<D0A9><D7AA>.
|
|
|
|
|
|
//
|
|
|
|
|
|
namespace
|
|
|
|
|
|
{
|
|
|
|
|
|
const float GLOBAL_SCALE = 100.0f;
|
|
|
|
|
|
|
2019-02-12 16:12:15 +08:00
|
|
|
|
b2Vec2 Vec2Convert(const Point& pos)
|
2019-02-03 22:38:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
return b2Vec2(pos.x / GLOBAL_SCALE, pos.y / GLOBAL_SCALE);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-02-12 16:12:15 +08:00
|
|
|
|
Point Vec2Convert(const b2Vec2& pos)
|
2019-02-03 22:38:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
return Point(pos.x * GLOBAL_SCALE, pos.y * GLOBAL_SCALE);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// СԲ<D0A1><D4B2>
|
2019-02-12 16:12:15 +08:00
|
|
|
|
E2D_DECLARE_SMART_PTR(Circle);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
class Circle
|
|
|
|
|
|
: public Sprite
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
Circle(b2World* world, const Point& pos)
|
|
|
|
|
|
{
|
|
|
|
|
|
Load(L"circle.png");
|
|
|
|
|
|
SetAnchor(0.5f, 0.5f);
|
|
|
|
|
|
SetScale(0.7f);
|
|
|
|
|
|
|
|
|
|
|
|
b2BodyDef bodyDef;
|
|
|
|
|
|
bodyDef.type = b2_dynamicBody;
|
2019-02-12 16:12:15 +08:00
|
|
|
|
bodyDef.position = Vec2Convert(pos);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
|
|
|
|
|
|
b2Body* body = world->CreateBody(&bodyDef);
|
|
|
|
|
|
|
|
|
|
|
|
SetUserData(body);
|
|
|
|
|
|
|
|
|
|
|
|
b2CircleShape shape;
|
|
|
|
|
|
shape.m_radius = GetWidth() / GLOBAL_SCALE / 2 * 0.7f;
|
|
|
|
|
|
|
|
|
|
|
|
b2FixtureDef fixtureDef;
|
|
|
|
|
|
fixtureDef.shape = &shape;
|
|
|
|
|
|
fixtureDef.density = 1.0f;
|
|
|
|
|
|
fixtureDef.friction = 0.3f;
|
|
|
|
|
|
|
|
|
|
|
|
body->CreateFixture(&fixtureDef);
|
|
|
|
|
|
body->SetUserData(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// С<><D0A1><EFBFBD><EFBFBD>
|
2019-02-12 16:12:15 +08:00
|
|
|
|
E2D_DECLARE_SMART_PTR(Square);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
class Square
|
|
|
|
|
|
: public Sprite
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
Square(b2World* world, const Point& pos)
|
|
|
|
|
|
{
|
|
|
|
|
|
Load(L"square.png");
|
|
|
|
|
|
SetAnchor(0.5f, 0.5f);
|
|
|
|
|
|
SetScale(0.7f);
|
|
|
|
|
|
|
|
|
|
|
|
b2BodyDef bodyDef;
|
|
|
|
|
|
bodyDef.type = b2_dynamicBody;
|
2019-02-12 16:12:15 +08:00
|
|
|
|
bodyDef.position = Vec2Convert(pos);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
|
|
|
|
|
|
b2Body* body = world->CreateBody(&bodyDef);
|
|
|
|
|
|
|
|
|
|
|
|
SetUserData(body);
|
|
|
|
|
|
|
|
|
|
|
|
b2PolygonShape shape;
|
2019-02-12 16:12:15 +08:00
|
|
|
|
b2Vec2 sz = Vec2Convert(GetSize() / 2 * 0.7f);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
shape.SetAsBox(sz.x, sz.y);
|
|
|
|
|
|
|
|
|
|
|
|
b2FixtureDef fixtureDef;
|
|
|
|
|
|
fixtureDef.shape = &shape;
|
|
|
|
|
|
fixtureDef.density = 1.0f;
|
|
|
|
|
|
fixtureDef.friction = 0.3f;
|
|
|
|
|
|
|
|
|
|
|
|
body->CreateFixture(&fixtureDef);
|
|
|
|
|
|
body->SetUserData(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// <20>̶<EFBFBD><CCB6><EFBFBD>ľ<EFBFBD><C4BE>
|
2019-02-12 16:12:15 +08:00
|
|
|
|
E2D_DECLARE_SMART_PTR(Board);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
class Board
|
|
|
|
|
|
: public GeometryNode
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
Board(b2World* world, const Size& size, const Point& pos)
|
|
|
|
|
|
{
|
2019-02-12 16:12:15 +08:00
|
|
|
|
GeometryPtr geo = new RectangleGeometry(Point(), size);
|
|
|
|
|
|
SetGeometry(geo);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
SetStrokeColor(Color::White);
|
|
|
|
|
|
SetFillColor(Color(0, 0, 0, 0));
|
|
|
|
|
|
|
|
|
|
|
|
SetSize(size);
|
|
|
|
|
|
SetAnchor(0.5f, 0.5f);
|
|
|
|
|
|
SetRotation(10);
|
|
|
|
|
|
SetPosition(pos);
|
|
|
|
|
|
|
|
|
|
|
|
b2BodyDef groundBodyDef;
|
2019-02-12 16:12:15 +08:00
|
|
|
|
groundBodyDef.position = Vec2Convert(GetPosition());
|
2019-02-03 22:38:39 +08:00
|
|
|
|
groundBodyDef.angle = 10 * math::constants::PI_F / 180.f;
|
|
|
|
|
|
|
|
|
|
|
|
b2Body* groundBody = world->CreateBody(&groundBodyDef);
|
|
|
|
|
|
|
|
|
|
|
|
b2PolygonShape groundBox;
|
2019-02-12 16:12:15 +08:00
|
|
|
|
b2Vec2 sz = Vec2Convert(Point{ size.x / 2, size.y / 2 });
|
2019-02-03 22:38:39 +08:00
|
|
|
|
groundBox.SetAsBox(sz.x, sz.y);
|
|
|
|
|
|
groundBody->CreateFixture(&groundBox, 0.0f);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class MainScene
|
|
|
|
|
|
: public Scene
|
|
|
|
|
|
{
|
|
|
|
|
|
b2World* world_;
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
MainScene()
|
|
|
|
|
|
{
|
2019-03-12 00:27:54 +08:00
|
|
|
|
// <20><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>Ӧ״̬, ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD> Click <20><>Ϣ
|
2019-02-03 22:38:39 +08:00
|
|
|
|
SetResponsible(true);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
2019-02-12 16:12:15 +08:00
|
|
|
|
AddListener(Event::Click, Closure(this, &MainScene::Click));
|
2019-02-03 22:38:39 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
world_ = new b2World(b2Vec2(0, 10));
|
|
|
|
|
|
|
2019-03-12 00:27:54 +08:00
|
|
|
|
BoardPtr board = new Board(world_, Size(GetWidth() - 100, 20), Point(GetWidth() / 2, GetHeight() - 50));
|
2019-02-03 22:38:39 +08:00
|
|
|
|
AddChild(board);
|
|
|
|
|
|
|
2019-02-12 16:12:15 +08:00
|
|
|
|
CirclePtr circle = new Circle(world_, Point(320, 240));
|
2019-02-03 22:38:39 +08:00
|
|
|
|
AddChild(circle);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
~MainScene()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (world_)
|
|
|
|
|
|
delete world_;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnUpdate(Duration dt) override
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> Box2D <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
world_->Step(dt.Seconds(), 6, 2);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ÿһ<C3BF><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ú<EFBFBD><C3BA><EFBFBD>ת<EFBFBD>Ƕ<EFBFBD>
|
|
|
|
|
|
b2Body* body = world_->GetBodyList();
|
|
|
|
|
|
while (body)
|
|
|
|
|
|
{
|
|
|
|
|
|
Node* node = (Node*)body->GetUserData();
|
|
|
|
|
|
b2Body* next = body->GetNext();
|
|
|
|
|
|
if (node)
|
|
|
|
|
|
{
|
|
|
|
|
|
const b2Vec2& pos = body->GetPosition();
|
2019-02-12 16:12:15 +08:00
|
|
|
|
node->SetPosition(Vec2Convert(pos));
|
2019-02-03 22:38:39 +08:00
|
|
|
|
node->SetRotation(body->GetAngle() * 180.f / math::constants::PI_F);
|
|
|
|
|
|
|
|
|
|
|
|
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>䵽<EFBFBD><E4B5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (node->GetPosition().y > GetHeight() + 50)
|
|
|
|
|
|
{
|
|
|
|
|
|
body->SetUserData(0);
|
|
|
|
|
|
world_->DestroyBody(body);
|
|
|
|
|
|
|
|
|
|
|
|
node->RemoveFromParent();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
body = next;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Click(Event const& evt)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (evt.mouse.button == MouseButton::Left)
|
|
|
|
|
|
{
|
2019-02-12 16:12:15 +08:00
|
|
|
|
CirclePtr circle = new Circle(world_, Point{ evt.mouse.x, evt.mouse.y });
|
2019-02-03 22:38:39 +08:00
|
|
|
|
AddChild(circle);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (evt.mouse.button == MouseButton::Right)
|
|
|
|
|
|
{
|
2019-02-12 16:12:15 +08:00
|
|
|
|
SquarePtr rect = new Square(world_, Point{ evt.mouse.x, evt.mouse.y });
|
2019-02-03 22:38:39 +08:00
|
|
|
|
AddChild(rect);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Application app;
|
2019-03-12 00:27:54 +08:00
|
|
|
|
|
|
|
|
|
|
Options options(L"Box2D Demo");
|
|
|
|
|
|
app.Init(options);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
|
|
|
|
|
|
ScenePtr scene = new MainScene;
|
|
|
|
|
|
app.EnterScene(scene);
|
|
|
|
|
|
app.Run();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (std::exception& e)
|
|
|
|
|
|
{
|
2019-03-10 13:44:02 +08:00
|
|
|
|
::MessageBoxA(nullptr, e.what(), "An exception has occurred!", MB_ICONERROR | MB_OK);
|
2019-02-03 22:38:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|