Reputation: 736
I have a couple sprites in a swift game that have identical action lists (technically [SKAction]). They're all at different points in the action sequence, and I need to rank them in order of most complete (with the action) to least complete. How do I get the progress of a sprite (or at least the step of the action it's on)? Preferably, I'd like to get the percentage of completion for the step it's on.
For the sake of sample code:
let sprite1 = SKShapeNode.init(rectOf: CGSize.init(width: 20, height: 20), cornerRadius: 5)
let sprite2 = SKShapeNode.init(rectOf: CGSize.init(width: 20, height: 20), cornerRadius: 5)
let sprite3 = SKShapeNode.init(rectOf: CGSize.init(width: 20, height: 20), cornerRadius: 5)
sprite1.position = CGPoint(x: -100, y: 0)
sprite2.position = CGPoint(x: 0, y: 0)
sprite3.position = CGPoint(x: 100, y: 0)
let sequence : [SKAction] = [SKAction.move(by: CGVector(dx: 50, dy: 0), duration: 1.5),
SKAction.rotate(byAngle: CGFloat(M_PI / 2), duration: 1.0),
SKAction.move(by: CGVector(dx: 0, dy: 50), duration: 1.5),
SKAction.rotate(byAngle: CGFloat(M_PI / 2), duration: 1.0),
SKAction.move(by: CGVector(dx: -50, dy: 0), duration: 1.5)]
sprite1.run(SKAction.sequence(sequence))
//wait 1 second
sprite2.run(SKAction.sequence(sequence))
//wait another second
sprite3.run(SKAction.sequence(sequence))
var spriteAccord : [SKSpriteNode] = //insert ranking code
Upvotes: 0
Views: 174
Reputation: 16837
As long as the speed of the sprite is constant (AKA no bullet time effect) I would just use a dictionary to store starting times:
var startingTimes = [SKNode:NSTimeInterval]()
Then store when a sprite starts his sequence
sprite1.run(SKAction.sequence(sequence))
startingTimes[sprite1 as! SKNode] = currentTime
Finally, sort by the startingTime
let sortedStartingTimes = startingTimes.sort(){
(time1,time2)->Bool in
return time1 <= time2
}
Then, just iterate through the dictionary, or grab the first item, whatever you need to do here.
This can be popped into playgrounds to test the above code:
var startingTimes = [String:NSTimeInterval]()
startingTimes["A"] = 1
startingTimes["C"] = 3
startingTimes["B"] = 2
let sortedStartingTimes = startingTimes.sort(){
(time1,time2)->Bool in
return time1 <= time2
}
print("start")
for time in startingTimes
{
print(time)
}
print("sort")
for time in sortedStartingTimes
{
print(time)
}
To get the percentage of completion is a little more complex. You need to take your currentTime - startingTime, then figure out based on this where you are at in your sprite.
So I have a total of 3 steps, each 1 second.
My currentTime - startingTime is 1.5 seconds.
var deltaTime = currentTime - startingTime
I take 1.5 - step 1 time, so result is .5 seconds
deltaTime -= step1Time
deltaTime > 0, I am in a new step
I take .5 - step 2 time, so result is .5 seconds
deltaTime -= step2Time
deltaTime <= 0 I am in this step
so deltaTime / step2time , that is my percentage in the step2 timeline
let completionPercentage = deltaTime / step2Time
Upvotes: 1
Reputation: 4526
You can insert runBlock actions between your existing actions. In the block you can then increment counters to track the progress of each node through the actions.
Upvotes: 1