Magic_Game/project/Box2DSample/main.cpp

223 lines
4.3 KiB
C++
Raw Normal View History

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;
b2Vec2 Vec2Convert(const Point& pos)
2019-02-03 22:38:39 +08:00
{
return b2Vec2(pos.x / GLOBAL_SCALE, pos.y / GLOBAL_SCALE);
}
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>
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;
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>
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;
bodyDef.position = Vec2Convert(pos);
2019-02-03 22:38:39 +08:00
b2Body* body = world->CreateBody(&bodyDef);
SetUserData(body);
b2PolygonShape shape;
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>
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)
{
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;
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;
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()
{
// <20>޸ij<DEB8><C4B3><EFBFBD><EFBFBD><EFBFBD>С, <20><><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>Ӧ״̬, ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD> Click <20><>Ϣ
auto size = Window::Instance().GetSize();
SetSize(size);
2019-02-03 22:38:39 +08:00
SetResponsible(true);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
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));
BoardPtr board = new Board(world_, Size(GetWidth() - 100, 20), Point(size.x / 2, size.y - 50));
2019-02-03 22:38:39 +08:00
AddChild(board);
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();
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)
{
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)
{
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;
app.Init();
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;
}