runAction SKAction.sequence not working - ios

I can't get the runAction method to work for this code block. I'm not sure what I am doing wrong or if there is a problem outside the block, but if anyone sees anything inside that is wrong, let's start there (*Edited to include entire function). All variables work and I'm getting zero compile errors, the program just appears to skip the line currentTestIndicator.runAction(SKAction.sequence(runCheck)). All print statements work except the one inside recurse, also current++ isn't getting called. I tried running the code without recurse and it still didn't work. Ideas?
func runLevelCheck(node: SKSpriteNode, _ state: SKSpriteNode, _ bluePatterns:Array<Array<String>>, _ blueSize: CGFloat, _ blueLocations: Array<CGPoint>, _ greenPatterns:Array<Array<String>>, _ greenSize: CGFloat, _ greenLocations:Array<CGPoint>, _ redPatterns:Array<Array<String>>, _ redSize: CGFloat, _ redLocations:Array<CGPoint>, _ orangePatterns:Array<Array<String>>, _ orangeSize: CGFloat, _ orangeLocations:Array<CGPoint>)->Bool {
var passLevel = true
var current = 0
let currentTestIndicator = SKSpriteNode()
currentTestIndicator.name = "indicator"
currentTestIndicator.size = CGSizeMake(0, 128)
blueLocations[current].y)
currentTestIndicator.anchorPoint = CGPoint(x: 0.0, y: 0.5)
currentTestIndicator.zPosition = 0
node.addChild(currentTestIndicator)
let patterns = [bluePatterns, greenPatterns, redPatterns, orangePatterns]
let sizes = [blueSize, greenSize, redSize, orangeSize]
let locations = [blueLocations, greenLocations, redLocations, orangeLocations]
let colors = [color("Light Blue 01"), color("Light Green 01"), color("Light Red 01"), color("Light Orange 01")]
for sets in patterns {
for rows in sets {
if rows != [] {
print("Current set: \(current)")
print(rows)
currentTestIndicator.color = colors[current]
currentTestIndicator.position = CGPoint(x: 0.0, y: locations[current][0].y)
print(currentTestIndicator.position)
print("Sizes current = \(sizes[current])")
let growRight = SKAction.resizeToWidth(sizes[current], duration: 0.2)
let recurse = SKAction.runBlock() {
recursion(state, rows, 0, 0, &passLevel)
current++
print("Changed current value to \(current)")
}
let pause = SKAction.waitForDuration(5.0)
let shrinkLeft = SKAction.resizeToWidth(0, duration: 0.2)
let runCheck = [growRight, recurse, pause, shrinkLeft]
currentTestIndicator.runAction(SKAction.sequence(runCheck))
}
}
current = 0
}
currentTestIndicator.removeFromParent()
print("Ran level check")
switch passLevel {
case true:
print("Level passed")
case false:
print("Lavel failed")
}
return passLevel
}

Related

"lldb" crash with XCODE & ARKIT : 0 __ UpdateAudioTransform

I have written a game using ARKIT that pops up random nodes (with drones) in the 3d space around the player, using ARKIT, and I get an incomprehensible crash, as only thing in the console is "lldb" , and the rest of the crash details are on the screenshot attached (I am still a newbie in Swift so not able to debug it).
The crash happens when there's a lot of nodes on the screen (maybe 20-30) and the FPS drops - ie happens "mid - game" and the FPS drops a lot.
Can someone point me to the right direction for this crash?
The part of the code that is in my opinion relevant is the function that spawns the random 3d nodes (they also have SCNActions attached that play sounds when they're tapped - perhaps this could be relevant as the left hand side debugger opens with that line highlighted when the crash occurs, as per the photo attached). In case it is also relevant, the program uses some SCNParticleSystem calls as well. Attaching relevant code, and also the snapshot of the crash screen:
var droneSound : SCNAudioSource()
override func viewDidLoad() {
super.viewDidLoad()
droneSound = SCNAudioSource(named: "Sounds/drone1.wav")!
playDroneSound = SCNAction.playAudio(self.droneSound, waitForCompletion: true)
}
func startGame() {
DispatchQueue.main.async {
self.spawnTimer = Timer.scheduledTimer(timeInterval: TimeInterval(self.randomFloat(min: 2.5, max: 5)), target: self, selector: #selector(self.spawnDronesInterim), userInfo: nil, repeats: true)
}
}
#objc func spawnDronesInterim() {
for _ in 0...5 {
spawnDrone()
}
}
#objc func spawnDrone() {
let newDroneScene = SCNScene(named: "Ar.scnassets/DroneScene.scn")!
var newDroneNode = newDroneScene.rootNode.childNode(withName: "Drone", recursively: false)!
newDroneNode.name = "Drone\(self.droneCounter)"
newDroneNode = newDroneScene.rootNode.childNode(withName: "Drone\(self.droneCounter)", recursively: false)!
newDroneNode.position.x = newDroneNode.presentation.position.x + self.randomFloat(min: -10, max: 10)
newDroneNode.position.y = newDroneNode.presentation.position.y + self.randomFloat(min: -1, max: 5)
newDroneNode.position.z = newDroneNode.presentation.position.z + self.randomFloat(min: -10, max: 10)
let move1 = SCNAction.move(to: SCNVector3((self.randomFloat(min: -7, max: 7)), (self.randomFloat(min: 1, max: 5)), (self.randomFloat(min: -7, max: 7))), duration: 15)
let disappearMove = SCNAction.move(to: SCNVector3((self.randomFloat(min: -10, max: 10)), (self.randomFloat(min: 1, max: 5)), (self.randomFloat(min: -10, max: 10))), duration: 3)
let rotateAction = SCNAction.run { (SCNNode) in
let rotate = SCNAction.rotateBy(x: 0, y: CGFloat(360.degreesToRadians), z: 0, duration: 2)
newDroneNode.runAction(rotate)
}
let removeIt = SCNAction.removeFromParentNode()
let sequence = SCNAction.sequence([waitFive,move1,rotateAction,waitFive,disappearMove,waitTwo,removeIt])
newDroneNode.runAction(sequence)
self.sceneView.scene.rootNode.addChildNode(newDroneNode)
if self.droneCounter >= 5 {
self.sceneView.scene.rootNode.childNode(withName: "Drone\(self.droneCounter)", recursively: true)!.runAction(SCNAction.repeatForever(self.playDroneSound))
}
self.droneCounter += 1
}
when user taps on one of the 3d nodes, this gets called:
func handleExplosion (node : SCNNode) {
self.sceneView.scene.rootNode.childNode(withName: node.name!, recursively: true)!.runAction(self.playExplosionSound)
node.opacity = 0
print (self.sceneView.scene.rootNode.position)
let confetti = SCNParticleSystem(named: "Ar.scnassets/confetti.scnp", inDirectory: nil)
confetti?.loops = false
confetti?.particleLifeSpan = 1.5
confetti?.emitterShape = node.geometry
let confettiNode = SCNNode()
confettiNode.addParticleSystem(confetti!)
confettiNode.position = node.presentation.position
self.sceneView.scene.rootNode.addChildNode(confettiNode)
let fire = SCNParticleSystem(named: "Ar.scnassets/fire", inDirectory: nil)
fire?.loops = false
fire?.particleLifeSpan = 0.1
fire?.emitterShape = node.geometry
let fireNode = SCNNode()
fireNode.addParticleSystem(fire!)
fireNode.position = node.presentation.position
self.sceneView.scene.rootNode.addChildNode(fireNode)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
node.removeFromParentNode()
self.killedLabel.text = "Killed: \(self.killedCount)"
self.dronesOut -= 1
}
}
Any pointer to the right direction for solving this crash would be greatly appreciated]1

detecting if a spritenode exists in swift

I am trying to detect if one of the nodes that I have made through a subclass of SKNode (called Achievements) exists and if it doesn't exist then i'm trying to turn off a boolean variable.
What I use to locate the SKShapeNode (called "Indicator")
func checkIndicatorStatus() {
moveableArea.enumerateChildNodes(withName: "Achievement") {
(node, stop) in
let Indicate = node
Indicate.enumerateChildNodes(withName: "Indicator") {
node, stop in
if let Achievement = node as? Achievements {
menuAchieveNotificationOn = false
}
}
}
}
I have enumerated through the nodes specifically and tried searching for it but it doesn't seem to do anything. what am I doing wrong?
Here is my subclass. I have many of them named achievement displayed in my scene.
class Achievements: SKNode {
//Nodes used throughout the SKNode class
var achievementLabel = SKLabelNode()
var achievementTitleLabel = SKLabelNode()
var achievementNode = SKSpriteNode()
var notifyCircle = SKShapeNode()
//Amount Variables used as Achievement Properties
var image: String = ""
var information: String = ""
var title: String = ""
var amount = 0
var neededAmount = 0
var notification:Bool = false
var stage = 0
func getachievementData(AchName: String) {
let getDataRequest:NSFetchRequest<Achievement> = Achievement.fetchRequest()
getDataRequest.predicate = NSPredicate(format: "theSearchName == %#" , AchName)
do {
let searchResults = try CoreDatabaseContoller.getContext().fetch(getDataRequest)
//print("number of results: \(searchResults.count)")
for result in searchResults as [Achievement] {
title = result.theName!
information = result.theDescription!
image = result.theImage!
amount = Int(result.aAmount!)
neededAmount = Int(result.aNeededAmount!)
stage = Int(result.aStage!)
if result.aHasBeenAchieved!.intValue == 1 {
notification = true
}
}
}
catch {
print("ERROR: \(error)")
}
createAchievement()
}
func createAchievement() {
let tex:SKTexture = SKTexture(imageNamed: image)
achievementNode = SKSpriteNode(texture: tex, color: SKColor.black, size: CGSize(width: 85, height: 85)) //frame.maxX / 20, height: frame.maxY / 20))
achievementNode.zPosition = -10
achievementSprites.append(achievementNode)
self.name = "Achievement"
self.addChild(achievementNode)
self.zPosition = -11
createAchievementLabels()
}
func createAchievementLabels() {
achievementTitleLabel = SKLabelNode(fontNamed: "Avenir-Black")
achievementTitleLabel.fontColor = UIColor.black;
achievementTitleLabel.fontSize = 15 //self.frame.maxY/30
achievementTitleLabel.position = CGPoint (x: 0, y: 50)
achievementTitleLabel.text = "\(title)"
achievementTitleLabel.zPosition = -9
addChild(achievementTitleLabel)
achievementLabel = SKLabelNode(fontNamed: "Avenir-Black")
achievementLabel.fontColor = UIColor.black;
achievementLabel.fontSize = 13 //self.frame.maxY/30
achievementLabel.position = CGPoint (x: 0, y: -55)
achievementLabel.text = ("\(amount) / \(neededAmount)")
achievementLabel.zPosition = -9
addChild(achievementLabel)
if notification == true {
notifyCircle = SKShapeNode(circleOfRadius: 10)
notifyCircle.fillColor = .red
notifyCircle.position = CGPoint(x: 30 , y: 35)
notifyCircle.zPosition = 1000
notifyCircle.name = "Indicator"
addChild(notifyCircle)
}
}
}
EDIT 1
As you can see from the image below, there are a number of different achievement nodes each with their individual names and unlock criteria, when an achievement becomes unlocked it makes an indicator and changes the graphic, which is seen for the two X nodes here with the coloured red circle in the top right corners of each of them which is the "indicator" (if you look at the subclass at the bottom of it the creation of the indicator is there)
Now as you can seen the big red button in the bottom right hand corner of the picture is the achievement menu button which also has an indicator which is controlled by the bool variable (menuAchieveNotificationOn) what i'm trying to achieve is once the achievements with the indicators have each been pressed they are removed from the node.
what i'm trying to do is search each of the nodes to see if the indicator still exists if not I want to turn the variable (menuAchieveNotificationOn) to false.
You should be able to use this:
if let indicatorNode = childNode(withName: "//Indicator") as! SKShapeNode? {
menuAchieveNotificationOn = false
} else {
menuAchieveNotificationOn = true
}
EDIT: to run some code for EVERY "indicator" node in the scene. If any are found, achievementsFound is set to true:
achievementsFound = false
enumerateChildNodes(withName: "//Indicator") { indicatorNode, _ in
// Do something with indicatorNode
achievementsFound = true
}
Although this seems too simple, so I might have misunderstood your aim.

How to choose from an array of sprites in swift

So basically I am looking to choose one of the 4 different coloured balls at random to come into the scene which each have an animation, physics properties and movement & spacing that I have already coded. I am not sure exactly how to make the array then choose at random from the array of the 4 coloured balls so that I have one ball chosen at random to come into the scene.
To make it more clear what I'm asking here's some code (I only use two balls in this code so you don't have to read as much):
var moveandremove = SKAction() < this is in my ballScene.swift
The spawn runBlock is inside didMovetoView
let spawn = SKAction.runBlock({
() in
self.allballs()
})
let delay = SKAction.waitForDuration(2.0)
let SpawnDelay = SKAction.sequence([spawn, delay])
let spawndelayforever = SKAction.repeatActionForever(SpawnDelay)
self.runAction(spawndelayforever)
let distance = CGFloat(brnball.frame.width * 20 + brnball.frame.width)
let moveball = SKAction.moveByX(-distance, y: 0, duration: NSTimeInterval(0.003 * distance))
let removeball = SKAction.removeFromParent()
moveandremove = SKAction.sequence([moveball])
}
func allballs() {
TextureAtlasblk = SKTextureAtlas(named: "blkball")
for i in 1...TextureAtlasblk.textureNames.count{
var Name = "blkball_\(i)"
blkarray.append(SKTexture(imageNamed: Name))
}
blkball = SKSpriteNode(imageNamed: "blkball_1")
blkball.position = CGPoint(x: CGRectGetMidX(self.frame) + 100, y: CGRectGetMidY(self.frame))
blkball.zPosition = 7
blkball.setScale(0.1)
self.addChild(blkball)
blkball.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(blkarray, timePerFrame: 0.2)))
//brownball
TextureAtlasbrn = SKTextureAtlas(named: "brnball")
for i in 1...TextureAtlasbrn.textureNames.count{
var Name = "brnball_\(i)"
brnarray.append(SKTexture(imageNamed: Name))
}
brnball = SKSpriteNode(imageNamed: "brnball_1")
brnball.position = CGPoint(x: CGRectGetMidX(self.frame) + 50, y: CGRectGetMidY(self.frame))
brnball.zPosition = 7
brnball.setScale(0.1)
self.addChild(brnball)
brnball.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(brnarray, timePerFrame: 0.2)))
Here is my terrible starting point at trying to make an array to choose from each ball (this is inside my allballs() function):
var ballarray: NSMutableArray = [blkball, brnball, yelball, bluball]
runAction(moveandremove)
I am new to swift and pretty hopeless, would be awesome if someone could help me out :)
Thanks
It's hard for me to find the array that you're talking about in your code. But nevertheless, I can still show you how.
Let's say we have an [Int]:
let ints = [10, 50, 95, 48, 77]
And we want to get a randomly chosen element of that array.
As you may already know, you use the subscript operator with the index of the element to access an element in the array, e.g. ints[2] returns 95. So if you give a random index to the subscript, a random item in the array will be returned!
Let's see how can we generate a random number.
The arc4random_uniform function returns a uniformly distributed random number between 0 and one less the parameter. Note that this function takes a UInt32 as a parameter and the return value is of the same type. So you need to do some casting:
let randomNumber = Int(arc4random_uniform(UInt32(ints.count)))
With randomNumber, we can access a random element in the array:
let randomItem = ints[randomNumber]
Try to apply this technique to your situation.
Here's a generic method to do this as well:
func randomItemInArray<T> (array: [T]) -> T? {
if array.isEmpty {
return nil
}
let randomNumber = Int(arc4random_uniform(UInt32(array.count)))
return array[randomNumber]
}
Note that if the array passed in is empty, it returns nil.
You could make and extension for Array that returns a random element.
extension Array {
func randomElement() -> Element {
let i = Int(arc4random_uniform(UInt32(count - 1)))
return self[i]
}
}
You could take that a step further and allow a function to be applied directly to a random element.
mutating func randomElement(perform: (Element) -> Element) {
let i = Int(arc4random_uniform(UInt32(count - 1)))
self[i] = perform(self[i])
}
You can use this function when using an array of reference types.
func randomElement(perform: (Element) -> ()) {
let i = Int(arc4random_uniform(UInt32(count - 1)))
perform(self[i])
}

stopping an asynchronous call once it's out in the wild in swift

I have some problems with my version of this loadingOverlay singleton.
What's supposed to happen, is it comes onto the screen, with a view and a label that has the text, "Loading, please wait." or something like that. then if loading is longer than 2 seconds (i've changed it to 10 for debugging) the text changes to a random cute phrase.
first of all the animation that should change the text doesn't seem to happen. instead, the text just instantly changes.
more importantly, If, for some reason, my asynchronous call block is executed multiple times, I only want the most recent call to it to run, and I want the previous instances of it to terminate before running.
I was reading about callbacks and promises, which look promising. Is that a swifty pattern to follow?
by the way, as I'm learning swift and iOS, I've been experimenting, and I tried [unowned self] and now i'm experimenting with [weak self], but I'm not really certain which is most appropriate here.
// from http://stackoverflow.com/questions/33064908/adding-removing-a-view-overlay-in-swift/33064946#33064946
import UIKit
class LoadingOverlay{
static let sharedInstance = LoadingOverlay()
//above swifty singleton syntax from http://krakendev.io/blog/the-right-way-to-write-a-singleton
var overlayView = UIView()
var spring: CASpringAnimation!
var springAway: CASpringAnimation!
var hidden = false
private init() {} //This line prevents others from using the default () initializer for this class
func setupSpringAnimation(startY: CGFloat, finishY: CGFloat) {
overlayView.layer.position.y = startY
spring = CASpringAnimation(keyPath: "position.y")
spring.damping = 10
spring.fromValue = startY
spring.toValue = finishY
spring.duration = 1.0
spring.fillMode = kCAFillModeBackwards
}
func showOverlay() {
print("show overlay")
overlayView.alpha = 1
hidden = false
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate,
let window = appDelegate.window {
setupSpringAnimation(-window.frame.height / 2, finishY: window.frame.height / 2)
let overlayViewFramesize = 0.65 * min(window.frame.height, window.frame.width)
overlayView.frame = CGRectMake(0, 0, overlayViewFramesize, overlayViewFramesize)
overlayView.center = window.center
overlayView.backgroundColor = UIColor.greenColor()
overlayView.clipsToBounds = true
overlayView.layer.cornerRadius = overlayViewFramesize / 8
let label = UILabel(frame: CGRectMake(0,0,overlayViewFramesize * 0.8 , overlayViewFramesize))
label.text = " \nLoading, please wait\n "
label.tag = 12
overlayView.addSubview(label)
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.numberOfLines = 0 //as many as needed
label.sizeToFit()
label.textAlignment = NSTextAlignment.Center
label.center = CGPointMake(overlayViewFramesize / 2, overlayViewFramesize / 2)
overlayView.bringSubviewToFront(label)
window.addSubview(overlayView)
overlayView.layer.addAnimation(spring, forKey: nil)
RunAfterDelay(10.0) {
if self.hidden == true { return }
//strongSelf boilerplate code technique from https://www.raywenderlich.com/133102/swift-style-guide-april-2016-update?utm_source=raywenderlich.com+Weekly&utm_campaign=ea47726fdd-raywenderlich_com_Weekly4_26_2016&utm_medium=email&utm_term=0_83b6edc87f-ea47726fdd-415681129
UIView.animateWithDuration(2, delay: 0, options: [UIViewAnimationOptions.CurveEaseInOut, UIViewAnimationOptions.BeginFromCurrentState, UIViewAnimationOptions.TransitionCrossDissolve], animations: { [weak self] in
guard let strongSelf = self else { return }
(strongSelf.overlayView.viewWithTag(12) as! UILabel).text = randomPhrase()
(strongSelf.overlayView.viewWithTag(12) as! UILabel).sizeToFit()
print ((strongSelf.overlayView.viewWithTag(12) as! UILabel).bounds.width)
(strongSelf.overlayView.viewWithTag(12) as! UILabel).center = CGPointMake(overlayViewFramesize / 2, overlayViewFramesize / 2)
}, completion: { (finished: Bool)in
print ("animation to change label occured")})
}
}
}
func hideOverlayView() {
hidden = true
UIView.animateWithDuration(1.0, delay: 0.0, options: [UIViewAnimationOptions.BeginFromCurrentState], animations: { [unowned self] in
//I know this is clunky... what's the right way?
(self.overlayView.viewWithTag(12) as! UILabel).text = ""
self.overlayView.alpha = 0
}) { [unowned self] _ in
//I know this is clunky. what's the right way?
for view in self.overlayView.subviews {
view.removeFromSuperview()
}
self.overlayView.removeFromSuperview()
print("overlayView after removing:", self.overlayView.description)
}
//here i have to deinitialize stuff to prepare for the next use
}
deinit {
print("Loading Overlay deinit")
}
}
What I basically wanted, was to be able to delay a block of code, and possibly cancel it before it executes. I found the answer here:
GCD and Delayed Invoking

Swift for loop not working

I'm baffled by this loop in my Swift code that won't work. Here's the entirety of the function--"pulseChar" is giving me the error "index out of range":
func openingSequence(){
let nodeList = [self.drum,self.piano,self.guitarBoard]
let offset = SKAction.waitForDuration(10)
let stOne = SKAction.runBlock { () -> Void in
for var i in 0...nodeList.count-1{
nodeList[i].runAction(SKAction.fadeAlphaTo(0.3, duration: 0.3))
i++
}
}
let firstLineWait = SKAction.waitForDuration(4)
let moveSprites = SKAction.runBlock { () -> Void in
moveScale(self.rheaBoard, duration: 0.5, to: CGPoint(x: 100, y: self.frame.height - 85), size: 0.4)
moveScale(self.guitarBoard, duration: 0.5, to: CGPoint(x: self.frame.midX - self.frame.midX/2, y: 65), size: 0.35)
for var i in 0...nodeList.count-1{
nodeList[i].runAction(fadeI)
i++
}
}
let fadeAudio = SKAction.runBlock { () -> Void in
fadeOtherTracksOut([9,8,4,2,1])
}
let moveFade = SKAction.group([moveSprites,fadeAudio])
let pulseChar = SKAction.runBlock { () -> Void in
for var i in 0...nodeList.count-1{
self.background.runAction(SKAction.runBlock({ () -> Void in
pulse(nodeList[i], startScale: 0.35, endScale: 0.4)
}))
i++
}
self.startInteaction = true
}
background.runAction(SKAction.sequence([offset,stOne,firstLineWait,moveFade,pulseChar]))
}
My compiler is telling me that i = 3 when it fails...but "i" should not get to three, as
nodeList.count = 3
and I use the range
for var i in 0...nodeList.count-1
Also, the identical loops before it work just fine...what's going on here? I'm new to programming so if this is a ridiculously simple fix you'll have to excuse me. But help would be greatly appreciated.
EDIT
It seems that the operator i++ needed to be inside the runBlock:
let pulseChar = SKAction.runBlock { () -> Void in
for var i in 0...nodeList.count-1{
self.background.runAction(SKAction.runBlock({ () -> Void in
pulse(nodeList[i], startScale: 0.35, endScale: 0.4)
i++
}))
}
This fixes the problem, but I would really appreciate it if someone wouldn't mind explaining why this is the case. It seems to me that if the operator i++ is within the loop it should never == 3.
Don't increment the index variable i "manually", the repeat loop does that automatically.
And you can use the half-open range operator to avoid the extra subtraction, for example
for i in 0..<nodeList.count {
nodeList[i].runAction(SKAction.fadeAlphaTo(0.3, duration: 0.3))
}
or
for node in nodeList {
node.runAction(SKAction.fadeAlphaTo(0.3, duration: 0.3))
}
if the numeric index is not needed.
Or even
nodeList.forEach{ $0.runAction(SKAction.fadeAlphaTo(0.3, duration: 0.3)) }
From swift programming guide provided by apple Check Here For More Details
Care Fully look at the following code and it's output.
for index in 1...5 {
print("\(index) times 5 is \(index * 5)")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25
In For in loop we do not require to increment the counter.
The increment part is handled by the loop it self
Try Following Updated code.
func openingSequence(){
let nodeList = [self.drum,self.piano,self.guitarBoard]
let offset = SKAction.waitForDuration(10)
let stOne = SKAction.runBlock { () -> Void in
for var i in 0..<nodeList.count{
nodeList[i].runAction(SKAction.fadeAlphaTo(0.3, duration: 0.3))
}
}
let firstLineWait = SKAction.waitForDuration(4)
let moveSprites = SKAction.runBlock { () -> Void in
moveScale(self.rheaBoard, duration: 0.5, to: CGPoint(x: 100, y: self.frame.height - 85), size: 0.4)
moveScale(self.guitarBoard, duration: 0.5, to: CGPoint(x: self.frame.midX - self.frame.midX/2, y: 65), size: 0.35)
for var i in 0..<nodeList.count{
nodeList[i].runAction(fadeI)
}
}
let fadeAudio = SKAction.runBlock { () -> Void in
fadeOtherTracksOut([9,8,4,2,1])
}
let moveFade = SKAction.group([moveSprites,fadeAudio])
let pulseChar = SKAction.runBlock { () -> Void in
for var i in 0..<nodeList.count{
self.background.runAction(SKAction.runBlock({ () -> Void in
pulse(nodeList[i], startScale: 0.35, endScale: 0.4)
}))
}
self.startInteaction = true
}
background.runAction(SKAction.sequence([offset,stOne,firstLineWait,moveFade,pulseChar]))
}

Resources