/*************************************************************** * * ?Copyright 2021 by 海阳富润德智能科技有限公司 * ***************************************************************/ #include "simple.h"
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 = 10.0f;//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);//位置 ? ? 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 defRect; ? ? defRect.position = b2Vec2(300/PTM_RATIO,30/PTM_RATIO); ? ? defRect.type = b2_dynamicBody;//b2_kinematicBody;// ? ? defRect.linearVelocity = b2Vec2(0,10.0);//x轴、y轴移动单位数 ? ? defRect.fixedRotation=true; ? ? defRect.angularVelocity= b2Rot(45).GetAngle();// 45 * 3.14 /180; ? ? b2Body* bodyRect = world->CreateBody(&defRect); ? ? //2.物体形状 ? ? vs[0].Set(-0.5,0.5); ? ? vs[1].Set(0.5,0.5); ? ? vs[2].Set(0.5,-0.5); ? ? vs[3].Set(-0.5,-0.5); ? ? b2PolygonShape shapeRect; ? ? shapeRect.Set(vs,4); // ? ?shapeRect.SetAsBox(0.5f/PTM_RATIO, 0.5f/PTM_RATIO, b2Vec2(0.25f/PTM_RATIO, 0.25f/PTM_RATIO),60*3.14/180); // ? ?shapeRect.SetAsBox(0.5f, 0.5f, b2Vec2(0.25f, 0.25f),60*3.14/180); ? ? shapeRect.SetAsBox(0.5,0.5);//设定边框.这是一个向量,本质上说他就是一个形状的中心坐标
? ? //3.物体的物质属性,如密度、摩擦系数、弹性系数等,还有物体的形状。 ? ? b2FixtureDef fixtureDefRect; ? ? fixtureDefRect.shape = &shapeRect; ? ? fixtureDefRect.density =1;//密度 ? ? fixtureDefRect.friction =0.2;//摩擦系数 ? ? fixtureDefRect.restitution =0.6;//弹性 ? ? bodyRect->CreateFixture(&fixtureDefRect);
? ? //*** 三、画物体 2 球形 *** ? ? //1.物体的运动和状态相关属性,如类型、线速度、角速度等。 ? ? b2BodyDef defCircle; ? ? defCircle.type = b2_dynamicBody; ? ? defCircle.position = b2Vec2(164/PTM_RATIO,3/PTM_RATIO); ? ? //2.物体形状 ? ? b2CircleShape shapeCircle; ? ? shapeCircle.m_p = b2Vec2(0,0);//在b2Body中的位置 ? ? shapeCircle.m_radius =11.0 / PTM_RATIO; ? ? //3.赋予物体大小、形状和其他有形特征 ? ? b2FixtureDef fixtureDefCircle; ? ? fixtureDefCircle.shape = &shapeCircle; ? ? fixtureDefCircle.density =1;//密度 ? ? fixtureDefCircle.friction =0.3;//摩擦系数 ? ? fixtureDefCircle.restitution =0.6;//弹性 ? ? for (int i = 0; i < 3; i++) ? ? { ? ? ? ? defCircle.position.Set((170 + i * 100) / PTM_RATIO, 20 / PTM_RATIO); ? ? ? ? defCircle.angularVelocity = b2Rot(10).GetAngle(); ? ? ? ? bodies[i] = world->CreateBody(&defCircle); ? ? ? ? fixtureDefCircle.friction = 0.3 * (i + 1); ? ? ? ? fixtureDefCircle.restitution = 0.3 * (i + 1); ? ? ? ? bodies[i]->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); // ?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(); ? ? ? ? float angle = b->GetAngle();
? ? ? ? b2Vec2 center = b->GetWorldCenter(); ? ? ? ? center.x = center.x *PTM_RATIO; ? ? ? ? center.y = center.y *PTM_RATIO; ? ? ? ? printf("type=%i %4.2f %4.2f angle=%4.2f\n", b->GetType(), position.x, position.y,angle);
? ? ? ? wxGraphicsPath pathGround = gc->CreatePath(); ? ? ? ? if(b->GetType() ==b2BodyType::b2_staticBody)// b2BodyType::b2_kinematicBody)// ? ? ? ? { ? ? ? ? ? ? pathGround.AddRectangle(position.x * PTM_RATIO ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? , position.y * PTM_RATIO ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? , 400, 50); ? ? ? ? } ? ? ? ? else ? ? ? ? { ? ? ? ? ? ? b2Fixture* fixture = b->GetFixtureList(); ? ? ? ? ? ? b2Shape* shape = b->GetFixtureList()->GetShape(); ? ? ? ? ? ? position = b->GetPosition(); ? ? ? ? ? ? printf("type=%i x = %4.2f y=%4.2f angle=%4.2f\n" ? ? ? ? ? ? ? ? ? ?, shape->GetType() ? ? ? ? ? ? ? ? ? ?, position.x, position.y ? ? ? ? ? ? ? ? ? ?,angle);
? ? ? ? ? ? if (shape->GetType() == b2Shape::e_circle) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? b2CircleShape* circle = (b2CircleShape*) shape; ? ? ? ? ? ? ? ? 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 + circle->m_radius*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];
? ? ? ? ? ? ? ? printf("center count=%i x=%4.2f y=%4.2f\n",vertexCount,center.x,center.y);
? ? ? ? ? ? ? ? for (int i = 0; i < vertexCount; i++) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? v[i] = poly->m_vertices[i] + position;;// ? ? ? ? ? ? ? ? ? ? v[i].x = v[i].x ?* PTM_RATIO; ? ? ? ? ? ? ? ? ? ? v[i].y = v[i].y ?* PTM_RATIO; ? ? ? ? ? ? ? ? ? ? pathGround.AddLineToPoint(v[i].x ,v[i].y );
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } ? ? ? ? ? ? else ? ? ? ? ? ? { ? ? ? ? ? ? ? ? pathGround.AddRectangle(position.x * PTM_RATIO ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? , position.y * PTM_RATIO ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? , 50, 50); ? ? ? ? ? ? }//end if ? ? ? ? }//end if
????????//刚体旋转 ? ? ? ? if(angle != 0.0) ? ? ? ? { ? ? ? ? ? ? wxGraphicsMatrix mx = gc->CreateMatrix(); ? ? ? ? ? ? mx.Translate(center.x, center.y); ? ? ? ? ? ? mx.Rotate(angle);//*3.14/180);//);// ? ? ? ? ? ? mx.Translate(-center.x, -center.y); ? ? ? ? ? ? pathGround.Transform(mx); ? ? ? ? }
? ? ? ? pathGround.CloseSubpath(); ? ? ? ? gc->FillPath(pathGround); ? ? ? ? gc->StrokePath(pathGround); ? ? }//end for ? ? delete gc; }
void Simple::OnKeyDown(wxKeyEvent& event) { // ? ?wxLogMessage("you pressed '%i'",event.GetKeyCode()); ? ? switch(event.GetKeyCode()) ? ? { ? ? case WXK_LEFT: ? ? ? ? bodies[0]->ApplyForce(b2Vec2(0,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(0,1),1); ? ? ? ? break; ? ? case WXK_DOWN: ? ? ? ? break; ? ? case WXK_F1: ? ? ? ? break; ? ? }
}
|