Simple::~Simple(){
delete world;
}
Simple::Simple(const wxString& title)
:wxFrame(NULL,-1,title,wxPoint(-1,-1),wxSize(800,600))
{
SetBackgroundStyle(wxBG_STYLE_PAINT);
srand(time(NULL));
timer = new wxTimer(this,-1);
// nWidth = GetSize().GetWidth();
// nHeight = GetSize().GetHeight();
float x = 0.0f;//x轴重力
float y = 9.8f;//y轴重力 9.8简化为10.0,方便计算
b2Vec2 gravity(x, y);
world = new b2World (gravity);
//*** 一、画地面 ***
//1.地面的运动各状态等属性
b2BodyDef groundDef;
groundDef.type = b2_staticBody;//地面是静止的 b2_kinematicBody;//
groundDef.position = b2Vec2(0,(nHeight-50)/PTM_RATIO);//位置
// groundDef.angularVelocity=-45;//旋转
b2Body* groundBody = world->CreateBody(&groundDef);
//2.形状
b2PolygonShape groundShape;//多边形
groundShape.SetAsBox(nWidth/PTM_RATIO,0.5/PTM_RATIO);//在物理世界中的半长 的 半宽 是多少米
//3.地面的属性
b2FixtureDef groundFixtureDef;
groundFixtureDef.shape = &groundShape;//形状
groundFixtureDef.density = 1;//密度
groundFixtureDef.friction = 0.3; //摩擦系数 取值范围[ 0 - 1 ]
groundFixtureDef.restitution=0.5;//弹性系数 取值范围[ 0 - 1 ]
groundBody->CreateFixture(&groundFixtureDef);
//*** 二、画物体 1.正方形 ***
//1.物体的运动和状态相关属性,如类型、线速度、角速度等。
b2BodyDef def;
def.position = b2Vec2(64/PTM_RATIO,3/PTM_RATIO);
def.type = b2_dynamicBody;
def.linearVelocity = b2Vec2(0,9.8f);
def.angularVelocity = b2Rot(72).GetAngle();//
b2Body* body = world->CreateBody(&def);
//2.物体形状
b2PolygonShape shape;
shape.SetAsBox(0.5,0.5);//设定边框.这是一个向量,本质上说他就是一个形状的中心坐标
//3.物体的物质属性,如密度、摩擦系数、弹性系数等,还有物体的形状。
b2FixtureDef fixtureDef;
fixtureDef.shape = &shape;
fixtureDef.density =1;//密度
fixtureDef.friction =0.3;//摩擦系数
fixtureDef.restitution =0.7;//弹性
body->CreateFixture(&fixtureDef);
//*** 三、画物体 2 球形 ***
//1.物体的运动和状态相关属性,如类型、线速度、角速度等。
b2BodyDef defCircle;
defCircle.type = b2_dynamicBody;
defCircle.position = b2Vec2(164/PTM_RATIO,150/PTM_RATIO);
// defCircle.linearVelocity = b2Vec2(0,10.0);
// defCircle.linearDamping = 0.3;
// b2Body* bodyCircle = world->CreateBody(&defCircle);
//2.物体形状
b2CircleShape shapeCircle;
shapeCircle.m_p = b2Vec2(0,0);
shapeCircle.m_radius = 15.0f / PTM_RATIO;
// shapeCircle.SetAsBox(0.5,0.5);//设定边框.这是一个向量,本质上说他就是一个形状的中心坐标
//3.赋予物体大小、形状和其他有形特征
b2FixtureDef fixtureDefCircle;
fixtureDefCircle.shape = &shapeCircle;
fixtureDefCircle.density =1;//密度
fixtureDefCircle.friction =0.6;//摩擦系数
fixtureDefCircle.restitution =0.6;//弹性
// bodyCircle->CreateFixture(&fixtureDefCircle);
for (int j = 0; j < 3; j++)
{
defCircle.position=b2Vec2((70 + j * 100) / PTM_RATIO, 150 / PTM_RATIO);
defCircle.angularVelocity = b2Rot(45).GetAngle();
bodies[j] = world->CreateBody(&defCircle);
bodies[j]->CreateFixture(&fixtureDefCircle);
}
// simullation.
timeStep = 1.0f / 60.0f;//delta延迟几秒的画面
velocityIterations = 8;//
positionIterations = 3;//
Bind(wxEVT_PAINT,wxPaintEventHandler(Simple::OnPaint),this);
Bind(wxEVT_TIMER,wxCommandEventHandler( Simple::OnTimer),this);
Bind(wxEVT_KEY_DOWN,wxKeyEventHandler(Simple::OnKeyDown),this);
timer->Start(100);
Centre();
}
void Simple::OnTimer(wxCommandEvent& event)
{
world->Step(timeStep, velocityIterations, positionIterations);
Refresh();
}
void Simple::OnPaint(wxPaintEvent& event)
{
wxBufferedPaintDC dc(this);
dc.Clear();
wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
gc->SetPen(*wxRED);
// gc->SetBrush(*wxRED);
// e_circle = 0, e_edge = 1, e_polygon = 2, e_chain = 3, e_typeCount = 4
for (b2Body *b = world->GetBodyList(); b; b = b->GetNext())
{
b2Vec2 position = b->GetPosition();
b2Shape* shape = b->GetFixtureList()->GetShape();
printf("type=%i %4.2f %4.2f\n", b->GetType(), position.x, position.y);
wxGraphicsPath pathGround = gc->CreatePath();
if(b->GetType() == b2BodyType::b2_staticBody) // b2BodyType::b2_kinematicBody)//
{
if(shape->GetType() == b2Shape::e_polygon)
{
b2PolygonShape* poly = (b2PolygonShape*)shape;
int vertexCount = poly->m_count;
b2Vec2 v[vertexCount];
for(int j = 0; j < vertexCount; j++)
{
v[j] = b->GetWorldPoint(poly->m_vertices[j]);
v[j].x *= PTM_RATIO;
v[j].y *= PTM_RATIO;
pathGround.AddLineToPoint(v[j].x, v[j].y);
}
}
}else if(b->GetType() == b2BodyType::b2_kinematicBody)// b2BodyType::b2_kinematicBody)//
{
pathGround.AddRectangle(position.x * PTM_RATIO
, position.y * PTM_RATIO
, 400, 50);
}
else
{
if (shape->GetType() == b2Shape::e_circle)
{
b2CircleShape* circle = (b2CircleShape*) shape;
// position = b->GetWorldPoint(circle->m_p);
// printf("radius = %f\n",circle->m_radius);
pathGround.AddCircle(position.x * PTM_RATIO
, position.y * PTM_RATIO
, circle->m_radius * PTM_RATIO );
pathGround.MoveToPoint(position.x * PTM_RATIO, position.y * PTM_RATIO);
pathGround.AddLineToPoint(position.x * PTM_RATIO
, position.y * PTM_RATIO + circle->m_radius * PTM_RATIO );
}
else if(shape->GetType() == b2Shape::e_polygon)
{
b2PolygonShape* poly = (b2PolygonShape*)shape;
int vertexCount = poly->m_count;
b2Vec2 v[vertexCount];
for(int j = 0; j < vertexCount; j++)
{
v[j] = b->GetWorldPoint(poly->m_vertices[j]);
v[j].x *= PTM_RATIO;
v[j].y *= PTM_RATIO;
pathGround.AddLineToPoint(v[j].x, v[j].y);
}
}
}
pathGround.CloseSubpath();
gc->FillPath(pathGround);
gc->StrokePath(pathGround);
// if(angle > 0.0){
// gc->Translate(0,0);
// gc->Rotate(angle);
// }
}
delete gc;
// printf("y:%fm\n",b->GetPosition().y);
// if (b->GetUserData()) {
// // 刚体绑定的 精灵
// s = (Sprite*)b->GetUserData();
// // 更新精灵 在cocos2d中的位置 ; 单位要从米转成像素 只需 米*RATIO 即可
// s->setPosition(b->GetPosition().x*RATIO,b->GetPosition().y*RATIO);
// }
// }
//return;
// pathGround.AddRectangle(25.0, 25.0, 50.0, 50.0);
// return;
// gc->SetPen(*wxBLUE);
// gc->SetBrush(*wxBLUE);
// wxGraphicsPath path = gc->CreatePath();
// b2Vec2 position = body->GetPosition();
// printf("%4.2f %4.2f\n", position.x, position.y);
// path.AddCircle(position.x*10,position.y*10,10);
//
//
// path.CloseSubpath();
// gc->StrokePath(path);
//
// if(gc) delete gc;
}
void Simple::OnKeyDown(wxKeyEvent& event)
{
// wxLogMessage("you pressed '%i'",event.GetKeyCode());
switch(event.GetKeyCode())
{
case WXK_LEFT:
bodies[0]->ApplyForce(b2Vec2(1,1),bodies[0]->GetWorldCenter(),true);
break;
case WXK_RIGHT:
bodies[1]->ApplyForceToCenter(b2Vec2(1,1),false);//,bodies[0]->GetWorldCenter(),true);
break;
case WXK_UP:
bodies[2]->SetTransform(b2Vec2(1,1),0);
break;
case WXK_DOWN:
break;
case WXK_F1:
break;
}
}
fixtureDefCircle.shape = &shapeCircle;
fixtureDefCircle.density =1;//密度
fixtureDefCircle.friction =0.6;//摩擦系数
fixtureDefCircle.restitution =0.6;//弹性
bodyCircle->CreateFixture(&fixtureDefCircle);
// simullation.
timeStep = 1.0f / 60.0f;//delta延迟几秒的画面
velocityIterations = 8;//
positionIterations = 3;//
Bind(wxEVT_PAINT,wxPaintEventHandler(Simple::OnPaint),this);
Bind(wxEVT_TIMER,wxCommandEventHandler( Simple::OnTimer),this);
timer->Start(100);
Centre();
}