Game crashes after call to setPhysicsBody

Hello,

I’m getting this very strange crash after I try to add a physical body to my sprite.

Exception thrown at 0x00E18D3D (libcocos2d.dll) in Game.exe: 0xC0000005: Access violation reading location 0x00000000

if I remove this line of code the game runs:

this->playerSprite->setPhysicsBody(this->playerBody);

At the very top of the stack is this: libcocos2d.dll!cocos2d::PhysicsBody::addToPhysicsWorld(void)

I have also tried using:

this->playerSprite->addComponent(this->playerBody)

but that also results in a crash.

Here is my scene create code:

// Create scene.
Scene* GameScene::createScene() {
	auto scene = GameScene::createWithPhysics();
	scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
	return scene;
}

Any idea what can be the mistake here? Thank you!

Some more information:

I created a break point right after I create my body and the _world property of the body is null which will probably explain why the game crashes.

Why would the world be null? Am I missing a step some where?

obviously you are using _world before it is initialized or in other words before initWithPhysics() is called.
so you should probably create a custom createWithPhysics() method like this:

Scene * GameScene::createWithPhysics2()
{
	GameScene *ret = new (std::nothrow) GameScene();
	if (ret && ret->initWithPhysics() && ret->init())
	{
		ret->autorelease();
		return ret;
	}
	else
	{
		CC_SAFE_DELETE(ret);
		return nullptr;
	}
}

now initWithPhysics() will be called before init() and hence fix your problem.

1 Like

You answer gave me a hint and my fix turned out to be simpler.

// Init super.
if(!Scene::initWithPhysics()) {
    return false;
}

so calling initWithPhysisc() vs plain init() did the trick. I have been following a couple of physics tutorials and none of them use initWithPhysisc however the usually create a layer. For example:

Scene* GameScene::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::createWithPhysics( );
    scene->getPhysicsWorld( )->setDebugDrawMask( PhysicsWorld::DEBUGDRAW_ALL );
    
    // 'layer' is an autorelease object
    auto layer = GameScene::create();
    layer->SetPhysicsWorld( scene->getPhysicsWorld( ) );

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

I thought on newer versions of cocos2dx you no longer have to do that.

:confused:

If someone can elaborate a little on that, it will be awesome.

Thank you.