【问题标题】:Box2d Cocos2d circle crash on contact with groundBox2d Cocos2d 圆形与地面接触时崩溃
【发布时间】:2011-11-13 09:46:06
【问题描述】:

这是我在这里的第一个问题,如果我做错了什么或者这太长了,很抱歉。我一直在阅读 Ray Wenderlich 的this tutorial,我对其进行了修改,使其更平坦并逐渐下山。基本上我有一个球滚下一个颠簸的小山,但此刻球只从大约 100 像素上方落下。每当触摸时,应用程序就会崩溃(该应用程序是 Mac Cocos2d Box2d 应用程序)。球码是这样的:

CGSize winSize = [CCDirector sharedDirector].winSize;
self.oeva = [CCSprite spriteWithTexture:[[CCTextureCache sharedTextureCache] addImage:@"Ball.png"]rect:CGRectMake(0, 0, 64, 64)]; 
_oeva.position = CGPointMake(68, winSize.height/2);
[self addChild:_oeva z:1];
b2BodyDef oevaBodyDef;
oevaBodyDef.type = b2_dynamicBody;
oevaBodyDef.position.Set(68/PTM_RATIO, (winSize.height/2)/PTM_RATIO);
// oevaBodyDef.userData = _oeva;
_oevaBody = world->CreateBody(&oevaBodyDef);
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;

bodyDef.position.Set(60/PTM_RATIO, 400/PTM_RATIO);
bodyDef.userData = _oeva;
b2Body *body = world->CreateBody(&bodyDef);

// Define another box shape for our dynamic body.
b2CircleShape dynamicBox;
dynamicBox.m_radius = 70/PTM_RATIO;//These are mid points for our 1m box

// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox; 
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);

效果很好。这是地形代码,这也很好用:

-(void)generateTerrainWithWorld: (b2World *) inputWorld: (int) hillSize;{
b2BodyDef bd;
bd.position.Set(0, 0);

body = inputWorld->CreateBody(&bd);

b2PolygonShape shape;
b2FixtureDef fixtureDef;
currentSlope = 0;

CGSize winSize = [CCDirector sharedDirector].winSize;    
float xf = 0;
float yf = (arc4random() % 10)+winSize.height/3;
int x = 200;
for(int i = 0; i < maxHillPoints; ++i) {
    hillPoints[i] = CGPointMake(xf, yf);
    xf = xf+ (arc4random() % x/2)+x/2;
    yf = ((arc4random() % 30)+winSize.height/3)-currentSlope;
    currentSlope +=10;
}

int hSegments;

for (int i=0; i<maxHillPoints-1; i++) {
    CGPoint p0 = hillPoints[i-1];
    CGPoint p1 = hillPoints[i];
    hSegments = floorf((p1.x-p0.x)/cosineSegmentWidth);
    float dx = (p1.x - p0.x) / hSegments;
    float da = M_PI / hSegments;
    float ymid = (p0.y + p1.y) / 2;
    float ampl = (p0.y - p1.y) / 2;

    CGPoint pt0, pt1;
    pt0 = p0;
    for (int j = 0; j < hSegments+1; ++j) {

        pt1.x = p0.x + j*dx;
        pt1.y = ymid + ampl * cosf(da*j);

        fullHillPoints[fullHillPointsCount++] = pt1;

        pt0 = pt1;
    }        

}

b2Vec2 p1v, p2v;
for (int i=0; i<fullHillPointsCount-1; i++) {
    p1v = b2Vec2(fullHillPoints[i].x/PTM_RATIO,fullHillPoints[i].y/PTM_RATIO);
    p2v = b2Vec2(fullHillPoints[i+1].x/PTM_RATIO,fullHillPoints[i+1].y/PTM_RATIO);
    shape.SetAsEdge(p1v, p2v);
    body->CreateFixture(&shape, 0);
}

}

但是,一旦两者发生碰撞,应用就会崩溃。崩溃错误是:

线程 6 CVDisplayLink:程序接收到的信号:“SIGABRT”

错误出现在b2ContactSolver.cpp的第96行:

b2Assert(kNormal > b2_epsilon);

错误日志是:

断言失败:(kNormal > 1.19209290e-7F),函数 b2ContactSolver,文件 /Users/coooli01/Documents/Xcode Projects/Cocos2d/Hill Slide/Hill Slide/libs/Box2D/Dynamics/Contacts/b2ContactSolver.cpp,行96.

对不起,如果我啰嗦了太久,我已经被困了很久了。

【问题讨论】:

    标签: objective-c crash cocos2d-iphone box2d collision


    【解决方案1】:

    这看起来不太健康:

    for (int i=0; i<maxHillPoints-1; i++) {
        CGPoint p0 = hillPoints[i-1];//first iteration accesses hillPoints[-1]
    

    除此之外,它对我来说还可以(只是猜测这里没有给出的一些值)。

    【讨论】:

    • 非常感谢!我不敢相信导致这次崩溃的唯一原因是只有 1 个数字!如果可以的话,我会投票,但我需要更多的声誉。
    • Off By One 无疑是计算机科学中最常见的错误。
    【解决方案2】:

    当两个物体的质量都为零时,通常会发生这种碰撞。

    [Source]

    你的地面不需要有质量,因为它是由边缘组成的,但你的身体应该有质量,(通过设置它的密度)。我看到您正在设置密度,但请确保在碰撞时它没有更改。

    【讨论】:

    • 谢谢,我现在看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多