Box2d SDL无法在动态实体上应用世界设置

Box2d SDL cannot apply world setting on a dynamic body

本文关键字:应用 世界 设置 实体 动态 SDL Box2d      更新时间:2023-10-16

设置好世界后,我的动态身体没有倒下。它没有跟随重力。即使我在身体上施力也无济于事。

b2Vec2 gravity(0.0f, -9.8f);
b2World world(gravity);
//PineCone
class PineCone
{
    private:
        //Surface box
        SDL_Rect box;
        //Real position
        float rX, rY;
        //Velocity
        float xVel, yVel;
        //Physics world
        b2World* world;
        //Body
        b2Body* pBodyPineCone;
    public:
        //Specify
        void specify(int w, int h, SDL_Surface* source, SDL_Surface* dest, b2World* world);
        //Input
        void handle_input();
        //Motion
        void updatepos();
        //void checkStanding(SDL_Rect env[], int N_SOLIDS);
        //Render
        void show();
};
void PineCone::specify(int w, int h, SDL_Surface* source, SDL_Surface* dest, b2World* world)
{
    //Source
    pPineCone = source;
    //Destination
    pScreen = dest;
    // Define the dynamic pinecone. We set its position and call the body factory.
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;  
    // Define a ball shape for our dynamic body.
    b2CircleShape dynamicPineCone;
    dynamicPineCone.m_p.Set(0, 0); //position, relative to body position
    dynamicPineCone.m_radius = 0.5; //radius
    // Define the dynamic body fixture.
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicPineCone;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.3f;
    // Add the shape to the body.
    bodyDef.position.Set(0, 20);
    pBodyPineCone = world->CreateBody(&bodyDef);
    pBodyPineCone->CreateFixture(&fixtureDef);
}
void PineCone::show()
{
    int blit = SDL_BlitSurface( pPineCone, NULL, pScreen, &box );
    if( blit < 0 )
    {
        exit(1);
    }
}

我不确定我是不是错过了什么。

int main(int argc, char *argv[])
{
    B2_NOT_USED(argc);
    B2_NOT_USED(argv);
    // Prepare for simulation. Typically we use a time step of 1/60 of a
    // second (60Hz) and 10 iterations. This provides a high quality simulation
    // in most game scenarios.
    float32 timeStep = 1.0f / 60.0f;
    int32 velocityIterations = 6;
    int32 positionIterations = 2;
    // Start the timer
    g_dwStartTicks = SDL_GetTicks();

    init();
    load_files();
    //PineCone
    PineCone myPineCone;
    myPineCone.specify(g_iPineConeSize, g_iPineConeSize, pPineCone, pScreen, &world);
    //
    // The Main Game Loop
    //
    do
    {
        // Record the current time
        g_dwStartTime = SDL_GetTicks();
        //
        // Handle they keyboard events here
        //
        while (SDL_PollEvent(&event) > 0)
        {
            if (event.type == SDL_QUIT)
            {
                // Quit event! (Window close, kill signal, etc.)
                g_iLoopDone = TRUE;
            }
        }
        world.Step(timeStep, velocityIterations, positionIterations);
        myPineCone.handle_input();
        if (g_bPlaying || g_bEnd)
        {    
            //Show pinecone
            myPineCone.show();
        }
        // Update the display
        SDL_Flip(pScreen);
        g_dwEndTime = SDL_GetTicks();
        if (g_dwEndTime < g_dwStartTime + (1000 / 60))
        {
            SDL_Delay(g_dwStartTime + (1000 / 60) - g_dwEndTime);
        }
    }while (!g_iLoopDone);
    //Clean Up
    clean_up();
    return 0;
}
I can think for example that the physical self is updating're not visualizing
what the Sprite (Image) not update the corresponding value of its physical body.
Try to give it a Box2D body position if the image does not move you do not
have to be the update of physics.
Try this:
void setL1b2SpritePosition(Point position)
{
    pBodyPineCone->SetAwake (true);
    pBodyPineCone->setPosition(position);
    //update box2d
    pBodyPineCone->SetTransform( 
            b2Vec2(position.x / PTM_RATIO, position.y/ PTM_RATIO),
            _body->GetAngle());
}

void updatePhysics()
{
    _world->Step(.1, 10, 10);
    for (b2Body *b = _world->GetBodyList(); b; b = b->GetNext())
    {
        if (b->GetUserData() != NULL)
        {
            Sprite *ballData = dynamic_cast<Sprite*> ((Sprite *) b->GetUserData());
            ballData->setPosition(b->GetPosition().x * PTM_RATIO,
                              b->GetPosition().y * PTM_RATIO);
            ballData->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()));
        }
    }
}