Падение позиции спрайта cocos2d box2d - PullRequest
0 голосов
/ 20 апреля 2011

У меня есть следующий код:

for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
    if (b->GetUserData() != NULL) 
    {               
        CCSprite *itemSprite = (CCSprite*)b->GetUserData();
        CGSize SpriteSize;
        SpriteSize.height = itemSprite.contentSize.height;
        SpriteSize.width = itemSprite.contentSize.width;
        CGPoint SpritePosition=[itemSprite position];           
    }
}

Просто получите позицию спрайта, но иногда происходит сбой этой программы:

SpriteSize.height = itemSprite.contentSize.height;

и эта строка:

CGPoint SpritePosition=[itemSprite position];

Я использую cocos2d .99.5.

Edit: вот мой журнал сбоев:

Тип исключения: EXC_BAD_ACCESS (SIGBUS) Коды исключений: KERN_PROTECTION_FAILURE в 0x0000000f Разбитая нить: 0

Thread 0 Crashed:
0   libobjc.A.dylib                 0x00002666 objc_msgSend_stret + 14
1   ShootTheMonkey                  0x0004c066 -[LevelFour ccTouchBegan:withEvent:] (LevelFour.mm:1432)
2   ShootTheMonkey                  0x00321bf0 -[CCTouchDispatcher touches:withEvent:withTouchType:] (CCTouchDispatcher.m:238)
3   ShootTheMonkey                  0x00322454 -[CCTouchDispatcher touchesBegan:withEvent:] (CCTouchDispatcher.m:305)
4   ShootTheMonkey                  0x003240ec -[EAGLView touchesBegan:withEvent:] (EAGLView.m:318)
5   UIKit                           0x00053d72 -[UIWindow _sendTouchesForEvent:] + 254
6   UIKit                           0x000536fe -[UIWindow sendEvent:] + 74
7   UIKit                           0x0004f320 -[UIApplication sendEvent:] + 260
8   UIKit                           0x0004ec8c _UIApplicationHandleEvent + 4772
9   GraphicsServices                0x00003b2c PurpleEventCallback + 660
10  CoreFoundation                  0x00022d96 CFRunLoopRunSpecific + 2214
11  CoreFoundation                  0x000224da CFRunLoopRunInMode + 42
12  GraphicsServices                0x000030d4 GSEventRunModal + 108
13  GraphicsServices                0x00003180 GSEventRun + 56
14  UIKit                           0x0000342a -[UIApplication _run] + 374
15  UIKit                           0x00001954 UIApplicationMain + 636
16  ShootTheMonkey                  0x0000377e main (main.m:13)
17  ShootTheMonkey                  0x0000373c start + 32

Ответы [ 2 ]

1 голос
/ 20 апреля 2011

Что мы знаем наверняка, так это то, что спрайт был присвоен userData и позже был освобожден. Я вижу, что назначенный вами спрайт был автоматически выпущенным объектом, и, скорее всего, это означает, что спрайт за пределами области действия получил массаж релиза. Чтобы убедиться, что это правда, попробуйте создать спрайт следующим образом: [[CCSprite alloc] initWithSprite:@"apple.png"]; Но помните, что позже вы должны выпустить его.
Если у вас получилось, воспользуйтесь предложением выше.

1 голос
/ 20 апреля 2011

Поскольку вы не публикуете аварийный дамп или трассировку стека, я могу только догадываться. У AFAIK есть как минимум две причины:

  1. Вы присваиваете объекты нескольких классов body->SetUserData(). Сбой происходит, когда вы приводите пользовательские данные в CCSprite, когда на самом деле это не CCSprite. Хотя я сомневаюсь, что это так, поскольку обычно люди присваивают ему объекты одного класса.

  2. Вторая причина более вероятна из-за того, что люди обычно зависят от CCLayer, чтобы сохранить своих детей CCSprite (а не сохранять их явно). Когда вы удаляете CCSprites из родительского CCLayer, последний освобождает первый, и если сохраняется число == 0 (очень вероятно), CCSprites освобождаются из кучи. Но помните, что некоторые из b2Bodies все еще удерживают указатели на эти CCSprites через атрибуты пользовательских данных? Так что же происходит, когда вы перебираете все тела и пытаетесь использовать выпущенные CCSprites, которые все еще привязаны к пользовательским данным? Крах!

Способ исправить это состоит в том, что вам нужно удалять тела, когда их соответствующие спрайты удаляются из их CCLayer, либо подклассом CCSprite, чтобы добавить ивар, который указывает на b2Body, либо оборачивая оба объекта (то есть sprite и body) в другом классе. Затем добавьте код для удаления тела, когда спрайт собирается быть выделенным.

Надеюсь, это поможет. Если нет, пожалуйста, опубликуйте более подробную информацию (аварийный дамп или трассировка стека).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...