在初始化时将信息传递给类

时间:2016-08-06 18:01:18

标签: swift xcode sprite-kit

我很难理解课程初始化是如何运作的。从查看解决方案到其他问题,我将此作为我的应用程序中的类的示例。

import Foundation
import SpriteKit

class Ground : SKSpriteNode {

override init(texture: SKTexture!, color: SKColor, size: CGSize) {

    super.init(texture: texture, color: color, size: size)

    self.zPosition = -20
    self.name = "Ground";

}

func configure (size: CGSize, position: CGPoint) {
    self.size = size
    self.position = position
    // Set up the Physics
    self.physicsBody = SKPhysicsBody(rectangleOf: size)
    self.physicsBody?.contactTestBitMask = PhysicsCategory.Player
    self.physicsBody?.categoryBitMask = PhysicsCategory.Ground
    self.physicsBody?.collisionBitMask = PhysicsCategory.All
    self.physicsBody?.affectedByGravity = false
    self.physicsBody?.allowsRotation = false
    self.physicsBody?.isDynamic = false
    self.physicsBody?.mass = 1.99999
}

convenience init(color: SKColor, isActive: Bool = false) {
    let size = CGSize(width: 10, height: 10);
    self.init(texture:nil, color: color, size: size)
}

required init?(coder aDecoder: NSCoder) {
    // Decoding length here would be nice...
    super.init(coder: aDecoder)
}
}

我已将'configure'功能作为kludge修复程序让我将场景传递给类,因此我可以根据设备屏幕的大小设置大小。理想情况下,我想在初始化时提取这些信息,但我尝试的所有内容都会引发我不理解的错误。

我不确定哪种方式是正确的,但我首先想知道,我如何将参数传递给类开始......例如..

let myClass = Ground(scene: self) 

或者我可以以某种方式直接从课程中提取场景信息?我可以将信息传递给函数/方法,就像我使用'configure'一样,但是我无法将它用于初始化,这肯定会更清晰。

你们会怎么做?

2 个答案:

答案 0 :(得分:1)

大小

您不应该以编程方式更改精灵的大小,具体取决于当前设备,只需使用相同的大小,然后让SpriteKit为您调整大小。

从.sks

加载

此初始化程序

init?(coder aDecoder: NSCoder)
从.sks文件加载Sprite时使用

。但是在Xcode 7中,您无法将.sks中的值传递给精灵来设置属性。我不确定您是否使用.sks文件,所以现在我只是在这里抛出一个fatal_error。但是,在Xcode 8中,您可以将.sks文件中的值传递给您自己的类。

required init?(coder aDecoder: NSCoder) {
    fatalError("Not implemented")
}

场景

您不需要将当前场景的引用传递给您的班级。每个SKNode都有scene属性,只需使用它来检索节点所在的场景。当然请记住,如果您在之前调用.scene 节点已添加到场景中,则会返回nil

代码

这是最终代码

class Ground : SKSpriteNode {

    init(color: SKColor = .clearColor(), isActive:Bool = false) {
        let texture = SKTexture(imageNamed: "ground")
        super.init(texture: texture, color: color, size: texture.size())
        self.name = "Ground"
        self.zPosition = -20

        let physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
        physicsBody.contactTestBitMask = PhysicsCategory.Player
        physicsBody.categoryBitMask = PhysicsCategory.Ground
        physicsBody.collisionBitMask = PhysicsCategory.All
        physicsBody.affectedByGravity = false
        physicsBody.allowsRotation = false
        physicsBody.dynamic = false
        physicsBody.mass = 1.99999
        self.physicsBody = physicsBody
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("Not implemented")
    }
}

答案 1 :(得分:0)

除非我遗漏了你想要做的其他事情,否则你应该能够将您的PhysicsBody和其他属性的初始化从configure()方法移动到类的init()中。然后,您可以在实例化时预先调整传入的纹理大小,以获得适当的设备大小。

此外,SKSpriteNode的position属性可以由实例化类设置。这意味着您可以在场景中实例化之后以及在将其添加为场景的子项之前,基于设备和位置属性的设置来完成大小调整。

增加:

class Ground : SKSpriteNode {

override init(texture: SKTexture!, color: SKColor, size: CGSize) {
    super.init(texture: texture, color: color, size: size)

}



convenience init(texture: String, scene: SKScene, isActive: Bool = false) {
    let texture = SKTexture(imageNamed: "\(yourtexturename)")
    self.init(texture:teture, color: color, size: scene.size)
    self.size = size
    self.position = [YOU CAN NOW SET POSITION BASED ON THE SCENE] 
    self.physicsBody = SKPhysicsBody(rectangleOf: size)
    self.physicsBody?.contactTestBitMask = PhysicsCategory.Player
    self.physicsBody?.categoryBitMask = PhysicsCategory.Ground
    self.physicsBody?.collisionBitMask = PhysicsCategory.All
    self.physicsBody?.affectedByGravity = false
    self.physicsBody?.allowsRotation = false
    self.physicsBody?.isDynamic = false
    self.physicsBody?.mass = 1.99999

    self.zPosition = -20
    self.name = "Ground";
}

required init?(coder aDecoder: NSCoder) {
    // Decoding length here would be nice...
    super.init(coder: aDecoder)
}

}

您可能不需要覆盖原始的init()方法,但我没有测试任何内容。