精灵套件 - 确定轻弹精灵的滑动手势矢量

时间:2014-10-24 16:03:09

标签: ios objective-c sprite-kit skphysicsbody

我有一个游戏,圆形物体从屏幕底部向上射击,我希望能够轻扫它们以向我的滑动方向轻弹。我的问题是,我不知道如何计算滑动的矢量/方向,以便使圆形物体以适当的速度在正确的方向上轻弹。

静态向量"(5,5)"我正在使用需要通过滑动的滑动速度和方向来计算。此外,我需要确保一旦我第一次接触到对象,就不再发生这种情况,以避免双重击中对象。这就是我现在正在做的事情:

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

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

    SKNode* node = [self nodeAtPoint:location];
    [node.physicsBody applyImpulse:CGVectorMake(5, 5) atPoint:location];
}
}

3 个答案:

答案 0 :(得分:9)

以下是如何检测滑动手势的示例:

首先,定义实例变量以存储起始位置和时间。

    CGPoint start;
    NSTimeInterval startTime;

在touchesBegan中,保存触摸事件的位置/时间。

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

    /* Avoid multi-touch gestures (optional) */
    if ([touches count] > 1) {
        return;
    }
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    // Save start location and time
    start = location;
    startTime = touch.timestamp;
}

定义滑动手势的参数。相应地调整这些。

#define kMinDistance    25
#define kMinDuration    0.1
#define kMinSpeed       100
#define kMaxSpeed       500

在touchesEnded中,通过比较起始位置和结束位置与时间戳之间的差异来确定用户的手势是否是滑动。

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

    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    // Determine distance from the starting point
    CGFloat dx = location.x - start.x;
    CGFloat dy = location.y - start.y;
    CGFloat magnitude = sqrt(dx*dx+dy*dy);
    if (magnitude >= kMinDistance) {
        // Determine time difference from start of the gesture
        CGFloat dt = touch.timestamp - startTime;
        if (dt > kMinDuration) {
            // Determine gesture speed in points/sec
            CGFloat speed = magnitude / dt;
            if (speed >= kMinSpeed && speed <= kMaxSpeed) {
                // Calculate normalized direction of the swipe
                dx = dx / magnitude;
                dy = dy / magnitude;
                NSLog(@"Swipe detected with speed = %g and direction (%g, %g)",speed, dx, dy);
            }
        }
    }
}

答案 1 :(得分:1)

还有另一种方法,你可以添加一个平移手势,然后从中获取速度:

首先在视图中添加平移手势:

UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
    [self.view addGestureRecognizer:gestureRecognizer];

然后处理手势:

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        CGPoint location = [recognizer locationInView:recognizer.view];
        if ([_object containsPoint:location]){
            self.movingObject = YES;
            <.. object start moving ..>
        }

    } else if (recognizer.state == UIGestureRecognizerStateChanged) {

        if (!self.movingObject)
            return;

        CGPoint translation = [recognizer translationInView:recognizer.view];
        object.position = CGPointMake(object.position.x + translation.x, object.position.y + translation.y);

        [recognizer setTranslation:CGPointZero inView:recognizer.view];

    } else if (recognizer.state == UIGestureRecognizerStateEnded) {

        if (!self.movingObject)
            return;

        self.movingObject = NO;
        float force = 1.0f;
        CGPoint gestureVelocity = [recognizer velocityInView:recognizer.view];
        CGVector impulse = CGVectorMake(gestureVelocity.x * force, gestureVelocity.y * force);

        <.. Move object with that impulse using an animation..>
    }
}

答案 2 :(得分:0)

touchesBegan中将触摸位置保存为CGPoint,您可以在整个应用中访问。

touchesEnded中计算初始触摸的距离和方向(touchesBegan)和结束触摸(touchesEnded)。然后应用适当的Impulse。

要避免双击,请添加一个bool canHit,在你施加冲动时你设置为NO,当你准备再次击中时设置回YES。在应用脉冲之前,请确保将canHit设置为YES。