我如何(有效地)测试 SKTexture 的可见内容?
How can I (efficiently) test an SKTexture for visible content?
我的应用目前使用 SpriteKit 制作了数千个 "mini textures" 动画。每个感兴趣的对象的转换过程是 UIView 到 UIImage 到 SKTexture 到很多很多非常小的 SKTextures(miniTextures)。我遇到的问题是如何仅进一步处理那些 "useful."
的 miniTexture
许多迷你纹理来自 object/view/image/texture 的空白部分,不包含任何有用的视觉信息(即,它们是空白的)。因此,为它们设置动画是一种浪费。问题是,我不知道对此有任何好的、有效的测试。我曾希望能够以某种方式检查每个纹理的像素,如果纹理中的每个像素的 alpha 值为 0,则该纹理将不会被处理(即,不会为其创建 SKSpriteNode)。
作为一种变通方法,我尝试使用 SKPhysicsBody(texture: alphaThreshold: size:) 为每个 miniTexture 创建一个 SKPhysicsBody(参见下面的代码),当纹理中没有任何内容超过 alphaThreshold 时 returns nil。那可能至少让我能够测试并有选择地处理有用的 miniTexture。但是在这样做的时候,我 运行 遇到了两个问题:首先,模拟器变慢到几乎停止。其次,当把贴图做的很小的时候,不管我的alphaThreshold是多少,都确定为nil。
见解?解决方案?同情?
for j in stride(from: 0, to: 1, by: yFraction) {
for i in stride(from: 0, to: 1, by: xFraction) {
let miniTexture = SKTexture(rect: CGRect(x: CGFloat(i),
y: CGFloat(j),
width: CGFloat(xFraction),
height: CGFloat(yFraction)),
in: texture)
spriteNode.physicsBody = SKPhysicsBody(texture: miniTexture,
alphaThreshold: 0.5,
size: CGSize(width: 1,
height: 1))
// BUT WHEN THE miniTextures ARE VERY SMALL, THESE ALL ARE NIL!
// AND THE ANIMATION COMES TO A VIRTUAL STANDSTILL!
if spriteNode.physicsBody == 0 { continue }
// spriteNode.position details here
// spritNode.run(specificAnimation) details here
let spriteNode = SKSpriteNode(texture: miniTexture)
spriteNodes.addChild(spriteNode)
}
}
事实证明,SpriteKit 已经默认剔除不可见和屏幕外的节点,这可能就是为什么我的应用程序在没有测试和删除完全透明的 SKSpriteNodes 的情况下表现不佳的原因。 (但也许我的理解是错误的,if by "invisible" Apple means "set to isHidden.")
Apple 的 shouldCullNonVisibleNodes 实例文档 属性(默认值为 true)是 here。
更好的上游解决方案是在创建images/textures之前测试隐身性,但这需要对低级iOS 图形操作比我现在拥有的更多。
我的应用目前使用 SpriteKit 制作了数千个 "mini textures" 动画。每个感兴趣的对象的转换过程是 UIView 到 UIImage 到 SKTexture 到很多很多非常小的 SKTextures(miniTextures)。我遇到的问题是如何仅进一步处理那些 "useful."
的 miniTexture许多迷你纹理来自 object/view/image/texture 的空白部分,不包含任何有用的视觉信息(即,它们是空白的)。因此,为它们设置动画是一种浪费。问题是,我不知道对此有任何好的、有效的测试。我曾希望能够以某种方式检查每个纹理的像素,如果纹理中的每个像素的 alpha 值为 0,则该纹理将不会被处理(即,不会为其创建 SKSpriteNode)。
作为一种变通方法,我尝试使用 SKPhysicsBody(texture: alphaThreshold: size:) 为每个 miniTexture 创建一个 SKPhysicsBody(参见下面的代码),当纹理中没有任何内容超过 alphaThreshold 时 returns nil。那可能至少让我能够测试并有选择地处理有用的 miniTexture。但是在这样做的时候,我 运行 遇到了两个问题:首先,模拟器变慢到几乎停止。其次,当把贴图做的很小的时候,不管我的alphaThreshold是多少,都确定为nil。
见解?解决方案?同情?
for j in stride(from: 0, to: 1, by: yFraction) {
for i in stride(from: 0, to: 1, by: xFraction) {
let miniTexture = SKTexture(rect: CGRect(x: CGFloat(i),
y: CGFloat(j),
width: CGFloat(xFraction),
height: CGFloat(yFraction)),
in: texture)
spriteNode.physicsBody = SKPhysicsBody(texture: miniTexture,
alphaThreshold: 0.5,
size: CGSize(width: 1,
height: 1))
// BUT WHEN THE miniTextures ARE VERY SMALL, THESE ALL ARE NIL!
// AND THE ANIMATION COMES TO A VIRTUAL STANDSTILL!
if spriteNode.physicsBody == 0 { continue }
// spriteNode.position details here
// spritNode.run(specificAnimation) details here
let spriteNode = SKSpriteNode(texture: miniTexture)
spriteNodes.addChild(spriteNode)
}
}
事实证明,SpriteKit 已经默认剔除不可见和屏幕外的节点,这可能就是为什么我的应用程序在没有测试和删除完全透明的 SKSpriteNodes 的情况下表现不佳的原因。 (但也许我的理解是错误的,if by "invisible" Apple means "set to isHidden.")
Apple 的 shouldCullNonVisibleNodes 实例文档 属性(默认值为 true)是 here。
更好的上游解决方案是在创建images/textures之前测试隐身性,但这需要对低级iOS 图形操作比我现在拥有的更多。