Sprite Kit – Déterminer le vector de geste de balayage pour flick sprite

J'ai un jeu où des objects circulaires surgissent du bas de l'écran et je voudrais pouvoir les balayer pour les balancer dans le sens de mon coup. Mon problème est, je ne sais pas comment calculer le vector / la direction du balayage afin d'get l'object circulaire à être déplacé dans la bonne direction avec la vitesse appropriée.

Le vector statique "(5,5)" que j'utilise doit être calculé par la vitesse de balayage et la direction du balayage. Aussi, je dois m'assurer qu'une fois que je fais le premier contact avec l'object, cela ne se produit plus, pour éviter de bash deux fois l'object. Voici ce que je suis en train de faire:

-(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]; } } 

Voici un exemple de détection d'un mouvement de balayage:

Commencez par définir les variables d'instance pour stocker l'location et l'heure de début.

  CGPoint start; NSTimeInterval startTime; 

Dans touchesBegan, enregistrez l'location / heure d'un événement tactile.

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

Définissez les parameters du geste de balayage. Ajustez-les en conséquence.

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

Dans touchesFin, déterminez si le geste de l'user était un glissement en comparant les différences entre les locations de début et de fin et les horodatages.

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

Il y a une autre façon de le faire, vous pouvez append un mouvement de panoramique et ensuite en get la vélocité:

Ajoutez d'abord un geste panoramique à votre vue:

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

Puis gérer le geste:

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

Dans touchesBegan save l'location tactile comme un CGPoint, vous pouvez accéder à travers votre application.

En touchesEnded calculer la distance et la direction de votre toucher initial (touchezBegan) et touchez fin (toucheEnded). Puis appliquez l'impulsion appropriée.

Pour éviter de bash deux fois, ajoutez un bool canHit que vous réglez sur NO lorsque l'impulsion est appliquée et réglez sur YES lorsque vous êtes prêt à bash à nouveau. Avant d'appliquer l'impulsion, assurez-vous que le paramètre canHit est défini sur YES.