#xcode5 #sprite-kit
#xcode5 #спрайт-набор
Вопрос:
Привет, коллеги-разработчики,
Я новичок в Sprite Kit и только начал внедрять физику в свою игру. У меня есть только два спрайта, которые должны вступить в контакт. Один из них — главный герой, бабочка «bfly», а другой — энергетический шар, который дает здоровье главному персонажу при контакте.
Однако в моей игре происходит что-то странное, несмотря на то, что я реализовал все свои линии, чтобы физика работала, иногда, при определенных условиях, которые я не понимаю, энергетический шар просто проходит прямо через главного героя и игнорирует, что контакт и эффекты, которые реализует контакт, должны произойти. Затем я должен активно искать энергетический шар, чтобы это произошло, и пытаться касаться его несколько раз, чтобы добиться успеха.
Я хочу, чтобы контакт всегда происходил, независимо от того, случайно ли энергия попала в меня, или я активно ее ищу. Когда эти два спрайта каким-либо образом касаются друг друга, должен произойти контакт. Я перепробовал все и, наконец, решил обратиться за помощью.
Вот мой делегат:
@interface CloudScene () <SKPhysicsContactDelegate>
Обратите внимание, что я добавил эти свойства в надежде устранить проблему, но проблема была там до них:
@property(assign, nonatomic) uint32_t contactTestBitMask;
@property(nonatomic) BOOL usesPreciseCollisionDetection;
static const uint32_t bflyCategory = 0x1 << 0;
static const uint32_t energyCategory = 0x1 << 1;
Метод initWithSize:
self.physicsWorld.gravity = CGVectorMake(0, 0);
self.physicsWorld.contactDelegate = self;
Физика обоих (обратите внимание, что столкновения были установлены на 0 раньше, и проблема все еще существовала, я добавил их только в надежде, что эффект отскока, по крайней мере, не позволит мячу пройти прямо через символ bfly, но не сработал) :
_bfly.name = @"bflyNode";
_bfly.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_bfly.frame.size];
_bfly.physicsBody.categoryBitMask = bflyCategory;
_bfly.physicsBody.contactTestBitMask = energyCategory;
_bfly.physicsBody.collisionBitMask = bflyCategory | energyCategory;
_bfly.physicsBody.usesPreciseCollisionDetection = YES;
_bfly.physicsBody.dynamic = YES;
_bfly.physicsBody.affectedByGravity = NO;
_bfly.physicsBody.mass = 1;
energyball.name = @"energyballNode";
energyball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:energyball.frame.size];
energyball.physicsBody.categoryBitMask = energyCategory;
energyball.physicsBody.contactTestBitMask = bflyCategory;
energyball.physicsBody.collisionBitMask = energyCategory | bflyCategory;
energyball.physicsBody.usesPreciseCollisionDetection = YES;
energyball.physicsBody.dynamic = YES;
energyball.physicsBody.affectedByGravity = NO;
energyball.physicsBody.mass = 1;
И, наконец, вот мой метод didBeginContact:
-(void)didBeginContact:(SKPhysicsContact *)contact{
SKPhysicsBody *bfly;
SKPhysicsBody *energyball;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
bfly = contact.bodyA;
energyball = contact.bodyB;
}
else
{
bfly = contact.bodyB;
energyball = contact.bodyA;
}
if ((bfly.categoryBitMask amp; bflyCategory) != 0)
{
SKNode * energyball = (contact.bodyA.categoryBitMask amp; bflyCategory) ? contact.bodyB.node : contact.bodyA.node;
SKAction*energySound = [SKAction playSoundFileNamed:@"Energybell.m4a" waitForCompletion:NO];
[energyball runAction:energySound];
energyball.hidden = YES;
[self addChild:[self FenergyNode:@"energy"]];
[self adjustScoreBy:2];
[scoreLabel setText: [NSString stringWithFormat:@"Score: %d", [GameState sharedInstance].score]];
_bflyHP =MAX(0, _bflyHP 100);
[energyball runAction:[SKAction removeFromParent]];
}
}
Заранее спасибо !
Ответ №1:
Я думаю, вы стреляете себе в ногу этой строкой:
SKNode * energyball = (contact.bodyA.categoryBitMask amp; bflyCategory) ?
contact.bodyB.node : contact.bodyA.node;
Если я правильно понимаю ваш код, energy balls categoryBitMask
никогда не устанавливается на bflyCategory
. Следовательно, вы всегда выбираете узел bodyA. Поскольку A и B могут измениться в любое время, полагаясь на то, что energyBall всегда является bodyA, в какой-то момент может произойти сбой.
Более того, вы уже выбрали SKPhysicsBody* energyBall
ранее, что вы должны были использовать вместо этого. Что также должно вызвать предупреждение компилятора типа «x затеняет локальную переменную y», потому что они используют один и тот же идентификатор (имя переменной).
Попробуйте заменить строку выше на эту:
SKNode* ball = energyball.node;
И измените любое использование SKNode* energyball
на ball
.