0

In my SpriteKit game, I wish to resize my sprite (named "manta" below) based on user vertical drag. Up drag should make the sprite bigger while drag down should shrink it.

I have implemented a UIPanGestureRecognizer and in rec.state == .Changed, I have below code:

let deltaY = startPoint.y - currentPoint.y
newScale = mantaCurrentScale + ((deltaY / dragHeight ) * mantaScaleDiff )
if (newScale <= mantaMaxScale) && (newScale >= mantaMinScale) {
    manta.xScale = newScale
    manta.yScale = newScale
    mantaCurrentScale = newScale
}

It works but is not reliable, the responsiveness of resizing is sluggish and not useable in a live game.

Are there any SprikeKit tricks I am not aware of, to give priority to this process or there are better alternatives to UIPanGestureRecognizer to create such a control in SpriteKit?

Kashif
  • 4,642
  • 7
  • 44
  • 97

3 Answers3

0

I personally wouldn't use gesture recognizers because this would be much easier if you could know touch point.

Here is an example in sudo code that you might find works. All of these functions can be overridden inside of a SKScene, and the position can easily be found.

var dragging:boolean = false

TouchesBegan()
{
   if (fingerHasClickedSquare == true)
   {dragging=true}
   else
   {dragging=false}
}

TouchesEnded()
{
    dragging = false
}

TouchesMoved() 
{
   if (dragging == true)
   {
      manta.size.width = (fingerPosition.x - squarePosition.x) * 2 //this either needs to be *2 or /2 or *1 I dont remember which
   }
}

If you need further help translating this to real swift code this topic shows some of the lines of code you will need to get the touch position, and the node that it is touching.

Community
  • 1
  • 1
J.Doe
  • 1,502
  • 13
  • 47
0

avoid UIPanGestureRecognizer you can do it this way

#import "GameScene.h"

@implementation GameScene
{
    CGPoint startPoint;
    CGPoint endPoint;
    SKSpriteNode *node;
}
-(void)didMoveToView:(SKView *)view {


    node=[SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(200, 200)];
    node.position = CGPointMake(CGRectGetMidX(self.frame),
                                CGRectGetMidY(self.frame));

    [self addChild:node];
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    startPoint=location;
    //store location of first touch
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    endPoint=location;
    CGFloat yDist = (endPoint.y - startPoint.y);
    if(yDist<-50)
    {
        yDist=-50;
    }
    if(node.xScale <0.25)
    {
        node.xScale=0.25;
        node.yScale=0.25;
    }
    node.xScale=1.0+yDist/100.0;
    node.yScale=1.0+yDist/100.0;

}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}

@end
dragoneye
  • 703
  • 6
  • 14
0

Not to downplay the answers from other fellows here. I am writing an answer to my own question because the issue I was facing was resolved by using a different technique and someone else might be facing the same issue.

The sluggishness, I was experiencing was due to the fact that resizing was being capped due to <= and >= operators I was using.

I had to implement this code in rec.Changed to ensure the manta was resized to the smallest or largest size even when the pan was much bigger than required to do so.:

if manta.newSize < manta.minSize {
    manta.newSize = manta.minSize
} else if manta.newSize > manta.maxSize {
    manta.newSize = manta.maxSize
}

Now the resizing is smooth as as the user would expect in real game play.

Kashif
  • 4,642
  • 7
  • 44
  • 97