【问题标题】:How to give to sprite exact touch place?如何给精灵精确的触摸位置?
【发布时间】:2020-04-14 14:00:23
【问题描述】:

我的问题是

当我触摸黑色箭头区域时,我仍然会触摸整个图片,但我只想在 仅触摸红色区域时触摸并进行操作。 我试图为 spriteNode plane = childNode(withName: "play") 命名,但它不仅占用/触摸所有图像帧 alphaBody。

red and black areas

我在谷歌上进行了一些搜索,但没有得到肯定的结果。

非常感谢。

【问题讨论】:

    标签: ios swift sprite-kit textures skspritenode


    【解决方案1】:

    一个非常简单的解决方案可能是在您的平面对象上放置命中测试区域(我在示例中将它们稍微保留为红色,但您可以让它们透明)。我在编辑器中创建了我的飞机类并将其作为参考拖到我的场景中,但您也可以轻松地从头开始对命中区域进行编程。

    然后在您的平面类中将它们添加到平面并检测平面类本身的触摸。这并不准确,但与图片中的 alpha 跟踪相差不远。

    这种方法的一个很好的好处是您可以将这种接触隔离到平面的区域。一些用途可能是......

    • 触摸左/右翼来转向那个方向
    • 触摸身体加油
    • 触摸翅膀换枪

    这是我在 Plane 类中使用的代码

    class Plane: SKSpriteNode {
    
        private var background: SKSpriteNode!
        private var wingsHitTest: SKSpriteNode!
        private var bodyHitTest: SKSpriteNode!
        private var smallWingsHitTest: SKSpriteNode!
    
        init() {
    
            super.init(texture: nil, color: .clear, size: CGSize.zero)
        }
    
        required init?(coder aDecoder: NSCoder) {
    
            super.init(coder: aDecoder)
            setup()
        }
    
        func setup() {
    
            isUserInteractionEnabled = true
            self.color = .clear
    
            if let background = self.childNode(withName: "//background") as? SKSpriteNode {
                self.background = background
            }
    
            if let wingsHitTest = self.childNode(withName: "//wingsHitTest") as? SKSpriteNode {
                self.wingsHitTest = wingsHitTest
            }
    
            if let bodyHitTest = self.childNode(withName: "//bodyHitTest") as? SKSpriteNode {
                self.bodyHitTest = bodyHitTest
            }
    
            if let smallWingsHitTest = self.childNode(withName: "//smallWingsHitTest") as? SKSpriteNode {
                self.smallWingsHitTest = smallWingsHitTest
            }
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            if let touch = touches.first as UITouch? {
    
                let touchLocation = touch.location(in: self)
    
                if wingsHitTest.contains(touchLocation) {
                    print("hit in the wings")
                }
                else if smallWingsHitTest.contains(touchLocation) {
                    print("hit in the back wings")
                }
                else if bodyHitTest.contains(touchLocation) {
                    print("hit in the body")
                }
            }
        }
    }
    

    【讨论】:

    • 很高兴它对你有用,请检查它是否正确,以便其他人可以从这个问题和答案中受益
    • 并且没有其他选项可以使用完整的纹理形状,包括现在不可触摸的部分?
    【解决方案2】:

    It seems like SpriteKit 中不包含您想要的行为,因此您必须自己实现它。

    引用上面的链接:

    您必须找出 UITouch 对象对象的 locationInNode(spriteNode) 以获取精灵内的坐标,然后从精灵图像中读取 alpha 值(不平凡)或预先计算位掩码(一和零)您的图像并读取精灵位掩码中相应点的值

    因此,您需要将图像加载为 UIImage 或 CGImage 并检查发生触摸的像素处的颜色是否透明。您可以在此问题中找到有关如何执行此操作的更多信息:How to get pixel color from SKSpriteNode or from SKTexture?

    【讨论】:

    • 哇这也是一个好方法,谢谢你也打开了我的心。谢谢你的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多