Search code examples
macosswiftsprite-kitskscene

Required init method in GameScene class


I'm learning swift and playing with the sprite-kit framework. These problem it's so weird for me. The code compiles and i solved all the errors, but the code only compiles when I accepts the Xcode solution for the init method.

Code suggested :

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

When running the app the debug interpreter marks the line of the fatal error. I don't know how to solve this error. I saw other sprite-kit examples for iOS and no one needs a init method in the gameScene class, and by default this class doesn't have an init method. I didn't modify the appDelegate class too and the GameScene's properties are initialized. Also all the class properties takes values in the didMovetoView method.

Here the head of the class :

class GameScene: SKScene, SKPhysicsContactDelegate
{

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

    var world : SKNode
    var hud : SKNode
    var cursor : UInt32 = 0
    var Joystick : joystick
    var map : Map
    var exit : SKSpriteNode
    var spriteAtlas : SKTextureAtlas
    var player : SKSpriteNode
    var playerShadow : SKSpriteNode
    var isExitingLevel : Bool
    var playerIdleAnimationFrames : [SKTexture] = []
    var playerWalkAnimationFrames : [SKTexture] = []
    var playerAnimationID : Int = 0; // 0 = idle; 1 = walk
    var lastUpdateTimeInterval : NSTimeInterval = 0.0

    override func didMoveToView(view: SKView)
    {
        // Setup your scene here
        let myLabel = SKLabelNode(fontNamed:"Chalkduster")
        myLabel.text = "Hello, World!";
        myLabel.fontSize = 65;
        myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));

        self.addChild(myLabel)


        // Inicio todas las variables de mi juego (nada de método init ni hostias)
        backgroundColor = NSColor(red:175.0/255.0, green:143.0/255.0, blue:106.0/255.0, alpha:1.0);
        isExitingLevel = false;

        // Add a node for the world - this is where sprites and tiles are added
        world = SKNode()

        // Load the atlas that contains the sprites
        spriteAtlas = SKTextureAtlas(named:"sprites")

        Joystick.velocity = CGPoint(x: 0, y: 0)

        // Create a new map
        map = Map()

        // Create the exit
        exit = SKSpriteNode(imageNamed: "exit")
        exit.position = self.map.exitPoint
        exit.physicsBody = SKPhysicsBody(rectangleOfSize: exit.size )
        exit.physicsBody?.categoryBitMask = CollisionType.Exit;
        exit.physicsBody?.collisionBitMask = 0;

        // Create a player node
        player = SKSpriteNode(imageNamed: "idle_0")
        player.position = self.map.spawnPoint;
        player.physicsBody?.allowsRotation = false;
        player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size )
        player.physicsBody?.categoryBitMask = CollisionType.Player;
        player.physicsBody?.contactTestBitMask = CollisionType.Exit;
        player.physicsBody?.collisionBitMask = CollisionType.Wall;

        // Load sprites for player into arrays for the animations
        playerIdleAnimationFrames.append(self.spriteAtlas.textureNamed("idle_0"))

        playerWalkAnimationFrames.extend([self.spriteAtlas.textureNamed("walk_0"), self.spriteAtlas.textureNamed("walk_1"), self.spriteAtlas.textureNamed("walk_2")])

        playerShadow = SKSpriteNode(imageNamed: "shadow")
        playerShadow.xScale = 0.6
        playerShadow.yScale = 0.5
        playerShadow.alpha = 0.4

        playerAnimationID = 0;

        world.addChild(self.map)
        world.addChild(self.exit)
        world.addChild(self.playerShadow)
        world.addChild(self.player)

        // Create a node for the HUD - this is where the DPad to control the player sprite will be added
        self.hud = SKNode()

        // Add the world and hud nodes to the scene
        self.addChild(self.world)
        self.addChild(self.hud)

        // Initialize physics
        self.physicsWorld.gravity = CGVectorMake(0, 0);
    }

Thanks in advance.


Solution

  • I think the problem is, the only initializer you have is the required init method so it is called every time when creating an item of the class. So the fatal error is thrown every time. You need to declare an init() method where you set all your properties (I wonder why this code does even compile). In this init method you also have to init you superclasses by super.init(). Then the other init function won't be called. But actually you can't delete this function.

    The required init has to be implemented because the superclass UIView has this required initializer. Every subclass of UIView has to implement this initializer as it is required.