比较SceneKit中不同物体的颜色

Comparing the colors of different objects in SceneKit

我正在使用 SceneKit 开发一个简单的游戏。在创建了一个 nxn 球体网格(每个球体具有五种随机颜色中的一种)之后,玩家连续选择其中三个,如果它们具有相同的颜色,则将它们从网格中移除。我对代码的选择部分很好,但我无法比较三重奏的颜色来检查它是否有效。我使用的函数是

func respondToPanGesture(gesture: UIGestureRecognizer) {

    var colorsTrio = Array<NSObject>()

    var numberOfWhiteSpheres: Int {
        var count = 0   
        for child in scnView.scene!.rootNode.childNodes {
            let materials = child.geometry?!.materials as! [SCNMaterial]
            let material = materials[0]
            if  material.diffuse.contents as! NSObject == UIColor.whiteColor(){
                count++
            }
        }
        return count
    }

    if let panGesture = gesture as? UIPanGestureRecognizer {

        let location = gesture.locationInView(scnView)

        let hitResults = scnView.hitTest(location, options: nil)
        if hitResults?.count > 0 && (numberOfWhiteSpheres < 3) {
            let result = hitResults![0] as! SCNHitTestResult
            let node = result.node
            SCNTransaction.begin()
            SCNTransaction.setAnimationDuration(1.0)
            let materials = node.geometry?.materials as! [SCNMaterial]
            let material = materials[0]
            colorsTrio.append(material.diffuse.contents as! [UIColor])
            material.diffuse.contents = UIColor.whiteColor()
            SCNTransaction.commit()

        }
    }
}

我的想法是将我的球体的颜色属性存储在一个数组中,然后使用另一个函数比较它们。我可以成功构建程序,但是一旦我开始选择其中一个球体,我就会遇到以下错误:"Could not cast value of type 'UICachedDeviceRGBColor' (0x101ebfd80) to 'NSArray' (0x100af4470)." 我知道无法将 属性 附加到我的数组。关于如何规避此问题的任何想法?

你正在吃 material.diffuse.contents[UIColor](即一组颜色)。不应该只是 UIColor 吗?

material.diffuse.contents as! UIColor

您因为这一行而收到该错误:

colorsTrio.append(material.diffuse.contents as! [UIColor])

material.diffuse.contents 中的对象是 UIColor(的子类)的单个实例,您正试图将其转换为 UIColor 的实例数组。 Array.append 方法将一个元素作为其参数,而不是另一个元素数组,因此您可以通过更改转换来修复此错误:

colorsTrio.append(material.diffuse.contents as! UIColor)

但是,这仍然不是一个好主意。 比较颜色是一件非常模糊的事情。 (对于您的目的,#FF0000#FE0000 的红色真的不同吗?不同颜色空间中的相同 RGB 值怎么样?)在您描述的程序中,您有一些具有语义的颜色它们含义上的区别——你关心的是红色球体和蓝色球体之间的区别,而不是颜色空间和分量值之间的细微区别。

在任何游戏中,让游戏玩法模型独立于显示器是个好主意 — 您希望能够独立于将球体放在屏幕上的代码来测试匹配球体的逻辑。因此,制作一个包含语义颜色值的模型。例如:

enum Color {
    case Red, Yellow, White /* ... etc ... */
}
class GameNode: SCNNode {
    var color: Color
    // ...
}

// elsewhere...
let hitResults = scnView.hitTest(location, options: nil) as! [SCNHitTestResult]
if let result = hitResults.first {
    if let node = result.node as GameNode {
        colorsTrio.append(node.color)
        // ...
    }
}

// still elsewhere...
if (colorsTrio[0] == colorsTrio[1] && colorsTrio[1] == colorsTrio[2]) {
    // match!
}