使用SKPhysics(碰撞)拖动SKSpriteNode(跟随手指移动)

时间:2014-07-15 15:45:28

标签: ios objective-c sprite-kit skspritenode skphysicsbody

想要使用SKPhysics拖动SKSpriteNode(按照您的手指动作)(启用碰撞)

2个失败的解决方案:

1)

a)解决方案:更改SKSpriteNode的位置

b)问题:SKSpriteNode将会神奇地"当用户快速通过墙壁拖动spriteNode时,意外地穿过墙壁(物理似乎不起作用)

c)代码:

@property (nonatomic) CGPoint translationBy;

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    [self selectNodeForTouch:positionInScene];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPoint previousPosition = [touch previousLocationInNode:self];

    CGPoint translation = CGPointMake(positionInScene.x - previousPosition.x, positionInScene.y - previousPosition.y);

    [self panForTranslation:translation];
}

- (void)panForTranslation:(CGPoint)translation {
    CGPoint position = [_selectedNode position];
    if([[_selectedNode name] isEqualToString:PLAYER_NAME]) {
        [_selectedNode setPosition:CGPointMake(position.x + translation.x, position.y + translation.y)];
    }
}

2)在这里搜索后发现advice来自@ LearnCocos2D"当你使用物理时,坚持通过力,冲动或直接改变体速来移动物理体。"所以我试过了:

a)解决方案:在精灵节点上施加脉冲。

b)问题:即使我没有拖动精灵节点,精灵节点也会继续移动。 (表现得像一艘漂浮的船。一旦拖动停止,精灵节点将停止;预计它将像汽车一样;一旦拖动开始,它将跟随手指。)

c)代码:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    [self selectNodeForTouch:positionInScene];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPoint previousPosition = [touch previousLocationInNode:self];

    CGPoint translation = CGPointMake(positionInScene.x - previousPosition.x, positionInScene.y - previousPosition.y);

    CGVector forceVector = CGVectorMake(translation.x, translation.y);
    [self.player.physicsBody applyImpulse:forceVector];
    //[self.player.physicsBody setVelocity:CGVectorMake(0, 0)];

}

- >>>>>>>>>>>>>>>>>>>>>>&GT ;>>>>>>>>>>>>>>>>>>>>>

更新:

来自评论: " i)您可以确定节点到手指位置的距离,然后在每次更新时设置速度:这样它将完全位于手指在下一帧的位置。 ii)如果手指和节点位置相同,这将抵消任何移动,否则节点将在执行所有物理碰撞时粘在您的手指上,并且在受阻的情况下将继续在自身和手指之间推动物体。&# 34;

a)问题:如何禁用轻弹?

b)问题:精灵节点会在轻微(意外)轻弹的情况下移动很远。

c)代码:

@property (nonatomic) CGPoint translationBy;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPoint previousPosition = [touch previousLocationInNode:self];
    //    1) You could determine the distance of the node to the finger location,

    CGPoint xyTranslation = CGPointMake(positionInScene.x - previousPosition.x, positionInScene.y - previousPosition.y);
    if (fabsf(positionInScene.x - previousPosition.x) < kPlayerMovementThreshold) {
        xyTranslation.x  = 0;
    }
    if (fabsf(positionInScene.y - previousPosition.y) < kPlayerMovementThreshold) {
        xyTranslation.y = 0;
    }
    self.translationBy = xyTranslation;
}

static const CGFloat kPlayerMovementSpeed = 55.0f;

static const CGFloat kPlayerMovementThreshold = 1.0f;

-(void)update:(CFTimeInterval)currentTime{
     // ii) then set the velocity every update: so that it will exactly be on the finger's position the next frame.

    CGFloat dx = self.translationBy.x*kPlayerMovementSpeed;
    CGFloat dy = self.translationBy.y*kPlayerMovementSpeed;
    CGVector velocityVector = CGVectorMake(dx,dy);
    [self.player.physicsBody setVelocity:velocityVector];
}

1 个答案:

答案 0 :(得分:2)

我所做的是制作一个SKNode,我们称之为'a',附带一个非常小的物理主体。这个新节点通过SKPhysicsJointSpring连接到我想要移动的节点,让我们称之为'b'。新节点a跟踪我的手指移动,弹簧确保目标节点b遵循该节点。因为节点b使用物理定位,所以碰撞检测按预期工作。