2014-02-22 54 views
2

请帮助我,我一直试图解决这个问题24小时,我疯了:)我试图通过didBeginContact委托方法检测Sprite套件中的碰撞,但是这方法不开除,我已经试过在互联网上所有的答案IOS精灵套件didBeginContact不叫

#import "MyScene.h" 
#import "GameOverScene.h" 


static const uint32_t basketCategory  = 1 << 0; 
static const uint32_t ballCategory  = 1 << 1; 


// 1 
@interface MyScene() <SKPhysicsContactDelegate> 
//@interface MyScene() 
@property BOOL contentCreated; 
@property (nonatomic) SKSpriteNode * basket; 
@property (nonatomic) SKSpriteNode * ball; 
@property (nonatomic) NSTimeInterval lastSpawnTimeInterval; 
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval; 
@property (nonatomic) int ballDestroyed; 
@property (nonatomic) int score; 
@end 

static inline CGPoint rwAdd(CGPoint a, CGPoint b) { 
    return CGPointMake(a.x + b.x, a.y + b.y); 
} 

static inline CGPoint rwSub(CGPoint a, CGPoint b) { 
    return CGPointMake(a.x - b.x, a.y - b.y); 
} 

static inline CGPoint rwMult(CGPoint a, float b) { 
    return CGPointMake(a.x * b, a.y * b); 
} 

static inline float rwLength(CGPoint a) { 
    return sqrtf(a.x * a.x + a.y * a.y); 
} 

// Makes a vector have a length of 1 
static inline CGPoint rwNormalize(CGPoint a) { 
    float length = rwLength(a); 
    return CGPointMake(a.x/length, a.y/length); 
} 



@implementation MyScene 
float balltime; 

-(id)initWithSize:(CGSize)size {  
    if (self = [super initWithSize:size]) { 
     /* Setup your scene here */ 

    } 
    return self; 
} 


- (void)didMoveToView:(SKView *)view 
{ 

     if (!self.contentCreated) { 
      self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0]; 
      self.physicsWorld.gravity = CGVectorMake(0,0); 
      self.physicsWorld.contactDelegate = self; 
      self.basket = [SKSpriteNode spriteNodeWithImageNamed:@"basket"]; 
      self.basket.size = CGSizeMake(100, 100); 
      self.basket.position = CGPointMake(self.frame.size.width/2, self.basket.size.height/2); 
      self.basket.physicsBody.dynamic = YES; // 2 
      self.basket.physicsBody.categoryBitMask = basketCategory; // 3 
      self.basket.physicsBody.contactTestBitMask = ballCategory; // 4 
      self.basket.physicsBody.collisionBitMask = 0; // 5 
      self.basket.physicsBody.usesPreciseCollisionDetection = YES; 
      [self addChild:self.basket]; 
     // self.physicsWorld.contactDelegate = self; 
     } 

} 





- (void)addball { 
    balltime=1; 
    // Create sprite 
    self.ball = [SKSpriteNode spriteNodeWithImageNamed:@"basketball"]; 
    self.ball.size = CGSizeMake(100, 100); 
    self.ball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.ball.size]; // 1 
    self.ball.physicsBody.dynamic = YES; // 2 
    self.ball.physicsBody.categoryBitMask = ballCategory; // 3 
    self.ball.physicsBody.contactTestBitMask = basketCategory; // 4 
    self.ball.physicsBody.collisionBitMask = 0; // 5 
    self.ball.physicsBody.usesPreciseCollisionDetection = YES; 
    // self.physicsWorld.contactDelegate = self; 

    // Determine where to spawn the ball along the x axis 
    int minX = self.ball.size.width/2; 
    int maxX = self.frame.size.width - self.ball.size.width/2; 
    int rangeX = maxX - minX; 
    int actualX = (arc4random() % rangeX) + minX; 

    // Create the monster slightly off-screen along the right edge, 
    // and along a random position along the X axis as calculated above 
    // ball.position = CGPointMake(actualX,self.frame.size.height + ball.size.height/2); 
    self.ball.position = CGPointMake(actualX,self.frame.size.height + 300); 
    [self addChild:self.ball]; 

    // Determine speed of the ball 
    int minDuration = 3.99; 
    int maxDuration = 4.0; 
    int rangeDuration = maxDuration - minDuration; 
    int actualDuration = (arc4random() % rangeDuration) + minDuration; 

    // Create the actions 
    SKAction * actionMove = [SKAction moveTo:CGPointMake(actualX,-self.ball.size.height/2) duration:actualDuration]; 
    SKAction * actionMoveDone = [SKAction removeFromParent]; 
    SKAction * loseAction = [SKAction runBlock:^{ 
     SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5]; 
     SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:NO]; 
     [self.view presentScene:gameOverScene transition: reveal]; 
    }]; 
    [self.ball runAction:[SKAction sequence:@[actionMove, actionMoveDone]]]; 

} 

- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast { 

    self.lastSpawnTimeInterval += timeSinceLast; 
    if (self.lastSpawnTimeInterval > balltime) { 
     self.lastSpawnTimeInterval = 0; 
     [self addball]; 
    } 
} 

- (void)update:(NSTimeInterval)currentTime { 
    // Handle time delta. 
    // If we drop below 60fps, we still want everything to move the same distance. 
    CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval; 
    self.lastUpdateTimeInterval = currentTime; 
    if (timeSinceLast > 1) { // more than a second since last update 
     timeSinceLast = 1.0/60.0; 
     self.lastUpdateTimeInterval = currentTime; 
    } 

    [self updateWithTimeSinceLastUpdate:timeSinceLast]; 

} 



- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 

    UITouch *touch = [touches anyObject]; 
    CGPoint positionInScene = [touch locationInNode:self]; 
    self.basket.position=positionInScene; 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 

    UITouch *touch = [touches anyObject]; 
    CGPoint positionInScene = [touch locationInNode:self]; 
    self.basket.position=positionInScene; 
} 




- (void)ball:(SKSpriteNode *)ball didCollideWithbasket:(SKSpriteNode *)basket { 
    NSLog(@"Hit"); 
    [self.ball removeFromParent]; 
    self.ballDestroyed++; 
    if (self.ballDestroyed > 20) { 
     SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5]; 
     SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:YES]; 
     [self.view presentScene:gameOverScene transition: reveal]; 
    } 
} 

- (void)didBeginContact:(SKPhysicsContact *)contact 
{ 

     NSLog(@"contact"); 
    // 1 
    SKPhysicsBody *firstBody, *secondBody; 

    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) 
    { 
     firstBody = contact.bodyA; 
     secondBody = contact.bodyB; 
    } 
    else 
    { 
     firstBody = contact.bodyB; 
     secondBody = contact.bodyA; 
    } 

    // 2 
    if ((firstBody.categoryBitMask & basketCategory) != 0 && 
     (secondBody.categoryBitMask & ballCategory) != 0) 
    { 
     [self ball:(SKSpriteNode *) firstBody.node didCollideWithbasket:(SKSpriteNode *) secondBody.node]; 
    } 
} 

回答

2

尝试移动<SKPhysicsContactDelegate>您MyScene.h文件,并改变你的类别位掩码看起来像这样。 static const uint32_t basketCategory = 0x1 << 0;并确保您设置了碰撞位掩码。我发现如果没有设置碰撞位掩码,它将不会触发接触方法。

2

您忘记创建球的物理体,因为它不会自动为您创建。所以,你的代码

 self.basket = [SKSpriteNode spriteNodeWithImageNamed:@"basket"]; 
     self.basket.size = CGSizeMake(100, 100); 
     self.basket.position = CGPointMake(self.frame.size.width/2, self.basket.size.height/2); 
     self.basket.physicsBody.dynamic = YES; // 2 
     self.basket.physicsBody.categoryBitMask = basketCategory; // 3 
     self.basket.physicsBody.contactTestBitMask = ballCategory; // 4 
     self.basket.physicsBody.collisionBitMask = 0; // 5 
     self.basket.physicsBody.usesPreciseCollisionDetection = YES; 
     [self addChild:self.basket]; 

实际上并没有做任何的self.basket.physicsBody因为self.basket.physicsBody为零。

你应该改变你的代码,成为

 self.basket = [SKSpriteNode spriteNodeWithImageNamed:@"basket"]; 
     self.basket.size = CGSizeMake(100, 100); 
     self.basket.position = CGPointMake(self.frame.size.width/2, self.basket.size.height/2); 

     // Next line is new 
     self.basket.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.basket.frame.size]; 

     self.basket.physicsBody.dynamic = YES; // 2 
     self.basket.physicsBody.categoryBitMask = basketCategory; // 3 
     self.basket.physicsBody.contactTestBitMask = ballCategory; // 4 
     self.basket.physicsBody.collisionBitMask = 0; // 5 
     self.basket.physicsBody.usesPreciseCollisionDetection = YES; 
     [self addChild:self.basket]; 

这应该做的伎俩!

0

-(id)initWithSize:(CGSize)size 

结束前回归自我添加

self.physicsWorld.contactDelegate = self;