引用类名作为变量

时间:2017-05-02 20:14:44

标签: swift3 sprite-kit

我想知道是否有更好的方法来编写这段代码。这是非常多余的,在我这样做之前,我认为应该有一种方法来做变量作为类名,但遇到了很多问题,最终以这种方式做到了。现在每次我看它都困扰着我。我对这个主题做了很多研究,并没有提出任何建议。可能是因为我不确定会做什么样的事情。

为了便于论证,假设以下代码位于轻触SKSpriteNode时调用的函数中。每个“按钮”都以其将要转换到的场景命名。实际上还有12个case语句。

let name = sender.name
switch(name){
    case "newGame":
        defaults.set(true,forKey: "isFirstRun")
        defaults.set(true,forKey: "isNewGame")
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = Setup(fileNamed:"Setup")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    case "IceFishing":
        defaults.set(2, forKey: "currentLocation")
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = IceFishing(fileNamed:"IceFishing")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    case "OpeningScene":
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = OpeningScene(fileNamed:"OpeningScene")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    case "House":
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = SodHouse(fileNamed:"House")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    default:
        break
}

我会想(或希望)有办法做某事......

let name = sender.name
let _Class = name as! SKScene //Not right, but i was guessing

let transition = SKTransition.crossFade(withDuration: 1.0)
let nextScene = _Class(fileNamed:name)
nextScene?.scaleMode = .aspectFill
scene?.view?.presentScene(nextScene!, transition: transition)

所有sks文件和Swift类的名称都相同。

1 个答案:

答案 0 :(得分:1)

你基本上希望代码看起来像这样(我为你添加了一些警卫):

let name = sender.name
let transition = SKTransition.crossFade(withDuration: 1.0)
guard let nextScene = SKScene(fileNamed:sender.name) else {fatalError("unable to find next scene")}
guard let scene = scene else {fatalError("unable to find scene")}
guard let view = scene.view else {fatalError("unable to find view")}

nextScene.scaleMode = .aspectFill

case "newGame":
    //I would avoid using defaults unless you plan on saving when the app exits
    defaults.set(true,forKey: "isFirstRun")
    defaults.set(true,forKey: "isNewGame")

case "IceFishing":
    defaults.set(2, forKey: "currentLocation")

default: break
}

view.presentScene(nextScene!, transition: transition)

基本上我们正在做的是依靠sks文件中的自定义类字段为我们加载自定义类。

编辑:现在为了更清理代码,我会抛弃默认值。只有在想要跨游戏会话而不是游戏中保存数据时,您才需要使用此功能。

let name = sender.name
let transition = SKTransition.crossFade(withDuration: 1.0)
guard let nextScene = SKScene(fileNamed:sender.name) else {fatalError("unable to find next scene")}
guard let scene = scene else {fatalError("unable to find scene")}
guard let view = scene.view else {fatalError("unable to find view")}

nextScene.scaleMode = .aspectFill

nextScene.userData += scene.userData
//Move these to the SKS file under UserData section, then you can pull it using scene.userData?
//    defaults.set(2, forKey: "currentLocation")    
//    defaults.set(true,forKey: "isFirstRun") 
//    defaults.set(true,forKey: "isNewGame")

view.presentScene(nextScene!, transition: transition)