【问题标题】:Sprite Kit - Determine vector of swipe gesture to flick spriteSprite Kit - 确定滑动手势的矢量以轻弹精灵
【发布时间】:2014-10-24 16:03:08
【问题描述】:

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

我使用的静态向量“(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];
}
}

【问题讨论】:

    标签: ios objective-c sprite-kit skphysicsbody


    【解决方案1】:

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

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

        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);
                }
            }
        }
    }
    

    【讨论】:

    • 你的老板!谢谢兄弟!
    • @iTroyd23 根据需要调整 kMinSpeed 和 kMaxSpeed(以及其他常量)
    【解决方案2】:

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

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

    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..>
        }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      要避免双重打击,请添加一个 bool canHit,在应用脉冲时将其设置为 NO,并在准备再次打击时设置为 YES。在应用脉冲之前,请确保 canHit 设置为 YES。

      【讨论】:

      • 我明白这一点,但我很难弄清楚它的代码。能否提供代码示例?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-05
      相关资源
      最近更新 更多