Jack Frye
Jack Frye

Reputation: 583

Improper Instantiation of SKSpriteNode Subclass

I have created an SKSpriteNode subclass and have attempted to instantiate it in an SKScene and set some SKSpriteNode properties with other properties that I have stored in the subclass on instantiation. Here is the class definition.

class WalkingMonster: SKSpriteNode {
    var rangeOfMovement: CGFloat
    var originalPosition: CGFloat
    var platformNumber: Int
    var imageName = "walkingAlien"
    var sizes = [CGSize(width: CGFloat(30.0), height: CGFloat(30.0)), CGSize(width: CGFloat(30.0), height: CGFloat(15.0)), CGSize(width: CGFloat(30.0), height: CGFloat(7.0))]
    var monsterName: String
    var textureName: String

    init(texture: SKTexture, color: UIColor, size: CGSize, rangeOfMovement: CGFloat, originalPosition: CGFloat, platformNumber: Int, name: String, textureName: String) {
        self.rangeOfMovement = rangeOfMovement
        self.originalPosition = originalPosition
        self.platformNumber = platformNumber
        self.monsterName = name
        self.textureName = textureName
        super.init(texture: texture, color: color, size: size)

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

  }

Here is the instantiation of the class:

var walkingMonsters = [WalkingMonster(texture: SKTexture(), color: UIColor(), size: CGSize(), rangeOfMovement: CGFloat(25.0), originalPosition: CGFloat(750.0), platformNumber: -1, name: "walkingMonster1", textureName: "walkingAlien1")]

This is how I am setting its properties in the SKScene within didMoveToView():

for monster in walkingMonsters {
            let texture = SKTexture(imageNamed: monster.textureName)
            monster.texture = texture
            monster.size = monster.sizes[0]
            monster.position.x = monster.originalPosition

            //If it is supposed to sit on the ground
            if monster.platformNumber < 0 {
                monster.position.y = self.groundHeight + super.groundBlockSize.height / 2 + monster.size.height / 2
            }
            monster.physicsBody?.categoryBitMask = physicsBitMasks.walkingEnemy
            monster.physicsBody?.contactTestBitMask = physicsBitMasks.ground | physicsBitMasks.player | physicsBitMasks.aerialBlock
            monster.physicsBody?.contactTestBitMask =  physicsBitMasks.ground | physicsBitMasks.player | physicsBitMasks.aerialBlock
            monster.physicsBody?.dynamic = true
            monster.physicsBody?.affectedByGravity = true
            self.addChild(monster)
        }
    }

At runtime there is a monster that spawns, but he (or at least his texture) appears to be off the ground a little. When the player (who has categoryBitMask of .player and whose contact and collision bit masks include .walkingEnemy) walks into him, nothing happens to the movement of the main character and the walkingMonster (walkingMonsters[0]) does not move either. I am not sure if there is some small thing I am missing syntactically or if there is a larger blocker.

My other method of doing this, which I have already implemented successfully, was to store those member variables of what should stylistically be a subclass of SKSpriteNode in corresponding parameter vectors, then set them after using the SKSpriteNode convenience initializer SKSpriteNode(imageNamed: "whatever"). I think subclassing is the way to go however.

Upvotes: 0

Views: 53

Answers (1)

Jack Frye
Jack Frye

Reputation: 583

The issue was that I was not initializing the physicsbody for each monster in the loop.

for monster in walkingMonsters {
    let body = SKPhysicsBody(rectangleOfSize: monster.sizes[0])
    monster.physicsBody = body
    //rest of setting comes here
}

Upvotes: 0

Related Questions