【问题标题】:CCLayer update method with box2d bodies failureCCLayer 更新方法与 box2d 实体失败
【发布时间】:2013-01-06 11:47:38
【问题描述】:

我正在阅读 Rod Strougo 和 Ray Wenderlich 的《Learning Cocos2D》一书,我决定使用 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 );

这是我的代码:

//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 循环处崩溃。请注意,如果我注释掉 for 循环,一切正常,但精灵不会附加到 box2D 主体上。

如果你不能给出答案,出了什么问题,请告诉我可能出现的问题列表。 谢谢!

【问题讨论】:

    标签: iphone ios cocoa-touch cocos2d-iphone box2d


    【解决方案1】:

    您好,错误说是内存问题;您正在尝试访问一些不存在的东西。 2件事;在您的代码中,我在任何地方都看不到精灵主体与世界相连。 二、为什么Box2dSprite类的body属性是assign的,不应该是retain吗?

    【讨论】:

    • 感谢第一个回答,但我还是有同样的问题。
    • 我意识到问题出在 world->GetBodyList() 或 b->GetNext()
    【解决方案2】:

    我终于解决了这个问题!我只需要检查我要更新的主体是否不是静态的。现在一切正常。更正的更新方法如下所示:

    -(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);
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      相关资源
      最近更新 更多