Я разрабатываю игру для iPhone, используя cocos2d с бурундуком. Поэтому я создал приложение из шаблона и изменил код HelloWorldScene, чтобы на уровне было мало статических фигур. Итак, все хорошо. Новые формы динамики создаются на ощупь, столкновения в порядке.
Но проблемы возникают, когда я перемещаю код из addNewSprite в другой класс (создание cpBody, cpShape и CCSprite). В случайное время (я не обнаружил никакой зависимости от чего-либо) столкновения не обнаруживаются, поэтому мои объекты либо проходят сквозь статические объекты и летят со сцены, либо просто исчезают.
Итак, когда фигуры создаются в одном классе, который выполняет симуляцию, все в порядке. Но когда они в другом классе - случаются случайные ошибки.
вот рабочий вариант кода:
-(void) addNewSpriteX: (float)x y:(float)y
{
CCSpriteBatchNode *batch = (CCSpriteBatchNode*) [self getChildByTag:kTagBatchNode];
CCSprite *sprite = [CCSprite spriteWithBatchNode:batch rect:CGRectMake(0, 0, 50, 46)];
[batch addChild: sprite];
sprite.position = ccp(x,y);
int num = 4;
CGPoint verts[] = {
ccp(-25,-20),
ccp(-25, 20),
ccp( 25, 20),
ccp( 25,-20),
};
cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, CGPointZero));
cpBodySetMass(body, 10);
// TIP:
// since v0.7.1 you can assign CGPoint to chipmunk instead of cpVect.
// cpVect == CGPoint
body->p = ccp(x, y);
cpSpaceAddBody(mSpace, body);
cpShape* shape = cpPolyShapeNew(body, num, verts, CGPointZero);
shape->e = 0.5f; shape->u = 0.5f;
shape->data = sprite;
cpSpaceAddShape(mSpace, shape);
}
static void
eachShape(void *ptr, void* unused)
{
cpShape *shape = (cpShape*) ptr;
CCSprite *sprite = (CCSprite *)shape->data;
if( sprite ) {
cpBody *body = shape->body;
// TIP: cocos2d and chipmunk uses the same struct to store it's position
// chipmunk uses: cpVect, and cocos2d uses CGPoint but in reality the are the same
// since v0.7.1 you can mix them if you want.
[sprite setPosition: body->p];
NSLog(@"x:%f, y:%f", body->p.x, body->p.y);
[sprite setRotation: (float) CC_RADIANS_TO_DEGREES( -body->a )];
}
}
и вот мой вариант, который не работает:
-(void) addNewSpriteX: (float)x y:(float)y
{
AtomDesc ad;
ad.mass = 10;
PolyShapeDesc *psd = (PolyShapeDesc *)malloc(sizeof(PolyShapeDesc));
psd->vertNum = 4;
psd->vertices = (CGPoint *)malloc(sizeof(CGPoint)*4);
psd->vertices[0] = ccp(-25,-20);
psd->vertices[1] = ccp(-25, 20);
psd->vertices[2] = ccp( 25, 20);
psd->vertices[3] = ccp( 25,-20);
SpriteDesc *sd = (SpriteDesc *)malloc(sizeof(SpriteDesc));
sd->filename = [NSString stringWithString:@"poof.png"];
sd->pos = CGPointMake(x, y);
sd->rotation = 0;
sd->scale = 1;
ad.shapeDesc = psd;
ad.spriteDesc = sd;
ad.pos = CGPointMake(x, y);
Atom *a = [[Atom alloc] initAtomWithDescriptor:&(ad) :mSpace];
atoms.push_back(a);
[self addChild:a];
free(psd->vertices);
free(psd);
free(sd);
}
static void
eachShape(void *ptr, void* unused)
{
cpShape *shape = (cpShape*) ptr;
if(shape->data && [shape->data isKindOfClass:[Atom class]])
{
Atom *a = (Atom *)shape->data;
[a update:0];
}
}
@implementation Atom
- (id) initAtomWithDescriptor:(AtomDesc *)descriptor :(cpSpace *)space
{
if( (self=[super init]))
{
mSpace = space;
PolyShapeDesc *psd;
cpShape *shape;
psd = descriptor->shapeDesc;
mBody = cpBodyNew(1.0f, cpMomentForPoly(1.0f, psd->vertNum, psd->vertices, CGPointZero));
cpBodySetMass(mBody, descriptor->mass);
mBody->p = descriptor->pos;
cpSpaceAddBody(mSpace, mBody);
shape = cpPolyShapeNew(mBody, psd->vertNum, psd->vertices, psd->pos);
shape->u = psd->friction;
shape->e = psd->elasticity;
shape->data = self;
cpSpaceAddShape(mSpace, shape);
SpriteDesc *sd;
sd = descriptor->spriteDesc;
mSprite = [CCSprite spriteWithFile:sd->filename];
mSprite.position = sd->pos;
mSprite.rotation = sd->rotation;
mSprite.scale = sd->scale;
[self addChild:mSprite];
}
return self;
}
- (bool)update:(float)dt
{
[mSprite setPosition: mBody->p];
[mSprite setRotation: (float) CC_RADIANS_TO_DEGREES( -mBody->a )];
return true;
}
Итак, у вас есть какие-нибудь идеи об этом странном поведении?