gpt4 book ai didi

swift - .sks 文件中 SKSpriteNode 的子类

转载 作者:搜寻专家 更新时间:2023-11-01 05:45:35 27 4
gpt4 key购买 nike

我正在使用 SpriteKit .sks 文件 我可以将 .sks 中的 Sprite 制作成 SKSpriteNode 子类的实例吗?

这是我的子类中的 init 方法:

    init(imageNamed: String) {

let blockTexture = SKTexture(imageNamed: imageNamed)

super.init(texture: blockTexture, color: nil, size: blockTexture.size())
}

在 GameScene.swift 中,我可以创建一个这样的实例:
var myObj = Block(imageNamed: "Block")

我的问题是如何将此实例与 .sks 文件相关联?

我尝试了这行代码,但它不起作用。
myObj     = childNodeWithName("block1") as Block

有什么帮助吗?

谢谢。

最佳答案

这里有几个问题需要解决......
.sks 加载如何工作

当您加载 .sks 文件时,SpriteKit 会使用 NSKeyedUnarchiver 实例化其中的所有内容。这意味着里面的所有节点都被加载为 Xcode 在创建 .sks 文件时指定的任何基类 - SKSpriteNode 用于具有纹理艺术的 Sprite ,SKLabelNode 用于文本,SKFieldNode 用于物理场等。目前 Xcode 没有提供一个选项来为 .sks 文件中的节点设置自定义类。

(对此的一个异常(exception)是更改场景本身的运行时类 — .sks 文件中所有内容的顶级容器。这只是因为项目模板中为您提供的自定义 SKNode.unarchiveFromFile 实现。它在以下位置更改类的技术当存档中只有一个特定类的一个实例时,加载时间有效——对 SKScene 有利,对场景中的许多节点不利。)

类型转换的工作原理

当你写这样的东西时:

myObj = childNodeWithName("block1") as Block

你在告诉编译器这样的事情:“嘿,你知道你从 childNodeWithName 得到的东西吗?你只知道它是一个 SKNode ,但我知道它真的是一个 Block ,所以请让我调用 Block 方法(编译器说,“好吧,随便吧。”)

但是在运行时,你得到的东西最好 真的是 a Block ,否则你的应用程序会崩溃,因为你试图用不是 Block 的东西做一些 Block y 的事情。而且,根据上面加载的 .sks 位,那个东西不是也不能是 Block — Xcode 不知道如何将 Block 放入 .sks 文件中。所以你不能从中得到 Block,所以你的应用程序肯定会崩溃。

解决方法

那么,如果您不能将自定义类放入 .sks 文件中,您能做什么?这在一定程度上取决于您究竟要完成什么。但是有一个很好的技巧,通常也可能是好的游戏/应用程序设计:使用 .sks 文件进行一般布局和配置,并使用第二遍引入需要自定义行为的东西。

例如,如果您在 2D 平台游戏中构建关卡,即使可以,您也不会真的希望 .sks 文件包含 Plumber 类的实例——该类可能有很多关于高度或高度的详细信息这个人很胖,他跳多高, mustache 的形状等等,你不想每次创建新关卡时都重新设置,更不用说在每个关卡的 .sks 文件中再次保存它们.相反,在每个级别文件中您真正需要知道的唯一事情是他开始的位置。因此,在 Xcode 中拖出一个“空节点”,并在加载时,将该节点替换为 Plumber 类的实例,如下所示:
let spawnPoint = childNodeWithName("spawnPoint")
let player = Plumber()
player.position = spawnPoint.position
addChild(player)
spawnPoint.removeFromParent()

如果您想在 .sks 文件中设置更多配置详细信息,则可以考虑自动化该过程。
  • 制作一个执行上述节点交换技巧的方法。 (称之为 replaceNode(_:withNode:) 之类的东西。)
  • 为您的自定义类创建一个初始化程序,它采用 SKNodeSKSpriteNode ,并让它从该节点设置其所有继承属性(或至少您关心的属性,如颜色和纹理)。
  • 使用 enumerateChildNodesWithName:usingBlock: search pattern 查找场景中具有某种名称的所有节点,并将它们替换为使用初始化程序创建的新节点。就像是:
    enumerateChildNodesWithName("//brick_[0-9]*") { node, stop in
    self.replaceNode(node, withNode: BrickBlock(node))
    }
    enumerateChildNodesWithName("//question_[0-9]*") { node, stop in
    self.replaceNode(node, withNode: QuestionBlock(node))
    }
  • 关于swift - .sks 文件中 SKSpriteNode 的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27908165/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com