Сбой круга Box2d Cocos2d при контакте с землей

#objective-c #crash #cocos2d-iphone #box2d #collision

#objective-c #сбой #cocos2d-iphone #box2d #столкновение

Вопрос:

это мой первый вопрос, поэтому извините, если я делаю что-то не так или это слишком длинно. Я читал этот учебник Рэя Вендерлиха, я изменил его, чтобы он был более плоским и постепенно спускался с холма. В принципе, у меня мяч катится вниз по ухабистому склону, но на данный момент мяч падает только с высоты примерно 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(amp;oevaBodyDef);
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;

bodyDef.position.Set(60/PTM_RATIO, 400/PTM_RATIO);
bodyDef.userData = _oeva;
b2Body *body = world->CreateBody(amp;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 = amp;dynamicBox; 
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(amp;fixtureDef);
  

Это работает нормально. Это код местности, он также отлично работает:

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

body = inputWorld->CreateBody(amp;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(amp;shape, 0);
}
  

}

Однако, когда они сталкиваются, приложение выходит из строя. Ошибка сбоя заключается в:

Поток 6 CVDisplayLink: Программа получила сигнал: «SIGABRT»

Ошибка возникает в строке 96 из b2ContactSolver.cpp:

 b2Assert(kNormal > b2_epsilon);
  

Журнал ошибок:

Ошибка утверждения: (нормальное значение> 1.19209290 e-7F), функция b2ContactSolver, файл / Пользователи / coooli01 / Документы / Проекты Xcode / Cocos2d / Слайд холма / Hill Slide/libs/Box2D/Dynamics/Contacts/b2ContactSolver.cpp, строка 96.

Извините, если я слишком долго болтал, я застрял на этом целую вечность.

Ответ №1:

Это не выглядит здоровым:

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

В остальном у меня все работало нормально (просто угадываю некоторые значения, не приведенные здесь).

Комментарии:

1. Большое спасибо! Я не могу поверить, что единственной причиной этого сбоя было всего 1 число! Я бы проголосовал «за», если бы мог, но мне нужно больше репутации.

2. Отключение на единицу, безусловно, является самой распространенной ошибкой в информатике.

Ответ №2:

Этот сбой обычно происходит, когда оба тела имеют нулевую массу.

[Источник]

Ваша земля не обязательно должна иметь массу, поскольку она состоит из ребер, но ваше тело должно иметь массу (путем настройки его плотности). Я вижу, что вы устанавливаете плотность, но убедитесь, что она не была изменена во время столкновения.

Комментарии:

1. Спасибо, я посмотрю на это сейчас.