图像文件夹:创建并填充 SKShapeNodes,每个节点 1 个

Folder of images: create and fill SKShapeNodes, 1 of each

是否可以创建一个文件夹并让 SpriteKit 遍历该文件夹,找到每个图像(不管名称),并为该文件夹中的每个图像创建一个 SKShapeNode(无论有多少)?

假设所有图像大小相同,所有 .png 文件准备用作唯一图像作为填充 SKShapeNode 的纹理,并且所有 SKShapeNode 大小相同。

我想知道,一旦完成,已经创建了多少个形状,并根据所使用的纹理图像的名称对它们进行唯一命名。

但我正在阅读的所有内容似乎都是关于事先知道有多少图像以及它们的名称。

不知道从哪里开始搜索如何执行此操作。

更新:不知道如何用图像引用 "folder":

我已经将这些图片连同它们极具想象力的名称 [一、二、三、四、五等] 一起转储到文件夹中 "atlas",如下所示:

但根据 Allessandro 的精彩回答,我不知道如何解决这个问题 "folder" 并了解其中的内容。

我认为是这一行我完全错了:

let folderPath = Bundle.main.path(forResource: "Images", ofType: nil)

我不知道用什么替换 "Images"

更新 2:

找到了一种更简单的方法:

let myTextureAtlas = SKTextureAtlas(named: "demoArt")

        print(myTextureAtlas)
        print(myTextureAtlas.textureNames)

请求太多,所以我试着用一些代码来帮助你:

创建文件夹:

func createDir(folderName:String) {
        let fileManager = FileManager.default
        if let directory = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "APP_GROUP_IDENTIFIER") {
            let newDirectory = directory.appendingPathComponent(folderName)
            try! fileManager.createDirectory(at: newDirectory, withIntermediateDirectories: false, attributes: nil)
        }
}

现在您有了自己的文件夹,因此您可以决定是保存文件还是将一个文件从文档复制到这个新目录。最后一个我打个比方。

复制文件:

let fileManager = FileManager.default
do {
   try fileManager.copyItem(atPath: "hero.png", toPath: "subfolder/hero.swift")
}
catch let error as NSError {
   print("Something went wrong: \(error)")
}

现在您想知道如何从目录中提取所有文件。

从目录中提取所有文件:

func extractAllFile(atPath path: String, withExtension fileExtension:String) -> [String] {
        let pathURL = NSURL(fileURLWithPath: path, isDirectory: true)
        var allFiles: [String] = []
        let fileManager = FileManager.default
        if let enumerator = fileManager.enumerator(atPath: path) {
            for file in enumerator {
                if #available(iOS 9.0, *) {
                    if let path = NSURL(fileURLWithPath: file as! String, relativeTo: pathURL as URL).path
                        , path.hasSuffix(".\(fileExtension)"){
                        allFiles.append(path)
                    }
                } else {
                    // Fallback on earlier versions
                }
            }
        }
        return allFiles
    }

用法:

let folderPath = Bundle.main.path(forResource: "Images", ofType: nil)
let allPngFiles = extractAllFile(atPath: folderPath!, withExtension: "png") // returns file path of all the png files inside the folder

之后,您可以使用 fillTextureallPngFiles 创建一个 SKShapeNode 的数组,并使用从每个图像创建的 SKTexture 并为每个节点提供 name使用的文件的数量(所以你最后也知道你从 array.count 创建了多少节点)。

这里的答案略有不同。我不确定为什么需要创建目录并复制文件。在您的屏幕截图中,您有一个包含 7 个文件(one.png、two.png 等)的 demoArt.atlas。您表示要生成 SKShapeNode。我仍然不清楚为什么要 SKShapeNode,但忽略它,您只需要知道文件夹名称即可。您会注意到文件夹是蓝色的,这意味着它是一个参考。这意味着在图像中,文件夹被保留。

这将为您提供该目录中的所有文件:

let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let texPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent("demoArt.atlas")

let filemanager:FileManager = FileManager()
// Error check/ensure path exists
let files = filemanager.enumerator(atPath:texPath!.path)

while let file = files?.nextObject() {
    print(file)
    // Create your SKShapeNode here, you can load file from this
    // This is all relative path, so "file" would be one.png, two.png, etc. If you need the full path, you
    // need to prepend texPath
}

注意这里的关键差异不是复制文件。也许我只是不明白这个问题以及为什么它需要副本。

如果你想把它放在一个数组中,你可以。但是在这里你会有你当然需要加载的纹理文件名。

实际上,您想先异步加载这些纹理,然后构建您的 SKShapeNode