didBeginContact输入得太早

时间:2016-01-13 02:46:08

标签: sprite-kit skspritenode skphysicsjoint

我试图在接触点碰撞时将球粘到旋转器上。但是,似乎在联系开始之前调用了didBeginContact。图片如下图所示,两者都在一起旋转但是空间很大。

enter image description here

代码如下:

#import "GameScene.h"

@implementation GameScene
@synthesize _flowIsON;

NSString *const kFlowTypeRed = @"RED_FLOW_PARTICLE";
const float kRED_DELAY_BETWEEN_PARTICLE_DROP = 0.01; //delay for particle drop in seconds

static const uint32_t kRedParticleCategory         =  0x1 << 0;
static const uint32_t kSpinnnerCategory            =  0x1 << 1;

NSString *const kStartBtn = @"START_BTN";
NSString *const kLever = @"Lever";

NSString *const START_BTN_TEXT = @"Start Game";

CFTimeInterval lastTime;


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

    _bkgNode = (SKSpriteNode *)[self.scene childNodeWithName:@"Background"];

    [self initializeScene];

}

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


    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode: self];

        SKNode *node = [self nodeAtPoint:location];

        if ([node.name isEqualToString:kStartBtn]) {
            [node removeFromParent];

            //initalize to ON
            _flowIsON = YES;

            //[self initializeScene];
        }
    }
}

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

}

-(void)update:(CFTimeInterval)currentTime {

    float deltaTimeInSeconds = currentTime - lastTime;

    //NSLog(@"Time is %f and flow is %d",deltaTimeInSeconds, _flowIsON);

    if ((deltaTimeInSeconds > kRED_DELAY_BETWEEN_PARTICLE_DROP)) {


        //TBD
        SKAction *rotation = [SKAction rotateByAngle: M_PI/8.0 duration:0];
        [_spinner runAction:rotation];


        //only if its been past 1 second do we set the lasttime to the current time
        lastTime = currentTime;

    }



}


- (void) initializeScene {

    self.physicsWorld.contactDelegate = self;


    //create ball
    SKSpriteNode *ball = [SKSpriteNode spriteNodeWithImageNamed:@"Ball"];
    ball.size = CGSizeMake(50, 50);
    ball.position = CGPointMake(320, 1050);
    ball.zPosition = 1;
    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:25];
    ball.physicsBody.restitution = 0.0;
    ball.physicsBody.categoryBitMask = kRedParticleCategory;
    ball.physicsBody.contactTestBitMask = kSpinnnerCategory;
    ball.physicsBody.collisionBitMask = kSpinnnerCategory;
    ball.name = @"Ball";

    NSLog(@"Ball size is %f",ball.size.width);

    [self addChild:ball];



    //Create spinner
    _spinner = [SKSpriteNode spriteNodeWithImageNamed:@"Spinner"];
    _spinner.size = CGSizeMake(300, 300);
    _spinner.position = CGPointMake(320, 500);
    _spinner.zPosition = 1;
    _spinner.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:150];
    _spinner.physicsBody.affectedByGravity = NO;
    _spinner.physicsBody.allowsRotation = YES;
    _spinner.physicsBody.dynamic = NO;
    _spinner.physicsBody.restitution = 0.0;
    _spinner.physicsBody.categoryBitMask = kSpinnnerCategory;
    _spinner.physicsBody.contactTestBitMask = kRedParticleCategory;
    _spinner.physicsBody.collisionBitMask = kRedParticleCategory;
    _spinner.name = @"Spinner";

    [self addChild:_spinner];


    //create pipe

//    CGPoint center = CGPointMake(400, 600) ;
//    
//    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
//    [bezierPath addArcWithCenter:center radius:400   startAngle:1.825777 endAngle:2.011118 clockwise:YES];
//    [bezierPath addLineToPoint:center];
//    [bezierPath closePath];
//    
//    SKShapeNode *shapeNode = [SKShapeNode shapeNodeWithPath:bezierPath.CGPath];
//    shapeNode.strokeColor = [UIColor whiteColor];
//    shapeNode.fillColor = [UIColor whiteColor];
//    [self addChild:shapeNode];

}






# pragma mark -- SKPhysicsContactDelegate Methods

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

    if ([contact.bodyA.node.name isEqualToString:@"Ball"] && [contact.bodyB.node.name isEqualToString:@"Spinner"]) {

        [self connectNode1:(SKSpriteNode *)contact.bodyA.node toNode2:(SKSpriteNode *)contact.bodyB.node withContact:contact];

    }

}


- (void)didEndContact:(SKPhysicsContact *) contact {
    //NSLog(@"didEndContact called");

}

- (void) connectNode1:(SKSpriteNode *)node1 toNode2:(SKSpriteNode *)node2 withContact: (SKPhysicsContact *)contact
{

    SKPhysicsJointFixed *joint = [SKPhysicsJointFixed jointWithBodyA:node1.physicsBody
                                                               bodyB:node2.physicsBody
                                                              anchor:node2.position];
    [self.physicsWorld addJoint:joint];
}


@end

如果我注释掉了确定的开始接触方法,你可以看到图像尺寸正确,因为它们碰撞时它们完美地相互依赖。

enter image description here

当我注释掉didEnterContact方法时,contact.contactPoint怎么会与两个身体碰撞的点不一样?知道怎么解决吗?

1 个答案:

答案 0 :(得分:0)

'didBeginContact'没有太早调用..问题是在场景循环中先前评估了动作:首先'didEvaluateActions()'然后'didSimulatePhysics()'。所以,即使你的SKactions看起来是正确的,之后还会进行物理评估。我建议在使用物理引擎时不要使用动作来进行旋转校正。也许使用约束,这些是在物理更新之后......