SpriteKit texture change according to sprite x-axis direction

351 views Asked by At

This seems like a simple problem to solve, yet I can't. As the title suggests, I need my sprite to change to a different texture depending on which way it's going - left or right. Here's what I tried doing:

if (self.sprite.position.x > 0) //also tried "self.sprite.position.x" instead of 0.
{
    [self.sprite setTexture:[SKTexture textureWithImageNamed:@"X"]];
}
if (self.sprite.position.x < 0)
{
    [self.sprite setTexture:[SKTexture textureWithImageNamed:@"XX"]];
}

Neither worked (Except when the sprite's x-axis == 0 -_-).

I've read this: SpriteKit: Change texture based on direction It didn't help.

EDIT: Pardon, I forgot to mention the movement of the sprite is completely random in 2D space. I use arc4random() for that. I don't need any texture changes when it's going up or down. But left & right are essential.

I must be writing something wrong:

if (self.sprite.physicsBody.velocity.dx > 0)
if (self.sprite.physicsBody.velocity.dx < 0)

isn't working for me. Neither is

if (self.sprite.physicsBody.velocity.dx > 5)
if (self.sprite.physicsBody.velocity.dx < -5)

Just to be clear about this sprite's movement one more time: it is randomly moving with the help of the

-(void)update:(CFTimeInterval)currentTime

method. This is achieved like so:

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

    if (!spritehMoving)
    {   
        CGFloat fX = [self getRandomNumberBetweenMin:-5 andMax:5];
        CGFloat fY = [self getRandomNumberBetweenMin:-5 andMax:7];


        int waitDuration = arc4random() %3;

        SKAction *moveXTo       = [SKAction moveBy:CGVectorMake(fX, fY) duration:1.0];
        SKAction *wait          = [SKAction waitForDuration:waitDuration];
        SKAction *sequence      = [SKAction sequence:@[moveXTo, wait]];
        [self.sprite runAction:sequence];
    }

}

1

There are 1 answers

1
AMI289 On BEST ANSWER

You could just check to see if fX is greater or lower than 0, meaning the 'force' on the x-axis is either positive (right movement) or negative (left movement).

Here is a modified code that should do the trick-
BTW- I've also set the SpritehMoving BOOL at the start and at the end of the movement, otherwise, this method will be called even if the sprite is moving (which there is nothing wrong with it, but it seems to beat the purpose of checking the BOOL value.

if (!spritehMoving)
{   
    spritehMoving = YES;  

    CGFloat fX = [self getRandomNumberBetweenMin:-5 andMax:5];
    CGFloat fY = [self getRandomNumberBetweenMin:-5 andMax:7];


    int waitDuration = arc4random() %3;  

    SKAction *changeTexture;  

    if(fX > 0) { // Sprite will move to the right  
        changeTexture = [SKAction setTexture:[SKTexture textureWithImageNamed:@"RightTexture.png"]];  
    } else if (fX < 0) { // Sprite will move to the left  
        changeTexture = [SKAction setTexture:[SKTexture textureWithImageNamed:@"LeftTexture.png"]];  
    } else {  
        // Here I'm creating an action that doesn't do anything, so in case  
        // fX == 0 the texture won't change direction, and the app won't crash    
        // because of nil action  
        changeTexture = [SKAction runBlock:(dispatch_block_t)^(){}];
    }

    SKAction *moveXTo    = [SKAction moveBy:CGVectorMake(fX, fY) duration:1.0];
    SKAction *wait       = [SKAction waitForDuration:waitDuration];  
    SKAction *completion = [SKAction runBlock:(dispatch_block_t)^(){ SpritehMoving = NO; }];
    SKAction *sequence   = [SKAction sequence:@[changeTexture, moveXTo, wait, completion]];
    [self.sprite runAction:sequence];
}