将物理应用到自定义 SKSpriteNode 类
Posted
技术标签:
【中文标题】将物理应用到自定义 SKSpriteNode 类【英文标题】:apply physics to a custom SKSpriteNode class 【发布时间】:2016-12-19 18:18:57 【问题描述】:我想以更有序和更清晰的方式设置我的 SpriteKit 游戏,因此我决定为每种类型的精灵节点使用类。
在我的例子中,我在 swift 中创建了一个单独的 Player 类,看起来像这样
import SpriteKit
class Player: SKSpriteNode
func initializePlayer()
self.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.size.width, height: self.size.height))
self.physicsBody?.affectedByGravity = true
func moveLeft ()
print("left")
func moveRight ()
print("right")
我在场景编辑器的自定义类检查器中正确引用了这个 Sprite 节点,我可以毫无问题地触发类方法 - 所以效果很好。
我像这样在我的 GameScene 中引用 Player 类:
class GameplayScene: SKScene
var player: Player = Player()
let myNode = SKSpriteNode(imageNamed: "player")
override func didMove(to view: SKView)
player.initializePlayer()
但是没有应用物理体,我不知道为什么会这样。
在我将物理体添加到精灵节点后,我希望节点会从屏幕上掉下来。但这不会发生,我不知道为什么。
有人知道如何在课堂上应用物理体吗?
【问题讨论】:
你说的物理体没有应用是什么意思? 在我将物理体添加到精灵节点后,我希望节点从屏幕上掉下来。但这不会发生,我不知道为什么。 我在发布的代码中看不到,您只是将物理体添加到 self.更具体并发布更多代码。 @Mina 感谢您的反馈,我更新了我的描述,希望我的问题现在更清楚一点 在调用initializePlayer()
之前是否设置了节点的大小?也许物理体的大小是 0x0 并引起了问题?
【参考方案1】:
我可以用 initializePlayer
以外的其他名称调用您的函数,这与实现的代码更相关:
func setPhysics()
self.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.size.width, height: self.size.height))
self.physicsBody?.affectedByGravity = true
之后,如果您想从场景编辑器中检索您的精灵,您可以使用:
if let node = self.childNode(withName:"//mySpriteNodeName") as? Player
// Set up your sprite here
node.setPhysics()
P.S.:我还添加了//
:这指定搜索应该从根节点开始,并在整个节点树中递归执行。否则,它会从当前位置执行递归搜索。
【讨论】:
感谢您的支持。我尝试了您的方法,但仍然从所需的 init 方法中得到相同的错误。 @Mina 向我推荐的解决方案是我不明白的,我不知道如何解决这个问题。你觉得你可以再看看吗? 在 Mina 代码的第一部分中,她向您解释了如何将 Player 类构建为 SKSpriteNode 子类,但您也可以决定不覆盖 init 方法并构建其他自定义函数离开原始的 init 函数保持不变。【参考方案2】:问题是你没有在 SKSpriteNode 内置的 init 函数中初始化你的播放器节点。
使用以下代码:
init()
let texture = SKTexture(imageNamed: "Spaceship")
super.init(texture: texture, color: UIColor.blue, size: texture.size())
self.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.size.width, height: self.size.height))
self.physicsBody?.affectedByGravity = true
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
fatalError("init(coder:) has not been implemented")
代替:
func initializePlayer()
self.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.size.width, height: self.size.height))
self.physicsBody?.affectedByGravity = true
它将解决您的问题并正确应用物理体。
【讨论】:
这在我的情况下不起作用。编译器会抛出一个错误:“致命错误:init(coder:) 尚未实现:file / Player.swift 此外,我不需要也不想在启动实例时指定纹理。我想从在 SceneEditor 中。 我已经测试过了,它一定不会出错。但是你可以使用这个thread来解决这个错误。 @Mina 您的代码是正确的,但 OP 遇到该错误,因为 initWIthCoder: 被调用。这是因为他从 .sks 文件加载 Player。 @Whirlwind 这是什么意思?你可以解释吗?我想不出一个解决方案:-/以上是关于将物理应用到自定义 SKSpriteNode 类的主要内容,如果未能解决你的问题,请参考以下文章