2. wxWidgets之Box2D第2个示例:增加了一个圆形


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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值