我正在制作一个有很多关卡的Swift游戏。每个级别都在一个带有顺序名称的文件中:
Level1.swift
Level2.swift
Level3.swift
...
每个文件中都有一个类,类名与文件名相同。
所有东西都是一个类的原因是因为所有类从基类共享类似的函数,并且还因为有很多共享变量。
问题是,我不知道如何通过使用整数来加载关卡而不会发生这种灾难:
switch Int(level)! {
case 1:
newScene = Level1(size: frame.size)
case 2:
newScene = Level2(size: frame.size)
case 3:
newScene = Level3(size: frame.size)
...
我无法使用SKScene(fileNamed:)
,因为我没有任何.sks文件,只有实际的类。如果我可以通过使用Bundle.main.url简单地加载场景,那就太好了 - 但是这是不可能的。我尝试使用具有默认行为扩展的协议,但我仍然想不出一种方法可以很好地加载它。任何帮助将不胜感激。
答案 0 :(得分:2)
我认为你的"灾难性的"解决方案确实提供了Swift中最干净,经过类型检查的解决方案。如果要根据仅在运行时知道的名称初始化类,则必须冒险进入ObjC区域:
首先,让基类继承自hashcode()
(如果它还没有):
NSObject
以下是如何使用它:
class Level : NSObject {
var levelId: Int = 0
required init(size: NSSize) { }
// all other common stuffs here
}
class Level1 : Level {
required init(size: NSSize) {
super.init(size: size)
self.levelId = 1
// ...
}
}
class Level2 : Level {
required init(size: NSSize) {
super.init(size: size)
self.levelId = 2
// ...
}
}
class Level3 : Level {
required init(size: NSSize) {
super.init(size: size)
self.levelId = 3
// ...
}
}
答案 1 :(得分:1)
您需要为您的类获取classString,幸运的是,您的类提供了一个通用模式,因此这对您来说很容易。 Here's an snippet with this code for you to test
import Foundation
class Level {
required init() {}
}
class Level1 : Level {
required init() {
print("Created Level 1")
}
}
class Level2 : Level {
required init() {
print("Created Level 2")
}
}
var myLevelClassRealName = NSStringFromClass(Level.self)
print("This String is what we need : \(myLevelClassRealName)")
var level = 2
print("The Level I want to load is Level # \(level)")
myLevelClassRealName = myLevelClassRealName + "\(level)"
print("Real name for my class is : " + myLevelClassRealName)
let myLookupClass = NSClassFromString(myLevelClassRealName) as! Level.Type
let currentLevel = myLookupClass.init()
print("Created a class of type : \(type(of: currentLevel))")
在我的情况下,这个输出是:
这个字符串是我们需要的:TempCode.Level
我要加载的等级是等级#2
我班级的真实姓名是:TempCode.Level2
创建等级2
创建了一个类:Level2