【发布时间】:2021-05-15 15:12:17
【问题描述】:
我迈出第一步进入 SpriteKt 并发现 SkSpriteNode.position 属性的这种明显奇怪的行为:它应该是 CGPoint,但是在分配和读回时,它的行为与任何其他 CGPoint 不同。
在下面的代码中,我测试了一些随机选择的点。其中一些可以分配给SkSpriteNode.position 属性并再次读取,一切似乎都正常。
其他一些,当分配时,被四舍五入到一些其他(接近)值。
这可能是一个浮点值表示四舍五入的问题,但更奇怪的是:完全相同的CGPoint,当分配给另一个CGPoint(而不是position属性,顺便说一句,声称是CGPoint) 没有出现四舍五入????
有人知道怎么回事吗?
check(position: CGPoint.zero)
check(position: CGPoint(x: 1, y: 1))
check(position: CGPoint(x: 100, y: 700))
check(position: CGPoint(x: -500, y: 200))
check(position: CGPoint(x: 0.5, y: 0.5))
check(position: CGPoint(x: 1.12, y: 1.14))
check(position: CGPoint(x: 1.12, y: 1.1415161718))
func check(position: CGPoint) {
let sprite = SKSpriteNode(color: .cyan, size: CGSize(width: 32, height: 32))
let point = position
sprite.position = position
print("position = \(position)")
print("point = \(point)")
print("sprite = \(sprite.position)")
if sprite.position == position {
print("✅ they match")
} else {
print("❌ they don't match")
}
assert(position == point, "assign \(position) to point result in \(point)")
}
在我的系统上(Xcode 版本 12.5 (12E262))输出是:
position = (0.0, 0.0)
point = (0.0, 0.0)
sprite = (0.0, 0.0)
✅ they match
position = (1.0, 1.0)
point = (1.0, 1.0)
sprite = (1.0, 1.0)
✅ they match
position = (100.0, 700.0)
point = (100.0, 700.0)
sprite = (100.0, 700.0)
✅ they match
position = (-500.0, 200.0)
point = (-500.0, 200.0)
sprite = (-500.0, 200.0)
✅ they match
position = (0.5, 0.5)
point = (0.5, 0.5)
sprite = (0.5, 0.5)
✅ they match
position = (1.12, 1.14)
point = (1.12, 1.14)
sprite = (1.1200000047683716, 1.1399999856948853)
❌ they don't match
position = (1.12, 1.1415161718)
point = (1.12, 1.1415161718)
sprite = (1.1200000047683716, 1.1415162086486816)
❌ they don't match
【问题讨论】:
-
1.12 和 1.14 是经典的浮点问题以及随之而来的不准确性。我对您的“点”变量的猜测是它只是存储对 CGPoint 位置的内存地址的引用,而不是实际复制或用它做任何事情。而 sprite.position 不会引用 CGPoint 位置,而是创建/复制它自己版本的 CGPoint 位置到内存的新部分。这就是浮点问题的来源。无论如何,这是我最好的猜测。
-
感谢@JohnL 的回复!据我所知, CGPoint 应该是一个结构,除非编译器做了一些疯狂的事情,否则当你将一个值类型分配给另一个值类型时,理论上内容会被复制。也许我错了,但 Swift 编译器使用更改时复制策略对此进行了优化。这对于
point变量和position属性都应该成立。
标签: swift floating-point sprite-kit cgpoint