我正在使用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()
}
}
}
我的想法是将我的球体的颜色属性存储在一个数组中,然后使用另一个函数比较它们。我可以成功构建程序,但是一旦我开始选择其中一个领域,我会遇到以下错误:“无法将'UICachedDeviceRGBColor'类型的值(0x101ebfd80)转换为'NSArray'(0x100af4470)。”我知道将该属性附加到我的数组是不可能的。关于如何规避这个问题的任何想法?
答案 0 :(得分:1)
你正在吃material.diffuse.contents
到[UIColor]
(即一系列颜色)。难道不仅仅是UIColor
吗?
material.diffuse.contents as! UIColor
答案 1 :(得分:1)
由于这一行,你得到了这个错误:
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!
}