自定義的scene用initWithPhysics初始化出現的問題

pamxy發表於2014-05-25

 

1.那些使用box2d的例子通常都是auto scene=Scene::createWithPhysics()函式獲得一個擁有PhysicsWorldScene,那如果需要自定義怎麼辦呢?進入Scene::createWithPhysics()後,發現:

Scene *Scene::createWithPhysics()

{

if (ret && ret->initWithPhysics())

{

ret->autorelease();

return ret;

}

...

原來只是在呼叫初始化函式不同,其他都一樣,所以就照著在自定義的Sceneinit函式裡(也可以在建構函式裡)新增”Scene::initWithPhysics();” 這麼一句,本以為已經可以了,誰知彈出這麼一個錯誤,如圖:

 

“hashElement->entry->markedForDeletion”,進入到CCScheduler.cpp的第482行也不知道是神馬問題,只好再進入Scene::initWithPhysics();函式:

bool Scene::initWithPhysics()

{

    bool ret = false;

    do

    {

        Director * director;

        CC_BREAK_IF( ! (director = Director::getInstance()) );

        this->setContentSize(director->getWinSize());

        CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::construct(*this)));

        

        this->scheduleUpdate();

        // success

        ret = true;

    } while (0);

    return ret;

}

 

結果發現了,原來已經幫我呼叫了scheduleUpdate()函式,那麼就清楚了,因為之前我的程式碼也呼叫了一次這個函式,這裡它也呼叫一次,就是呼叫了兩次這個函式,結果就出現了上面的問題了,這裡也是做的不夠好的,如果在this->scheduleUpdate();上加這麼一句this->unscheduleUpdate();的話就不會出現上述問題了,因為無論在呼叫unschedule前是否有呼叫過schedule都不會有問題,這樣正好就可以只呼叫一次schedule了!

 

2.還有別忘記了在自定義的Sceneupdate函式裡新增”Scene::update(dt);”不然不會發現

都已經呼叫了setDebugDrawMask函式,怎麼看不到紅色邊框的?,哈哈,我就遇到這事情了——  ——

 

3.還還還有一個問題,糾結我幾十分鐘如下圖:

 

 

在我新增了一個PhysicsBodySprite裡用DebugDraw檢視有紅框框後,證明構建物理世界成功了,但當關閉程式時,卻出現瞭如上問題!是野指標...妹的,哪來的野指標?最後終於發現,原來我在為了貪方便在自定義Scene的解構函式裡新增了一句:

this->removeAllChildren();

導致上述事件的發生,足可證明removeAllChildren裡的removeAllChildrenWithCleanup函式移除的不怎麼幹淨,還沒賦nullptr,導致執行完removeAllChildren後執行Scene::~Scene析構Scene裡的DebugDraw裡的_drawNode,出現了析構野指標的bug!

相關文章