0
votes

I am searching for the most efficient way to Nodes with random SKSpriteNodes on given positions.

I have 10 Platforms, on each of them I want to have an Enemy (SKNode) that contains for 3 different SKSpriteNodes which will randomly spawn. These SKSpriteNodes all do other behaviors, thats why I can't simply change the Texture of the SKNode.

As with my Code, I wanted to spawn the same Node on different Platforms. However, the code does not work properly, the nodes do spawn but only at 1 position(the position from the last SpawnEnemycode in didMoveToView), meaning 10 nodes at 1 position.

I also tried it with adding 10 different Enemy nodes, each given a Platform. But this just looks like a copy & paste code thats inefficient.

How can I fix my problem, or is there either another way to spawn them more efficiently?

My Code:

class GameScene: SKScene, SKPhysicsContactDelegate {

var Enemy: SKNode!

override func didMoveToView(view: SKView) {
    /* Setup your scene here */
    self.physicsWorld.contactDelegate = self
    self.physicsBody?.velocity = CGVectorMake(0, 0)
    self.anchorPoint = CGPoint(x: 0, y: 0.20)

    backgroundColor = SKColor(red: 81.0/255.0, green: 192.0/255.0, blue: 201.0/255.0, alpha: 1.0)

    self.Enemy1 = SKNode()
    addChild(Enemy1)

    SpawnPlayer()
    SpawnEnemy(CGPoint(x: self.frame.size.width / 2, y: Platform1.position.y + 15))
    SpawnEnemy(CGPoint(x: self.frame.size.width / 2, y: Platform2.position.y + 15))
    //Same code for all the other Platforms.
    }

 func SpawnEnemy(position: CGPoint!){

    switch (arc4random_uniform(3)){

    case 0:

        Picture1.filteringMode = .Nearest
        Picture2.filteringMode = .Nearest

        Animation1 = SKAction.animateWithTextures([Picture1,Picture2], timePerFrame: 0.5)
        AnimationRepeat1 = SKAction.repeatActionForever(Animation1)

        Sprite1 = SKSpriteNode (imageNamed: "Sprite1.png")
        Sprite1.size = CGSize(width: 64, height: 64)
        Sprite1.zPosition = 2

        Sprite1.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 45, height: 50))
        Sprite1.physicsBody?.dynamic = true
        Sprite1.physicsBody?.allowsRotation = false
        Sprite1.physicsBody?.restitution = 0.0
        Sprite1.physicsBody?.usesPreciseCollisionDetection = true

        Sprite1.physicsBody?.categoryBitMask = EnemyCategory
        Sprite1.physicsBody?.collisionBitMask = PlayerCategory | Platform1Category
        Sprite1.physicsBody?.contactTestBitMask = Wall1Category | Wall2Category | PlayerCategory

        Sprite1.runAction(AnimationRepeat1)

    Enemy.position = position
    Enemy.addChild(Sprite1)

    case 1:

        Picture3.filteringMode = .Nearest
        Picture4.filteringMode = .Nearest

        Animation1 = SKAction.animateWithTextures([Picture3,Picture4], timePerFrame: 0.5)
        AnimationRepeat1 = SKAction.repeatActionForever(Animation1)

        Sprite2 = SKSpriteNode (imageNamed: "Sprite2.png")
        Sprite2.size = CGSize(width: 64, height: 64)
        Sprite2.zPosition = 2

        Sprite2.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 45, height: 50))
        Sprite2.physicsBody?.dynamic = true
        Sprite2.physicsBody?.allowsRotation = false
        Sprite2.physicsBody?.restitution = 0.0
        Sprite2.physicsBody?.usesPreciseCollisionDetection = true

        Sprite2.physicsBody?.categoryBitMask = EnemyCategory
        Sprite2.physicsBody?.collisionBitMask = PlayerCategory | Platform1Category
        Sprite2.physicsBody?.contactTestBitMask = Wall1Category | Wall2Category | PlayerCategory

        Sprite2.runAction(AnimationRepeat1)

    Enemy.position = position
    Enemy.addChild(Sprite2)

    case 2:

        Picture5.filteringMode = .Nearest
        Picture6.filteringMode = .Nearest

        Animation1 = SKAction.animateWithTextures([Picture5,Picture6], timePerFrame: 0.5)
        AnimationRepeat1 = SKAction.repeatActionForever(Animation1)

        Sprite3 = SKSpriteNode (imageNamed: "Sprite3.png")
        Sprite3.size = CGSize(width: 64, height: 64)
        Sprite3.zPosition = 2

        Sprite3.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 45, height: 50))
        Sprite3.physicsBody?.dynamic = true
        Sprite3.physicsBody?.allowsRotation = false
        Sprite3.physicsBody?.restitution = 0.0
        Sprite3.physicsBody?.usesPreciseCollisionDetection = true

        Sprite3.physicsBody?.categoryBitMask = EnemyCategory
        Sprite3.physicsBody?.collisionBitMask = PlayerCategory | Platform1Category
        Sprite3.physicsBody?.contactTestBitMask = Wall1Category | Wall2Category | PlayerCategory

        Sprite3.runAction(AnimationRepeat1)

    Enemy.position = position
    Enemy.addChild(Sprite3)

    default:
        return
    }

}
1
You can't have same node on different positions. You need to create 10 enemy nodes. - John Tracid
But how does it come that it spawns these nodes, but takes the position of the last SpawnEnemy and all spawn on this position? - Albert

1 Answers

2
votes

The reason you're only seeing one position is that you're only creating one "enemy" and moving it around with SpawnEnemy. Since your sprites are all added to the same "enemy", they will all show up wherever your enemy was moved to last.

Let's chop down what your code is to the relevant bits:

var Enemy: SKNode!

override func didMoveToView(view: SKView) {

    self.Enemy1 = SKNode()
    addChild(Enemy1)
    SpawnEnemy(CGPoint(x: self.frame.size.width / 2, y: Platform1.position.y + 15))
    SpawnEnemy(CGPoint(x: self.frame.size.width / 2, y: Platform2.position.y + 15))

    }

 func SpawnEnemy(position: CGPoint!){

    switch (arc4random_uniform(3)){

    case 0:

        Enemy.position = position
        Enemy.addChild(Sprite1)

    case 1:

        Enemy.position = position
        Enemy.addChild(Sprite2)

    case 2:

        Enemy.position = position
        Enemy.addChild(Sprite3)

    default:
        return
    }

}

So, in didMoveToView(), you create one Enemy node. Then, as you call SpawnEnemy, you do a bunch of stuff to add other sprites, but as far as Enemy is concerned, you're just changing its position. Since you're adding the sprites to the same node, when you move that Enemy node, the child sprites move with it, too.

You have two options to fix this. Either add your sprites to some higher-level node (like the scene), or create new "enemy" nodes for each of the sprites you intend to add. Either should work, but the best choice will depend on what you're trying to accomplish with them - the scope of that discussion is beyond what you're talking about here.