Bane
Bane

Reputation: 341

SKActions not recognizing changes in certain values

I have 3 groups of sprites (EnemyGroups) and these groups are arranged in a specific sequence (one second delay for each). Please see the code:

EnemyGroup:

struct EnemyGroup    {
    var enemies : [Enemy]
    var isVisible : Bool
    var isStatic : Bool

    func setup   ()  {
    if isStatic {
        for enemy in enemies  {
            enemy.sprite.alpha = 1.0
            enemy.sprite.isUserInteractionEnabled = false

        }
        isVisible = true
    }
        }


    mutating func switchEnemiesON   ()  {
    if !isStatic {
    for enemy in enemies  {

        enemy.sprite.alpha = 1.0
        enemy.sprite.physicsBody?.categoryBitMask = enemyCategory
        enemy.sprite.physicsBody?.collisionBitMask = bombCategory

    }
    isVisible = true
    }
}

mutating func switchEnemiesOFF   ()  {
    if !isStatic {
        for enemy in enemies  {
        enemy.sprite.alpha = 0.0
        enemy.sprite.physicsBody?.collisionBitMask = 0
        enemy.sprite.physicsBody?.categoryBitMask = 0
    }

    isVisible = false
    }
}

in GameScene:

   func groupActionSequence (enemyGroup: EnemyGroup)  {
    for enemy in enemyGroup.enemies {
    var enemyGroupWithAction = enemyGroup
    let groupSequence = SKAction.sequence([
        SKAction.run({ enemyGroupWithAction.switchEnemiesON() }),
        SKAction.wait(forDuration: showTime),
        SKAction.run({ enemyGroupWithAction.switchEnemiesOFF() }),
        SKAction.wait(forDuration: hideTime)
        ])

    let repeatGroupAction = SKAction.repeatForever(groupSequence)
    enemy.sprite.run(repeatGroupAction)
    }
}

func groupActionSequenceWithDelay (delayTime: TimeInterval, enemyGroup: EnemyGroup, groupKey: String)   {
    for enemy in enemyGroup.enemies {

        var group = enemyGroup
    let groupSequence = SKAction.sequence([
        SKAction.run({ group.setup() }),
        SKAction.wait(forDuration: delayTime),
        SKAction.run({ self.groupActionSequence(enemyGroup: enemyGroup) })
        ])

    enemy.sprite.run(groupSequence, withKey: groupKey)
    }
}

setting actions for enemy groups:

 groupActionSequenceWithDelay(delayTime: 0, enemyGroup: enemyGroup1, groupKey: "group1")
 groupActionSequenceWithDelay(delayTime: 1, enemyGroup: enemyGroup2, groupKey: "group2")
 groupActionSequenceWithDelay(delayTime: 2, enemyGroup: enemyGroup3, groupKey: "group3")

I set enemyGroup1 and enemyGroup2 to have isStatic = false and enemyGroup3 to isStatic = true. I changed enemyGroup1 and enemyGroup2 isStatic to true the actions still are still running on enemyGroup1 and enemyGroup2 as ifisStatic = false. How can I getswitchEnemiesOFF()andswitchEnemiesON()to recognize changes in the value ofisStatic`? Also, I don't want to stop the actions because I want to keep the same sequence of each group having a one second difference in their running actions, that's why I protected some of the functions with if statements instead.

Upvotes: 2

Views: 37

Answers (1)

Alain T.
Alain T.

Reputation: 42143

Make EnemyGroup a class rather than a Struct.

Because it is a Struct, the enemyGroupWithAction variable captured in the run block closure is a copy of the one you received in parameter (which is also a copy of the one passed as parameter to the function). Each of these copies have their own separate value (Struct is a value type) and live separately. If enemyGroup was an object (class), only the reference would be captured (classes are reference types) and any modifications to is properties would affect the original object instance.

Upvotes: 1

Related Questions