SKSpriteNode 卡在 init(edgeLoopF​​rom:) - SKPhysicsBody

Posted

技术标签:

【中文标题】SKSpriteNode 卡在 init(edgeLoopF​​rom:) - SKPhysicsBody【英文标题】:SKSpriteNode Stuck with init(edgeLoopFrom:) - SKPhysicsBody 【发布时间】:2017-12-12 18:25:59 【问题描述】:

我在下面有一个名为“Floor”的单独类。

class Floor: SKNode 
    override init() 
        super.init()
        //let edgeFrame = CGRect(origin: CGPoint(x: 1,y: 1), size: CGSize(width: 1078, height: 1950))
        //self.physicsBody = SKPhysicsBody(edgeLoopFrom: edgeFrame)

        let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        borderBody.friction = 0
        self.physicsBody = borderBody

        // Apply a physics body to the node
       // self.physicsBody?.isDynamic = false

        // Set the bit mask properties
        self.physicsBody?.categoryBitMask = floorCategory
        self.physicsBody?.contactTestBitMask = nailDropCategory
        self.physicsBody?.collisionBitMask = balloonCategory
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemted")
    

我基本上有下降的 SKSpriteNode,它从屏幕顶部开始并到达底部,它接触“地板”并自行移除,然后再次从顶部重新启动。我遇到的问题是我所有的 SKSpriteNode 都一直卡在顶部,而不是从屏幕框架周围的边框掉下来。如何告诉我的应用程序忽略这些特定节点并让它们进入?感谢任何帮助!


这是在屏幕上左右移动的对象,但它只是从屏幕的一侧掉下来,没有边缘循环

if let accelerometerData = motionManager.accelerometerData 
            if UIDevice.current.orientation == UIDeviceOrientation.landscapeLeft 
                balloon.physicsBody?.velocity = CGVector(dx: accelerometerData.acceleration.x * -500.0, dy: 0)
             else 
                balloon.physicsBody?.velocity = CGVector(dx: accelerometerData.acceleration.x * 500.0, dy: 0)
                
            
        

【问题讨论】:

【参考方案1】:

正在发生的事情是您的对象正在触及边缘循环的顶部边界并且无法进入场景。

有几种方法可以做到这一点,如果你绝对需要两侧的边缘循环,我建议将循环拉长到高于场景并在循环内但在可见区域上方创建对象。但是,由于您没有给出任何迹象表明您实际上需要两侧的循环,所以我要做的就是摆脱边缘循环检测。

创建一个与场景宽度相同的框,并设置为 100 像素高,然后在其上放置一个 floorCategory 类型的物理体。然后将此框放在屏幕底部下方 50 px 处。假设您的地板精灵框的锚点为 0.5,0.5 这会将框隐藏在屏幕下方,并且框的顶部将与屏幕底部齐平。

现在您将能够检测到您的对象何时触及屏幕底部,您将不再需要担心它们会通过顶部的边缘循环。

拉长循环的一个例子是......

您创建一个比屏幕高的矩形(图像中的绿色边框)来应用边缘循环,而不是屏幕大小本身

【讨论】:

一个问题是我在显示器底部有一个 SKSpriteNode 图像,它基本上可以躲避从顶部掉落的物体。老实说,我只是拥有 edgeLoop,因此底部的对象不会离开屏幕,因为自从我更新了 Xcode 9 并且不得不为 iPhone X 更新我的应用程序后,它现在就这样了。如果我能知道如何保护我的节点不离开屏幕的一侧以及检测物体何时从屏幕顶部掉落并掉落到底部并撞击“地板”并移除但我似乎无法弄清楚。不过你的回答很有帮助! 如果有帮助的话,我已经添加了一张用于拉长循环的图片 我明白你在说什么 Rob,基本上不是在整个框架周围创建边界,我只需要在屏幕的最底部进行。也就是说,这个框有助于将 SKSpriteNode 图像保持在屏幕底部(不在下方),当我向左或向右倾斜 iPhone 时,它​​会滑出屏幕,因为这就是我设置节点的方式。如果我能知道如何将该节点设置在屏幕上,而不是在整个框架周围和底部设置边缘循环,那么我很乐意这样做 是 Ron ;) Rob 是另一个人。这就是为什么我添加了图像来向您展示另一种选择,它仍然可以为您提供边缘循环,但允许您将项目放在屏幕上 仅供参考,边缘循环比实心盒子更昂贵,因此您可能只想在侧面放置 2 个缓冲节点,在底部放置一个移除节点

以上是关于SKSpriteNode 卡在 init(edgeLoopF​​rom:) - SKPhysicsBody的主要内容,如果未能解决你的问题,请参考以下文章

SKSpriteNode 未更新

使用 Swift 创建 SKSpriteNode 子类

如何在 init() 之前获取屏幕尺寸?

编辑 SKSpriteNode 自定义类的属性?

为啥 SKSpriteNode(fileNamed:) 使用 Swift 在 iOS 中生成 nil?

卡在 "init 终止于 do_boot",undef,[rmbrDb,start,[],[],