2013-01-06 23 views
0

我正在讀的書:'學習Cocos2D'來自Rod Strougo和Ray Wenderlich,我決定用Cocos2d-Box2d製作我自己的iOS遊戲。 現在我遇到了一個我無法解決的問題。 我創建了一個名爲Box2dLayer的類,該類繼承自CCLayer,並且我有Level1Layer 繼承自Box2dLayer的類。 一切正常,直到我有兩個不同類型的box2d正文呈現在屏幕上。 現在我每次開始遊戲時都會失敗 - [Box2DLayer update:]方法給出以下內容: 線程1:EXC_BAD_ACCESS(code = 1,address = 0xsomething); 1 - [Box2DLayer更新:]在線路sp.position... 2 - [CCScheduler更新:]在線路entry->impMethod(entry->target, updateSelector, dt);CCLayer更新方法與box2d機構故障

這裏是我的代碼:

//Box2DSprite.h 
@interface Box2DSprite : CCSprite 
{ 
    b2Body *body; 
} 
@property (assign) b2Body *body; 
@end 

//Box2DSprite.mm 

@implementation Box2DSprite 
@synthesize body; 
-(void)dealloc 
{ 

    body = NULL; 
    [super dealloc]; 
} 
@end 

//Box2DLayer.h 
@interface Box2DLayer : CCLayer 
{ 
    b2World *world; 
    GLESDebugDraw *debugDraw; 
    b2MouseJoint *mouseJoint; 
    b2Body *groundBody; 
} 
-(void)setupGround; 
@end 

//Box2DLayer.mm 

@implementation Box2DLayer 
-(id)init 
{ 
    if (self = [super init]) { 
     [self scheduleUpdate]; 
     [self setupWorld]; 
     [self setupDebugDraw]; 
     [self setupGround]; 
     self.isTouchEnabled = YES; 
    } 
    return self; 
} 

- (void)setupWorld { 
    b2Vec2 gravity = b2Vec2(0.0f, -10.0f); 
    world = new b2World(gravity); 
    //world->SetContinuousPhysics(true); 
} 

-(void) draw {  
    ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position); 
    kmGLPushMatrix(); 
    world->DrawDebugData(); 
    kmGLPopMatrix(); 
} 

- (void)setupDebugDraw { 
    debugDraw = new GLESDebugDraw(PTM_RATIO *[[CCDirector sharedDirector] contentScaleFactor]); 
    world->SetDebugDraw(debugDraw); 
    debugDraw->SetFlags(b2Draw::e_shapeBit); 
} 
- (void)registerWithTouchDispatcher { 
    [[[CCDirectorIOS sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 
                  swallowsTouches:YES]; 
} 
-(void)update:(ccTime)dt { 
    int32 velocityIterations = 3; 
    int32 positionIterations = 2; 
    world->Step(dt, velocityIterations, positionIterations); 
    for(b2Body *b = world->GetBodyList(); b != NULL; b = b->GetNext()) 
    { 
     if (b->GetUserData() != NULL) { 
      Box2DSprite *sp = (Box2DSprite *) b->GetUserData(); 
      sp.position = ccp(b->GetPosition().x * PTM_RATIO*RETSIZE,b->GetPosition().y * PTM_RATIO*RETSIZE); 
      sp.rotation = CC_RADIANS_TO_DEGREES(b->GetAngle() * -1); 
     } 
    } 
} 
-(void)setupGround{ 
    CGSize winSize = [[CCDirector sharedDirector] winSize]; 
    b2BodyDef groundBodyDef; 

    groundBodyDef.type = b2_staticBody; 
    groundBodyDef.position.Set(0, 10/RETSIZE/PTM_RATIO); 
    groundBody = world->CreateBody(&groundBodyDef); 
    CCSprite *gsprite = [CCSprite spriteWithFile:@"ground.png"]; 
    groundBody->SetUserData(gsprite); 

    b2EdgeShape groundBox; 

    groundBox.Set(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO/RETSIZE-150/PTM_RATIO,0)); 
    groundBody->CreateFixture(&groundBox,0); 

} 
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{ 
    CGPoint touchLocation = [touch locationInView:[touch view]]; 
    touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation]; 
    touchLocation = [self convertToNodeSpace:touchLocation]; 

    b2Vec2 locationWorld = b2Vec2(touchLocation.x/PTM_RATIO/RETSIZE, touchLocation.y/PTM_RATIO/RETSIZE); 

    b2AABB aabb; 
    b2Vec2 delta = b2Vec2(1.0/PTM_RATIO/RETSIZE, 1.0/PTM_RATIO/RETSIZE); 
    aabb.lowerBound = locationWorld - delta; 
    aabb.upperBound = locationWorld + delta; 
    SimpleQueryCallback callback(locationWorld); 
    world->QueryAABB(&callback, aabb); 

    if (callback.fixtureFound) { 
     b2Body *body = callback.fixtureFound->GetBody(); 

     b2MouseJointDef joint; 
     joint.bodyA = groundBody; 
     joint.bodyB = body; 
     joint.target = locationWorld; 
     joint.maxForce = 100*body->GetMass(); 
     joint.collideConnected = true; 

     mouseJoint = (b2MouseJoint *)world->CreateJoint(&joint); 
     // body->SetAwake(false); 
     return YES; 
    } 

} 

-(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event{ 
    CGPoint touchLocation = [touch locationInView:[touch view]]; 
    touchLocation = [[CCDirector sharedDirector] 
        convertToGL:touchLocation]; 
    touchLocation = [self convertToNodeSpace:touchLocation]; 
    b2Vec2 locationWorld = b2Vec2(touchLocation.x/PTM_RATIO/RETSIZE, touchLocation.y/PTM_RATIO/RETSIZE); 
    if (mouseJoint) { 
     mouseJoint->SetTarget(locationWorld);   
    } 

} 

-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{ 
    if (mouseJoint) { 
     world->DestroyJoint(mouseJoint); 
     mouseJoint = NULL; 
     } 
} 
-(void) dealloc 
{ 
    if (world) { 
     delete world; 
     world = NULL; 

    } 
    if (debugDraw) { 
     delete debugDraw; 
     debugDraw = NULL; 
    } 
    [super dealloc]; 
} 
@end 

在程序崩潰的用於更新方法內循環。注意,如果我註釋掉for循環,一切正常,但精靈不會附加到box2D主體。

如果你不能給出答案,有什麼問題,請告訴我一個可能出現的問題列表。 謝謝!

回答

0

嗨錯誤說這是一個內存問題;你正試圖訪問一些不在那裏的東西。 2件事;在你的代碼中,我沒有看到任何地方的精靈身體被連接到世界。 秒,爲什麼Box2dSprite類中的body屬性被賦值,不應該被保留。

+0

感謝您的第一個答案,但我仍然有同樣的問題。 – kommancs96

+0

我意識到問題出在世界 - > GetBodyList()或b-> GetNext() – kommancs96

0

最後我解決了這個問題!我只是需要檢查,如果身體我想更新不static.Now一切正常罰款。修正更新的方法是這樣的:

-(void)update:(ccTime)dt { 
    int32 velocityIterations = 3; 
    int32 positionIterations = 2; 
    world->Step(dt, velocityIterations, positionIterations); 
    for(b2Body *bdy = (world->GetBodyList()); bdy != NULL; bdy = bdy->GetNext()) 
    { 
     if (bdy->GetType()!=b2_staticBody && bdy->GetUserData() != NULL) { 
      Box2DSprite *sp = (Box2DSprite *) bdy->GetUserData(); 
      sp.position = ccp(bdy->GetPosition().x * PTM_RATIO*RETSIZE,bdy->GetPosition().y * PTM_RATIO*RETSIZE); 
      sp.rotation = CC_RADIANS_TO_DEGREES(bdy->GetAngle() * -1); 

     } 
    } 
}