我正在研究SpriteKit中的元球效果。我有一个带有着色器的SKEffectNode,它可以压缩缓冲区的颜色范围。这个effectnode有一百多个SKSpriteNode作为它的子节点。这种效果在几秒钟内效果很好,但突然间,在几帧的过程中,所有的spritenodes从屏幕上消失,并且nodecount从100-odd下降到2(我猜其余2个是效果节点)本身,以及形成容纳球的容器的边缘链?)
如果我将球spritenodes直接添加到场景的根节点,则不会发生这种情况。只有当他们成为效果节点的孩子时,他们才会在几秒钟之后被淘汰。
有趣的是,(如果帧速率很低,这在模拟器中是可见的)SpriteNodes似乎以屏幕顶部到底部显示在屏幕上的垂直顺序被剔除。
如果视图的showsPhysics
属性设置为true,我可以看到SKSpriteNode的物理实体仍然在屏幕上,并且滚动。但他们的视觉表现已经消失,视图的节点数已经耗尽。根据文档showsNodeCount
“显示在场景中可见的物理实体。”因此,由于节点不再可见,节点数已经减少。
任何人都知道可能导致这种情况的原因,或者我可以使用哪些工具来调试它?
标准SpriteKit iOS Swift 2.2 Xcode 7模板,用以下代码替换GameScene文件:
import SpriteKit
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
// create walls to contain balls
let box = SKPhysicsBody(edgeLoopFromRect: CGRect(x: 0, y: 0, width: 800, height: 800))
let boxNode = SKNode()
boxNode.physicsBody = box
addChild(boxNode)
let radius: CGFloat = 5
let texture = createMetaballTexture(radius)
let centre = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
let rows = 12
let columns = 10
let metaballs = SKEffectNode()
let shaderString = [
"void main()",
"{",
"vec4 c = texture2D(u_texture, v_tex_coord);",
"gl_FragColor = smoothstep(0.3, 0.6, c); ",
"}"].joinWithSeparator("\n")
let map = SKShader(source: shaderString)
metaballs.shader = map
for i in 0...(rows * columns) {
let ball = SKSpriteNode(texture: texture)
let body = SKPhysicsBody(circleOfRadius: radius)
body.friction = 0.1
body.restitution = 0.8
ball.physicsBody = body
ball.position = CGPoint(x: centre.x + CGFloat(i % columns) * radius, y: centre.y + CGFloat(i / rows) * radius)
ball.blendMode = .Add
metaballs.addChild(ball) // change this to "addChild(ball)", and the nodes don't get culled
}
addChild(metaballs)
physicsWorld.speed = 0.2
backgroundColor = SKColor.darkGrayColor()
}
func createMetaballTexture(radius: CGFloat) -> SKTexture {
let metaballScale: CGFloat = 8
let ellipseOrigin = (metaballScale / 2) - 1.5
UIGraphicsBeginImageContext(CGSize(width: radius * metaballScale, height: radius * metaballScale))
let context = UIGraphicsGetCurrentContext()
SKColor.whiteColor().setFill()
CGContextFillEllipseInRect(context, CGRect(x: radius * ellipseOrigin, y: radius * ellipseOrigin, width: radius * 3, height: radius * 3))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return SKTexture(CGImage: blur(image!))
}
}
func blur(image: UIImage) -> CGImage {
let gaussianBlurFilter = CIFilter(name: "CIGaussianBlur")
let inputImage = CIImage(CGImage: image.CGImage!)
gaussianBlurFilter?.setValue(inputImage, forKey:kCIInputImageKey)
gaussianBlurFilter?.setValue(5, forKey: kCIInputRadiusKey)
let outputImage = gaussianBlurFilter?.outputImage
let context = CIContext(options: nil)
return context.createCGImage(outputImage!, fromRect: inputImage.extent)
}