iOS Swift SpriteKit:如何使子精灵节点的位置和动作与其父精灵节点相同?

Posted

技术标签:

【中文标题】iOS Swift SpriteKit:如何使子精灵节点的位置和动作与其父精灵节点相同?【英文标题】:iOS Swift SpriteKit: How to make a child spritenode's position and movements to be the same as its parent spritenode? 【发布时间】:2018-08-20 16:05:38 【问题描述】:

我想实现一个带有“彩色高亮”的 spritenode。 “突出显示可以有多种颜色。这是在沙盒应用程序中完成的。

我考虑过使用 SKTextures 来表示节点的“亮点”。但是,使用这种方法,我将不得不上传一些必须“预先附加”到主机 spritenode png 文件的“突出显示”文件。所以,如果我有 5 个 spritenode “host” png 文件和 5 个 “highlight” png 文件,那么我总共将有 5x5=25 个 png 文件,代表所有可能的组合。准备和维护的文件太多了。

所以,我宁愿让 spritenode“宿主”有一个子 spritenode,这是亮点。

主机和高亮精灵节点都需要一起移动,高亮精灵节点在“主机”精灵节点前面 1 zPosition。所以,2个精灵节点的cgposition应该是一样的。

我为宿主 spritenode 创建了一个 Class 文件。

class Host : SKSpriteNode 

    var highlight = SKSpriteNode()
        init(strPieceName : String)  
        let texture = SKTexture(imageNamed: strPieceName)
        super.init(texture: texture, color: UIColor.clear, size: texture.size())

    

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

    func addHighlight(withColour strColour : String) 

        highlight = SKSpriteNode(imageNamed: strColour)
        addChild(highlight)
            

在GameScene类中,我调用touchesBegan中的addHighlight函数

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

    for t in touches 

        let cgPointTouched = t.location(in: self)
        let skNodeTouched : SKNode = self.atPoint(cgPointTouched)
        switch skNodeTouched.name 
        case "Highlight":
         host.highlight.position = skNodeTouched.position
         host.highlight.anchorPoint = CGPoint(x: 0.5, y: 0.5)
         host.highlight.size = CGSize(width: 0.2, height: 0.2)
         host.highlight.alpha = 1
         host.highlight.zPosition = 3
         addChild(host.highlight)
    
    
 

这段代码的问题在于,虽然高亮精灵节点“跟随”了宿主精灵节点,但高亮精灵节点的位置的屏幕外观并不在宿主精灵节点的“顶部”。但奇怪的是,2个精灵节点的cgposition是一样的。

我认为它可以协调 GameScene 和 Highlight 类的系统不同,但我不知道如何解决这个问题以及为什么会发生这种情况。

【问题讨论】:

【参考方案1】:

不知道你为什么要做所有这些复杂的事情,但你不应该触及这个位置。将其保留为 0,0,并且永远不要将其添加到场景中。而是将它留在精灵上,它会一直跟随你的精灵。

当然,您可以随时使用colorBlendFactor 将精灵颜色与您的纹理混合以创建高光

你的班级应该是这样的:

class Host : SKSpriteNode 

    var highlight : SKSpriteNode!

    func addHighlight(withColour strColour : String) 
        highlight.removeFromParent()
        highlight = SKSpriteNode(imageNamed: strColour)
        //highlight.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        highlight.size = CGSize(width: 0.2, height: 0.2)
        //highlight.alpha = 1
        highlight.zPosition = 3

        highlight.moveToParent(self)
            


无需添加与其他初始化完全相同的额外初始化

您的触摸代码应如下所示:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

    for t in touches 

        let cgPointTouched = t.location(in: self)
        let skNodeTouched : SKNode = self.atPoint(cgPointTouched)
        switch skNodeTouched.name 
            case "Highlight":
            host.addHighlight(withColour:"whatevermycoloris")
        
    
 

当然,您总是可以通过这样做来避免多余的节点:

class Host : SKSpriteNode 

    func addHighlight(withColour : UIColor) 
        color = withColour
        colorBlendFactor = 0.75 //Change this intensity to 1 to add more color
            


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

    for t in touches 

        let cgPointTouched = t.location(in: self)
        let skNodeTouched : SKNode = self.atPoint(cgPointTouched)
        switch skNodeTouched.name 
            case "Highlight":
            host.addHighlight(withColour:UIColor.yellow)
        
    
 

【讨论】:

colorBlendFactor 没有达到我想要的效果,但值得一试。谢谢。 SKSpriteNode 方法,有两个问题,一是高亮节点的位置仍未与主机节点的位置对齐。所以我将addHighlight() 函数更改为接受位置参数,并传递skNodeTouched 的cgposition。这解决了位置问题。第二个问题是无论我使用什么 zPosition,Highlight 节点总是出现在 Host 节点的“顶部”。我希望突出显示节点位于主机节点的“后面”。谢谢。 什么和什么?你没有在你的问题中指定任何一个 如果位置与您的主机节点不对齐,那么您的主机节点被顶起,因为它实际上是假设挂在您的主机节点上,我建议修复您的主机。如果您希望突出显示在您的主机后面(那么您没有突出显示它)使 zPosition -1 现在我又在读这个了,你把 cgPointTouched 传递给你的亮点了吗?这意味着你的亮点在现场,而不是像我告诉你的那样在主持人身上

以上是关于iOS Swift SpriteKit:如何使子精灵节点的位置和动作与其父精灵节点相同?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 swift 使用带有 spriteKit 的情节提要

相交节点 ---- Objective-C - Swift - iOS - SpriteKit 节点

如何使用 Swift 5 在 SpriteKit 中以某个角度应用Impulse?

SKPhysics 与 Swift 和 SpriteKit

这个带有 SpriteKit 代码的 Swift 没有达到预期的效果

通过在 SpriteKit/Swift 中向上滑动来跳跃角色