2013-01-06 3 views
0

Rod Strougo와 Ray Wenderlich의 'Learning Cocos2D'라는 책을 읽고 있는데 Cocos2d-Box2d로 나만의 iOS 게임을 만들기로 결정했습니다. 이제 해결할 수없는 문제가 있습니다. CCLayer에서 상속받은 Box2dLayer라는 클래스를 만들었고 Level2Layer 클래스에 Box2dLayer에서 상속 한 클래스가 있습니다. 화면에 렌더링 할 두 가지 다른 유형의 box2d 바디가있을 때까지 모든 것이 잘 동작했습니다. 이제 게임을 시작할 때마다 다음을 제공하는 [Box2DLayer update :] 메서드가 실패합니다. 스레드 1 : EXC_BAD_ACCESS (코드 = 1, 주소 = 0xsomething); 1 - [Box2DLayer 업데이트 : 첫번째 라인에서 sp.position... 2 - [CCScheduler 업데이트 :] 줄 entry->impMethod(entry->target, updateSelector, dt);box2d 본문을 사용한 CCLayer 업데이트 방법

여기 내 코드는 다음에서

//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 클래스의 본문 속성이 할당 된 것이므로 보유하지 않아야합니다.

+0

감사합니다,하지만 난 여전히 같은 문제가 있습니다. – kommancs96

+0

문제가 world-> 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); 

     } 
    } 
}