0

I am trying to set duration for individual SKTextures in an animation. Below the armsAtlas texture atlas. I would like to set the upTexture to last between 1-4 seconds randomly followed by the downTexture to last between 0.3 - 1 second. How can I set these duration ranges for the individual textures?

let armsAtlas = SKTextureAtlas(named: "arms")
let downTexture = armsAtlas.textureNamed("down")
let upTexture = armsAtlas.textureNamed("up")
Alexey Pichukov
  • 3,377
  • 2
  • 19
  • 22
ErrorFree
  • 83
  • 7

2 Answers2

1

There are lots of ways to do this.

You could use SKAction delay to swap randomly between them...

func setTexture(texture: SKTexture, delay: NSTimeInterval, range: NSTimeInterval) -> SKAction {
    let textureAction = SKAction.setTexture(texture)
    let delayAction = SKAction.waitForDuration(delay, withRange: range)
    return SKAction.sequence([delayAction, textureAction])
}

No set up the action to switch between the two...

let downAction = setTexture(downTexture, delay: 0.65, range: 0.35)
let upAction = setTexture(upTexture, delay: 2.5, range: 1.5)
let sequenceAction = SKAction.sequence([downAction, upAction])
let repeatAction = SKAction.repeatActionForever(sequenceAction)

yourTexturedSprite.runAction(repeatAction)
Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • 1
    @Forgmeister SKAction.waitForDuration accepts NSTimeInterval, for both delay, and range parameters. – Whirlwind Jan 25 '16 at 15:45
  • @Whirlwind edited now, NSTimeInterval is just an alias for double (although I used float incorrectly) so they can be changed with no issues. Better to keep the actual named type though :D – Fogmeister Jan 25 '16 at 15:48
  • @Forgemeister There are actually few more errors with your code. 1. you can't use repeat keyword as an constant (or variable) name. 2. Third parameter (range) must be labeled in this case. – Whirlwind Jan 25 '16 at 16:05
  • @Whirlwind that's what you get for writing code in a browser window with no code checking. lol – Fogmeister Jan 25 '16 at 16:06
  • @Whirlwind also, names are auto completed when you type the first letter. Just hit tab to select the name. – Fogmeister Jan 25 '16 at 16:41
  • @Forgemeister I am aware of what you are saying, but because of beginners, who will likely just copy and paste the code, it is better to remove those errors. After all, those were errors. – Whirlwind Jan 25 '16 at 16:48
  • @Whirlwind no, I mean names on StackOverflow. Like my name. Fogmeister. You've got it wrong every time you replied. Just type @ and then the first letter. :) – Fogmeister Jan 25 '16 at 16:49
  • Ah, sorry about that. I see...Well sometimes it doesn't work for me after I enter "at" sign (maybe it's because of my browser), so I just write it manually. :). – Whirlwind Jan 25 '16 at 16:52
  • @Whirlwind ah, if it doesn't pop up an auto complete it's because that person will get a notification anyway :D (Normally because there is only one person or they are the OP). :) – Fogmeister Jan 25 '16 at 16:53
  • Yeah, you are right. Thanks :) The author of the post will always be notified, so no need for @name (like I was doing). – Whirlwind Jan 25 '16 at 17:10
1

You can use SKAction sequence and it's waitForDuration:withRange: method, like this:

//By default, the sprite is initialized with downTexture
let sprite = SKSpriteNode(texture: downTexture)
sprite.position = CGPoint(x: 200, y: 200)
addChild(sprite)
let sequence = SKAction.sequence([

    SKAction.runBlock({NSLog("Up texture set")}), //Added just for debugging to print a current time
    SKAction.setTexture(upTexture),
    SKAction.waitForDuration(2.5, withRange: 3.0),  //Wait between 1.0 and 4.0 seconds
    SKAction.runBlock({NSLog("Down texture set")}),
    SKAction.setTexture(downTexture),
    SKAction.waitForDuration(0.65, withRange: 0.7),//Wait between 0.3 and 1.0 seconds
    ])

let action = SKAction.repeatActionForever(sequence)

sprite.runAction(action, withKey: "aKey")

What this code does, is that it creates a sprite, initialize it with downTexture by default and:

  • swap texture to upTexture immediately
  • waits between 1 and 4 seconds
  • swap texture to downTexture
  • waits between 0.3 and 1 seconds
  • repeats all this forever

If you want to stop this action, you can access it like this:

if sprite.actionForKey("aKey") != nil {
            removeActionForKey("aKey")
}
Whirlwind
  • 14,286
  • 11
  • 68
  • 157